From dbe62fd1caeda010698342709e96e8272e83d1c1 Mon Sep 17 00:00:00 2001
From: jkito <belter@riseup.net>
Date: Fri, 5 Jul 2024 01:30:19 +0530
Subject: [PATCH] chore: update vendor after go version update

---
 go.mod                                        |    86 +-
 go.sum                                        |   328 +-
 .../github.com/andybalholm/brotli/README.md   |     7 +
 .../andybalholm/brotli/bitwriter.go           |    56 +
 .../andybalholm/brotli/brotli_bit_stream.go   |   311 +-
 .../brotli/compress_fragment_two_pass.go      |    51 +-
 .../github.com/andybalholm/brotli/encoder.go  |   168 +
 .../brotli/entropy_encode_static.go           |     5 +
 vendor/github.com/andybalholm/brotli/http.go  |    10 +-
 .../andybalholm/brotli/matchfinder/emitter.go |    45 +
 .../andybalholm/brotli/matchfinder/m0.go      |   169 +
 .../andybalholm/brotli/matchfinder/m4.go      |   297 +
 .../brotli/matchfinder/matchfinder.go         |   103 +
 .../brotli/matchfinder/textencoder.go         |    53 +
 .../github.com/andybalholm/brotli/writer.go   |    43 +
 vendor/github.com/cloudflare/circl/LICENSE    |    57 +
 .../cloudflare/circl/dh/x25519/curve.go       |    96 +
 .../cloudflare/circl/dh/x25519/curve_amd64.go |    30 +
 .../cloudflare/circl/dh/x25519/curve_amd64.h  |   111 +
 .../cloudflare/circl/dh/x25519/curve_amd64.s  |   157 +
 .../circl/dh/x25519/curve_generic.go          |    85 +
 .../cloudflare/circl/dh/x25519/curve_noasm.go |    11 +
 .../cloudflare/circl/dh/x25519/doc.go         |    19 +
 .../cloudflare/circl/dh/x25519/key.go         |    47 +
 .../cloudflare/circl/dh/x25519/table.go       |   268 +
 .../cloudflare/circl/dh/x448/curve.go         |   104 +
 .../cloudflare/circl/dh/x448/curve_amd64.go   |    30 +
 .../cloudflare/circl/dh/x448/curve_amd64.h    |   111 +
 .../cloudflare/circl/dh/x448/curve_amd64.s    |   194 +
 .../cloudflare/circl/dh/x448/curve_generic.go |   100 +
 .../cloudflare/circl/dh/x448/curve_noasm.go   |    11 +
 .../cloudflare/circl/dh/x448/doc.go           |    19 +
 .../cloudflare/circl/dh/x448/key.go           |    46 +
 .../cloudflare/circl/dh/x448/table.go         |   460 +
 .../circl/ecc/goldilocks/constants.go         |    71 +
 .../cloudflare/circl/ecc/goldilocks/curve.go  |    80 +
 .../circl/ecc/goldilocks/isogeny.go           |    52 +
 .../cloudflare/circl/ecc/goldilocks/point.go  |   171 +
 .../cloudflare/circl/ecc/goldilocks/scalar.go |   203 +
 .../cloudflare/circl/ecc/goldilocks/twist.go  |   138 +
 .../circl/ecc/goldilocks/twistPoint.go        |   135 +
 .../circl/ecc/goldilocks/twistTables.go       |   216 +
 .../circl/ecc/goldilocks/twist_basemult.go    |    62 +
 .../cloudflare/circl/ecc/p384/LICENSE         |    26 +
 .../cloudflare/circl/ecc/p384/arith.go        |   149 +
 .../cloudflare/circl/ecc/p384/arith_amd64.go  |     8 +
 .../cloudflare/circl/ecc/p384/arith_amd64.s   |   730 +
 .../cloudflare/circl/ecc/p384/arith_arm64.s   |   511 +
 .../cloudflare/circl/ecc/p384/doc.go          |    10 +
 .../cloudflare/circl/ecc/p384/p384.go         |    28 +
 .../cloudflare/circl/ecc/p384/p384_generic.go |    21 +
 .../cloudflare/circl/ecc/p384/p384opt.go      |   181 +
 .../cloudflare/circl/ecc/p384/point.go        |   358 +
 .../cloudflare/circl/ecc/p384/tableBase.go    |   331 +
 .../github.com/cloudflare/circl/hpke/aead.go  |   103 +
 .../github.com/cloudflare/circl/hpke/algs.go  |   278 +
 .../github.com/cloudflare/circl/hpke/hpke.go  |   271 +
 .../cloudflare/circl/hpke/hybridkem.go        |   232 +
 .../cloudflare/circl/hpke/kembase.go          |   241 +
 .../cloudflare/circl/hpke/marshal.go          |   151 +
 .../cloudflare/circl/hpke/shortkem.go         |   170 +
 .../github.com/cloudflare/circl/hpke/util.go  |   121 +
 .../github.com/cloudflare/circl/hpke/xkem.go  |   164 +
 .../cloudflare/circl/internal/conv/conv.go    |   140 +
 .../cloudflare/circl/internal/sha3/doc.go     |    62 +
 .../cloudflare/circl/internal/sha3/hashes.go  |    69 +
 .../cloudflare/circl/internal/sha3/keccakf.go |   391 +
 .../cloudflare/circl/internal/sha3/rc.go      |    29 +
 .../cloudflare/circl/internal/sha3/sha3.go    |   200 +
 .../circl/internal/sha3/sha3_s390x.s          |    33 +
 .../cloudflare/circl/internal/sha3/shake.go   |   119 +
 .../cloudflare/circl/internal/sha3/xor.go     |    15 +
 .../circl/internal}/sha3/xor_generic.go       |    13 +-
 .../circl/internal}/sha3/xor_unaligned.go     |    17 +-
 .../cloudflare/circl/kem/hybrid/ckem.go       |   207 +
 .../cloudflare/circl/kem/hybrid/hybrid.go     |   344 +
 .../cloudflare/circl/kem/hybrid/xkem.go       |   208 +
 vendor/github.com/cloudflare/circl/kem/kem.go |   118 +
 .../circl/kem/kyber/kyber1024/kyber.go        |   404 +
 .../circl/kem/kyber/kyber512/kyber.go         |   404 +
 .../circl/kem/kyber/kyber768/kyber.go         |   404 +
 .../cloudflare/circl/math/fp25519/fp.go       |   205 +
 .../cloudflare/circl/math/fp25519/fp_amd64.go |    45 +
 .../cloudflare/circl/math/fp25519/fp_amd64.h  |   351 +
 .../cloudflare/circl/math/fp25519/fp_amd64.s  |   112 +
 .../circl/math/fp25519/fp_generic.go          |   317 +
 .../cloudflare/circl/math/fp25519/fp_noasm.go |    13 +
 .../cloudflare/circl/math/fp448/fp.go         |   164 +
 .../cloudflare/circl/math/fp448/fp_amd64.go   |    43 +
 .../cloudflare/circl/math/fp448/fp_amd64.h    |   591 +
 .../cloudflare/circl/math/fp448/fp_amd64.s    |    75 +
 .../cloudflare/circl/math/fp448/fp_generic.go |   339 +
 .../cloudflare/circl/math/fp448/fp_noasm.go   |    12 +
 .../cloudflare/circl/math/fp448/fuzzer.go     |    75 +
 .../cloudflare/circl/math/mlsbset/mlsbset.go  |   122 +
 .../cloudflare/circl/math/mlsbset/power.go    |    64 +
 .../cloudflare/circl/math/primes.go           |    34 +
 .../github.com/cloudflare/circl/math/wnaf.go  |    84 +
 .../circl/pke/kyber/internal/common/amd64.go  |   302 +
 .../circl/pke/kyber/internal/common/amd64.s   |  2354 ++
 .../circl/pke/kyber/internal/common/field.go  |    74 +
 .../pke/kyber/internal/common/generic.go      |    77 +
 .../circl/pke/kyber/internal/common/ntt.go    |   193 +
 .../circl/pke/kyber/internal/common/params.go |    22 +
 .../kyber/internal/common/params/params.go    |    21 +
 .../circl/pke/kyber/internal/common/poly.go   |   332 +
 .../circl/pke/kyber/internal/common/sample.go |   236 +
 .../pke/kyber/internal/common/stubs_amd64.go  |    32 +
 .../pke/kyber/kyber1024/internal/cpapke.go    |   176 +
 .../circl/pke/kyber/kyber1024/internal/mat.go |    85 +
 .../pke/kyber/kyber1024/internal/params.go    |    21 +
 .../circl/pke/kyber/kyber1024/internal/vec.go |   125 +
 .../circl/pke/kyber/kyber1024/kyber.go        |   145 +
 .../pke/kyber/kyber512/internal/cpapke.go     |   174 +
 .../circl/pke/kyber/kyber512/internal/mat.go  |    83 +
 .../pke/kyber/kyber512/internal/params.go     |    21 +
 .../circl/pke/kyber/kyber512/internal/vec.go  |   123 +
 .../circl/pke/kyber/kyber512/kyber.go         |   145 +
 .../pke/kyber/kyber768/internal/cpapke.go     |   176 +
 .../circl/pke/kyber/kyber768/internal/mat.go  |    85 +
 .../pke/kyber/kyber768/internal/params.go     |    21 +
 .../circl/pke/kyber/kyber768/internal/vec.go  |   125 +
 .../circl/pke/kyber/kyber768/kyber.go         |   145 +
 vendor/github.com/cloudflare/circl/pki/pki.go |   182 +
 .../sign/dilithium/internal/common/aes.go     |    46 +
 .../sign/dilithium/internal/common/amd64.go   |   154 +
 .../sign/dilithium/internal/common/amd64.s    |  8407 +++++
 .../sign/dilithium/internal/common/field.go   |    52 +
 .../sign/dilithium/internal/common/generic.go |    81 +
 .../sign/dilithium/internal/common/ntt.go     |   217 +
 .../sign/dilithium/internal/common/pack.go    |   160 +
 .../sign/dilithium/internal/common/params.go  |    18 +
 .../internal/common/params/params.go          |    25 +
 .../sign/dilithium/internal/common/poly.go    |   101 +
 .../dilithium/internal/common/stubs_amd64.go  |    35 +
 .../circl/sign/dilithium/mode2/dilithium.go   |   181 +
 .../dilithium/mode2/internal/dilithium.go     |   477 +
 .../sign/dilithium/mode2/internal/mat.go      |    59 +
 .../sign/dilithium/mode2/internal/pack.go     |   270 +
 .../sign/dilithium/mode2/internal/params.go   |    16 +
 .../sign/dilithium/mode2/internal/rounding.go |   142 +
 .../sign/dilithium/mode2/internal/sample.go   |   370 +
 .../sign/dilithium/mode2/internal/vec.go      |   281 +
 .../circl/sign/dilithium/mode3/dilithium.go   |   181 +
 .../dilithium/mode3/internal/dilithium.go     |   475 +
 .../sign/dilithium/mode3/internal/mat.go      |    57 +
 .../sign/dilithium/mode3/internal/pack.go     |   268 +
 .../sign/dilithium/mode3/internal/params.go   |    16 +
 .../sign/dilithium/mode3/internal/rounding.go |   140 +
 .../sign/dilithium/mode3/internal/sample.go   |   368 +
 .../sign/dilithium/mode3/internal/vec.go      |   279 +
 .../cloudflare/circl/sign/ed25519/ed25519.go  |   453 +
 .../cloudflare/circl/sign/ed25519/modular.go  |   175 +
 .../cloudflare/circl/sign/ed25519/mult.go     |   180 +
 .../cloudflare/circl/sign/ed25519/point.go    |   195 +
 .../cloudflare/circl/sign/ed25519/pubkey.go   |     9 +
 .../circl/sign/ed25519/pubkey112.go           |     7 +
 .../cloudflare/circl/sign/ed25519/signapi.go  |    87 +
 .../cloudflare/circl/sign/ed25519/tables.go   |   213 +
 .../cloudflare/circl/sign/ed448/ed448.go      |   411 +
 .../cloudflare/circl/sign/ed448/signapi.go    |    87 +
 .../circl/sign/eddilithium2/eddilithium.go    |   239 +
 .../circl/sign/eddilithium2/signapi.go        |    93 +
 .../circl/sign/eddilithium3/eddilithium.go    |   234 +
 .../circl/sign/eddilithium3/signapi.go        |    93 +
 .../cloudflare/circl/sign/schemes/schemes.go  |    46 +
 .../github.com/cloudflare/circl/sign/sign.go  |   110 +
 .../circl/simd/keccakf1600/f1600x.go          |   163 +
 .../circl/simd/keccakf1600/f1600x2_arm64.go   |    13 +
 .../circl/simd/keccakf1600/f1600x2_arm64.s    |   136 +
 .../circl/simd/keccakf1600/f1600x4_amd64.go   |    10 +
 .../circl/simd/keccakf1600/f1600x4_amd64.s    |   899 +
 .../simd/keccakf1600/f1600x4stubs_amd64.go    |     8 +
 .../circl/simd/keccakf1600/fallback.go        |     8 +
 .../cloudflare/circl/xof/k12/k12.go           |   400 +
 vendor/github.com/cloudflare/circl/xof/xof.go |    85 +
 vendor/github.com/gaukas/godicttls/.gitignore |    15 -
 vendor/github.com/go-logr/logr/.golangci.yaml |     3 -
 vendor/github.com/go-logr/logr/README.md      |   127 +-
 vendor/github.com/go-logr/logr/SECURITY.md    |    18 +
 .../go-logr/logr/context.go}                  |    22 +-
 .../github.com/go-logr/logr/context_noslog.go |    49 +
 .../github.com/go-logr/logr/context_slog.go   |    83 +
 vendor/github.com/go-logr/logr/discard.go     |    32 +-
 vendor/github.com/go-logr/logr/funcr/funcr.go |   277 +-
 .../github.com/go-logr/logr/funcr/slogsink.go |   105 +
 vendor/github.com/go-logr/logr/logr.go        |   240 +-
 vendor/github.com/go-logr/logr/sloghandler.go |   192 +
 vendor/github.com/go-logr/logr/slogr.go       |   100 +
 vendor/github.com/go-logr/logr/slogsink.go    |   120 +
 .../go-openapi/analysis/.golangci.yml         |    53 +-
 .../github.com/go-openapi/analysis/README.md  |    10 +-
 .../go-openapi/analysis/appveyor.yml          |    32 -
 vendor/github.com/go-openapi/analysis/doc.go  |    10 +-
 .../github.com/go-openapi/analysis/flatten.go |    64 +-
 .../go-openapi/analysis/flatten_name.go       |    39 +-
 .../go-openapi/analysis/flatten_options.go    |     1 +
 .../analysis/internal/debug/debug.go          |     4 +-
 .../internal/flatten/replace/replace.go       |    42 +-
 .../analysis/internal/flatten/sortref/keys.go |     2 +-
 .../github.com/go-openapi/analysis/mixin.go   |    16 +-
 .../github.com/go-openapi/analysis/schema.go  |    12 +-
 .../go-openapi/errors/.golangci.yml           |    52 +-
 vendor/github.com/go-openapi/errors/README.md |     5 +-
 vendor/github.com/go-openapi/errors/api.go    |    18 +-
 vendor/github.com/go-openapi/errors/schema.go |     6 +-
 .../go-openapi/jsonpointer/.golangci.yml      |    61 +
 .../go-openapi/jsonpointer/.travis.yml        |    15 -
 .../go-openapi/jsonpointer/README.md          |     8 +-
 .../go-openapi/jsonpointer/pointer.go         |   191 +-
 .../go-openapi/jsonreference/.golangci.yml    |    50 +-
 .../go-openapi/jsonreference/.travis.yml      |    24 -
 .../go-openapi/jsonreference/README.md        |    14 +-
 .../jsonreference/internal/normalize_url.go   |    22 +-
 .../github.com/go-openapi/loads/.golangci.yml |    49 +-
 vendor/github.com/go-openapi/loads/README.md  |     2 +-
 vendor/github.com/go-openapi/loads/doc.go     |     9 +-
 vendor/github.com/go-openapi/loads/loaders.go |     9 +-
 vendor/github.com/go-openapi/loads/spec.go    |    35 +-
 .../go-openapi/runtime/.golangci.yml          |    56 +-
 .../github.com/go-openapi/runtime/README.md   |    11 +-
 .../go-openapi/runtime/bytestream.go          |   149 +-
 .../go-openapi/runtime/client/keepalive.go    |     3 +-
 .../runtime/client/opentelemetry.go           |    10 +-
 .../go-openapi/runtime/client/request.go      |    17 +-
 .../go-openapi/runtime/client/runtime.go      |    87 +-
 .../go-openapi/runtime/client_operation.go    |     4 +-
 .../go-openapi/runtime/client_request.go      |     4 +-
 vendor/github.com/go-openapi/runtime/csv.go   |   327 +-
 .../go-openapi/runtime/csv_options.go         |   121 +
 .../go-openapi/runtime/logger/standard.go     |     2 +
 .../go-openapi/runtime/middleware/context.go  |   175 +-
 .../runtime/middleware/denco/router.go        |    37 +-
 .../go-openapi/runtime/middleware/doc.go      |    87 +-
 .../go-openapi/runtime/middleware/go18.go     |     9 -
 .../runtime/middleware/header/header.go       |     9 +-
 .../runtime/middleware/parameter.go           |    22 +-
 .../go-openapi/runtime/middleware/pre_go18.go |     9 -
 .../go-openapi/runtime/middleware/rapidoc.go  |    72 +-
 .../go-openapi/runtime/middleware/redoc.go    |    69 +-
 .../go-openapi/runtime/middleware/request.go  |    23 +-
 .../go-openapi/runtime/middleware/router.go   |   109 +-
 .../go-openapi/runtime/middleware/spec.go     |    76 +-
 .../runtime/middleware/swaggerui.go           |    89 +-
 .../runtime/middleware/swaggerui_oauth2.go    |    31 +-
 .../runtime/middleware/ui_options.go          |   173 +
 .../runtime/middleware/untyped/api.go         |    15 +-
 .../runtime/middleware/validation.go          |    12 +-
 .../github.com/go-openapi/runtime/request.go  |    14 +-
 .../runtime/security/authenticator.go         |    19 +-
 .../go-openapi/runtime/yamlpc/yaml.go         |     3 +-
 vendor/github.com/go-openapi/spec/.gitignore  |     3 +-
 .../github.com/go-openapi/spec/.golangci.yml  |    21 +-
 vendor/github.com/go-openapi/spec/README.md   |    28 +-
 .../github.com/go-openapi/spec/appveyor.yml   |    32 -
 vendor/github.com/go-openapi/spec/bindata.go  |   297 -
 vendor/github.com/go-openapi/spec/embed.go    |    17 +
 vendor/github.com/go-openapi/spec/expander.go |    75 +-
 vendor/github.com/go-openapi/spec/info.go     |    19 +
 .../go-openapi/spec/normalizer_nonwindows.go  |     2 +-
 .../github.com/go-openapi/spec/operation.go   |     5 +-
 .../github.com/go-openapi/spec/parameter.go   |    42 +-
 .../github.com/go-openapi/spec/properties.go  |     6 +-
 .../github.com/go-openapi/spec/responses.go   |    27 +-
 .../go-openapi/spec/schema_loader.go          |     9 +-
 .../spec/schemas/jsonschema-draft-04.json     |   149 +
 .../go-openapi/spec/schemas/v2/schema.json    |  1607 +
 vendor/github.com/go-openapi/spec/spec.go     |     6 +-
 vendor/github.com/go-openapi/spec/swagger.go  |     4 +-
 vendor/github.com/go-openapi/spec/url_go18.go |     8 -
 vendor/github.com/go-openapi/spec/url_go19.go |     3 -
 .../go-openapi/strfmt/.golangci.yml           |    92 +-
 vendor/github.com/go-openapi/strfmt/README.md |     5 +-
 vendor/github.com/go-openapi/strfmt/bson.go   |     6 +-
 .../github.com/go-openapi/strfmt/default.go   |    52 +-
 vendor/github.com/go-openapi/strfmt/format.go |     5 +-
 vendor/github.com/go-openapi/strfmt/time.go   |     8 +-
 vendor/github.com/go-openapi/swag/.gitignore  |     1 +
 .../github.com/go-openapi/swag/.golangci.yml  |    54 +-
 .../github.com/go-openapi/swag/BENCHMARK.md   |    52 +
 vendor/github.com/go-openapi/swag/README.md   |     8 +-
 .../go-openapi/swag/initialism_index.go       |   202 +
 vendor/github.com/go-openapi/swag/loading.go  |   105 +-
 .../github.com/go-openapi/swag/name_lexem.go  |    70 +-
 .../github.com/go-openapi/swag/post_go18.go   |    24 -
 .../github.com/go-openapi/swag/post_go19.go   |    68 -
 vendor/github.com/go-openapi/swag/pre_go18.go |    24 -
 vendor/github.com/go-openapi/swag/pre_go19.go |    70 -
 vendor/github.com/go-openapi/swag/split.go    |   470 +-
 .../go-openapi/swag/string_bytes.go           |     8 +
 vendor/github.com/go-openapi/swag/util.go     |   210 +-
 vendor/github.com/go-openapi/swag/yaml.go     |    39 +-
 .../go-openapi/validate/.golangci.yml         |    53 +-
 .../go-openapi/validate/BENCHMARK.md          |    31 +
 .../github.com/go-openapi/validate/README.md  |     8 +-
 .../go-openapi/validate/appveyor.yml          |    32 -
 .../go-openapi/validate/default_validator.go  |   109 +-
 vendor/github.com/go-openapi/validate/doc.go  |    70 +-
 .../go-openapi/validate/example_validator.go  |    67 +-
 .../github.com/go-openapi/validate/formats.go |    78 +-
 .../github.com/go-openapi/validate/helpers.go |    23 +-
 .../go-openapi/validate/object_validator.go   |   448 +-
 .../github.com/go-openapi/validate/options.go |    21 +-
 .../github.com/go-openapi/validate/pools.go   |   366 +
 .../go-openapi/validate/pools_debug.go        |  1012 +
 .../github.com/go-openapi/validate/result.go  |   131 +-
 .../github.com/go-openapi/validate/schema.go  |   260 +-
 .../go-openapi/validate/schema_option.go      |    31 +-
 .../go-openapi/validate/schema_props.go       |   412 +-
 .../go-openapi/validate/slice_validator.go    |    57 +-
 vendor/github.com/go-openapi/validate/spec.go |   188 +-
 .../go-openapi/validate/spec_messages.go      |    12 +-
 vendor/github.com/go-openapi/validate/type.go |    72 +-
 .../go-openapi/validate/validator.go          |   936 +-
 .../github.com/go-openapi/validate/values.go  |    12 +-
 .../klauspost/compress/.goreleaser.yml        |    22 +-
 .../github.com/klauspost/compress/README.md   |    66 +-
 .../github.com/klauspost/compress/SECURITY.md |     2 +-
 .../klauspost/compress/fse/bitwriter.go       |     3 +-
 .../klauspost/compress/fse/compress.go        |     5 +-
 .../klauspost/compress/huff0/bitwriter.go     |     3 +-
 .../klauspost/compress/huff0/bytereader.go    |    44 -
 .../klauspost/compress/huff0/compress.go      |    25 +-
 .../klauspost/compress/huff0/huff0.go         |     4 +-
 .../compress/internal/snapref/encode_other.go |     2 +-
 vendor/github.com/klauspost/compress/s2sx.mod |     2 +-
 .../klauspost/compress/zstd/README.md         |     2 +-
 .../klauspost/compress/zstd/bitreader.go      |    34 +-
 .../klauspost/compress/zstd/bitwriter.go      |     3 +-
 .../klauspost/compress/zstd/blockdec.go       |     3 +
 .../klauspost/compress/zstd/blockenc.go       |    49 +-
 .../klauspost/compress/zstd/decodeheader.go   |    56 +-
 .../klauspost/compress/zstd/decoder.go        |     2 +-
 .../klauspost/compress/zstd/dict.go           |   410 +-
 .../klauspost/compress/zstd/enc_base.go       |     1 +
 .../klauspost/compress/zstd/enc_best.go       |    94 +-
 .../klauspost/compress/zstd/enc_better.go     |    30 +-
 .../klauspost/compress/zstd/enc_dfast.go      |     2 +-
 .../klauspost/compress/zstd/enc_fast.go       |    11 +-
 .../klauspost/compress/zstd/encoder.go        |    13 +-
 .../compress/zstd/encoder_options.go          |     6 +-
 .../klauspost/compress/zstd/frameenc.go       |     6 +-
 .../compress/zstd/fse_decoder_generic.go      |    11 +-
 .../zstd/internal/xxhash/xxhash_arm64.s       |     4 +-
 .../klauspost/compress/zstd/matchlen_amd64.s  |    10 +-
 .../klauspost/compress/zstd/seqdec.go         |    17 +-
 .../klauspost/compress/zstd/seqdec_amd64.s    |   264 +-
 .../klauspost/compress/zstd/seqdec_generic.go |     2 +-
 .../klauspost/compress/zstd/snappy.go         |     5 +-
 .../github.com/klauspost/cpuid/v2/README.md   |     1 +
 vendor/github.com/klauspost/cpuid/v2/cpuid.go |   429 +-
 .../klauspost/cpuid/v2/detect_x86.go          |     1 +
 .../klauspost/cpuid/v2/featureid_string.go    |   364 +-
 .../klauspost/reedsolomon/README.md           |     7 +-
 .../klauspost/reedsolomon/galois.go           |     6 +-
 .../klauspost/reedsolomon/galois_gen_amd64.s  |    60 -
 .../klauspost/reedsolomon/galois_gen_arm64.go |   125 +
 .../klauspost/reedsolomon/galois_gen_arm64.s  | 26958 ++++++++++++++++
 .../klauspost/reedsolomon/galois_gen_none.go  |    38 +-
 .../reedsolomon/galois_gen_switch_amd64.go    |    35 +-
 .../reedsolomon/galois_gen_switch_arm64.go    |   195 +
 .../galois_gen_switch_nopshufb_amd64.go       |    31 +-
 .../galois_gen_switch_nopshufb_arm64.go       |    22 +
 .../klauspost/reedsolomon/galois_notamd64.go  |    13 -
 .../klauspost/reedsolomon/leopard.go          |    18 +-
 .../klauspost/reedsolomon/leopard8.go         |    18 +-
 .../klauspost/reedsolomon/options.go          |    11 +-
 .../klauspost/reedsolomon/reedsolomon.go      |   198 +-
 .../github.com/mattn/go-isatty/isatty_bsd.go  |     3 +-
 .../mattn/go-isatty/isatty_others.go          |     5 +-
 .../mattn/go-isatty/isatty_tcgets.go          |     3 +-
 vendor/github.com/pion/datachannel/.gitignore |     3 +
 .../github.com/pion/datachannel/.golangci.yml |    40 +-
 .../pion/datachannel/.goreleaser.yml          |     5 +
 .../github.com/pion/datachannel/AUTHORS.txt   |    17 -
 vendor/github.com/pion/datachannel/DESIGN.md  |    20 -
 vendor/github.com/pion/datachannel/LICENSE    |    20 +-
 vendor/github.com/pion/datachannel/README.md  |    15 +-
 .../github.com/pion/datachannel/codecov.yml   |     2 +
 .../pion/datachannel/datachannel.go           |    25 +-
 vendor/github.com/pion/datachannel/errors.go  |     3 +
 vendor/github.com/pion/datachannel/message.go |     4 +
 .../pion/datachannel/message_channel_ack.go   |     9 +-
 .../pion/datachannel/message_channel_open.go  |    26 +-
 .../github.com/pion/datachannel/renovate.json |    25 +-
 vendor/github.com/pion/dtls/v2/conn.go        |   105 +-
 vendor/github.com/pion/dtls/v2/resume.go      |     6 +-
 vendor/github.com/pion/ice/v2/agent.go        |   116 +-
 vendor/github.com/pion/ice/v2/agent_config.go |     7 +
 .../github.com/pion/ice/v2/agent_handlers.go  |   137 +-
 .../github.com/pion/ice/v2/candidate_base.go  |    11 +-
 vendor/github.com/pion/ice/v2/selection.go    |    31 +-
 vendor/github.com/pion/ice/v2/tcp_mux.go      |    63 +-
 .../github.com/pion/ice/v2/tcp_packet_conn.go |    28 +-
 vendor/github.com/pion/ice/v2/udp_mux.go      |    23 +-
 .../github.com/pion/ice/v2/udp_muxed_conn.go  |   236 +-
 .../github.com/pion/interceptor/.golangci.yml |    26 +-
 .../github.com/pion/interceptor/AUTHORS.txt   |    34 -
 vendor/github.com/pion/interceptor/README.md  |     2 +-
 .../pkg/report/receiver_interceptor.go        |     6 +-
 .../pkg/report/sender_interceptor.go          |     7 +-
 vendor/github.com/pion/mdns/.golangci.yml     |    19 +-
 vendor/github.com/pion/mdns/AUTHORS.txt       |    20 -
 vendor/github.com/pion/mdns/README.md         |     2 +-
 vendor/github.com/pion/mdns/config.go         |     6 +
 vendor/github.com/pion/mdns/conn.go           |   247 +-
 vendor/github.com/pion/rtcp/.golangci.yml     |    19 +-
 vendor/github.com/pion/rtcp/AUTHORS.txt       |    31 -
 vendor/github.com/pion/rtcp/README.md         |     2 +-
 .../github.com/pion/rtcp/extended_report.go   |     3 +-
 vendor/github.com/pion/rtp/.golangci.yml      |    26 +-
 vendor/github.com/pion/rtp/AUTHORS.txt        |    48 -
 vendor/github.com/pion/rtp/README.md          |     4 +-
 .../pion/rtp/abscapturetimeextension.go       |    16 +
 .../pion/rtp/codecs/av1/obu/leb128.go         |    16 +
 .../github.com/pion/rtp/codecs/av1_packet.go  |    32 +-
 vendor/github.com/pion/rtp/codecs/common.go   |    12 +-
 .../github.com/pion/rtp/codecs/h264_packet.go |    26 +-
 .../github.com/pion/rtp/codecs/vp8_packet.go  |     5 +-
 vendor/github.com/pion/rtp/depacketizer.go    |     4 +
 vendor/github.com/pion/rtp/packetizer.go      |    33 +
 vendor/github.com/pion/rtp/payload_types.go   |    68 +
 vendor/github.com/pion/rtp/vlaextension.go    |   360 +
 vendor/github.com/pion/sctp/.golangci.yml     |    26 +-
 vendor/github.com/pion/sctp/AUTHORS.txt       |    35 -
 vendor/github.com/pion/sctp/README.md         |     2 +-
 vendor/github.com/pion/sctp/ack_timer.go      |    86 +-
 vendor/github.com/pion/sctp/association.go    |   291 +-
 .../github.com/pion/sctp/association_stats.go |    50 +-
 vendor/github.com/pion/sctp/chunk_init.go     |    20 +-
 .../github.com/pion/sctp/chunk_init_common.go |    21 +-
 .../pion/sctp/chunk_payload_data.go           |     6 +-
 .../pion/sctp/error_cause_header.go           |     7 +
 vendor/github.com/pion/sctp/packet.go         |    44 +-
 vendor/github.com/pion/sctp/param.go          |     2 +
 .../sctp/param_requested_hmac_algorithm.go    |     8 +-
 .../pion/sctp/param_zero_checksum.go          |    56 +
 vendor/github.com/pion/sctp/paramheader.go    |    34 +-
 vendor/github.com/pion/sctp/paramtype.go      |    57 +-
 vendor/github.com/pion/sctp/payload_queue.go  |   147 +-
 vendor/github.com/pion/sctp/queue.go          |    70 +
 .../github.com/pion/sctp/reassembly_queue.go  |    21 +-
 .../pion/sctp/receive_payload_queue.go        |   186 +
 vendor/github.com/pion/sctp/rtx_timer.go      |   168 +-
 vendor/github.com/pion/sctp/stream.go         |     8 +-
 vendor/github.com/pion/sdp/v3/.gitignore      |     3 +
 vendor/github.com/pion/sdp/v3/.golangci.yml   |    33 +-
 vendor/github.com/pion/sdp/v3/.goreleaser.yml |     5 +
 vendor/github.com/pion/sdp/v3/AUTHORS.txt     |    32 -
 vendor/github.com/pion/sdp/v3/LICENSE         |    20 +-
 vendor/github.com/pion/sdp/v3/README.md       |    14 +-
 vendor/github.com/pion/sdp/v3/base_lexer.go   |    47 +-
 vendor/github.com/pion/sdp/v3/codecov.yml     |     2 +
 .../pion/sdp/v3/common_description.go         |   118 +-
 vendor/github.com/pion/sdp/v3/direction.go    |     3 +
 vendor/github.com/pion/sdp/v3/extmap.go       |     3 +
 vendor/github.com/pion/sdp/v3/fuzz.go         |    31 -
 vendor/github.com/pion/sdp/v3/jsep.go         |    10 +-
 vendor/github.com/pion/sdp/v3/marshal.go      |   224 +-
 .../pion/sdp/v3/media_description.go          |    62 +-
 vendor/github.com/pion/sdp/v3/renovate.json   |    25 +-
 vendor/github.com/pion/sdp/v3/sdp.go          |     3 +
 .../pion/sdp/v3/session_description.go        |    85 +-
 .../pion/sdp/v3/time_description.go           |    42 +-
 vendor/github.com/pion/sdp/v3/unmarshal.go    |   292 +-
 .../github.com/pion/sdp/v3/unmarshal_cache.go |    44 +
 vendor/github.com/pion/sdp/v3/util.go         |    76 +-
 .../pion/transport/v2/deadline/deadline.go    |    97 +-
 .../pion/transport/v2/deadline/timer.go       |    13 +
 .../transport/v2/deadline/timer_generic.go    |    15 +
 .../pion/transport/v2/deadline/timer_js.go    |    67 +
 .../pion/transport/v2/packetio/buffer.go      |    45 +-
 .../github.com/pion/transport/v2/udp/conn.go  |    19 +-
 vendor/github.com/pion/turn/v2/client.go      |    10 +-
 .../turn/v2/internal/allocation/allocation.go |    10 +-
 .../internal/allocation/allocation_manager.go |     6 +-
 .../turn/v2/internal/allocation/five_tuple.go |    30 +-
 .../pion/turn/v2/internal/client/udp_conn.go  |     2 +-
 .../pion/turn/v2/internal/server/errors.go    |     2 +-
 .../pion/turn/v2/internal/server/nonce.go     |    71 +
 .../pion/turn/v2/internal/server/server.go    |     5 +-
 .../pion/turn/v2/internal/server/stun.go      |     2 +-
 .../pion/turn/v2/internal/server/turn.go      |    24 +-
 .../pion/turn/v2/internal/server/util.go      |    34 +-
 vendor/github.com/pion/turn/v2/server.go      |    12 +-
 vendor/github.com/pion/webrtc/v3/constants.go |     7 +
 .../github.com/pion/webrtc/v3/datachannel.go  |    19 +
 .../pion/webrtc/v3/dtlstransport.go           |     2 +-
 .../github.com/pion/webrtc/v3/icegatherer.go  |     1 +
 .../github.com/pion/webrtc/v3/interceptor.go  |    13 +
 .../pion/webrtc/v3/internal/fmtp/av1.go       |    41 +
 .../pion/webrtc/v3/internal/fmtp/fmtp.go      |    45 +-
 .../pion/webrtc/v3/internal/fmtp/vp9.go       |    41 +
 .../github.com/pion/webrtc/v3/mediaengine.go  |    11 +-
 .../github.com/pion/webrtc/v3/operations.go   |    17 +-
 .../pion/webrtc/v3/peerconnection.go          |   124 +-
 .../pion/webrtc/v3/peerconnectionstate.go     |    11 -
 .../github.com/pion/webrtc/v3/rtpreceiver.go  |   102 +-
 vendor/github.com/pion/webrtc/v3/rtpsender.go |     2 +-
 .../pion/webrtc/v3/rtptransceiver.go          |     6 +-
 .../pion/webrtc/v3/sctptransport.go           |     1 +
 vendor/github.com/pion/webrtc/v3/sdp.go       |     6 +
 .../pion/webrtc/v3/sessiondescription.go      |     2 +-
 .../pion/webrtc/v3/settingengine.go           |    19 +
 .../pion/webrtc/v3/track_local_static.go      |    25 +
 .../github.com/pion/webrtc/v3/track_remote.go |    47 +-
 .../refraction-networking/utls/README.md      |    16 +-
 .../refraction-networking/utls/SECURITY.md    |    11 +
 .../refraction-networking/utls/alert.go       |    12 +
 .../refraction-networking/utls/auth.go        |    55 +-
 .../refraction-networking/utls/cache.go       |    95 +
 .../refraction-networking/utls/cfkem.go       |   101 +
 .../utls/cipher_suites.go                     |    81 +-
 .../refraction-networking/utls/common.go      |   257 +-
 .../refraction-networking/utls/conn.go        |   245 +-
 .../utls/dicttls}/LICENSE                     |     0
 .../utls/dicttls}/README.md                   |     6 +
 .../utls/dicttls}/alerts.go                   |     2 +-
 .../dicttls}/authorization_data_formats.go    |     2 +-
 .../dicttls}/cachedinformationtype_values.go  |     2 +-
 .../certificate_compression_algorithm_ids.go  |     2 +-
 .../utls/dicttls}/certificate_status_types.go |     2 +-
 .../utls/dicttls}/certificte_types.go         |     2 +-
 .../utls/dicttls}/cipher_suites.go            |     2 +-
 .../clientcertificatetype_identifiers.go      |     2 +-
 .../utls/dicttls}/comp_meth_ids.go            |     2 +-
 .../utls/dicttls}/contenttype.go              |     2 +-
 .../utls/dicttls}/ec_curve_types.go           |     2 +-
 .../utls/dicttls}/ec_point_formats.go         |     2 +-
 .../utls/dicttls}/exttype_values.go           |     9 +-
 .../utls/dicttls}/handshaketype.go            |     2 +-
 .../utls/dicttls}/hashalgorithm.go            |     2 +-
 .../utls/dicttls}/heartbeat_message_types.go  |     2 +-
 .../utls/dicttls}/heartbeat_mode.go           |     2 +-
 .../utls/dicttls/hpke_aead_identifiers.go     |    19 +
 .../utls/dicttls/hpke_kdf_identifiers.go}     |    11 +-
 .../utls/dicttls/hpke_kem_identifiers.go      |    53 +
 .../utls/dicttls}/psk_key_exchange_mode.go    |     2 +-
 .../utls/dicttls/quic_frame_types.go          |   112 +
 .../dicttls/quic_transport_error_codes.go     |    70 +
 .../utls/dicttls/quic_transport_parameters.go |    91 +
 .../utls/dicttls}/signaturealgorithm.go       |     2 +-
 .../utls/dicttls}/signaturescheme.go          |     2 +-
 .../dicttls}/supplemental_data_formats.go     |     2 +-
 .../utls/dicttls}/supported_groups.go         |     2 +-
 .../utls/dicttls}/usermappingtype_values.go   |     2 +-
 .../utls/handshake_client.go                  |   374 +-
 .../utls/handshake_client_tls13.go            |   345 +-
 .../utls/handshake_messages.go                |    87 +-
 .../utls/handshake_server.go                  |   217 +-
 .../utls/handshake_server_tls13.go            |   249 +-
 .../utls/internal/boring/notboring.go         |    20 +
 .../internal/quicvarint/protocol/protocol.go  |   157 +
 .../utls/internal/quicvarint/varint.go        |   146 +
 .../utls/key_agreement.go                     |    39 +-
 .../utls/key_schedule.go                      |   103 +-
 .../refraction-networking/utls/notboring.go   |    22 +-
 .../refraction-networking/utls/prf.go         |    26 +-
 .../refraction-networking/utls/quic.go        |   421 +
 .../refraction-networking/utls/ticket.go      |   495 +-
 .../refraction-networking/utls/tls.go         |    30 +-
 .../refraction-networking/utls/tls_cf.go      |    66 +
 .../refraction-networking/utls/u_alias.go     |    12 +
 .../utls/u_clienthello_json.go                |    32 +-
 .../refraction-networking/utls/u_common.go    |   156 +-
 .../refraction-networking/utls/u_conn.go      |   446 +-
 .../refraction-networking/utls/u_ech.go       |   329 +
 .../utls/u_ech_config.go                      |   135 +
 .../utls/u_fingerprinter.go                   |     6 +-
 .../utls/u_handshake_client.go                |   172 +-
 .../utls/u_handshake_messages.go              |     7 +
 .../refraction-networking/utls/u_hpke.go      |    62 +
 .../refraction-networking/utls/u_parrots.go   |   932 +-
 .../utls/u_pre_shared_key.go                  |   471 +
 .../refraction-networking/utls/u_prng.go      |    10 +-
 .../refraction-networking/utls/u_public.go    |   255 +-
 .../refraction-networking/utls/u_quic.go      |   212 +
 .../utls/u_quic_transport_parameters.go       |   319 +
 .../utls/u_session_controller.go              |   359 +
 .../utls/u_session_ticket.go                  |    82 +
 .../utls/u_tls_extensions.go                  |   366 +-
 vendor/github.com/rs/zerolog/README.md        |    18 +-
 vendor/github.com/rs/zerolog/array.go         |     6 +-
 vendor/github.com/rs/zerolog/console.go       |    91 +-
 vendor/github.com/rs/zerolog/context.go       |    22 +-
 vendor/github.com/rs/zerolog/encoder.go       |    12 +-
 vendor/github.com/rs/zerolog/event.go         |    14 +-
 vendor/github.com/rs/zerolog/fields.go        |    18 +-
 vendor/github.com/rs/zerolog/globals.go       |    24 +-
 .../rs/zerolog/internal/cbor/decode_stream.go |     2 +-
 .../rs/zerolog/internal/cbor/time.go          |    10 +-
 .../rs/zerolog/internal/cbor/types.go         |    12 +-
 .../rs/zerolog/internal/json/time.go          |    10 +-
 .../rs/zerolog/internal/json/types.go         |    45 +-
 vendor/github.com/rs/zerolog/log.go           |     2 +-
 vendor/github.com/rs/zerolog/sampler.go       |     2 +-
 .../testify/assert/assertion_compare.go       |    28 +-
 .../assert/assertion_compare_can_convert.go   |    16 -
 .../assert/assertion_compare_legacy.go        |    16 -
 .../testify/assert/assertion_format.go        |    32 +-
 .../testify/assert/assertion_forward.go       |    59 +-
 .../stretchr/testify/assert/assertions.go     |   207 +-
 .../testify/assert/http_assertions.go         |    27 +-
 .../stretchr/testify/require/require.go       |    65 +-
 .../testify/require/require_forward.go        |    59 +-
 vendor/github.com/xtaci/kcp-go/v5/fec.go      |    64 +-
 vendor/github.com/xtaci/kcp-go/v5/sess.go     |    18 +-
 vendor/go.etcd.io/bbolt/.go-version           |     1 +
 vendor/go.etcd.io/bbolt/README.md             |    23 +-
 vendor/go.etcd.io/bbolt/bolt_openbsd.go       |    15 +-
 vendor/go.etcd.io/bbolt/bucket.go             |    30 +-
 vendor/go.etcd.io/bbolt/cursor.go             |    11 +-
 vendor/go.etcd.io/bbolt/db.go                 |    46 +-
 vendor/go.etcd.io/bbolt/freelist.go           |    11 +-
 vendor/go.etcd.io/bbolt/page.go               |     6 +-
 vendor/go.etcd.io/bbolt/unsafe.go             |    12 -
 .../bson/bsoncodec/array_codec.go             |     9 +-
 .../mongo-driver/bson/bsoncodec/bsoncodec.go  |   156 +-
 .../bson/bsoncodec/byte_slice_codec.go        |    35 +-
 .../bson/bsoncodec/codec_cache.go             |   166 +
 .../bson/bsoncodec/default_value_decoders.go  |   162 +-
 .../bson/bsoncodec/default_value_encoders.go  |   190 +-
 .../mongo-driver/bson/bsoncodec/doc.go        |    73 +-
 .../bson/bsoncodec/empty_interface_codec.go   |    30 +-
 .../mongo-driver/bson/bsoncodec/map_codec.go  |    60 +-
 .../bson/bsoncodec/pointer_codec.go           |    73 +-
 .../mongo-driver/bson/bsoncodec/registry.go   |   487 +-
 .../bson/bsoncodec/slice_codec.go             |    51 +-
 .../bson/bsoncodec/string_codec.go            |    29 +-
 .../bson/bsoncodec/struct_codec.go            |   258 +-
 .../bson/bsoncodec/struct_tag_parser.go       |    11 +-
 .../mongo-driver/bson/bsoncodec/time_codec.go |    30 +-
 .../mongo-driver/bson/bsoncodec/types.go      |     1 +
 .../mongo-driver/bson/bsoncodec/uint_codec.go |    35 +-
 .../bsonoptions/byte_slice_codec_options.go   |    11 +
 .../empty_interface_codec_options.go          |    11 +
 .../bson/bsonoptions/map_codec_options.go     |    15 +
 .../bson/bsonoptions/slice_codec_options.go   |    11 +
 .../bson/bsonoptions/string_codec_options.go  |    11 +
 .../bson/bsonoptions/struct_codec_options.go  |    20 +
 .../bson/bsonoptions/time_codec_options.go    |    11 +
 .../bson/bsonoptions/uint_codec_options.go    |    11 +
 .../mongo-driver/bson/bsonrw/copier.go        |    56 +-
 .../bson/bsonrw/extjson_parser.go             |     2 +-
 .../bson/bsonrw/extjson_reader.go             |    13 +-
 .../bson/bsonrw/extjson_wrappers.go           |     4 +-
 .../bson/bsonrw/extjson_writer.go             |    23 +-
 .../mongo-driver/bson/bsonrw/json_scanner.go  |    26 +-
 .../mongo-driver/bson/bsonrw/reader.go        |     2 +
 .../mongo-driver/bson/bsonrw/value_reader.go  |    32 +-
 .../mongo-driver/bson/bsonrw/value_writer.go  |    84 +-
 .../mongo-driver/bson/bsonrw/writer.go        |     9 +
 .../mongo-driver/bson/bsontype/bsontype.go    |    21 +-
 .../mongo-driver/bson/decoder.go              |    79 +-
 .../go.mongodb.org/mongo-driver/bson/doc.go   |    90 +-
 .../mongo-driver/bson/encoder.go              |   110 +-
 .../mongo-driver/bson/marshal.go              |   225 +-
 .../mongo-driver/bson/primitive/decimal.go    |    17 +-
 .../mongo-driver/bson/primitive/objectid.go   |    12 +-
 .../mongo-driver/bson/primitive/primitive.go  |    46 +-
 .../mongo-driver/bson/primitive_codecs.go     |    40 +-
 .../go.mongodb.org/mongo-driver/bson/raw.go   |    34 +-
 .../mongo-driver/bson/raw_element.go          |     7 +-
 .../mongo-driver/bson/raw_value.go            |    27 +-
 .../mongo-driver/bson/registry.go             |    31 +-
 .../go.mongodb.org/mongo-driver/bson/types.go |    16 +-
 .../mongo-driver/bson/unmarshal.go            |    92 +-
 .../mongo-driver/x/bsonx/bsoncore/array.go    |    10 +-
 .../mongo-driver/x/bsonx/bsoncore/bsoncore.go |    64 +-
 .../mongo-driver/x/bsonx/bsoncore/doc.go      |    34 +
 .../mongo-driver/x/bsonx/bsoncore/document.go |    10 +-
 .../mongo-driver/x/bsonx/bsoncore/element.go  |     2 +-
 .../mongo-driver/x/bsonx/bsoncore/value.go    |    23 +-
 .../go.opentelemetry.io/otel/.codespellignore |     9 +
 vendor/go.opentelemetry.io/otel/.codespellrc  |    10 +
 vendor/go.opentelemetry.io/otel/.gitignore    |     9 +-
 vendor/go.opentelemetry.io/otel/.gitmodules   |     3 -
 vendor/go.opentelemetry.io/otel/.golangci.yml |   106 +-
 vendor/go.opentelemetry.io/otel/CHANGELOG.md  |   750 +-
 vendor/go.opentelemetry.io/otel/CODEOWNERS    |     4 +-
 .../go.opentelemetry.io/otel/CONTRIBUTING.md  |   242 +-
 vendor/go.opentelemetry.io/otel/Makefile      |   192 +-
 vendor/go.opentelemetry.io/otel/README.md     |    63 +-
 vendor/go.opentelemetry.io/otel/RELEASING.md  |    38 +-
 .../otel/attribute/README.md                  |     3 +
 .../go.opentelemetry.io/otel/attribute/doc.go |    13 +-
 .../otel/attribute/encoder.go                 |    13 +-
 .../otel/attribute/filter.go                  |    49 +
 .../otel/attribute/iterator.go                |    13 +-
 .../go.opentelemetry.io/otel/attribute/key.go |    13 +-
 .../go.opentelemetry.io/otel/attribute/kv.go  |    13 +-
 .../go.opentelemetry.io/otel/attribute/set.go |   221 +-
 .../otel/attribute/value.go                   |    31 +-
 .../otel/baggage/README.md                    |     3 +
 .../otel/baggage/baggage.go                   |   572 +-
 .../otel/baggage/context.go                   |    13 +-
 .../go.opentelemetry.io/otel/baggage/doc.go   |    13 +-
 .../go.opentelemetry.io/otel/codes/README.md  |     3 +
 .../go.opentelemetry.io/otel/codes/codes.go   |    13 +-
 vendor/go.opentelemetry.io/otel/codes/doc.go  |    15 +-
 vendor/go.opentelemetry.io/otel/doc.go        |    15 +-
 .../go.opentelemetry.io/otel/error_handler.go |    13 +-
 .../go.opentelemetry.io/otel/get_main_pkgs.sh |    13 +-
 vendor/go.opentelemetry.io/otel/handler.go    |    79 +-
 .../otel/internal/attribute/attribute.go      |    37 +-
 .../otel/internal/baggage/baggage.go          |    13 +-
 .../otel/internal/baggage/context.go          |    13 +-
 .../go.opentelemetry.io/otel/internal/gen.go  |    18 +
 .../otel/internal/global/handler.go           |    36 +
 .../otel/internal/global/instruments.go       |   412 +
 .../otel/internal/global/internal_logging.go  |    55 +-
 .../otel/internal/global/meter.go             |   368 +
 .../otel/internal/global/propagator.go        |    13 +-
 .../otel/internal/global/state.go             |   116 +-
 .../otel/internal/global/trace.go             |    29 +-
 .../otel/internal/rawhelpers.go               |    13 +-
 .../otel/internal_logging.go                  |    13 +-
 vendor/go.opentelemetry.io/otel/metric.go     |    42 +
 .../otel/metric}/LICENSE                      |     4 +-
 .../go.opentelemetry.io/otel/metric/README.md |     3 +
 .../otel/metric/asyncfloat64.go               |   260 +
 .../otel/metric/asyncint64.go                 |   258 +
 .../go.opentelemetry.io/otel/metric/config.go |    81 +
 vendor/go.opentelemetry.io/otel/metric/doc.go |   177 +
 .../otel/metric/embedded/README.md            |     3 +
 .../otel/metric/embedded/embedded.go          |   243 +
 .../otel/metric/instrument.go                 |   368 +
 .../go.opentelemetry.io/otel/metric/meter.go  |   265 +
 .../otel/metric/syncfloat64.go                |   226 +
 .../otel/metric/syncint64.go                  |   226 +
 .../go.opentelemetry.io/otel/propagation.go   |    13 +-
 .../otel/propagation/README.md                |     3 +
 .../otel/propagation/baggage.go               |    13 +-
 .../otel/propagation/doc.go                   |    13 +-
 .../otel/propagation/propagation.go           |    13 +-
 .../otel/propagation/trace_context.go         |   111 +-
 vendor/go.opentelemetry.io/otel/renovate.json |    24 +
 .../go.opentelemetry.io/otel/requirements.txt |     1 +
 .../otel/semconv/internal/http.go             |   336 -
 .../otel/semconv/internal/v2/http.go          |   393 +
 .../otel/semconv/internal/v2/net.go           |   313 +
 .../otel/semconv/v1.12.0/doc.go               |    20 -
 .../otel/semconv/v1.12.0/exception.go         |    20 -
 .../otel/semconv/v1.12.0/http.go              |   114 -
 .../otel/semconv/v1.12.0/resource.go          |  1042 -
 .../otel/semconv/v1.12.0/schema.go            |    20 -
 .../otel/semconv/v1.12.0/trace.go             |  1704 -
 .../otel/semconv/v1.17.0/README.md            |     3 +
 .../otel/semconv/v1.17.0/doc.go               |     9 +
 .../otel/semconv/v1.17.0/event.go             |   188 +
 .../otel/semconv/v1.17.0/exception.go         |     9 +
 .../otel/semconv/v1.17.0/http.go              |    10 +
 .../otel/semconv/v1.17.0/httpconv/README.md   |     3 +
 .../otel/semconv/v1.17.0/httpconv/http.go     |   141 +
 .../otel/semconv/v1.17.0/resource.go          |  1999 ++
 .../otel/semconv/v1.17.0/schema.go            |     9 +
 .../otel/semconv/v1.17.0/trace.go             |  3364 ++
 vendor/go.opentelemetry.io/otel/trace.go      |    13 +-
 .../go.opentelemetry.io/otel/trace/README.md  |     3 +
 .../go.opentelemetry.io/otel/trace/config.go  |    14 +-
 .../go.opentelemetry.io/otel/trace/context.go |    17 +-
 vendor/go.opentelemetry.io/otel/trace/doc.go  |    77 +-
 .../otel/trace/embedded/README.md             |     3 +
 .../otel/trace/embedded/embedded.go           |    45 +
 .../otel/trace/nonrecording.go                |    13 +-
 vendor/go.opentelemetry.io/otel/trace/noop.go |    34 +-
 .../go.opentelemetry.io/otel/trace/trace.go   |    59 +-
 .../otel/trace/tracestate.go                  |   212 +-
 .../otel/verify_examples.sh                   |    13 +-
 .../otel/verify_readmes.sh                    |    21 +
 vendor/go.opentelemetry.io/otel/version.go    |    15 +-
 vendor/go.opentelemetry.io/otel/versions.yaml |    54 +-
 vendor/golang.org/x/crypto/blake2b/blake2b.go |   291 +
 .../x/crypto/blake2b/blake2bAVX2_amd64.go     |    37 +
 .../x/crypto/blake2b/blake2bAVX2_amd64.s      |   744 +
 .../x/crypto/blake2b/blake2b_amd64.s          |   278 +
 .../x/crypto/blake2b/blake2b_generic.go       |   182 +
 .../x/crypto/blake2b/blake2b_ref.go           |    11 +
 vendor/golang.org/x/crypto/blake2b/blake2x.go |   177 +
 .../golang.org/x/crypto/blake2b/register.go   |    30 +
 vendor/golang.org/x/crypto/blake2s/blake2s.go |   254 +
 .../x/crypto/blake2s/blake2s_386.go           |    32 +
 .../golang.org/x/crypto/blake2s/blake2s_386.s |   429 +
 .../x/crypto/blake2s/blake2s_amd64.go         |    37 +
 .../x/crypto/blake2s/blake2s_amd64.s          |   432 +
 .../x/crypto/blake2s/blake2s_generic.go       |   178 +
 .../x/crypto/blake2s/blake2s_ref.go           |    17 +
 vendor/golang.org/x/crypto/blake2s/blake2x.go |   178 +
 vendor/golang.org/x/crypto/blowfish/cipher.go |     2 +-
 vendor/golang.org/x/crypto/cast5/cast5.go     |     2 +-
 .../x/crypto/chacha20/chacha_ppc64le.s        |   110 +-
 .../chacha20poly1305/chacha20poly1305.go      |     2 +-
 .../x/crypto/cryptobyte/asn1/asn1.go          |     2 +-
 .../golang.org/x/crypto/cryptobyte/string.go  |     2 +-
 .../x/crypto/curve25519/curve25519.go         |    39 +-
 .../x/crypto/curve25519/curve25519_compat.go  |   105 -
 .../x/crypto/curve25519/curve25519_go120.go   |    46 -
 .../x/crypto/curve25519/internal/field/README |     7 -
 .../x/crypto/curve25519/internal/field/fe.go  |   416 -
 .../curve25519/internal/field/fe_amd64.go     |    15 -
 .../curve25519/internal/field/fe_amd64.s      |   378 -
 .../internal/field/fe_amd64_noasm.go          |    11 -
 .../curve25519/internal/field/fe_arm64.go     |    15 -
 .../curve25519/internal/field/fe_arm64.s      |    42 -
 .../internal/field/fe_arm64_noasm.go          |    11 -
 .../curve25519/internal/field/fe_generic.go   |   264 -
 .../curve25519/internal/field/sync.checkpoint |     1 -
 .../crypto/curve25519/internal/field/sync.sh  |    19 -
 vendor/golang.org/x/crypto/ed25519/ed25519.go |     4 +-
 vendor/golang.org/x/crypto/hkdf/hkdf.go       |     2 +-
 .../x/crypto/internal/poly1305/sum_ppc64le.s  |    14 +-
 .../x/crypto/nacl/secretbox/secretbox.go      |     2 +-
 vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go   |     2 +-
 .../x/crypto/salsa20/salsa/hsalsa20.go        |     2 +-
 vendor/golang.org/x/crypto/salsa20/salsa20.go |     2 +-
 vendor/golang.org/x/crypto/sha3/doc.go        |     2 +-
 vendor/golang.org/x/crypto/sha3/hashes.go     |    42 +-
 .../x/crypto/sha3/hashes_generic.go           |    27 -
 .../golang.org/x/crypto/sha3/hashes_noasm.go  |    23 +
 vendor/golang.org/x/crypto/sha3/register.go   |    18 -
 vendor/golang.org/x/crypto/sha3/sha3.go       |    62 +-
 vendor/golang.org/x/crypto/sha3/sha3_s390x.go |    67 +-
 vendor/golang.org/x/crypto/sha3/shake.go      |    16 +-
 .../golang.org/x/crypto/sha3/shake_generic.go |    19 -
 .../golang.org/x/crypto/sha3/shake_noasm.go   |    15 +
 vendor/golang.org/x/crypto/sha3/xor.go        |    45 +-
 vendor/golang.org/x/crypto/twofish/twofish.go |     2 +-
 vendor/golang.org/x/crypto/xtea/cipher.go     |     2 +-
 .../golang.org/x/net/http/httpguts/httplex.go |    13 +-
 vendor/golang.org/x/net/http2/frame.go        |    40 +-
 vendor/golang.org/x/net/http2/http2.go        |    19 +-
 vendor/golang.org/x/net/http2/pipe.go         |    11 +-
 vendor/golang.org/x/net/http2/server.go       |   116 +-
 vendor/golang.org/x/net/http2/timer.go        |    20 +
 vendor/golang.org/x/net/http2/transport.go    |   234 +-
 .../x/net/http2/writesched_priority.go        |     4 +-
 vendor/golang.org/x/net/proxy/per_host.go     |     8 +-
 vendor/golang.org/x/sys/cpu/cpu.go            |     1 +
 vendor/golang.org/x/sys/cpu/cpu_arm64.go      |    10 +
 vendor/golang.org/x/sys/cpu/cpu_arm64.s       |     8 +
 vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go   |     1 +
 .../golang.org/x/sys/cpu/cpu_linux_arm64.go   |     5 +
 vendor/golang.org/x/sys/unix/aliases.go       |     2 +-
 vendor/golang.org/x/sys/unix/asm_zos_s390x.s  |   665 +-
 vendor/golang.org/x/sys/unix/bpxsvc_zos.go    |   657 +
 vendor/golang.org/x/sys/unix/bpxsvc_zos.s     |   192 +
 vendor/golang.org/x/sys/unix/epoll_zos.go     |   220 -
 vendor/golang.org/x/sys/unix/fstatfs_zos.go   |   163 -
 vendor/golang.org/x/sys/unix/mkerrors.sh      |     2 +
 vendor/golang.org/x/sys/unix/mmap_nomremap.go |     2 +-
 vendor/golang.org/x/sys/unix/mremap.go        |     5 +
 vendor/golang.org/x/sys/unix/pagesize_unix.go |     2 +-
 .../x/sys/unix/readdirent_getdirentries.go    |     2 +-
 vendor/golang.org/x/sys/unix/sockcmsg_zos.go  |    58 +
 .../golang.org/x/sys/unix/symaddr_zos_s390x.s |    75 +
 .../golang.org/x/sys/unix/syscall_darwin.go   |    12 +
 .../x/sys/unix/syscall_darwin_libSystem.go    |     2 +-
 .../golang.org/x/sys/unix/syscall_freebsd.go  |    12 +-
 vendor/golang.org/x/sys/unix/syscall_linux.go |    99 +
 vendor/golang.org/x/sys/unix/syscall_unix.go  |     9 +
 .../x/sys/unix/syscall_zos_s390x.go           |  1509 +-
 vendor/golang.org/x/sys/unix/sysvshm_unix.go  |     2 +-
 .../x/sys/unix/sysvshm_unix_other.go          |     2 +-
 vendor/golang.org/x/sys/unix/zerrors_linux.go |    29 +-
 .../x/sys/unix/zerrors_linux_386.go           |     1 +
 .../x/sys/unix/zerrors_linux_amd64.go         |     1 +
 .../x/sys/unix/zerrors_linux_arm64.go         |     1 +
 .../x/sys/unix/zerrors_zos_s390x.go           |   233 +-
 .../x/sys/unix/zsymaddr_zos_s390x.s           |   364 +
 .../x/sys/unix/zsyscall_darwin_amd64.go       |    33 +
 .../x/sys/unix/zsyscall_darwin_amd64.s        |    10 +
 .../x/sys/unix/zsyscall_darwin_arm64.go       |    33 +
 .../x/sys/unix/zsyscall_darwin_arm64.s        |    10 +
 .../golang.org/x/sys/unix/zsyscall_linux.go   |    10 +
 .../x/sys/unix/zsyscall_zos_s390x.go          |  3113 +-
 .../x/sys/unix/zsysnum_linux_386.go           |     5 +
 .../x/sys/unix/zsysnum_linux_amd64.go         |     5 +
 .../x/sys/unix/zsysnum_linux_arm.go           |     5 +
 .../x/sys/unix/zsysnum_linux_arm64.go         |     5 +
 .../x/sys/unix/zsysnum_linux_loong64.go       |     5 +
 .../x/sys/unix/zsysnum_linux_mips.go          |     5 +
 .../x/sys/unix/zsysnum_linux_mips64.go        |     5 +
 .../x/sys/unix/zsysnum_linux_mips64le.go      |     5 +
 .../x/sys/unix/zsysnum_linux_mipsle.go        |     5 +
 .../x/sys/unix/zsysnum_linux_ppc.go           |     5 +
 .../x/sys/unix/zsysnum_linux_ppc64.go         |     5 +
 .../x/sys/unix/zsysnum_linux_ppc64le.go       |     5 +
 .../x/sys/unix/zsysnum_linux_riscv64.go       |     5 +
 .../x/sys/unix/zsysnum_linux_s390x.go         |     5 +
 .../x/sys/unix/zsysnum_linux_sparc64.go       |     5 +
 .../x/sys/unix/zsysnum_zos_s390x.go           |  5507 ++--
 vendor/golang.org/x/sys/unix/ztypes_linux.go  |   119 +-
 .../golang.org/x/sys/unix/ztypes_linux_386.go |     8 -
 .../x/sys/unix/ztypes_linux_amd64.go          |     9 -
 .../golang.org/x/sys/unix/ztypes_linux_arm.go |     9 -
 .../x/sys/unix/ztypes_linux_arm64.go          |     9 -
 .../x/sys/unix/ztypes_linux_loong64.go        |     9 -
 .../x/sys/unix/ztypes_linux_mips.go           |     9 -
 .../x/sys/unix/ztypes_linux_mips64.go         |     9 -
 .../x/sys/unix/ztypes_linux_mips64le.go       |     9 -
 .../x/sys/unix/ztypes_linux_mipsle.go         |     9 -
 .../golang.org/x/sys/unix/ztypes_linux_ppc.go |     9 -
 .../x/sys/unix/ztypes_linux_ppc64.go          |     9 -
 .../x/sys/unix/ztypes_linux_ppc64le.go        |     9 -
 .../x/sys/unix/ztypes_linux_riscv64.go        |     9 -
 .../x/sys/unix/ztypes_linux_s390x.go          |     9 -
 .../x/sys/unix/ztypes_linux_sparc64.go        |     9 -
 .../golang.org/x/sys/unix/ztypes_zos_s390x.go |   146 +-
 vendor/golang.org/x/sys/windows/aliases.go    |     2 +-
 vendor/golang.org/x/sys/windows/empty.s       |     8 -
 .../x/sys/windows/security_windows.go         |    25 +-
 .../golang.org/x/sys/windows/svc/service.go   |     5 +-
 .../x/sys/windows/syscall_windows.go          |    82 +
 .../golang.org/x/sys/windows/types_windows.go |    24 +
 .../x/sys/windows/zsyscall_windows.go         |   144 +-
 vendor/gopkg.in/yaml.v2/.travis.yml           |    17 -
 vendor/gopkg.in/yaml.v2/LICENSE.libyaml       |    31 -
 vendor/gopkg.in/yaml.v2/README.md             |   133 -
 vendor/gopkg.in/yaml.v2/apic.go               |   744 -
 vendor/gopkg.in/yaml.v2/decode.go             |   815 -
 vendor/gopkg.in/yaml.v2/emitterc.go           |  1685 -
 vendor/gopkg.in/yaml.v2/encode.go             |   390 -
 vendor/gopkg.in/yaml.v2/parserc.go            |  1095 -
 vendor/gopkg.in/yaml.v2/readerc.go            |   412 -
 vendor/gopkg.in/yaml.v2/resolve.go            |   258 -
 vendor/gopkg.in/yaml.v2/scannerc.go           |  2711 --
 vendor/gopkg.in/yaml.v2/sorter.go             |   113 -
 vendor/gopkg.in/yaml.v2/writerc.go            |    26 -
 vendor/gopkg.in/yaml.v2/yaml.go               |   478 -
 vendor/gopkg.in/yaml.v2/yamlh.go              |   739 -
 vendor/gopkg.in/yaml.v2/yamlprivateh.go       |   173 -
 vendor/modules.txt                            |   198 +-
 932 files changed, 114780 insertions(+), 28895 deletions(-)
 create mode 100644 vendor/github.com/andybalholm/brotli/bitwriter.go
 create mode 100644 vendor/github.com/andybalholm/brotli/encoder.go
 create mode 100644 vendor/github.com/andybalholm/brotli/matchfinder/emitter.go
 create mode 100644 vendor/github.com/andybalholm/brotli/matchfinder/m0.go
 create mode 100644 vendor/github.com/andybalholm/brotli/matchfinder/m4.go
 create mode 100644 vendor/github.com/andybalholm/brotli/matchfinder/matchfinder.go
 create mode 100644 vendor/github.com/andybalholm/brotli/matchfinder/textencoder.go
 create mode 100644 vendor/github.com/cloudflare/circl/LICENSE
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x25519/curve.go
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.go
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.h
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x25519/curve_generic.go
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x25519/curve_noasm.go
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x25519/doc.go
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x25519/key.go
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x25519/table.go
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x448/curve.go
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.go
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.h
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x448/curve_generic.go
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x448/curve_noasm.go
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x448/doc.go
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x448/key.go
 create mode 100644 vendor/github.com/cloudflare/circl/dh/x448/table.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/goldilocks/constants.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/goldilocks/isogeny.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/goldilocks/point.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/goldilocks/scalar.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/goldilocks/twist.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/goldilocks/twistPoint.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/goldilocks/twistTables.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/goldilocks/twist_basemult.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/p384/LICENSE
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/p384/arith.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.s
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/p384/arith_arm64.s
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/p384/doc.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/p384/p384.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/p384/p384_generic.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/p384/p384opt.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/p384/point.go
 create mode 100644 vendor/github.com/cloudflare/circl/ecc/p384/tableBase.go
 create mode 100644 vendor/github.com/cloudflare/circl/hpke/aead.go
 create mode 100644 vendor/github.com/cloudflare/circl/hpke/algs.go
 create mode 100644 vendor/github.com/cloudflare/circl/hpke/hpke.go
 create mode 100644 vendor/github.com/cloudflare/circl/hpke/hybridkem.go
 create mode 100644 vendor/github.com/cloudflare/circl/hpke/kembase.go
 create mode 100644 vendor/github.com/cloudflare/circl/hpke/marshal.go
 create mode 100644 vendor/github.com/cloudflare/circl/hpke/shortkem.go
 create mode 100644 vendor/github.com/cloudflare/circl/hpke/util.go
 create mode 100644 vendor/github.com/cloudflare/circl/hpke/xkem.go
 create mode 100644 vendor/github.com/cloudflare/circl/internal/conv/conv.go
 create mode 100644 vendor/github.com/cloudflare/circl/internal/sha3/doc.go
 create mode 100644 vendor/github.com/cloudflare/circl/internal/sha3/hashes.go
 create mode 100644 vendor/github.com/cloudflare/circl/internal/sha3/keccakf.go
 create mode 100644 vendor/github.com/cloudflare/circl/internal/sha3/rc.go
 create mode 100644 vendor/github.com/cloudflare/circl/internal/sha3/sha3.go
 create mode 100644 vendor/github.com/cloudflare/circl/internal/sha3/sha3_s390x.s
 create mode 100644 vendor/github.com/cloudflare/circl/internal/sha3/shake.go
 create mode 100644 vendor/github.com/cloudflare/circl/internal/sha3/xor.go
 rename vendor/{golang.org/x/crypto => github.com/cloudflare/circl/internal}/sha3/xor_generic.go (59%)
 rename vendor/{golang.org/x/crypto => github.com/cloudflare/circl/internal}/sha3/xor_unaligned.go (75%)
 create mode 100644 vendor/github.com/cloudflare/circl/kem/hybrid/ckem.go
 create mode 100644 vendor/github.com/cloudflare/circl/kem/hybrid/hybrid.go
 create mode 100644 vendor/github.com/cloudflare/circl/kem/hybrid/xkem.go
 create mode 100644 vendor/github.com/cloudflare/circl/kem/kem.go
 create mode 100644 vendor/github.com/cloudflare/circl/kem/kyber/kyber1024/kyber.go
 create mode 100644 vendor/github.com/cloudflare/circl/kem/kyber/kyber512/kyber.go
 create mode 100644 vendor/github.com/cloudflare/circl/kem/kyber/kyber768/kyber.go
 create mode 100644 vendor/github.com/cloudflare/circl/math/fp25519/fp.go
 create mode 100644 vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.go
 create mode 100644 vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.h
 create mode 100644 vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s
 create mode 100644 vendor/github.com/cloudflare/circl/math/fp25519/fp_generic.go
 create mode 100644 vendor/github.com/cloudflare/circl/math/fp25519/fp_noasm.go
 create mode 100644 vendor/github.com/cloudflare/circl/math/fp448/fp.go
 create mode 100644 vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.go
 create mode 100644 vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.h
 create mode 100644 vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s
 create mode 100644 vendor/github.com/cloudflare/circl/math/fp448/fp_generic.go
 create mode 100644 vendor/github.com/cloudflare/circl/math/fp448/fp_noasm.go
 create mode 100644 vendor/github.com/cloudflare/circl/math/fp448/fuzzer.go
 create mode 100644 vendor/github.com/cloudflare/circl/math/mlsbset/mlsbset.go
 create mode 100644 vendor/github.com/cloudflare/circl/math/mlsbset/power.go
 create mode 100644 vendor/github.com/cloudflare/circl/math/primes.go
 create mode 100644 vendor/github.com/cloudflare/circl/math/wnaf.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.s
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/internal/common/field.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/internal/common/ntt.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/internal/common/params.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/internal/common/params/params.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/internal/common/poly.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/internal/common/sample.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/internal/common/stubs_amd64.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/cpapke.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/mat.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/params.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/vec.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/kyber.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/cpapke.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/mat.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/params.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/vec.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber512/kyber.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/cpapke.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/mat.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/params.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/vec.go
 create mode 100644 vendor/github.com/cloudflare/circl/pke/kyber/kyber768/kyber.go
 create mode 100644 vendor/github.com/cloudflare/circl/pki/pki.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/aes.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.s
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/field.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/generic.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/ntt.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/pack.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/params.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/params/params.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/poly.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/stubs_amd64.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode2/dilithium.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/dilithium.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/mat.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/pack.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/params.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/rounding.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/sample.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/vec.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode3/dilithium.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/dilithium.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/mat.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/pack.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/params.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/rounding.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/sample.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/vec.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/ed25519/ed25519.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/ed25519/modular.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/ed25519/mult.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/ed25519/point.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/ed25519/pubkey.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/ed25519/pubkey112.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/ed25519/signapi.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/ed25519/tables.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/ed448/ed448.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/ed448/signapi.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/eddilithium2/eddilithium.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/eddilithium2/signapi.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/eddilithium3/eddilithium.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/eddilithium3/signapi.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/schemes/schemes.go
 create mode 100644 vendor/github.com/cloudflare/circl/sign/sign.go
 create mode 100644 vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x.go
 create mode 100644 vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.go
 create mode 100644 vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.s
 create mode 100644 vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.go
 create mode 100644 vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.s
 create mode 100644 vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4stubs_amd64.go
 create mode 100644 vendor/github.com/cloudflare/circl/simd/keccakf1600/fallback.go
 create mode 100644 vendor/github.com/cloudflare/circl/xof/k12/k12.go
 create mode 100644 vendor/github.com/cloudflare/circl/xof/xof.go
 delete mode 100644 vendor/github.com/gaukas/godicttls/.gitignore
 create mode 100644 vendor/github.com/go-logr/logr/SECURITY.md
 rename vendor/{gopkg.in/yaml.v2/NOTICE => github.com/go-logr/logr/context.go} (51%)
 create mode 100644 vendor/github.com/go-logr/logr/context_noslog.go
 create mode 100644 vendor/github.com/go-logr/logr/context_slog.go
 create mode 100644 vendor/github.com/go-logr/logr/funcr/slogsink.go
 create mode 100644 vendor/github.com/go-logr/logr/sloghandler.go
 create mode 100644 vendor/github.com/go-logr/logr/slogr.go
 create mode 100644 vendor/github.com/go-logr/logr/slogsink.go
 delete mode 100644 vendor/github.com/go-openapi/analysis/appveyor.yml
 create mode 100644 vendor/github.com/go-openapi/jsonpointer/.golangci.yml
 delete mode 100644 vendor/github.com/go-openapi/jsonpointer/.travis.yml
 delete mode 100644 vendor/github.com/go-openapi/jsonreference/.travis.yml
 create mode 100644 vendor/github.com/go-openapi/runtime/csv_options.go
 delete mode 100644 vendor/github.com/go-openapi/runtime/middleware/go18.go
 delete mode 100644 vendor/github.com/go-openapi/runtime/middleware/pre_go18.go
 create mode 100644 vendor/github.com/go-openapi/runtime/middleware/ui_options.go
 delete mode 100644 vendor/github.com/go-openapi/spec/appveyor.yml
 delete mode 100644 vendor/github.com/go-openapi/spec/bindata.go
 create mode 100644 vendor/github.com/go-openapi/spec/embed.go
 create mode 100644 vendor/github.com/go-openapi/spec/schemas/jsonschema-draft-04.json
 create mode 100644 vendor/github.com/go-openapi/spec/schemas/v2/schema.json
 delete mode 100644 vendor/github.com/go-openapi/spec/url_go18.go
 create mode 100644 vendor/github.com/go-openapi/swag/BENCHMARK.md
 create mode 100644 vendor/github.com/go-openapi/swag/initialism_index.go
 delete mode 100644 vendor/github.com/go-openapi/swag/post_go18.go
 delete mode 100644 vendor/github.com/go-openapi/swag/post_go19.go
 delete mode 100644 vendor/github.com/go-openapi/swag/pre_go18.go
 delete mode 100644 vendor/github.com/go-openapi/swag/pre_go19.go
 create mode 100644 vendor/github.com/go-openapi/swag/string_bytes.go
 create mode 100644 vendor/github.com/go-openapi/validate/BENCHMARK.md
 delete mode 100644 vendor/github.com/go-openapi/validate/appveyor.yml
 create mode 100644 vendor/github.com/go-openapi/validate/pools.go
 create mode 100644 vendor/github.com/go-openapi/validate/pools_debug.go
 delete mode 100644 vendor/github.com/klauspost/compress/huff0/bytereader.go
 create mode 100644 vendor/github.com/klauspost/reedsolomon/galois_gen_arm64.go
 create mode 100644 vendor/github.com/klauspost/reedsolomon/galois_gen_arm64.s
 create mode 100644 vendor/github.com/klauspost/reedsolomon/galois_gen_switch_arm64.go
 create mode 100644 vendor/github.com/klauspost/reedsolomon/galois_gen_switch_nopshufb_arm64.go
 delete mode 100644 vendor/github.com/klauspost/reedsolomon/galois_notamd64.go
 create mode 100644 vendor/github.com/pion/datachannel/.goreleaser.yml
 delete mode 100644 vendor/github.com/pion/datachannel/AUTHORS.txt
 delete mode 100644 vendor/github.com/pion/datachannel/DESIGN.md
 delete mode 100644 vendor/github.com/pion/interceptor/AUTHORS.txt
 delete mode 100644 vendor/github.com/pion/mdns/AUTHORS.txt
 delete mode 100644 vendor/github.com/pion/rtcp/AUTHORS.txt
 delete mode 100644 vendor/github.com/pion/rtp/AUTHORS.txt
 create mode 100644 vendor/github.com/pion/rtp/payload_types.go
 create mode 100644 vendor/github.com/pion/rtp/vlaextension.go
 delete mode 100644 vendor/github.com/pion/sctp/AUTHORS.txt
 create mode 100644 vendor/github.com/pion/sctp/param_zero_checksum.go
 create mode 100644 vendor/github.com/pion/sctp/queue.go
 create mode 100644 vendor/github.com/pion/sctp/receive_payload_queue.go
 create mode 100644 vendor/github.com/pion/sdp/v3/.goreleaser.yml
 delete mode 100644 vendor/github.com/pion/sdp/v3/AUTHORS.txt
 delete mode 100644 vendor/github.com/pion/sdp/v3/fuzz.go
 create mode 100644 vendor/github.com/pion/sdp/v3/unmarshal_cache.go
 create mode 100644 vendor/github.com/pion/transport/v2/deadline/timer.go
 create mode 100644 vendor/github.com/pion/transport/v2/deadline/timer_generic.go
 create mode 100644 vendor/github.com/pion/transport/v2/deadline/timer_js.go
 create mode 100644 vendor/github.com/pion/turn/v2/internal/server/nonce.go
 create mode 100644 vendor/github.com/pion/webrtc/v3/internal/fmtp/av1.go
 create mode 100644 vendor/github.com/pion/webrtc/v3/internal/fmtp/vp9.go
 create mode 100644 vendor/github.com/refraction-networking/utls/SECURITY.md
 create mode 100644 vendor/github.com/refraction-networking/utls/cache.go
 create mode 100644 vendor/github.com/refraction-networking/utls/cfkem.go
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/LICENSE (100%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/README.md (77%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/alerts.go (99%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/authorization_data_formats.go (98%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/cachedinformationtype_values.go (96%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/certificate_compression_algorithm_ids.go (96%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/certificate_status_types.go (95%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/certificte_types.go (96%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/cipher_suites.go (99%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/clientcertificatetype_identifiers.go (98%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/comp_meth_ids.go (95%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/contenttype.go (97%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/ec_curve_types.go (96%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/ec_point_formats.go (96%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/exttype_values.go (95%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/handshaketype.go (99%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/hashalgorithm.go (97%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/heartbeat_message_types.go (95%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/heartbeat_mode.go (96%)
 create mode 100644 vendor/github.com/refraction-networking/utls/dicttls/hpke_aead_identifiers.go
 rename vendor/github.com/{gaukas/godicttls/kdf_identifiers.go => refraction-networking/utls/dicttls/hpke_kdf_identifiers.go} (52%)
 create mode 100644 vendor/github.com/refraction-networking/utls/dicttls/hpke_kem_identifiers.go
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/psk_key_exchange_mode.go (95%)
 create mode 100644 vendor/github.com/refraction-networking/utls/dicttls/quic_frame_types.go
 create mode 100644 vendor/github.com/refraction-networking/utls/dicttls/quic_transport_error_codes.go
 create mode 100644 vendor/github.com/refraction-networking/utls/dicttls/quic_transport_parameters.go
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/signaturealgorithm.go (98%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/signaturescheme.go (99%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/supplemental_data_formats.go (96%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/supported_groups.go (99%)
 rename vendor/github.com/{gaukas/godicttls => refraction-networking/utls/dicttls}/usermappingtype_values.go (95%)
 create mode 100644 vendor/github.com/refraction-networking/utls/internal/boring/notboring.go
 create mode 100644 vendor/github.com/refraction-networking/utls/internal/quicvarint/protocol/protocol.go
 create mode 100644 vendor/github.com/refraction-networking/utls/internal/quicvarint/varint.go
 create mode 100644 vendor/github.com/refraction-networking/utls/quic.go
 create mode 100644 vendor/github.com/refraction-networking/utls/tls_cf.go
 create mode 100644 vendor/github.com/refraction-networking/utls/u_alias.go
 create mode 100644 vendor/github.com/refraction-networking/utls/u_ech.go
 create mode 100644 vendor/github.com/refraction-networking/utls/u_ech_config.go
 create mode 100644 vendor/github.com/refraction-networking/utls/u_hpke.go
 create mode 100644 vendor/github.com/refraction-networking/utls/u_pre_shared_key.go
 create mode 100644 vendor/github.com/refraction-networking/utls/u_quic.go
 create mode 100644 vendor/github.com/refraction-networking/utls/u_quic_transport_parameters.go
 create mode 100644 vendor/github.com/refraction-networking/utls/u_session_controller.go
 create mode 100644 vendor/github.com/refraction-networking/utls/u_session_ticket.go
 delete mode 100644 vendor/github.com/stretchr/testify/assert/assertion_compare_can_convert.go
 delete mode 100644 vendor/github.com/stretchr/testify/assert/assertion_compare_legacy.go
 create mode 100644 vendor/go.etcd.io/bbolt/.go-version
 create mode 100644 vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/codec_cache.go
 create mode 100644 vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/doc.go
 create mode 100644 vendor/go.opentelemetry.io/otel/.codespellignore
 create mode 100644 vendor/go.opentelemetry.io/otel/.codespellrc
 delete mode 100644 vendor/go.opentelemetry.io/otel/.gitmodules
 create mode 100644 vendor/go.opentelemetry.io/otel/attribute/README.md
 create mode 100644 vendor/go.opentelemetry.io/otel/attribute/filter.go
 create mode 100644 vendor/go.opentelemetry.io/otel/baggage/README.md
 create mode 100644 vendor/go.opentelemetry.io/otel/codes/README.md
 create mode 100644 vendor/go.opentelemetry.io/otel/internal/gen.go
 create mode 100644 vendor/go.opentelemetry.io/otel/internal/global/handler.go
 create mode 100644 vendor/go.opentelemetry.io/otel/internal/global/instruments.go
 create mode 100644 vendor/go.opentelemetry.io/otel/internal/global/meter.go
 create mode 100644 vendor/go.opentelemetry.io/otel/metric.go
 rename vendor/{gopkg.in/yaml.v2 => go.opentelemetry.io/otel/metric}/LICENSE (99%)
 create mode 100644 vendor/go.opentelemetry.io/otel/metric/README.md
 create mode 100644 vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go
 create mode 100644 vendor/go.opentelemetry.io/otel/metric/asyncint64.go
 create mode 100644 vendor/go.opentelemetry.io/otel/metric/config.go
 create mode 100644 vendor/go.opentelemetry.io/otel/metric/doc.go
 create mode 100644 vendor/go.opentelemetry.io/otel/metric/embedded/README.md
 create mode 100644 vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go
 create mode 100644 vendor/go.opentelemetry.io/otel/metric/instrument.go
 create mode 100644 vendor/go.opentelemetry.io/otel/metric/meter.go
 create mode 100644 vendor/go.opentelemetry.io/otel/metric/syncfloat64.go
 create mode 100644 vendor/go.opentelemetry.io/otel/metric/syncint64.go
 create mode 100644 vendor/go.opentelemetry.io/otel/propagation/README.md
 create mode 100644 vendor/go.opentelemetry.io/otel/renovate.json
 create mode 100644 vendor/go.opentelemetry.io/otel/requirements.txt
 delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/internal/http.go
 create mode 100644 vendor/go.opentelemetry.io/otel/semconv/internal/v2/http.go
 create mode 100644 vendor/go.opentelemetry.io/otel/semconv/internal/v2/net.go
 delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.12.0/doc.go
 delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.12.0/exception.go
 delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.12.0/http.go
 delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.12.0/resource.go
 delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.12.0/schema.go
 delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.12.0/trace.go
 create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/README.md
 create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/doc.go
 create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/event.go
 create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/exception.go
 create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/http.go
 create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv/README.md
 create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv/http.go
 create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/resource.go
 create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/schema.go
 create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/trace.go
 create mode 100644 vendor/go.opentelemetry.io/otel/trace/README.md
 create mode 100644 vendor/go.opentelemetry.io/otel/trace/embedded/README.md
 create mode 100644 vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go
 create mode 100644 vendor/go.opentelemetry.io/otel/verify_readmes.sh
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b.go
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b_generic.go
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2b_ref.go
 create mode 100644 vendor/golang.org/x/crypto/blake2b/blake2x.go
 create mode 100644 vendor/golang.org/x/crypto/blake2b/register.go
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s.go
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s_386.go
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s_386.s
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s_generic.go
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2s_ref.go
 create mode 100644 vendor/golang.org/x/crypto/blake2s/blake2x.go
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/curve25519_compat.go
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/curve25519_go120.go
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/README
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe.go
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
 delete mode 100644 vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
 delete mode 100644 vendor/golang.org/x/crypto/sha3/hashes_generic.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/hashes_noasm.go
 delete mode 100644 vendor/golang.org/x/crypto/sha3/register.go
 delete mode 100644 vendor/golang.org/x/crypto/sha3/shake_generic.go
 create mode 100644 vendor/golang.org/x/crypto/sha3/shake_noasm.go
 create mode 100644 vendor/golang.org/x/net/http2/timer.go
 create mode 100644 vendor/golang.org/x/sys/unix/bpxsvc_zos.go
 create mode 100644 vendor/golang.org/x/sys/unix/bpxsvc_zos.s
 delete mode 100644 vendor/golang.org/x/sys/unix/epoll_zos.go
 delete mode 100644 vendor/golang.org/x/sys/unix/fstatfs_zos.go
 create mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_zos.go
 create mode 100644 vendor/golang.org/x/sys/unix/symaddr_zos_s390x.s
 create mode 100644 vendor/golang.org/x/sys/unix/zsymaddr_zos_s390x.s
 delete mode 100644 vendor/golang.org/x/sys/windows/empty.s
 delete mode 100644 vendor/gopkg.in/yaml.v2/.travis.yml
 delete mode 100644 vendor/gopkg.in/yaml.v2/LICENSE.libyaml
 delete mode 100644 vendor/gopkg.in/yaml.v2/README.md
 delete mode 100644 vendor/gopkg.in/yaml.v2/apic.go
 delete mode 100644 vendor/gopkg.in/yaml.v2/decode.go
 delete mode 100644 vendor/gopkg.in/yaml.v2/emitterc.go
 delete mode 100644 vendor/gopkg.in/yaml.v2/encode.go
 delete mode 100644 vendor/gopkg.in/yaml.v2/parserc.go
 delete mode 100644 vendor/gopkg.in/yaml.v2/readerc.go
 delete mode 100644 vendor/gopkg.in/yaml.v2/resolve.go
 delete mode 100644 vendor/gopkg.in/yaml.v2/scannerc.go
 delete mode 100644 vendor/gopkg.in/yaml.v2/sorter.go
 delete mode 100644 vendor/gopkg.in/yaml.v2/writerc.go
 delete mode 100644 vendor/gopkg.in/yaml.v2/yaml.go
 delete mode 100644 vendor/gopkg.in/yaml.v2/yamlh.go
 delete mode 100644 vendor/gopkg.in/yaml.v2/yamlprivateh.go

diff --git a/go.mod b/go.mod
index 4d44b63a..80b3bc4a 100644
--- a/go.mod
+++ b/go.mod
@@ -13,77 +13,77 @@ require (
 	github.com/dchest/siphash v1.2.3 // indirect
 	github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
 	github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19
-	github.com/pion/webrtc/v3 v3.2.24
+	github.com/pion/webrtc/v3 v3.2.44
 	github.com/sevlyar/go-daemon v0.1.6
 	github.com/smartystreets/goconvey v1.6.4
-	github.com/xtaci/kcp-go/v5 v5.6.3
+	github.com/xtaci/kcp-go/v5 v5.6.8
 	github.com/xtaci/smux v1.5.24
 	// Do not update obfs4 past e330d1b7024b, a backwards incompatible change was
 	// made that will break negotiation!! riseup should move to the newest asap.
 	gitlab.com/yawning/obfs4.git v0.0.0-20231012084234-c3e2d44b1033 // indirect
-	golang.org/x/sys v0.17.0
+	golang.org/x/sys v0.22.0
 )
 
 require (
 	0xacab.org/leap/bitmask-core v0.0.0-20240529192952-8ea2f4de269e
 	github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce
 	github.com/prometheus-community/pro-bing v0.4.0
-	github.com/rs/zerolog v1.32.0
-	github.com/stretchr/testify v1.8.4
+	github.com/rs/zerolog v1.33.0
+	github.com/stretchr/testify v1.9.0
 )
 
 require (
 	filippo.io/edwards25519 v1.1.0 // indirect
-	github.com/andybalholm/brotli v1.0.5 // indirect
+	github.com/andybalholm/brotli v1.1.0 // indirect
 	github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
 	github.com/asdine/storm/v3 v3.2.1 // indirect
 	github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6 // indirect
+	github.com/cloudflare/circl v1.3.9 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
-	github.com/gaukas/godicttls v0.0.3 // indirect
-	github.com/go-logr/logr v1.2.3 // indirect
+	github.com/go-logr/logr v1.4.2 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
-	github.com/go-openapi/analysis v0.21.4 // indirect
-	github.com/go-openapi/errors v0.20.4 // indirect
-	github.com/go-openapi/jsonpointer v0.19.5 // indirect
-	github.com/go-openapi/jsonreference v0.20.0 // indirect
-	github.com/go-openapi/loads v0.21.2 // indirect
-	github.com/go-openapi/runtime v0.26.0 // indirect
-	github.com/go-openapi/spec v0.20.8 // indirect
-	github.com/go-openapi/strfmt v0.21.7 // indirect
-	github.com/go-openapi/swag v0.22.4 // indirect
-	github.com/go-openapi/validate v0.22.1 // indirect
+	github.com/go-openapi/analysis v0.23.0 // indirect
+	github.com/go-openapi/errors v0.22.0 // indirect
+	github.com/go-openapi/jsonpointer v0.21.0 // indirect
+	github.com/go-openapi/jsonreference v0.21.0 // indirect
+	github.com/go-openapi/loads v0.22.0 // indirect
+	github.com/go-openapi/runtime v0.28.0 // indirect
+	github.com/go-openapi/spec v0.21.0 // indirect
+	github.com/go-openapi/strfmt v0.23.0 // indirect
+	github.com/go-openapi/swag v0.23.0 // indirect
+	github.com/go-openapi/validate v0.24.0 // indirect
 	github.com/google/uuid v1.6.0 // indirect
 	github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/jtolds/gls v4.20.0+incompatible // indirect
-	github.com/klauspost/compress v1.16.6 // indirect
-	github.com/klauspost/cpuid/v2 v2.2.6 // indirect
-	github.com/klauspost/reedsolomon v1.12.1 // indirect
+	github.com/klauspost/compress v1.17.9 // indirect
+	github.com/klauspost/cpuid/v2 v2.2.8 // indirect
+	github.com/klauspost/reedsolomon v1.12.2 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
 	github.com/mattn/go-colorable v0.1.13 // indirect
-	github.com/mattn/go-isatty v0.0.19 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/mapstructure v1.5.0 // indirect
 	github.com/oklog/ulid v1.3.1 // indirect
 	github.com/opentracing/opentracing-go v1.2.0 // indirect
-	github.com/pion/datachannel v1.5.5 // indirect
-	github.com/pion/dtls/v2 v2.2.9 // indirect
-	github.com/pion/ice/v2 v2.3.12 // indirect
-	github.com/pion/interceptor v0.1.25 // indirect
+	github.com/pion/datachannel v1.5.7 // indirect
+	github.com/pion/dtls/v2 v2.2.11 // indirect
+	github.com/pion/ice/v2 v2.3.28 // indirect
+	github.com/pion/interceptor v0.1.29 // indirect
 	github.com/pion/logging v0.2.2 // indirect
-	github.com/pion/mdns v0.0.9 // indirect
+	github.com/pion/mdns v0.0.12 // indirect
 	github.com/pion/randutil v0.1.0 // indirect
-	github.com/pion/rtcp v1.2.13 // indirect
-	github.com/pion/rtp v1.8.3 // indirect
-	github.com/pion/sctp v1.8.9 // indirect
-	github.com/pion/sdp/v3 v3.0.6 // indirect
+	github.com/pion/rtcp v1.2.14 // indirect
+	github.com/pion/rtp v1.8.6 // indirect
+	github.com/pion/sctp v1.8.18 // indirect
+	github.com/pion/sdp/v3 v3.0.9 // indirect
 	github.com/pion/srtp/v2 v2.0.18 // indirect
 	github.com/pion/stun v0.6.1 // indirect
-	github.com/pion/transport/v2 v2.2.4 // indirect
-	github.com/pion/turn/v2 v2.1.4 // indirect
+	github.com/pion/transport/v2 v2.2.5 // indirect
+	github.com/pion/turn/v2 v2.1.6 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/refraction-networking/utls v1.3.3 // indirect
+	github.com/refraction-networking/utls v1.6.7 // indirect
 	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
 	github.com/templexxx/cpu v0.1.0 // indirect
 	github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
@@ -93,15 +93,15 @@ require (
 	github.com/xtaci/kcp-go v5.4.20+incompatible // indirect
 	gitlab.com/yawning/edwards25519-extra v0.0.0-20231005122941-2149dcafc266 // indirect
 	gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.5.0 // indirect
-	go.etcd.io/bbolt v1.3.7 // indirect
-	go.mongodb.org/mongo-driver v1.11.3 // indirect
-	go.opentelemetry.io/otel v1.14.0 // indirect
-	go.opentelemetry.io/otel/trace v1.14.0 // indirect
-	golang.org/x/crypto v0.19.0 // indirect
-	golang.org/x/net v0.21.0 // indirect
-	golang.org/x/sync v0.6.0 // indirect
-	golang.org/x/text v0.14.0 // indirect
+	go.etcd.io/bbolt v1.3.10 // indirect
+	go.mongodb.org/mongo-driver v1.16.0 // indirect
+	go.opentelemetry.io/otel v1.28.0 // indirect
+	go.opentelemetry.io/otel/metric v1.28.0 // indirect
+	go.opentelemetry.io/otel/trace v1.28.0 // indirect
+	golang.org/x/crypto v0.25.0 // indirect
+	golang.org/x/net v0.27.0 // indirect
+	golang.org/x/sync v0.7.0 // indirect
+	golang.org/x/text v0.16.0 // indirect
 	gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/go.sum b/go.sum
index 56ee9356..5da2143c 100644
--- a/go.sum
+++ b/go.sum
@@ -18,8 +18,6 @@ github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t
 github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
 github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:D+aZah+k14Gn6kmL7eKxoo/4Dr/lK3ChBcwce2+SQP4=
 github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4=
-github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
-github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
 github.com/Sereal/Sereal v0.0.0-20190618215532-0b8ac451a863 h1:BRrxwOZBolJN4gIwvZMJY1tzqBvQgpaZiQRuIDD40jM=
 github.com/Sereal/Sereal v0.0.0-20190618215532-0b8ac451a863/go.mod h1:D0JMgToj/WdxCgd30Kc1UcA9E+WdZoJqeVOuYW7iTBM=
 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
@@ -31,15 +29,14 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
-github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
-github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
+github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
+github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
 github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
 github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
 github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
-github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
 github.com/asdine/storm/v3 v3.2.1 h1:I5AqhkPK6nBZ/qJXySdI7ot5BlXSZ7qvDY1zAn5ZJac=
@@ -59,6 +56,8 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE=
+github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
 github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
@@ -68,7 +67,6 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
 github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
-github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/cretz/bine v0.2.0 h1:8GiDRGlTgz+o8H9DSnsl+5MeBK4HsExxgl6WgzOCuZo=
 github.com/cretz/bine v0.2.0/go.mod h1:WU4o9QR9wWp8AVKtTM1XD5vUHkEqnf2vVSo6dBqbetI=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -92,8 +90,6 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB
 github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/gaukas/godicttls v0.0.3 h1:YNDIf0d9adcxOijiLrEzpfZGAkNwLRzPaG6OjU7EITk=
-github.com/gaukas/godicttls v0.0.3/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@@ -102,72 +98,32 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
 github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
-github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
-github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY=
-github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc=
-github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo=
-github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
-github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
-github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
-github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M=
-github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk=
-github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
-github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
-github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
-github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
-github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g=
-github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro=
-github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw=
-github.com/go-openapi/runtime v0.26.0 h1:HYOFtG00FM1UvqrcxbEJg/SwvDRvYLQKGhw2zaQjTcc=
-github.com/go-openapi/runtime v0.26.0/go.mod h1:QgRGeZwrUcSHdeh4Ka9Glvo0ug1LC5WyE+EV88plZrQ=
-github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
-github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
-github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU=
-github.com/go-openapi/spec v0.20.8/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
-github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg=
-github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k=
-github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg=
-github.com/go-openapi/strfmt v0.21.7 h1:rspiXgNWgeUzhjo1YU01do6qsahtJNByjLVbPLNHb8k=
-github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew=
-github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
-github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
-github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
-github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
-github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
-github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU=
-github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
+github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=
+github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo=
+github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w=
+github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE=
+github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
+github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
+github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
+github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
+github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco=
+github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs=
+github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ=
+github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc=
+github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=
+github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
+github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c=
+github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4=
+github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
+github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
+github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=
+github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
 github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
-github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
-github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
-github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
-github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
-github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
-github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
-github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
-github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
-github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
-github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
-github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
-github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
-github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
-github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
-github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
-github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
-github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
-github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
-github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
-github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
-github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
-github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
-github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
-github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -187,28 +143,24 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
 github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
 github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
 github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
 github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
+github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -249,7 +201,6 @@ github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmK
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
 github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
-github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
 github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
 github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
@@ -264,28 +215,25 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
 github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
 github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
 github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
-github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
-github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
 github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19 h1:WjT3fLi9n8YWh/Ih8Q1LHAPsTqGddPcHqscN+PJ3i68=
 github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19/go.mod h1:hY+WOq6m2FpbvyrI93sMaypsttvaIL5nhVR92dTMUcQ=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk=
-github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
+github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
 github.com/klauspost/cpuid v1.2.4/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
-github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
-github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
+github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
+github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
 github.com/klauspost/reedsolomon v1.9.9/go.mod h1:O7yFFHiQwDR6b2t63KPUpccPtNdp5ADgh1gg4fd12wo=
-github.com/klauspost/reedsolomon v1.12.1 h1:NhWgum1efX1x58daOBGCFWcxtEhOhXKKl1HAPQUp03Q=
-github.com/klauspost/reedsolomon v1.12.1/go.mod h1:nEi5Kjb6QqtbofI6s+cbG/j1da11c96IBYBSnVGtuBs=
+github.com/klauspost/reedsolomon v1.12.2 h1:TC0hlL/tTRxiMNnqHCzKsY11E0fIIKGCoZ2vQoPKIEM=
+github.com/klauspost/reedsolomon v1.12.2/go.mod h1:nEi5Kjb6QqtbofI6s+cbG/j1da11c96IBYBSnVGtuBs=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
-github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -293,21 +241,17 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
 github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
 github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
-github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
 github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
-github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
-github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
 github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
-github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
 github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
@@ -320,8 +264,6 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
 github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
 github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 github.com/mmcloughlin/avo v0.0.0-20200803215136-443f81d77104/go.mod h1:wqKykBG2QzQDJEzvRkcS8x6MiSJkF52hXZsXcjaB3ls=
@@ -329,7 +271,6 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce h1:TqjP/BTDrwN7zP9xyXVuLsMBXYMt6LLYi55PlrIcq8U=
@@ -341,9 +282,7 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE
 github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
 github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
 github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
-github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
 github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
 github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
 github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
@@ -353,13 +292,10 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
 github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
-github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
-github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
-github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
 github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
 github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
@@ -374,51 +310,45 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
 github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
-github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
 github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
 github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
 github.com/pion/datachannel v1.4.21/go.mod h1:oiNyP4gHx2DIwRzX/MFyH0Rz/Gz05OgBlayAI2hAWjg=
-github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8=
-github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0=
+github.com/pion/datachannel v1.5.7 h1:Z2NXdUnAwuHTrjS+CAiLdkfCYaD/Wa+Ly4FShIgICsA=
+github.com/pion/datachannel v1.5.7/go.mod h1:5F8FSGAjVb63JcMmEBm2r6FDQGeijTuFLrE1QsYLVEo=
 github.com/pion/dtls/v2 v2.0.4/go.mod h1:qAkFscX0ZHoI1E07RfYPoRw3manThveu+mlTDdOxoGI=
 github.com/pion/dtls/v2 v2.0.8/go.mod h1:QuDII+8FVvk9Dp5t5vYIMTo7hh7uBkra+8QIm7QGm10=
 github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
-github.com/pion/dtls/v2 v2.2.9 h1:K+D/aVf9/REahQvqk6G5JavdrD8W1PWDKC11UlwN7ts=
-github.com/pion/dtls/v2 v2.2.9/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
+github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks=
+github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=
 github.com/pion/ice/v2 v2.0.15/go.mod h1:ZIiVGevpgAxF/cXiIVmuIUtCb3Xs4gCzCbXB6+nFkSI=
-github.com/pion/ice/v2 v2.3.11/go.mod h1:hPcLC3kxMa+JGRzMHqQzjoSj3xtE9F+eoncmXLlCL4E=
-github.com/pion/ice/v2 v2.3.12 h1:NWKW2b3+oSZS3klbQMIEWQ0i52Kuo0KBg505a5kQv4s=
-github.com/pion/ice/v2 v2.3.12/go.mod h1:hPcLC3kxMa+JGRzMHqQzjoSj3xtE9F+eoncmXLlCL4E=
+github.com/pion/ice/v2 v2.3.28 h1:BivQkL8+RV8HbWxIj0ehHVQfh2d/ZBxU196EqWtYmEo=
+github.com/pion/ice/v2 v2.3.28/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw=
 github.com/pion/interceptor v0.0.10/go.mod h1:qzeuWuD/ZXvPqOnxNcnhWfkCZ2e1kwwslicyyPnhoK4=
-github.com/pion/interceptor v0.1.25 h1:pwY9r7P6ToQ3+IF0bajN0xmk/fNw/suTgaTdlwTDmhc=
-github.com/pion/interceptor v0.1.25/go.mod h1:wkbPYAak5zKsfpVDYMtEfWEy8D4zL+rpxCxPImLOg3Y=
+github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M=
+github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4=
 github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
 github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
 github.com/pion/mdns v0.0.4/go.mod h1:R1sL0p50l42S5lJs91oNdUL58nm0QHrhxnSegr++qC0=
-github.com/pion/mdns v0.0.8/go.mod h1:hYE72WX8WDveIhg7fmXgMKivD3Puklk0Ymzog0lSyaI=
-github.com/pion/mdns v0.0.9 h1:7Ue5KZsqq8EuqStnpPWV33vYYEH0+skdDN5L7EiEsI4=
-github.com/pion/mdns v0.0.9/go.mod h1:2JA5exfxwzXiCihmxpTKgFUpiQws2MnipoPK09vecIc=
+github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8=
+github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk=
 github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
 github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
 github.com/pion/rtcp v1.2.6/go.mod h1:52rMNPWFsjr39z9B9MhnkqhPLoeHTv1aN63o/42bWE0=
-github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I=
 github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
-github.com/pion/rtcp v1.2.13 h1:+EQijuisKwm/8VBs8nWllr0bIndR7Lf7cZG200mpbNo=
-github.com/pion/rtcp v1.2.13/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
+github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE=
+github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
 github.com/pion/rtp v1.6.2/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
-github.com/pion/rtp v1.8.2/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
-github.com/pion/rtp v1.8.3 h1:VEHxqzSVQxCkKDSHro5/4IUUG1ea+MFdqR2R3xSpNU8=
 github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
+github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw=
+github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
 github.com/pion/sctp v1.7.10/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0=
 github.com/pion/sctp v1.7.11/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0=
-github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0=
-github.com/pion/sctp v1.8.8/go.mod h1:igF9nZBrjh5AtmKc7U30jXltsFHicFCXSmWA2GWRaWs=
-github.com/pion/sctp v1.8.9 h1:TP5ZVxV5J7rz7uZmbyvnUvsn7EJ2x/5q9uhsTtXbI3g=
-github.com/pion/sctp v1.8.9/go.mod h1:cMLT45jqw3+jiJCrtHVwfQLnfR0MGZ4rgOJwUOIqLkI=
+github.com/pion/sctp v1.8.18 h1:zsqVBs7WF54QCEWnqve1acj9nc1dL25FllPF6C/bMaI=
+github.com/pion/sctp v1.8.18/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE=
 github.com/pion/sdp/v3 v3.0.4/go.mod h1:bNiSknmJE0HYBprTHXKPQ3+JjacTv5uap92ueJZKsRk=
-github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw=
-github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw=
+github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY=
+github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M=
 github.com/pion/srtp/v2 v2.0.2/go.mod h1:VEyLv4CuxrwGY8cxM+Ng3bmVy8ckz/1t6A0q/msKOw0=
 github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo=
 github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA=
@@ -430,24 +360,25 @@ github.com/pion/transport v0.10.0/go.mod h1:BnHnUipd0rZQyTVB2SBGojFHT9CBt5C5TcsJ
 github.com/pion/transport v0.10.1/go.mod h1:PBis1stIILMiis0PewDw91WJeLJkyIMcEk+DwKOzf4A=
 github.com/pion/transport v0.12.1/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q=
 github.com/pion/transport v0.12.2/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q=
+github.com/pion/transport v0.12.3 h1:vdBfvfU/0Wq8kd2yhUMSDB/x+O4Z9MYVl2fJ5BT4JZw=
 github.com/pion/transport v0.12.3/go.mod h1:OViWW9SP2peE/HbwBvARicmAVnesphkNkCVZIWJ6q9A=
-github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40=
-github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI=
 github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
 github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc=
 github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
-github.com/pion/transport/v2 v2.2.4 h1:41JJK6DZQYSeVLxILA2+F4ZkKb4Xd/tFJZRFZQ9QAlo=
 github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
-github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM=
+github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc=
+github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
 github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
+github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4=
+github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0=
 github.com/pion/turn/v2 v2.0.5/go.mod h1:APg43CFyt/14Uy7heYUOGWdkem/Wu4PhCO/bjyrTqMw=
 github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
-github.com/pion/turn/v2 v2.1.4 h1:2xn8rduI5W6sCZQkEnIUDAkrBQNl2eYIBCHMZ3QMmP8=
-github.com/pion/turn/v2 v2.1.4/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
+github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc=
+github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
 github.com/pion/udp v0.1.0/go.mod h1:BPELIjbwE9PRbd/zxI/KYBnbo7B6+oA6YuEaNE8lths=
 github.com/pion/webrtc/v3 v3.0.15/go.mod h1:uUt2nRSsCnK/nfzTAfOmaeLan26ZJ0aP9iwjc/gcC2Y=
-github.com/pion/webrtc/v3 v3.2.24 h1:MiFL5DMo2bDaaIFWr0DDpwiV/L4EGbLZb+xoRvfEo1Y=
-github.com/pion/webrtc/v3 v3.2.24/go.mod h1:1CaT2fcZzZ6VZA+O1i9yK2DU4EOcXVvSbWG9pr5jefs=
+github.com/pion/webrtc/v3 v3.2.44 h1:wL2X6xSVneYvNRWMdroHoiNAkF2rM6IIhV/oIz+iwJs=
+github.com/pion/webrtc/v3 v3.2.44/go.mod h1:WRHWtbUNNtph0/FWtExX8cQl4EIpPrZec6gQf1tV6GE=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -482,15 +413,15 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
 github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
 github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/refraction-networking/utls v1.3.3 h1:f/TBLX7KBciRyFH3bwupp+CE4fzoYKCirhdRcC490sw=
-github.com/refraction-networking/utls v1.3.3/go.mod h1:DlecWW1LMlMJu+9qpzzQqdHDT/C2LAe03EdpLUz/RL8=
+github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
+github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
-github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
+github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
 github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
-github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
-github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
+github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
+github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
 github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
@@ -500,8 +431,6 @@ github.com/sevlyar/go-daemon v0.1.6 h1:EUh1MDjEM4BI109Jign0EaknA2izkOyi0LV3ro3QQ
 github.com/sevlyar/go-daemon v0.1.6/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
@@ -512,7 +441,6 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
 github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
 github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
@@ -520,6 +448,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -528,10 +457,10 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
 github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/templexxx/cpu v0.0.1/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
 github.com/templexxx/cpu v0.0.7/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
 github.com/templexxx/cpu v0.1.0 h1:wVM+WIJP2nYaxVxqgHPD4wGA2aJ9rvrQRV8CvFzNb40=
@@ -543,8 +472,6 @@ github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mn
 github.com/templexxx/xorsimd v0.4.1/go.mod h1:W+ffZz8jJMH2SXwuKu9WhygqBMbFnp14G2fqEr8qaNo=
 github.com/templexxx/xorsimd v0.4.2 h1:ocZZ+Nvu65LGHmCLZ7OoCtg8Fx8jnHKK37SjvngUoVI=
 github.com/templexxx/xorsimd v0.4.2/go.mod h1:HgwaPoDREdi6OnULpSfxhzaiiSUY4Fi3JPn1wpt28NI=
-github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
-github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
 github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
 github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
 github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
@@ -553,27 +480,20 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
 github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
 github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
-github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
-github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
-github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
-github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
-github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/xtaci/kcp-go v5.4.20+incompatible h1:TN1uey3Raw0sTz0Fg8GkfM0uH3YwzhnZWQ1bABv5xAg=
 github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
 github.com/xtaci/kcp-go/v5 v5.6.1/go.mod h1:W3kVPyNYwZ06p79dNwFWQOVFrdcBpDBsdyvK8moQrYo=
-github.com/xtaci/kcp-go/v5 v5.6.3 h1:yd59SKXdJ0PBxeMBy3apalxFCEmBLGgQmL6nP46tU0g=
-github.com/xtaci/kcp-go/v5 v5.6.3/go.mod h1:uIuw2KEg3FcmEdS4PeXHaGty9Ui7NYb1WKIrSDwpMg4=
+github.com/xtaci/kcp-go/v5 v5.6.8 h1:jlI/0jAyjoOjT/SaGB58s4bQMJiNS41A2RKzR6TMWeI=
+github.com/xtaci/kcp-go/v5 v5.6.8/go.mod h1:oE9j2NVqAkuKO5o8ByKGch3vgVX3BNf8zqP8JiGq0bM=
 github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
 github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E=
 github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0=
 github.com/xtaci/smux v1.5.15/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
 github.com/xtaci/smux v1.5.24 h1:77emW9dtnOxxOQ5ltR+8BbsX1kzcOxQ5gB+aaV9hXOY=
 github.com/xtaci/smux v1.5.24/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
-github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 gitlab.com/yawning/edwards25519-extra v0.0.0-20231005122941-2149dcafc266 h1:IvjshROr8z24+UCiOe/90cUWt3QDr8Rt+VkUjZsn+i0=
 gitlab.com/yawning/edwards25519-extra v0.0.0-20231005122941-2149dcafc266/go.mod h1:K/3SQWdJL6udzwInHk1gaYaECYxMp9dDayniPq6gCSo=
@@ -583,23 +503,22 @@ gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.5.0 h1
 gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.5.0/go.mod h1:70bhd4JKW/+1HLfm+TMrgHJsUHG4coelMWwiVEJ2gAg=
 go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
-go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
-go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
+go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0=
+go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ=
 go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
-go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
-go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng=
-go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8=
-go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y=
-go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
+go.mongodb.org/mongo-driver v1.16.0 h1:tpRsfBJMROVHKpdGyc1BBEzzjDUWjItxbVSZ8Ls4BQ4=
+go.mongodb.org/mongo-driver v1.16.0/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw=
 go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
 go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
-go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
-go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY=
-go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM=
-go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
-go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
+go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
+go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
+go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
+go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
+go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
+go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
+go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
+go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
 go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
@@ -611,12 +530,10 @@ golang.org/x/arch v0.0.0-20190909030613-46d78d1859ac/go.mod h1:flIaEI6LNU6xOCD5P
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -625,14 +542,13 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP
 golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
-golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
 golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
 golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
 golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
-golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
-golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
+golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
+golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
+golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -669,44 +585,35 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
 golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
-golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
-golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
 golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
 golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
-golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
-golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
-golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
+golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
+golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
+golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
-golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -716,12 +623,9 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -738,19 +642,15 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210317225723-c4fcb01b228e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -759,34 +659,32 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
-golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
+golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
-golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
 golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
 golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
 golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
+golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
+golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -797,11 +695,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -809,7 +703,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -843,15 +736,12 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
 google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
 google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
-google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
@@ -868,14 +758,8 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
-gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/vendor/github.com/andybalholm/brotli/README.md b/vendor/github.com/andybalholm/brotli/README.md
index 1ea7fdb7..00625211 100644
--- a/vendor/github.com/andybalholm/brotli/README.md
+++ b/vendor/github.com/andybalholm/brotli/README.md
@@ -2,6 +2,13 @@ This package is a brotli compressor and decompressor implemented in Go.
 It was translated from the reference implementation (https://github.com/google/brotli)
 with the `c2go` tool at https://github.com/andybalholm/c2go.
 
+I have been working on new compression algorithms (not translated from C)
+in the matchfinder package.
+You can use them with the NewWriterV2 function.
+Currently they give better results than the old implementation
+(at least for compressing my test file, Newton’s *Opticks*) 
+on levels 2 to 6.
+
 I am using it in production with https://github.com/andybalholm/redwood.
 
 API documentation is found at https://pkg.go.dev/github.com/andybalholm/brotli?tab=doc.
diff --git a/vendor/github.com/andybalholm/brotli/bitwriter.go b/vendor/github.com/andybalholm/brotli/bitwriter.go
new file mode 100644
index 00000000..dfc60360
--- /dev/null
+++ b/vendor/github.com/andybalholm/brotli/bitwriter.go
@@ -0,0 +1,56 @@
+package brotli
+
+/* Copyright 2010 Google Inc. All Rights Reserved.
+
+   Distributed under MIT license.
+   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
+*/
+
+/* Write bits into a byte array. */
+
+type bitWriter struct {
+	dst []byte
+
+	// Data waiting to be written is the low nbits of bits.
+	bits  uint64
+	nbits uint
+}
+
+func (w *bitWriter) writeBits(nb uint, b uint64) {
+	w.bits |= b << w.nbits
+	w.nbits += nb
+	if w.nbits >= 32 {
+		bits := w.bits
+		w.bits >>= 32
+		w.nbits -= 32
+		w.dst = append(w.dst,
+			byte(bits),
+			byte(bits>>8),
+			byte(bits>>16),
+			byte(bits>>24),
+		)
+	}
+}
+
+func (w *bitWriter) writeSingleBit(bit bool) {
+	if bit {
+		w.writeBits(1, 1)
+	} else {
+		w.writeBits(1, 0)
+	}
+}
+
+func (w *bitWriter) jumpToByteBoundary() {
+	dst := w.dst
+	for w.nbits != 0 {
+		dst = append(dst, byte(w.bits))
+		w.bits >>= 8
+		if w.nbits > 8 { // Avoid underflow
+			w.nbits -= 8
+		} else {
+			w.nbits = 0
+		}
+	}
+	w.bits = 0
+	w.dst = dst
+}
diff --git a/vendor/github.com/andybalholm/brotli/brotli_bit_stream.go b/vendor/github.com/andybalholm/brotli/brotli_bit_stream.go
index 7acfb180..ee655298 100644
--- a/vendor/github.com/andybalholm/brotli/brotli_bit_stream.go
+++ b/vendor/github.com/andybalholm/brotli/brotli_bit_stream.go
@@ -7,12 +7,18 @@ import (
 
 const maxHuffmanTreeSize = (2*numCommandSymbols + 1)
 
-/* The maximum size of Huffman dictionary for distances assuming that
-   NPOSTFIX = 0 and NDIRECT = 0. */
+/*
+The maximum size of Huffman dictionary for distances assuming that
+
+	NPOSTFIX = 0 and NDIRECT = 0.
+*/
 const maxSimpleDistanceAlphabetSize = 140
 
-/* Represents the range of values belonging to a prefix code:
-   [offset, offset + 2^nbits) */
+/*
+Represents the range of values belonging to a prefix code:
+
+	[offset, offset + 2^nbits)
+*/
 type prefixCodeRange struct {
 	offset uint32
 	nbits  uint32
@@ -96,9 +102,12 @@ func nextBlockTypeCode(calculator *blockTypeCodeCalculator, type_ byte) uint {
 	return type_code
 }
 
-/* |nibblesbits| represents the 2 bits to encode MNIBBLES (0-3)
-   REQUIRES: length > 0
-   REQUIRES: length <= (1 << 24) */
+/*
+|nibblesbits| represents the 2 bits to encode MNIBBLES (0-3)
+
+	REQUIRES: length > 0
+	REQUIRES: length <= (1 << 24)
+*/
 func encodeMlen(length uint, bits *uint64, numbits *uint, nibblesbits *uint64) {
 	var lg uint
 	if length == 1 {
@@ -132,8 +141,11 @@ func storeCommandExtra(cmd *command, storage_ix *uint, storage []byte) {
 	writeBits(uint(insnumextra+getCopyExtra(copycode)), bits, storage_ix, storage)
 }
 
-/* Data structure that stores almost everything that is needed to encode each
-   block switch command. */
+/*
+Data structure that stores almost everything that is needed to encode each
+
+	block switch command.
+*/
 type blockSplitCode struct {
 	type_code_calculator blockTypeCodeCalculator
 	type_depths          [maxBlockTypeSymbols]byte
@@ -154,9 +166,12 @@ func storeVarLenUint8(n uint, storage_ix *uint, storage []byte) {
 	}
 }
 
-/* Stores the compressed meta-block header.
-   REQUIRES: length > 0
-   REQUIRES: length <= (1 << 24) */
+/*
+Stores the compressed meta-block header.
+
+	REQUIRES: length > 0
+	REQUIRES: length <= (1 << 24)
+*/
 func storeCompressedMetaBlockHeader(is_final_block bool, length uint, storage_ix *uint, storage []byte) {
 	var lenbits uint64
 	var nlenbits uint
@@ -186,9 +201,12 @@ func storeCompressedMetaBlockHeader(is_final_block bool, length uint, storage_ix
 	}
 }
 
-/* Stores the uncompressed meta-block header.
-   REQUIRES: length > 0
-   REQUIRES: length <= (1 << 24) */
+/*
+Stores the uncompressed meta-block header.
+
+	REQUIRES: length > 0
+	REQUIRES: length <= (1 << 24)
+*/
 func storeUncompressedMetaBlockHeader(length uint, storage_ix *uint, storage []byte) {
 	var lenbits uint64
 	var nlenbits uint
@@ -312,8 +330,11 @@ func storeSimpleHuffmanTree(depths []byte, symbols []uint, num_symbols uint, max
 	}
 }
 
-/* num = alphabet size
-   depths = symbol depths */
+/*
+num = alphabet size
+
+	depths = symbol depths
+*/
 func storeHuffmanTree(depths []byte, num uint, tree []huffmanTree, storage_ix *uint, storage []byte) {
 	var huffman_tree [numCommandSymbols]byte
 	var huffman_tree_extra_bits [numCommandSymbols]byte
@@ -367,8 +388,11 @@ func storeHuffmanTree(depths []byte, num uint, tree []huffmanTree, storage_ix *u
 	storeHuffmanTreeToBitMask(huffman_tree_size, huffman_tree[:], huffman_tree_extra_bits[:], code_length_bitdepth[:], code_length_bitdepth_symbols[:], storage_ix, storage)
 }
 
-/* Builds a Huffman tree from histogram[0:length] into depth[0:length] and
-   bits[0:length] and stores the encoded tree to the bit stream. */
+/*
+Builds a Huffman tree from histogram[0:length] into depth[0:length] and
+
+	bits[0:length] and stores the encoded tree to the bit stream.
+*/
 func buildAndStoreHuffmanTree(histogram []uint32, histogram_length uint, alphabet_size uint, tree []huffmanTree, depth []byte, bits []uint16, storage_ix *uint, storage []byte) {
 	var count uint = 0
 	var s4 = [4]uint{0}
@@ -623,6 +647,203 @@ func buildAndStoreHuffmanTreeFast(histogram []uint32, histogram_total uint, max_
 	}
 }
 
+func buildAndStoreHuffmanTreeFastBW(histogram []uint32, histogram_total uint, max_bits uint, depth []byte, bits []uint16, bw *bitWriter) {
+	var count uint = 0
+	var symbols = [4]uint{0}
+	var length uint = 0
+	var total uint = histogram_total
+	for total != 0 {
+		if histogram[length] != 0 {
+			if count < 4 {
+				symbols[count] = length
+			}
+
+			count++
+			total -= uint(histogram[length])
+		}
+
+		length++
+	}
+
+	if count <= 1 {
+		bw.writeBits(4, 1)
+		bw.writeBits(max_bits, uint64(symbols[0]))
+		depth[symbols[0]] = 0
+		bits[symbols[0]] = 0
+		return
+	}
+
+	for i := 0; i < int(length); i++ {
+		depth[i] = 0
+	}
+	{
+		var max_tree_size uint = 2*length + 1
+		tree, _ := huffmanTreePool.Get().(*[]huffmanTree)
+		if tree == nil || cap(*tree) < int(max_tree_size) {
+			tmp := make([]huffmanTree, max_tree_size)
+			tree = &tmp
+		} else {
+			*tree = (*tree)[:max_tree_size]
+		}
+		var count_limit uint32
+		for count_limit = 1; ; count_limit *= 2 {
+			var node int = 0
+			var l uint
+			for l = length; l != 0; {
+				l--
+				if histogram[l] != 0 {
+					if histogram[l] >= count_limit {
+						initHuffmanTree(&(*tree)[node:][0], histogram[l], -1, int16(l))
+					} else {
+						initHuffmanTree(&(*tree)[node:][0], count_limit, -1, int16(l))
+					}
+
+					node++
+				}
+			}
+			{
+				var n int = node
+				/* Points to the next leaf node. */ /* Points to the next non-leaf node. */
+				var sentinel huffmanTree
+				var i int = 0
+				var j int = n + 1
+				var k int
+
+				sortHuffmanTreeItems(*tree, uint(n), huffmanTreeComparator(sortHuffmanTree1))
+
+				/* The nodes are:
+				   [0, n): the sorted leaf nodes that we start with.
+				   [n]: we add a sentinel here.
+				   [n + 1, 2n): new parent nodes are added here, starting from
+				                (n+1). These are naturally in ascending order.
+				   [2n]: we add a sentinel at the end as well.
+				   There will be (2n+1) elements at the end. */
+				initHuffmanTree(&sentinel, math.MaxUint32, -1, -1)
+
+				(*tree)[node] = sentinel
+				node++
+				(*tree)[node] = sentinel
+				node++
+
+				for k = n - 1; k > 0; k-- {
+					var left int
+					var right int
+					if (*tree)[i].total_count_ <= (*tree)[j].total_count_ {
+						left = i
+						i++
+					} else {
+						left = j
+						j++
+					}
+
+					if (*tree)[i].total_count_ <= (*tree)[j].total_count_ {
+						right = i
+						i++
+					} else {
+						right = j
+						j++
+					}
+
+					/* The sentinel node becomes the parent node. */
+					(*tree)[node-1].total_count_ = (*tree)[left].total_count_ + (*tree)[right].total_count_
+
+					(*tree)[node-1].index_left_ = int16(left)
+					(*tree)[node-1].index_right_or_value_ = int16(right)
+
+					/* Add back the last sentinel node. */
+					(*tree)[node] = sentinel
+					node++
+				}
+
+				if setDepth(2*n-1, *tree, depth, 14) {
+					/* We need to pack the Huffman tree in 14 bits. If this was not
+					   successful, add fake entities to the lowest values and retry. */
+					break
+				}
+			}
+		}
+
+		huffmanTreePool.Put(tree)
+	}
+
+	convertBitDepthsToSymbols(depth, length, bits)
+	if count <= 4 {
+		var i uint
+
+		/* value of 1 indicates a simple Huffman code */
+		bw.writeBits(2, 1)
+
+		bw.writeBits(2, uint64(count)-1) /* NSYM - 1 */
+
+		/* Sort */
+		for i = 0; i < count; i++ {
+			var j uint
+			for j = i + 1; j < count; j++ {
+				if depth[symbols[j]] < depth[symbols[i]] {
+					var tmp uint = symbols[j]
+					symbols[j] = symbols[i]
+					symbols[i] = tmp
+				}
+			}
+		}
+
+		if count == 2 {
+			bw.writeBits(max_bits, uint64(symbols[0]))
+			bw.writeBits(max_bits, uint64(symbols[1]))
+		} else if count == 3 {
+			bw.writeBits(max_bits, uint64(symbols[0]))
+			bw.writeBits(max_bits, uint64(symbols[1]))
+			bw.writeBits(max_bits, uint64(symbols[2]))
+		} else {
+			bw.writeBits(max_bits, uint64(symbols[0]))
+			bw.writeBits(max_bits, uint64(symbols[1]))
+			bw.writeBits(max_bits, uint64(symbols[2]))
+			bw.writeBits(max_bits, uint64(symbols[3]))
+
+			/* tree-select */
+			bw.writeSingleBit(depth[symbols[0]] == 1)
+		}
+	} else {
+		var previous_value byte = 8
+		var i uint
+
+		/* Complex Huffman Tree */
+		storeStaticCodeLengthCodeBW(bw)
+
+		/* Actual RLE coding. */
+		for i = 0; i < length; {
+			var value byte = depth[i]
+			var reps uint = 1
+			var k uint
+			for k = i + 1; k < length && depth[k] == value; k++ {
+				reps++
+			}
+
+			i += reps
+			if value == 0 {
+				bw.writeBits(uint(kZeroRepsDepth[reps]), kZeroRepsBits[reps])
+			} else {
+				if previous_value != value {
+					bw.writeBits(uint(kCodeLengthDepth[value]), uint64(kCodeLengthBits[value]))
+					reps--
+				}
+
+				if reps < 3 {
+					for reps != 0 {
+						reps--
+						bw.writeBits(uint(kCodeLengthDepth[value]), uint64(kCodeLengthBits[value]))
+					}
+				} else {
+					reps -= 3
+					bw.writeBits(uint(kNonZeroRepsDepth[reps]), kNonZeroRepsBits[reps])
+				}
+
+				previous_value = value
+			}
+		}
+	}
+}
+
 func indexOf(v []byte, v_size uint, value byte) uint {
 	var i uint = 0
 	for ; i < v_size; i++ {
@@ -674,12 +895,15 @@ func moveToFrontTransform(v_in []uint32, v_size uint, v_out []uint32) {
 	}
 }
 
-/* Finds runs of zeros in v[0..in_size) and replaces them with a prefix code of
-   the run length plus extra bits (lower 9 bits is the prefix code and the rest
-   are the extra bits). Non-zero values in v[] are shifted by
-   *max_length_prefix. Will not create prefix codes bigger than the initial
-   value of *max_run_length_prefix. The prefix code of run length L is simply
-   Log2Floor(L) and the number of extra bits is the same as the prefix code. */
+/*
+Finds runs of zeros in v[0..in_size) and replaces them with a prefix code of
+
+	the run length plus extra bits (lower 9 bits is the prefix code and the rest
+	are the extra bits). Non-zero values in v[] are shifted by
+	*max_length_prefix. Will not create prefix codes bigger than the initial
+	value of *max_run_length_prefix. The prefix code of run length L is simply
+	Log2Floor(L) and the number of extra bits is the same as the prefix code.
+*/
 func runLengthCodeZeros(in_size uint, v []uint32, out_size *uint, max_run_length_prefix *uint32) {
 	var max_reps uint32 = 0
 	var i uint
@@ -799,8 +1023,11 @@ func storeBlockSwitch(code *blockSplitCode, block_len uint32, block_type byte, i
 	writeBits(uint(len_nextra), uint64(len_extra), storage_ix, storage)
 }
 
-/* Builds a BlockSplitCode data structure from the block split given by the
-   vector of block types and block lengths and stores it to the bit stream. */
+/*
+Builds a BlockSplitCode data structure from the block split given by the
+
+	vector of block types and block lengths and stores it to the bit stream.
+*/
 func buildAndStoreBlockSplitCode(types []byte, lengths []uint32, num_blocks uint, num_types uint, tree []huffmanTree, code *blockSplitCode, storage_ix *uint, storage []byte) {
 	var type_histo [maxBlockTypeSymbols]uint32
 	var length_histo [numBlockLenSymbols]uint32
@@ -919,14 +1146,20 @@ func cleanupBlockEncoder(self *blockEncoder) {
 	blockEncoderPool.Put(self)
 }
 
-/* Creates entropy codes of block lengths and block types and stores them
-   to the bit stream. */
+/*
+Creates entropy codes of block lengths and block types and stores them
+
+	to the bit stream.
+*/
 func buildAndStoreBlockSwitchEntropyCodes(self *blockEncoder, tree []huffmanTree, storage_ix *uint, storage []byte) {
 	buildAndStoreBlockSplitCode(self.block_types_, self.block_lengths_, self.num_blocks_, self.num_block_types_, tree, &self.block_split_code_, storage_ix, storage)
 }
 
-/* Stores the next symbol with the entropy code of the current block type.
-   Updates the block type and block length at block boundaries. */
+/*
+Stores the next symbol with the entropy code of the current block type.
+
+	Updates the block type and block length at block boundaries.
+*/
 func storeSymbol(self *blockEncoder, symbol uint, storage_ix *uint, storage []byte) {
 	if self.block_len_ == 0 {
 		self.block_ix_++
@@ -945,9 +1178,12 @@ func storeSymbol(self *blockEncoder, symbol uint, storage_ix *uint, storage []by
 	}
 }
 
-/* Stores the next symbol with the entropy code of the current block type and
-   context value.
-   Updates the block type and block length at block boundaries. */
+/*
+Stores the next symbol with the entropy code of the current block type and
+
+	context value.
+	Updates the block type and block length at block boundaries.
+*/
 func storeSymbolWithContext(self *blockEncoder, symbol uint, context uint, context_map []uint32, storage_ix *uint, storage []byte, context_bits uint) {
 	if self.block_len_ == 0 {
 		self.block_ix_++
@@ -1268,8 +1504,11 @@ func storeMetaBlockFast(input []byte, start_pos uint, length uint, mask uint, is
 	}
 }
 
-/* This is for storing uncompressed blocks (simple raw storage of
-   bytes-as-bytes). */
+/*
+This is for storing uncompressed blocks (simple raw storage of
+
+	bytes-as-bytes).
+*/
 func storeUncompressedMetaBlock(is_final_block bool, input []byte, position uint, mask uint, len uint, storage_ix *uint, storage []byte) {
 	var masked_pos uint = position & mask
 	storeUncompressedMetaBlockHeader(uint(len), storage_ix, storage)
diff --git a/vendor/github.com/andybalholm/brotli/compress_fragment_two_pass.go b/vendor/github.com/andybalholm/brotli/compress_fragment_two_pass.go
index 172dc7f4..79f9c7fd 100644
--- a/vendor/github.com/andybalholm/brotli/compress_fragment_two_pass.go
+++ b/vendor/github.com/andybalholm/brotli/compress_fragment_two_pass.go
@@ -39,8 +39,11 @@ func isMatch1(p1 []byte, p2 []byte, length uint) bool {
 	return p1[4] == p2[4] && p1[5] == p2[5]
 }
 
-/* Builds a command and distance prefix code (each 64 symbols) into "depth" and
-   "bits" based on "histogram" and stores it into the bit stream. */
+/*
+Builds a command and distance prefix code (each 64 symbols) into "depth" and
+
+	"bits" based on "histogram" and stores it into the bit stream.
+*/
 func buildAndStoreCommandPrefixCode(histogram []uint32, depth []byte, bits []uint16, storage_ix *uint, storage []byte) {
 	var tree [129]huffmanTree
 	var cmd_depth = [numCommandSymbols]byte{0}
@@ -216,6 +219,25 @@ func storeMetaBlockHeader(len uint, is_uncompressed bool, storage_ix *uint, stor
 	writeSingleBit(is_uncompressed, storage_ix, storage)
 }
 
+func storeMetaBlockHeaderBW(len uint, is_uncompressed bool, bw *bitWriter) {
+	var nibbles uint = 6
+
+	/* ISLAST */
+	bw.writeBits(1, 0)
+
+	if len <= 1<<16 {
+		nibbles = 4
+	} else if len <= 1<<20 {
+		nibbles = 5
+	}
+
+	bw.writeBits(2, uint64(nibbles)-4)
+	bw.writeBits(nibbles*4, uint64(len)-1)
+
+	/* ISUNCOMPRESSED */
+	bw.writeSingleBit(is_uncompressed)
+}
+
 func createCommands(input []byte, block_size uint, input_size uint, base_ip_ptr []byte, table []int, table_bits uint, min_match uint, literals *[]byte, commands *[]uint32) {
 	var ip int = 0
 	var shift uint = 64 - table_bits
@@ -710,19 +732,22 @@ func compressFragmentTwoPassImpl(input []byte, input_size uint, is_last bool, co
 	}
 }
 
-/* Compresses "input" string to the "*storage" buffer as one or more complete
-   meta-blocks, and updates the "*storage_ix" bit position.
+/*
+Compresses "input" string to the "*storage" buffer as one or more complete
 
-   If "is_last" is 1, emits an additional empty last meta-block.
+	meta-blocks, and updates the "*storage_ix" bit position.
 
-   REQUIRES: "input_size" is greater than zero, or "is_last" is 1.
-   REQUIRES: "input_size" is less or equal to maximal metablock size (1 << 24).
-   REQUIRES: "command_buf" and "literal_buf" point to at least
-              kCompressFragmentTwoPassBlockSize long arrays.
-   REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero.
-   REQUIRES: "table_size" is a power of two
-   OUTPUT: maximal copy distance <= |input_size|
-   OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18) */
+	If "is_last" is 1, emits an additional empty last meta-block.
+
+	REQUIRES: "input_size" is greater than zero, or "is_last" is 1.
+	REQUIRES: "input_size" is less or equal to maximal metablock size (1 << 24).
+	REQUIRES: "command_buf" and "literal_buf" point to at least
+	           kCompressFragmentTwoPassBlockSize long arrays.
+	REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero.
+	REQUIRES: "table_size" is a power of two
+	OUTPUT: maximal copy distance <= |input_size|
+	OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18)
+*/
 func compressFragmentTwoPass(input []byte, input_size uint, is_last bool, command_buf []uint32, literal_buf []byte, table []int, table_size uint, storage_ix *uint, storage []byte) {
 	var initial_storage_ix uint = *storage_ix
 	var table_bits uint = uint(log2FloorNonZero(table_size))
diff --git a/vendor/github.com/andybalholm/brotli/encoder.go b/vendor/github.com/andybalholm/brotli/encoder.go
new file mode 100644
index 00000000..650d1e42
--- /dev/null
+++ b/vendor/github.com/andybalholm/brotli/encoder.go
@@ -0,0 +1,168 @@
+package brotli
+
+import "github.com/andybalholm/brotli/matchfinder"
+
+// An Encoder implements the matchfinder.Encoder interface, writing in Brotli format.
+type Encoder struct {
+	wroteHeader bool
+	bw          bitWriter
+	distCache   []distanceCode
+}
+
+func (e *Encoder) Reset() {
+	e.wroteHeader = false
+	e.bw = bitWriter{}
+}
+
+func (e *Encoder) Encode(dst []byte, src []byte, matches []matchfinder.Match, lastBlock bool) []byte {
+	e.bw.dst = dst
+	if !e.wroteHeader {
+		e.bw.writeBits(4, 15)
+		e.wroteHeader = true
+	}
+
+	var literalHisto [256]uint32
+	var commandHisto [704]uint32
+	var distanceHisto [64]uint32
+	literalCount := 0
+	commandCount := 0
+	distanceCount := 0
+
+	if len(e.distCache) < len(matches) {
+		e.distCache = make([]distanceCode, len(matches))
+	}
+
+	// first pass: build the histograms
+	pos := 0
+
+	// d is the ring buffer of the last 4 distances.
+	d := [4]int{-10, -10, -10, -10}
+	for i, m := range matches {
+		if m.Unmatched > 0 {
+			for _, c := range src[pos : pos+m.Unmatched] {
+				literalHisto[c]++
+			}
+			literalCount += m.Unmatched
+		}
+
+		insertCode := getInsertLengthCode(uint(m.Unmatched))
+		copyCode := getCopyLengthCode(uint(m.Length))
+		if m.Length == 0 {
+			// If the stream ends with unmatched bytes, we need a dummy copy length.
+			copyCode = 2
+		}
+		command := combineLengthCodes(insertCode, copyCode, false)
+		commandHisto[command]++
+		commandCount++
+
+		if command >= 128 && m.Length != 0 {
+			var distCode distanceCode
+			switch m.Distance {
+			case d[3]:
+				distCode.code = 0
+			case d[2]:
+				distCode.code = 1
+			case d[1]:
+				distCode.code = 2
+			case d[0]:
+				distCode.code = 3
+			case d[3] - 1:
+				distCode.code = 4
+			case d[3] + 1:
+				distCode.code = 5
+			case d[3] - 2:
+				distCode.code = 6
+			case d[3] + 2:
+				distCode.code = 7
+			case d[3] - 3:
+				distCode.code = 8
+			case d[3] + 3:
+				distCode.code = 9
+
+				// In my testing, codes 10–15 actually reduced the compression ratio.
+
+			default:
+				distCode = getDistanceCode(m.Distance)
+			}
+			e.distCache[i] = distCode
+			distanceHisto[distCode.code]++
+			distanceCount++
+			if distCode.code != 0 {
+				d[0], d[1], d[2], d[3] = d[1], d[2], d[3], m.Distance
+			}
+		}
+
+		pos += m.Unmatched + m.Length
+	}
+
+	storeMetaBlockHeaderBW(uint(len(src)), false, &e.bw)
+	e.bw.writeBits(13, 0)
+
+	var literalDepths [256]byte
+	var literalBits [256]uint16
+	buildAndStoreHuffmanTreeFastBW(literalHisto[:], uint(literalCount), 8, literalDepths[:], literalBits[:], &e.bw)
+
+	var commandDepths [704]byte
+	var commandBits [704]uint16
+	buildAndStoreHuffmanTreeFastBW(commandHisto[:], uint(commandCount), 10, commandDepths[:], commandBits[:], &e.bw)
+
+	var distanceDepths [64]byte
+	var distanceBits [64]uint16
+	buildAndStoreHuffmanTreeFastBW(distanceHisto[:], uint(distanceCount), 6, distanceDepths[:], distanceBits[:], &e.bw)
+
+	pos = 0
+	for i, m := range matches {
+		insertCode := getInsertLengthCode(uint(m.Unmatched))
+		copyCode := getCopyLengthCode(uint(m.Length))
+		if m.Length == 0 {
+			// If the stream ends with unmatched bytes, we need a dummy copy length.
+			copyCode = 2
+		}
+		command := combineLengthCodes(insertCode, copyCode, false)
+		e.bw.writeBits(uint(commandDepths[command]), uint64(commandBits[command]))
+		if kInsExtra[insertCode] > 0 {
+			e.bw.writeBits(uint(kInsExtra[insertCode]), uint64(m.Unmatched)-uint64(kInsBase[insertCode]))
+		}
+		if kCopyExtra[copyCode] > 0 {
+			e.bw.writeBits(uint(kCopyExtra[copyCode]), uint64(m.Length)-uint64(kCopyBase[copyCode]))
+		}
+
+		if m.Unmatched > 0 {
+			for _, c := range src[pos : pos+m.Unmatched] {
+				e.bw.writeBits(uint(literalDepths[c]), uint64(literalBits[c]))
+			}
+		}
+
+		if command >= 128 && m.Length != 0 {
+			distCode := e.distCache[i]
+			e.bw.writeBits(uint(distanceDepths[distCode.code]), uint64(distanceBits[distCode.code]))
+			if distCode.nExtra > 0 {
+				e.bw.writeBits(distCode.nExtra, distCode.extraBits)
+			}
+		}
+
+		pos += m.Unmatched + m.Length
+	}
+
+	if lastBlock {
+		e.bw.writeBits(2, 3) // islast + isempty
+		e.bw.jumpToByteBoundary()
+	}
+	return e.bw.dst
+}
+
+type distanceCode struct {
+	code      int
+	nExtra    uint
+	extraBits uint64
+}
+
+func getDistanceCode(distance int) distanceCode {
+	d := distance + 3
+	nbits := log2FloorNonZero(uint(d)) - 1
+	prefix := (d >> nbits) & 1
+	offset := (2 + prefix) << nbits
+	distcode := int(2*(nbits-1)) + prefix + 16
+	extra := d - offset
+	return distanceCode{distcode, uint(nbits), uint64(extra)}
+}
diff --git a/vendor/github.com/andybalholm/brotli/entropy_encode_static.go b/vendor/github.com/andybalholm/brotli/entropy_encode_static.go
index 5ddf3fcb..294aff4f 100644
--- a/vendor/github.com/andybalholm/brotli/entropy_encode_static.go
+++ b/vendor/github.com/andybalholm/brotli/entropy_encode_static.go
@@ -782,6 +782,11 @@ func storeStaticCodeLengthCode(storage_ix *uint, storage []byte) {
 	writeBits(40, 0x0000FF55555554, storage_ix, storage)
 }
 
+func storeStaticCodeLengthCodeBW(bw *bitWriter) {
+	bw.writeBits(32, 0x55555554)
+	bw.writeBits(8, 0xFF)
+}
+
 var kZeroRepsBits = [numCommandSymbols]uint64{
 	0x00000000,
 	0x00000000,
diff --git a/vendor/github.com/andybalholm/brotli/http.go b/vendor/github.com/andybalholm/brotli/http.go
index 1e981963..3d3a8a06 100644
--- a/vendor/github.com/andybalholm/brotli/http.go
+++ b/vendor/github.com/andybalholm/brotli/http.go
@@ -11,15 +11,7 @@ import (
 // the Accept-Encoding header, sets the Content-Encoding header, and returns a
 // WriteCloser that implements that compression. The Close method must be called
 // before the current HTTP handler returns.
-//
-// Due to https://github.com/golang/go/issues/31753, the response will not be
-// compressed unless you set a Content-Type header before you call
-// HTTPCompressor.
 func HTTPCompressor(w http.ResponseWriter, r *http.Request) io.WriteCloser {
-	if w.Header().Get("Content-Type") == "" {
-		return nopCloser{w}
-	}
-
 	if w.Header().Get("Vary") == "" {
 		w.Header().Set("Vary", "Accept-Encoding")
 	}
@@ -28,7 +20,7 @@ func HTTPCompressor(w http.ResponseWriter, r *http.Request) io.WriteCloser {
 	switch encoding {
 	case "br":
 		w.Header().Set("Content-Encoding", "br")
-		return NewWriter(w)
+		return NewWriterV2(w, DefaultCompression)
 	case "gzip":
 		w.Header().Set("Content-Encoding", "gzip")
 		return gzip.NewWriter(w)
diff --git a/vendor/github.com/andybalholm/brotli/matchfinder/emitter.go b/vendor/github.com/andybalholm/brotli/matchfinder/emitter.go
new file mode 100644
index 00000000..37ed8e13
--- /dev/null
+++ b/vendor/github.com/andybalholm/brotli/matchfinder/emitter.go
@@ -0,0 +1,45 @@
+package matchfinder
+
+// An absoluteMatch is like a Match, but it stores indexes into the byte
+// stream instead of lengths.
+type absoluteMatch struct {
+	// Start is the index of the first byte.
+	Start int
+
+	// End is the index of the byte after the last byte
+	// (so that End - Start = Length).
+	End int
+
+	// Match is the index of the previous data that matches
+	// (Start - Match = Distance).
+	Match int
+}
+
+// A matchEmitter manages the output of matches for a MatchFinder.
+type matchEmitter struct {
+	// Dst is the destination slice that Matches are added to.
+	Dst []Match
+
+	// NextEmit is the index of the next byte to emit.
+	NextEmit int
+}
+
+func (e *matchEmitter) emit(m absoluteMatch) {
+	e.Dst = append(e.Dst, Match{
+		Unmatched: m.Start - e.NextEmit,
+		Length:    m.End - m.Start,
+		Distance:  m.Start - m.Match,
+	})
+	e.NextEmit = m.End
+}
+
+// trim shortens m if it extends past maxEnd. Then if the length is at least
+// minLength, the match is emitted.
+func (e *matchEmitter) trim(m absoluteMatch, maxEnd int, minLength int) {
+	if m.End > maxEnd {
+		m.End = maxEnd
+	}
+	if m.End-m.Start >= minLength {
+		e.emit(m)
+	}
+}
diff --git a/vendor/github.com/andybalholm/brotli/matchfinder/m0.go b/vendor/github.com/andybalholm/brotli/matchfinder/m0.go
new file mode 100644
index 00000000..773b7c49
--- /dev/null
+++ b/vendor/github.com/andybalholm/brotli/matchfinder/m0.go
@@ -0,0 +1,169 @@
+package matchfinder
+
+import (
+	"encoding/binary"
+)
+
+// M0 is an implementation of the MatchFinder interface based
+// on the algorithm used by snappy, but modified to be more like the algorithm
+// used by compression level 0 of the brotli reference implementation.
+//
+// It has a maximum block size of 65536 bytes.
+type M0 struct {
+	// Lazy turns on "lazy matching," for higher compression but less speed.
+	Lazy bool
+
+	MaxDistance int
+	MaxLength   int
+}
+
+func (M0) Reset() {}
+
+const (
+	m0HashLen = 5
+
+	m0TableBits = 14
+	m0TableSize = 1 << m0TableBits
+	m0Shift     = 32 - m0TableBits
+	// m0TableMask is redundant, but helps the compiler eliminate bounds
+	// checks.
+	m0TableMask = m0TableSize - 1
+)
+
+func (m M0) hash(data uint64) uint64 {
+	hash := (data << (64 - 8*m0HashLen)) * hashMul64
+	return hash >> (64 - m0TableBits)
+}
+
+// FindMatches looks for matches in src, appends them to dst, and returns dst.
+// src must not be longer than 65536 bytes.
+func (m M0) FindMatches(dst []Match, src []byte) []Match {
+	const inputMargin = 16 - 1
+	const minNonLiteralBlockSize = 1 + 1 + inputMargin
+
+	if len(src) < minNonLiteralBlockSize {
+		dst = append(dst, Match{
+			Unmatched: len(src),
+		})
+		return dst
+	}
+	if len(src) > 65536 {
+		panic("block too long")
+	}
+
+	var table [m0TableSize]uint16
+
+	// sLimit is when to stop looking for offset/length copies. The inputMargin
+	// lets us use a fast path for emitLiteral in the main loop, while we are
+	// looking for copies.
+	sLimit := len(src) - inputMargin
+
+	// nextEmit is where in src the next emitLiteral should start from.
+	nextEmit := 0
+
+	// The encoded form must start with a literal, as there are no previous
+	// bytes to copy, so we start looking for hash matches at s == 1.
+	s := 1
+	nextHash := m.hash(binary.LittleEndian.Uint64(src[s:]))
+
+	for {
+		// Copied from the C++ snappy implementation:
+		//
+		// Heuristic match skipping: If 32 bytes are scanned with no matches
+		// found, start looking only at every other byte. If 32 more bytes are
+		// scanned (or skipped), look at every third byte, etc.. When a match
+		// is found, immediately go back to looking at every byte. This is a
+		// small loss (~5% performance, ~0.1% density) for compressible data
+		// due to more bookkeeping, but for non-compressible data (such as
+		// JPEG) it's a huge win since the compressor quickly "realizes" the
+		// data is incompressible and doesn't bother looking for matches
+		// everywhere.
+		//
+		// The "skip" variable keeps track of how many bytes there are since
+		// the last match; dividing it by 32 (ie. right-shifting by five) gives
+		// the number of bytes to move ahead for each iteration.
+		skip := 32
+
+		nextS := s
+		candidate := 0
+		for {
+			s = nextS
+			bytesBetweenHashLookups := skip >> 5
+			nextS = s + bytesBetweenHashLookups
+			skip += bytesBetweenHashLookups
+			if nextS > sLimit {
+				goto emitRemainder
+			}
+			candidate = int(table[nextHash&m0TableMask])
+			table[nextHash&m0TableMask] = uint16(s)
+			nextHash = m.hash(binary.LittleEndian.Uint64(src[nextS:]))
+			if m.MaxDistance != 0 && s-candidate > m.MaxDistance {
+				continue
+			}
+			if binary.LittleEndian.Uint32(src[s:]) == binary.LittleEndian.Uint32(src[candidate:]) {
+				break
+			}
+		}
+
+		// Invariant: we have a 4-byte match at s.
+		base := s
+		s = extendMatch(src, candidate+4, s+4)
+
+		origBase := base
+		if m.Lazy && base+1 < sLimit {
+			newBase := base + 1
+			h := m.hash(binary.LittleEndian.Uint64(src[newBase:]))
+			newCandidate := int(table[h&m0TableMask])
+			table[h&m0TableMask] = uint16(newBase)
+			okDistance := true
+			if m.MaxDistance != 0 && newBase-newCandidate > m.MaxDistance {
+				okDistance = false
+			}
+			if okDistance && binary.LittleEndian.Uint32(src[newBase:]) == binary.LittleEndian.Uint32(src[newCandidate:]) {
+				newS := extendMatch(src, newCandidate+4, newBase+4)
+				if newS-newBase > s-base+1 {
+					s = newS
+					base = newBase
+					candidate = newCandidate
+				}
+			}
+		}
+
+		if m.MaxLength != 0 && s-base > m.MaxLength {
+			s = base + m.MaxLength
+		}
+		dst = append(dst, Match{
+			Unmatched: base - nextEmit,
+			Length:    s - base,
+			Distance:  base - candidate,
+		})
+		nextEmit = s
+		if s >= sLimit {
+			goto emitRemainder
+		}
+
+		if m.Lazy {
+			// If lazy matching is enabled, we update the hash table for
+			// every byte in the match.
+			for i := origBase + 2; i < s-1; i++ {
+				x := binary.LittleEndian.Uint64(src[i:])
+				table[m.hash(x)&m0TableMask] = uint16(i)
+			}
+		}
+
+		// We could immediately start working at s now, but to improve
+		// compression we first update the hash table at s-1 and at s.
+		x := binary.LittleEndian.Uint64(src[s-1:])
+		prevHash := m.hash(x >> 0)
+		table[prevHash&m0TableMask] = uint16(s - 1)
+		nextHash = m.hash(x >> 8)
+	}
+
+emitRemainder:
+	if nextEmit < len(src) {
+		dst = append(dst, Match{
+			Unmatched: len(src) - nextEmit,
+		})
+	}
+	return dst
+}
diff --git a/vendor/github.com/andybalholm/brotli/matchfinder/m4.go b/vendor/github.com/andybalholm/brotli/matchfinder/m4.go
new file mode 100644
index 00000000..5b2acba2
--- /dev/null
+++ b/vendor/github.com/andybalholm/brotli/matchfinder/m4.go
@@ -0,0 +1,297 @@
+package matchfinder
+
+import (
+	"encoding/binary"
+	"math/bits"
+	"runtime"
+)
+
+// M4 is an implementation of the MatchFinder
+// interface that uses a hash table to find matches,
+// optional match chains,
+// and the advanced parsing technique from
+// https://fastcompression.blogspot.com/2011/12/advanced-parsing-strategies.html.
+type M4 struct {
+	// MaxDistance is the maximum distance (in bytes) to look back for
+	// a match. The default is 65535.
+	MaxDistance int
+
+	// MinLength is the length of the shortest match to return.
+	// The default is 4.
+	MinLength int
+
+	// HashLen is the number of bytes to use to calculate the hashes.
+	// The maximum is 8 and the default is 6.
+	HashLen int
+
+	// TableBits is the number of bits in the hash table indexes.
+	// The default is 17 (128K entries).
+	TableBits int
+
+	// ChainLength is how many entries to search on the "match chain" of older
+	// locations with the same hash as the current location.
+	ChainLength int
+
+	// DistanceBitCost is used when comparing two matches to see
+	// which is better. The comparison is primarily based on the length
+	// of the matches, but it can also take the distance into account,
+	// in terms of the number of bits needed to represent the distance.
+	// One byte of length is given a score of 256, so 32 (256/8) would
+	// be a reasonable first guess for the value of one bit.
+	// (The default is 0, which bases the comparison solely on length.)
+	DistanceBitCost int
+
+	table []uint32
+	chain []uint16
+
+	history []byte
+}
+
+func (q *M4) Reset() {
+	for i := range q.table {
+		q.table[i] = 0
+	}
+	q.history = q.history[:0]
+	q.chain = q.chain[:0]
+}
+
+func (q *M4) score(m absoluteMatch) int {
+	return (m.End-m.Start)*256 + bits.LeadingZeros32(uint32(m.Start-m.Match))*q.DistanceBitCost
+}
+
+func (q *M4) FindMatches(dst []Match, src []byte) []Match {
+	if q.MaxDistance == 0 {
+		q.MaxDistance = 65535
+	}
+	if q.MinLength == 0 {
+		q.MinLength = 4
+	}
+	if q.HashLen == 0 {
+		q.HashLen = 6
+	}
+	if q.TableBits == 0 {
+		q.TableBits = 17
+	}
+	if len(q.table) < 1<<q.TableBits {
+		q.table = make([]uint32, 1<<q.TableBits)
+	}
+
+	e := matchEmitter{Dst: dst}
+
+	if len(q.history) > q.MaxDistance*2 {
+		// Trim down the history buffer.
+		delta := len(q.history) - q.MaxDistance
+		copy(q.history, q.history[delta:])
+		q.history = q.history[:q.MaxDistance]
+		if q.ChainLength > 0 {
+			q.chain = q.chain[:q.MaxDistance]
+		}
+
+		for i, v := range q.table {
+			newV := int(v) - delta
+			if newV < 0 {
+				newV = 0
+			}
+			q.table[i] = uint32(newV)
+		}
+	}
+
+	// Append src to the history buffer.
+	e.NextEmit = len(q.history)
+	q.history = append(q.history, src...)
+	if q.ChainLength > 0 {
+		q.chain = append(q.chain, make([]uint16, len(src))...)
+	}
+	src = q.history
+
+	// matches stores the matches that have been found but not emitted,
+	// in reverse order. (matches[0] is the most recent one.)
+	var matches [3]absoluteMatch
+	for i := e.NextEmit; i < len(src)-7; i++ {
+		if matches[0] != (absoluteMatch{}) && i >= matches[0].End {
+			// We have found some matches, and we're far enough along that we probably
+			// won't find overlapping matches, so we might as well emit them.
+			if matches[1] != (absoluteMatch{}) {
+				e.trim(matches[1], matches[0].Start, q.MinLength)
+			}
+			e.emit(matches[0])
+			matches = [3]absoluteMatch{}
+		}
+
+		// Calculate and store the hash.
+		h := ((binary.LittleEndian.Uint64(src[i:]) & (1<<(8*q.HashLen) - 1)) * hashMul64) >> (64 - q.TableBits)
+		candidate := int(q.table[h])
+		q.table[h] = uint32(i)
+		if q.ChainLength > 0 && candidate != 0 {
+			delta := i - candidate
+			if delta < 1<<16 {
+				q.chain[i] = uint16(delta)
+			}
+		}
+
+		if i < matches[0].End && i != matches[0].End+2-q.HashLen {
+			continue
+		}
+		if candidate == 0 || i-candidate > q.MaxDistance {
+			continue
+		}
+
+		// Look for a match.
+		var currentMatch absoluteMatch
+
+		if i-candidate != matches[0].Start-matches[0].Match {
+			if binary.LittleEndian.Uint32(src[candidate:]) == binary.LittleEndian.Uint32(src[i:]) {
+				m := extendMatch2(src, i, candidate, e.NextEmit)
+				if m.End-m.Start > q.MinLength {
+					currentMatch = m
+				}
+			}
+		}
+
+		for j := 0; j < q.ChainLength; j++ {
+			delta := q.chain[candidate]
+			if delta == 0 {
+				break
+			}
+			candidate -= int(delta)
+			if candidate <= 0 || i-candidate > q.MaxDistance {
+				break
+			}
+			if i-candidate != matches[0].Start-matches[0].Match {
+				if binary.LittleEndian.Uint32(src[candidate:]) == binary.LittleEndian.Uint32(src[i:]) {
+					m := extendMatch2(src, i, candidate, e.NextEmit)
+					if m.End-m.Start > q.MinLength && q.score(m) > q.score(currentMatch) {
+						currentMatch = m
+					}
+				}
+			}
+		}
+
+		if currentMatch.End-currentMatch.Start < q.MinLength {
+			continue
+		}
+
+		overlapPenalty := 0
+		if matches[0] != (absoluteMatch{}) {
+			overlapPenalty = 275
+			if currentMatch.Start <= matches[1].End {
+				// This match would completely replace the previous match,
+				// so there is no penalty for overlap.
+				overlapPenalty = 0
+			}
+		}
+
+		if q.score(currentMatch) <= q.score(matches[0])+overlapPenalty {
+			continue
+		}
+
+		matches = [3]absoluteMatch{
+			currentMatch,
+			matches[0],
+			matches[1],
+		}
+
+		if matches[2] == (absoluteMatch{}) {
+			continue
+		}
+
+		// We have three matches, so it's time to emit one and/or eliminate one.
+		switch {
+		case matches[0].Start < matches[2].End:
+			// The first and third matches overlap; discard the one in between.
+			matches = [3]absoluteMatch{
+				matches[0],
+				matches[2],
+				absoluteMatch{},
+			}
+
+		case matches[0].Start < matches[2].End+q.MinLength:
+			// The first and third matches don't overlap, but there's no room for
+			// another match between them. Emit the first match and discard the second.
+			e.emit(matches[2])
+			matches = [3]absoluteMatch{
+				matches[0],
+				absoluteMatch{},
+				absoluteMatch{},
+			}
+
+		default:
+			// Emit the first match, shortening it if necessary to avoid overlap with the second.
+			e.trim(matches[2], matches[1].Start, q.MinLength)
+			matches[2] = absoluteMatch{}
+		}
+	}
+
+	// We've found all the matches now; emit the remaining ones.
+	if matches[1] != (absoluteMatch{}) {
+		e.trim(matches[1], matches[0].Start, q.MinLength)
+	}
+	if matches[0] != (absoluteMatch{}) {
+		e.emit(matches[0])
+	}
+
+	dst = e.Dst
+	if e.NextEmit < len(src) {
+		dst = append(dst, Match{
+			Unmatched: len(src) - e.NextEmit,
+		})
+	}
+
+	return dst
+}
+
+const hashMul64 = 0x1E35A7BD1E35A7BD
+
+// extendMatch returns the largest k such that k <= len(src) and that
+// 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 {
+	switch runtime.GOARCH {
+	case "amd64":
+		// As long as we are 8 or more bytes before the end of src, we can load and
+		// compare 8 bytes at a time. If those 8 bytes are equal, repeat.
+		for j+8 < len(src) {
+			iBytes := binary.LittleEndian.Uint64(src[i:])
+			jBytes := binary.LittleEndian.Uint64(src[j:])
+			if iBytes != jBytes {
+				// If those 8 bytes were not equal, XOR the two 8 byte values, and return
+				// the index of the first byte that differs. The BSF instruction finds the
+				// least significant 1 bit, the amd64 architecture is little-endian, and
+				// the shift by 3 converts a bit index to a byte index.
+				return j + bits.TrailingZeros64(iBytes^jBytes)>>3
+			}
+			i, j = i+8, j+8
+		}
+	case "386":
+		// On a 32-bit CPU, we do it 4 bytes at a time.
+		for j+4 < len(src) {
+			iBytes := binary.LittleEndian.Uint32(src[i:])
+			jBytes := binary.LittleEndian.Uint32(src[j:])
+			if iBytes != jBytes {
+				return j + bits.TrailingZeros32(iBytes^jBytes)>>3
+			}
+			i, j = i+4, j+4
+		}
+	}
+	for ; j < len(src) && src[i] == src[j]; i, j = i+1, j+1 {
+	}
+	return j
+}
+
+// Given a 4-byte match at src[start] and src[candidate], extendMatch2 extends it
+// upward as far as possible, and downward no farther than to min.
+func extendMatch2(src []byte, start, candidate, min int) absoluteMatch {
+	end := extendMatch(src, candidate+4, start+4)
+	for start > min && candidate > 0 && src[start-1] == src[candidate-1] {
+		start--
+		candidate--
+	}
+	return absoluteMatch{
+		Start: start,
+		End:   end,
+		Match: candidate,
+	}
+}
diff --git a/vendor/github.com/andybalholm/brotli/matchfinder/matchfinder.go b/vendor/github.com/andybalholm/brotli/matchfinder/matchfinder.go
new file mode 100644
index 00000000..f6bcfdb3
--- /dev/null
+++ b/vendor/github.com/andybalholm/brotli/matchfinder/matchfinder.go
@@ -0,0 +1,103 @@
+// The matchfinder package defines reusable components for data compression.
+//
+// Many compression libraries have two main parts:
+//   - Something that looks for repeated sequences of bytes
+//   - An encoder for the compressed data format (often an entropy coder)
+//
+// Although these are logically two separate steps, the implementations are
+// usually closely tied together. You can't use flate's matcher with snappy's
+// encoder, for example. This package defines interfaces and an intermediate
+// representation to allow mixing and matching compression components.
+package matchfinder
+
+import "io"
+
+// A Match is the basic unit of LZ77 compression.
+type Match struct {
+	Unmatched int // the number of unmatched bytes since the previous match
+	Length    int // the number of bytes in the matched string; it may be 0 at the end of the input
+	Distance  int // how far back in the stream to copy from
+}
+
+// A MatchFinder performs the LZ77 stage of compression, looking for matches.
+type MatchFinder interface {
+	// FindMatches looks for matches in src, appends them to dst, and returns dst.
+	FindMatches(dst []Match, src []byte) []Match
+
+	// Reset clears any internal state, preparing the MatchFinder to be used with
+	// a new stream.
+	Reset()
+}
+
+// An Encoder encodes the data in its final format.
+type Encoder interface {
+	// Encode appends the encoded format of src to dst, using the match
+	// information from matches.
+	Encode(dst []byte, src []byte, matches []Match, lastBlock bool) []byte
+
+	// Reset clears any internal state, preparing the Encoder to be used with
+	// a new stream.
+	Reset()
+}
+
+// A Writer uses MatchFinder and Encoder to write compressed data to Dest.
+type Writer struct {
+	Dest        io.Writer
+	MatchFinder MatchFinder
+	Encoder     Encoder
+
+	// BlockSize is the number of bytes to compress at a time. If it is zero,
+	// each Write operation will be treated as one block.
+	BlockSize int
+
+	err     error
+	inBuf   []byte
+	outBuf  []byte
+	matches []Match
+}
+
+func (w *Writer) Write(p []byte) (n int, err error) {
+	if w.err != nil {
+		return 0, w.err
+	}
+
+	if w.BlockSize == 0 {
+		return w.writeBlock(p, false)
+	}
+
+	w.inBuf = append(w.inBuf, p...)
+	var pos int
+	for pos = 0; pos+w.BlockSize <= len(w.inBuf) && w.err == nil; pos += w.BlockSize {
+		w.writeBlock(w.inBuf[pos:pos+w.BlockSize], false)
+	}
+	if pos > 0 {
+		n := copy(w.inBuf, w.inBuf[pos:])
+		w.inBuf = w.inBuf[:n]
+	}
+
+	return len(p), w.err
+}
+
+func (w *Writer) writeBlock(p []byte, lastBlock bool) (n int, err error) {
+	w.outBuf = w.outBuf[:0]
+	w.matches = w.MatchFinder.FindMatches(w.matches[:0], p)
+	w.outBuf = w.Encoder.Encode(w.outBuf, p, w.matches, lastBlock)
+	_, w.err = w.Dest.Write(w.outBuf)
+	return len(p), w.err
+}
+
+func (w *Writer) Close() error {
+	w.writeBlock(w.inBuf, true)
+	w.inBuf = w.inBuf[:0]
+	return w.err
+}
+
+func (w *Writer) Reset(newDest io.Writer) {
+	w.MatchFinder.Reset()
+	w.Encoder.Reset()
+	w.err = nil
+	w.inBuf = w.inBuf[:0]
+	w.outBuf = w.outBuf[:0]
+	w.matches = w.matches[:0]
+	w.Dest = newDest
+}
diff --git a/vendor/github.com/andybalholm/brotli/matchfinder/textencoder.go b/vendor/github.com/andybalholm/brotli/matchfinder/textencoder.go
new file mode 100644
index 00000000..75ecc590
--- /dev/null
+++ b/vendor/github.com/andybalholm/brotli/matchfinder/textencoder.go
@@ -0,0 +1,53 @@
+package matchfinder
+
+import "fmt"
+
+// A TextEncoder is an Encoder that produces a human-readable representation of
+// the LZ77 compression. Matches are replaced with <Length,Distance> symbols.
+type TextEncoder struct{}
+
+func (t TextEncoder) Reset() {}
+
+func (t TextEncoder) Encode(dst []byte, src []byte, matches []Match, lastBlock bool) []byte {
+	pos := 0
+	for _, m := range matches {
+		if m.Unmatched > 0 {
+			dst = append(dst, src[pos:pos+m.Unmatched]...)
+			pos += m.Unmatched
+		}
+		if m.Length > 0 {
+			dst = append(dst, []byte(fmt.Sprintf("<%d,%d>", m.Length, m.Distance))...)
+			pos += m.Length
+		}
+	}
+	if pos < len(src) {
+		dst = append(dst, src[pos:]...)
+	}
+	return dst
+}
+
+// A NoMatchFinder implements MatchFinder, but doesn't find any matches.
+// It can be used to implement the equivalent of the standard library flate package's
+// HuffmanOnly setting.
+type NoMatchFinder struct{}
+
+func (n NoMatchFinder) Reset() {}
+
+func (n NoMatchFinder) FindMatches(dst []Match, src []byte) []Match {
+	return append(dst, Match{
+		Unmatched: len(src),
+	})
+}
+
+// AutoReset wraps a MatchFinder that can return references to data in previous
+// blocks, and calls Reset before each block. It is useful for (e.g.) using a
+// snappy Encoder with a MatchFinder designed for flate. (Snappy doesn't
+// support references between blocks.)
+type AutoReset struct {
+	MatchFinder
+}
+
+func (a AutoReset) FindMatches(dst []Match, src []byte) []Match {
+	a.Reset()
+	return a.MatchFinder.FindMatches(dst, src)
+}
diff --git a/vendor/github.com/andybalholm/brotli/writer.go b/vendor/github.com/andybalholm/brotli/writer.go
index 39feaef5..8a688117 100644
--- a/vendor/github.com/andybalholm/brotli/writer.go
+++ b/vendor/github.com/andybalholm/brotli/writer.go
@@ -3,6 +3,8 @@ package brotli
 import (
 	"errors"
 	"io"
+
+	"github.com/andybalholm/brotli/matchfinder"
 )
 
 const (
@@ -117,3 +119,44 @@ type nopCloser struct {
 }
 
 func (nopCloser) Close() error { return nil }
+
+// NewWriterV2 is like NewWriterLevel, but it uses the new implementation
+// based on the matchfinder package. It currently supports up to level 7;
+// if a higher level is specified, level 7 will be used.
+func NewWriterV2(dst io.Writer, level int) *matchfinder.Writer {
+	var mf matchfinder.MatchFinder
+	if level < 2 {
+		mf = matchfinder.M0{Lazy: level == 1}
+	} else {
+		hashLen := 6
+		if level >= 6 {
+			hashLen = 5
+		}
+		chainLen := 64
+		switch level {
+		case 2:
+			chainLen = 0
+		case 3:
+			chainLen = 1
+		case 4:
+			chainLen = 2
+		case 5:
+			chainLen = 4
+		case 6:
+			chainLen = 8
+		}
+		mf = &matchfinder.M4{
+			MaxDistance:     1 << 20,
+			ChainLength:     chainLen,
+			HashLen:         hashLen,
+			DistanceBitCost: 57,
+		}
+	}
+
+	return &matchfinder.Writer{
+		Dest:        dst,
+		MatchFinder: mf,
+		Encoder:     &Encoder{},
+		BlockSize:   1 << 16,
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/LICENSE b/vendor/github.com/cloudflare/circl/LICENSE
new file mode 100644
index 00000000..67edaa90
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/LICENSE
@@ -0,0 +1,57 @@
+Copyright (c) 2019 Cloudflare. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Cloudflare nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+========================================================================
+
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/curve.go b/vendor/github.com/cloudflare/circl/dh/x25519/curve.go
new file mode 100644
index 00000000..f9057c2b
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve.go
@@ -0,0 +1,96 @@
+package x25519
+
+import (
+	fp "github.com/cloudflare/circl/math/fp25519"
+)
+
+// ladderJoye calculates a fixed-point multiplication with the generator point.
+// The algorithm is the right-to-left Joye's ladder as described
+// in "How to precompute a ladder" in SAC'2017.
+func ladderJoye(k *Key) {
+	w := [5]fp.Elt{} // [mu,x1,z1,x2,z2] order must be preserved.
+	fp.SetOne(&w[1]) // x1 = 1
+	fp.SetOne(&w[2]) // z1 = 1
+	w[3] = fp.Elt{   // x2 = G-S
+		0xbd, 0xaa, 0x2f, 0xc8, 0xfe, 0xe1, 0x94, 0x7e,
+		0xf8, 0xed, 0xb2, 0x14, 0xae, 0x95, 0xf0, 0xbb,
+		0xe2, 0x48, 0x5d, 0x23, 0xb9, 0xa0, 0xc7, 0xad,
+		0x34, 0xab, 0x7c, 0xe2, 0xee, 0xcd, 0xae, 0x1e,
+	}
+	fp.SetOne(&w[4]) // z2 = 1
+
+	const n = 255
+	const h = 3
+	swap := uint(1)
+	for s := 0; s < n-h; s++ {
+		i := (s + h) / 8
+		j := (s + h) % 8
+		bit := uint((k[i] >> uint(j)) & 1)
+		copy(w[0][:], tableGenerator[s*Size:(s+1)*Size])
+		diffAdd(&w, swap^bit)
+		swap = bit
+	}
+	for s := 0; s < h; s++ {
+		double(&w[1], &w[2])
+	}
+	toAffine((*[fp.Size]byte)(k), &w[1], &w[2])
+}
+
+// ladderMontgomery calculates a generic scalar point multiplication
+// The algorithm implemented is the left-to-right Montgomery's ladder.
+func ladderMontgomery(k, xP *Key) {
+	w := [5]fp.Elt{}      // [x1, x2, z2, x3, z3] order must be preserved.
+	w[0] = *(*fp.Elt)(xP) // x1 = xP
+	fp.SetOne(&w[1])      // x2 = 1
+	w[3] = *(*fp.Elt)(xP) // x3 = xP
+	fp.SetOne(&w[4])      // z3 = 1
+
+	move := uint(0)
+	for s := 255 - 1; s >= 0; s-- {
+		i := s / 8
+		j := s % 8
+		bit := uint((k[i] >> uint(j)) & 1)
+		ladderStep(&w, move^bit)
+		move = bit
+	}
+	toAffine((*[fp.Size]byte)(k), &w[1], &w[2])
+}
+
+func toAffine(k *[fp.Size]byte, x, z *fp.Elt) {
+	fp.Inv(z, z)
+	fp.Mul(x, x, z)
+	_ = fp.ToBytes(k[:], x)
+}
+
+var lowOrderPoints = [5]fp.Elt{
+	{ /* (0,_,1) point of order 2 on Curve25519 */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	},
+	{ /* (1,_,1) point of order 4 on Curve25519 */
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	},
+	{ /* (x,_,1) first point of order 8 on Curve25519 */
+		0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae,
+		0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a,
+		0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd,
+		0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00,
+	},
+	{ /* (x,_,1) second point of order 8 on Curve25519 */
+		0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24,
+		0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b,
+		0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86,
+		0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57,
+	},
+	{ /* (-1,_,1) a point of order 4 on the twist of Curve25519 */
+		0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
+	},
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.go b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.go
new file mode 100644
index 00000000..8a3d54c5
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.go
@@ -0,0 +1,30 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+package x25519
+
+import (
+	fp "github.com/cloudflare/circl/math/fp25519"
+	"golang.org/x/sys/cpu"
+)
+
+var hasBmi2Adx = cpu.X86.HasBMI2 && cpu.X86.HasADX
+
+var _ = hasBmi2Adx
+
+func double(x, z *fp.Elt)             { doubleAmd64(x, z) }
+func diffAdd(w *[5]fp.Elt, b uint)    { diffAddAmd64(w, b) }
+func ladderStep(w *[5]fp.Elt, b uint) { ladderStepAmd64(w, b) }
+func mulA24(z, x *fp.Elt)             { mulA24Amd64(z, x) }
+
+//go:noescape
+func ladderStepAmd64(w *[5]fp.Elt, b uint)
+
+//go:noescape
+func diffAddAmd64(w *[5]fp.Elt, b uint)
+
+//go:noescape
+func doubleAmd64(x, z *fp.Elt)
+
+//go:noescape
+func mulA24Amd64(z, x *fp.Elt)
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.h b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.h
new file mode 100644
index 00000000..8c1ae4d0
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.h
@@ -0,0 +1,111 @@
+#define ladderStepLeg          \
+    addSub(x2,z2)              \
+    addSub(x3,z3)              \
+    integerMulLeg(b0,x2,z3)    \
+    integerMulLeg(b1,x3,z2)    \
+    reduceFromDoubleLeg(t0,b0) \
+    reduceFromDoubleLeg(t1,b1) \
+    addSub(t0,t1)              \
+    cselect(x2,x3,regMove)     \
+    cselect(z2,z3,regMove)     \
+    integerSqrLeg(b0,t0)       \
+    integerSqrLeg(b1,t1)       \
+    reduceFromDoubleLeg(x3,b0) \
+    reduceFromDoubleLeg(z3,b1) \
+    integerMulLeg(b0,x1,z3)    \
+    reduceFromDoubleLeg(z3,b0) \
+    integerSqrLeg(b0,x2)       \
+    integerSqrLeg(b1,z2)       \
+    reduceFromDoubleLeg(x2,b0) \
+    reduceFromDoubleLeg(z2,b1) \
+    subtraction(t0,x2,z2)      \
+    multiplyA24Leg(t1,t0)      \
+    additionLeg(t1,t1,z2)      \
+    integerMulLeg(b0,x2,z2)    \
+    integerMulLeg(b1,t0,t1)    \
+    reduceFromDoubleLeg(x2,b0) \
+    reduceFromDoubleLeg(z2,b1)
+
+#define ladderStepBmi2Adx      \
+    addSub(x2,z2)              \
+    addSub(x3,z3)              \
+    integerMulAdx(b0,x2,z3)    \
+    integerMulAdx(b1,x3,z2)    \
+    reduceFromDoubleAdx(t0,b0) \
+    reduceFromDoubleAdx(t1,b1) \
+    addSub(t0,t1)              \
+    cselect(x2,x3,regMove)     \
+    cselect(z2,z3,regMove)     \
+    integerSqrAdx(b0,t0)       \
+    integerSqrAdx(b1,t1)       \
+    reduceFromDoubleAdx(x3,b0) \
+    reduceFromDoubleAdx(z3,b1) \
+    integerMulAdx(b0,x1,z3)    \
+    reduceFromDoubleAdx(z3,b0) \
+    integerSqrAdx(b0,x2)       \
+    integerSqrAdx(b1,z2)       \
+    reduceFromDoubleAdx(x2,b0) \
+    reduceFromDoubleAdx(z2,b1) \
+    subtraction(t0,x2,z2)      \
+    multiplyA24Adx(t1,t0)      \
+    additionAdx(t1,t1,z2)      \
+    integerMulAdx(b0,x2,z2)    \
+    integerMulAdx(b1,t0,t1)    \
+    reduceFromDoubleAdx(x2,b0) \
+    reduceFromDoubleAdx(z2,b1)
+
+#define difAddLeg              \
+    addSub(x1,z1)              \
+    integerMulLeg(b0,z1,ui)    \
+    reduceFromDoubleLeg(z1,b0) \
+    addSub(x1,z1)              \
+    integerSqrLeg(b0,x1)       \
+    integerSqrLeg(b1,z1)       \
+    reduceFromDoubleLeg(x1,b0) \
+    reduceFromDoubleLeg(z1,b1) \
+    integerMulLeg(b0,x1,z2)    \
+    integerMulLeg(b1,z1,x2)    \
+    reduceFromDoubleLeg(x1,b0) \
+    reduceFromDoubleLeg(z1,b1)
+
+#define difAddBmi2Adx          \
+    addSub(x1,z1)              \
+    integerMulAdx(b0,z1,ui)    \
+    reduceFromDoubleAdx(z1,b0) \
+    addSub(x1,z1)              \
+    integerSqrAdx(b0,x1)       \
+    integerSqrAdx(b1,z1)       \
+    reduceFromDoubleAdx(x1,b0) \
+    reduceFromDoubleAdx(z1,b1) \
+    integerMulAdx(b0,x1,z2)    \
+    integerMulAdx(b1,z1,x2)    \
+    reduceFromDoubleAdx(x1,b0) \
+    reduceFromDoubleAdx(z1,b1)
+
+#define doubleLeg              \
+    addSub(x1,z1)              \
+    integerSqrLeg(b0,x1)       \
+    integerSqrLeg(b1,z1)       \
+    reduceFromDoubleLeg(x1,b0) \
+    reduceFromDoubleLeg(z1,b1) \
+    subtraction(t0,x1,z1)      \
+    multiplyA24Leg(t1,t0)      \
+    additionLeg(t1,t1,z1)      \
+    integerMulLeg(b0,x1,z1)    \
+    integerMulLeg(b1,t0,t1)    \
+    reduceFromDoubleLeg(x1,b0) \
+    reduceFromDoubleLeg(z1,b1)
+
+#define doubleBmi2Adx          \
+    addSub(x1,z1)              \
+    integerSqrAdx(b0,x1)       \
+    integerSqrAdx(b1,z1)       \
+    reduceFromDoubleAdx(x1,b0) \
+    reduceFromDoubleAdx(z1,b1) \
+    subtraction(t0,x1,z1)      \
+    multiplyA24Adx(t1,t0)      \
+    additionAdx(t1,t1,z1)      \
+    integerMulAdx(b0,x1,z1)    \
+    integerMulAdx(b1,t0,t1)    \
+    reduceFromDoubleAdx(x1,b0) \
+    reduceFromDoubleAdx(z1,b1)
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s
new file mode 100644
index 00000000..ce9f0628
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve_amd64.s
@@ -0,0 +1,157 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+#include "textflag.h"
+
+// Depends on circl/math/fp25519 package
+#include "../../math/fp25519/fp_amd64.h"
+#include "curve_amd64.h"
+
+// CTE_A24 is (A+2)/4 from Curve25519
+#define CTE_A24 121666
+
+#define Size 32
+
+// multiplyA24Leg multiplies x times CTE_A24 and stores in z
+// Uses: AX, DX, R8-R13, FLAGS
+// Instr: x86_64, cmov
+#define multiplyA24Leg(z,x) \
+    MOVL $CTE_A24, AX; MULQ  0+x; MOVQ AX,  R8; MOVQ DX,  R9; \
+    MOVL $CTE_A24, AX; MULQ  8+x; MOVQ AX, R12; MOVQ DX, R10; \
+    MOVL $CTE_A24, AX; MULQ 16+x; MOVQ AX, R13; MOVQ DX, R11; \
+    MOVL $CTE_A24, AX; MULQ 24+x; \
+    ADDQ R12,  R9; \
+    ADCQ R13, R10; \
+    ADCQ  AX, R11; \
+    ADCQ  $0,  DX; \
+    MOVL $38,  AX; /* 2*C = 38 = 2^256 MOD 2^255-19*/ \
+    IMULQ AX, DX; \
+    ADDQ DX, R8; \
+    ADCQ $0,  R9;  MOVQ  R9,  8+z; \
+    ADCQ $0, R10;  MOVQ R10, 16+z; \
+    ADCQ $0, R11;  MOVQ R11, 24+z; \
+    MOVQ $0, DX; \
+    CMOVQCS AX, DX; \
+    ADDQ DX, R8;  MOVQ  R8,   0+z;
+
+// multiplyA24Adx multiplies x times CTE_A24 and stores in z
+// Uses: AX, DX, R8-R12, FLAGS
+// Instr: x86_64, cmov, bmi2
+#define multiplyA24Adx(z,x) \
+    MOVQ  $CTE_A24, DX; \
+    MULXQ  0+x,  R8, R10; \
+    MULXQ  8+x,  R9, R11;  ADDQ R10,  R9; \
+    MULXQ 16+x, R10,  AX;  ADCQ R11, R10; \
+    MULXQ 24+x, R11, R12;  ADCQ  AX, R11; \
+    ;;;;;;;;;;;;;;;;;;;;;  ADCQ  $0, R12; \
+    MOVL $38,  DX; /* 2*C = 38 = 2^256 MOD 2^255-19*/ \
+    IMULQ DX, R12; \
+    ADDQ R12, R8; \
+    ADCQ $0,  R9;  MOVQ  R9,  8+z; \
+    ADCQ $0, R10;  MOVQ R10, 16+z; \
+    ADCQ $0, R11;  MOVQ R11, 24+z; \
+    MOVQ $0, R12; \
+    CMOVQCS DX, R12; \
+    ADDQ R12, R8;  MOVQ  R8,  0+z;
+
+#define mulA24Legacy \
+    multiplyA24Leg(0(DI),0(SI))
+#define mulA24Bmi2Adx \
+    multiplyA24Adx(0(DI),0(SI))
+
+// func mulA24Amd64(z, x *fp255.Elt)
+TEXT ·mulA24Amd64(SB),NOSPLIT,$0-16
+    MOVQ z+0(FP), DI
+    MOVQ x+8(FP), SI
+    CHECK_BMI2ADX(LMA24, mulA24Legacy, mulA24Bmi2Adx)
+
+
+// func ladderStepAmd64(w *[5]fp255.Elt, b uint)
+// ladderStepAmd64 calculates a point addition and doubling as follows:
+// (x2,z2) = 2*(x2,z2) and (x3,z3) = (x2,z2)+(x3,z3) using as a difference (x1,-).
+//  work  = (x1,x2,z2,x3,z3) are five fp255.Elt of 32 bytes.
+//  stack = (t0,t1) are two fp.Elt of fp.Size bytes, and
+//          (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
+TEXT ·ladderStepAmd64(SB),NOSPLIT,$192-16
+    // Parameters
+    #define regWork DI
+    #define regMove SI
+    #define x1 0*Size(regWork)
+    #define x2 1*Size(regWork)
+    #define z2 2*Size(regWork)
+    #define x3 3*Size(regWork)
+    #define z3 4*Size(regWork)
+    // Local variables
+    #define t0 0*Size(SP)
+    #define t1 1*Size(SP)
+    #define b0 2*Size(SP)
+    #define b1 4*Size(SP)
+    MOVQ w+0(FP), regWork
+    MOVQ b+8(FP), regMove
+    CHECK_BMI2ADX(LLADSTEP, ladderStepLeg, ladderStepBmi2Adx)
+    #undef regWork
+    #undef regMove
+    #undef x1
+    #undef x2
+    #undef z2
+    #undef x3
+    #undef z3
+    #undef t0
+    #undef t1
+    #undef b0
+    #undef b1
+
+// func diffAddAmd64(w *[5]fp255.Elt, b uint)
+// diffAddAmd64 calculates a differential point addition using a precomputed point.
+// (x1,z1) = (x1,z1)+(mu) using a difference point (x2,z2)
+//    w    = (mu,x1,z1,x2,z2) are five fp.Elt, and
+//   stack = (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
+TEXT ·diffAddAmd64(SB),NOSPLIT,$128-16
+    // Parameters
+    #define regWork DI
+    #define regSwap SI
+    #define ui 0*Size(regWork)
+    #define x1 1*Size(regWork)
+    #define z1 2*Size(regWork)
+    #define x2 3*Size(regWork)
+    #define z2 4*Size(regWork)
+    // Local variables
+    #define b0 0*Size(SP)
+    #define b1 2*Size(SP)
+    MOVQ w+0(FP), regWork
+    MOVQ b+8(FP), regSwap
+    cswap(x1,x2,regSwap)
+    cswap(z1,z2,regSwap)
+    CHECK_BMI2ADX(LDIFADD, difAddLeg, difAddBmi2Adx)
+    #undef regWork
+    #undef regSwap
+    #undef ui
+    #undef x1
+    #undef z1
+    #undef x2
+    #undef z2
+    #undef b0
+    #undef b1
+
+// func doubleAmd64(x, z *fp255.Elt)
+// doubleAmd64 calculates a point doubling (x1,z1) = 2*(x1,z1).
+//  stack = (t0,t1) are two fp.Elt of fp.Size bytes, and
+//          (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
+TEXT ·doubleAmd64(SB),NOSPLIT,$192-16
+    // Parameters
+    #define x1 0(DI)
+    #define z1 0(SI)
+    // Local variables
+    #define t0 0*Size(SP)
+    #define t1 1*Size(SP)
+    #define b0 2*Size(SP)
+    #define b1 4*Size(SP)
+    MOVQ x+0(FP), DI
+    MOVQ z+8(FP), SI
+    CHECK_BMI2ADX(LDOUB,doubleLeg,doubleBmi2Adx)
+    #undef x1
+    #undef z1
+    #undef t0
+    #undef t1
+    #undef b0
+    #undef b1
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/curve_generic.go b/vendor/github.com/cloudflare/circl/dh/x25519/curve_generic.go
new file mode 100644
index 00000000..dae67ea3
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve_generic.go
@@ -0,0 +1,85 @@
+package x25519
+
+import (
+	"encoding/binary"
+	"math/bits"
+
+	fp "github.com/cloudflare/circl/math/fp25519"
+)
+
+func doubleGeneric(x, z *fp.Elt) {
+	t0, t1 := &fp.Elt{}, &fp.Elt{}
+	fp.AddSub(x, z)
+	fp.Sqr(x, x)
+	fp.Sqr(z, z)
+	fp.Sub(t0, x, z)
+	mulA24Generic(t1, t0)
+	fp.Add(t1, t1, z)
+	fp.Mul(x, x, z)
+	fp.Mul(z, t0, t1)
+}
+
+func diffAddGeneric(w *[5]fp.Elt, b uint) {
+	mu, x1, z1, x2, z2 := &w[0], &w[1], &w[2], &w[3], &w[4]
+	fp.Cswap(x1, x2, b)
+	fp.Cswap(z1, z2, b)
+	fp.AddSub(x1, z1)
+	fp.Mul(z1, z1, mu)
+	fp.AddSub(x1, z1)
+	fp.Sqr(x1, x1)
+	fp.Sqr(z1, z1)
+	fp.Mul(x1, x1, z2)
+	fp.Mul(z1, z1, x2)
+}
+
+func ladderStepGeneric(w *[5]fp.Elt, b uint) {
+	x1, x2, z2, x3, z3 := &w[0], &w[1], &w[2], &w[3], &w[4]
+	t0 := &fp.Elt{}
+	t1 := &fp.Elt{}
+	fp.AddSub(x2, z2)
+	fp.AddSub(x3, z3)
+	fp.Mul(t0, x2, z3)
+	fp.Mul(t1, x3, z2)
+	fp.AddSub(t0, t1)
+	fp.Cmov(x2, x3, b)
+	fp.Cmov(z2, z3, b)
+	fp.Sqr(x3, t0)
+	fp.Sqr(z3, t1)
+	fp.Mul(z3, x1, z3)
+	fp.Sqr(x2, x2)
+	fp.Sqr(z2, z2)
+	fp.Sub(t0, x2, z2)
+	mulA24Generic(t1, t0)
+	fp.Add(t1, t1, z2)
+	fp.Mul(x2, x2, z2)
+	fp.Mul(z2, t0, t1)
+}
+
+func mulA24Generic(z, x *fp.Elt) {
+	const A24 = 121666
+	const n = 8
+	var xx [4]uint64
+	for i := range xx {
+		xx[i] = binary.LittleEndian.Uint64(x[i*n : (i+1)*n])
+	}
+
+	h0, l0 := bits.Mul64(xx[0], A24)
+	h1, l1 := bits.Mul64(xx[1], A24)
+	h2, l2 := bits.Mul64(xx[2], A24)
+	h3, l3 := bits.Mul64(xx[3], A24)
+
+	var c3 uint64
+	l1, c0 := bits.Add64(h0, l1, 0)
+	l2, c1 := bits.Add64(h1, l2, c0)
+	l3, c2 := bits.Add64(h2, l3, c1)
+	l4, _ := bits.Add64(h3, 0, c2)
+	_, l4 = bits.Mul64(l4, 38)
+	l0, c0 = bits.Add64(l0, l4, 0)
+	xx[1], c1 = bits.Add64(l1, 0, c0)
+	xx[2], c2 = bits.Add64(l2, 0, c1)
+	xx[3], c3 = bits.Add64(l3, 0, c2)
+	xx[0], _ = bits.Add64(l0, (-c3)&38, 0)
+	for i := range xx {
+		binary.LittleEndian.PutUint64(z[i*n:(i+1)*n], xx[i])
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/curve_noasm.go b/vendor/github.com/cloudflare/circl/dh/x25519/curve_noasm.go
new file mode 100644
index 00000000..07fab97d
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/curve_noasm.go
@@ -0,0 +1,11 @@
+//go:build !amd64 || purego
+// +build !amd64 purego
+
+package x25519
+
+import fp "github.com/cloudflare/circl/math/fp25519"
+
+func double(x, z *fp.Elt)             { doubleGeneric(x, z) }
+func diffAdd(w *[5]fp.Elt, b uint)    { diffAddGeneric(w, b) }
+func ladderStep(w *[5]fp.Elt, b uint) { ladderStepGeneric(w, b) }
+func mulA24(z, x *fp.Elt)             { mulA24Generic(z, x) }
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/doc.go b/vendor/github.com/cloudflare/circl/dh/x25519/doc.go
new file mode 100644
index 00000000..3ce102d1
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/doc.go
@@ -0,0 +1,19 @@
+/*
+Package x25519 provides Diffie-Hellman functions as specified in RFC-7748.
+
+Validation of public keys.
+
+The Diffie-Hellman function, as described in RFC-7748 [1], works for any
+public key. However, if a different protocol requires contributory
+behaviour [2,3], then the public keys must be validated against low-order
+points [3,4]. To do that, the Shared function performs this validation
+internally and returns false when the public key is invalid (i.e., it
+is a low-order point).
+
+References:
+  - [1] RFC7748 by Langley, Hamburg, Turner (https://rfc-editor.org/rfc/rfc7748.txt)
+  - [2] Curve25519 by Bernstein (https://cr.yp.to/ecdh.html)
+  - [3] Bernstein (https://cr.yp.to/ecdh.html#validate)
+  - [4] Cremers&Jackson (https://eprint.iacr.org/2019/526)
+*/
+package x25519
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/key.go b/vendor/github.com/cloudflare/circl/dh/x25519/key.go
new file mode 100644
index 00000000..c76f72ac
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/key.go
@@ -0,0 +1,47 @@
+package x25519
+
+import (
+	"crypto/subtle"
+
+	fp "github.com/cloudflare/circl/math/fp25519"
+)
+
+// Size is the length in bytes of a X25519 key.
+const Size = 32
+
+// Key represents a X25519 key.
+type Key [Size]byte
+
+func (k *Key) clamp(in *Key) *Key {
+	*k = *in
+	k[0] &= 248
+	k[31] = (k[31] & 127) | 64
+	return k
+}
+
+// isValidPubKey verifies if the public key is not a low-order point.
+func (k *Key) isValidPubKey() bool {
+	fp.Modp((*fp.Elt)(k))
+	var isLowOrder int
+	for _, P := range lowOrderPoints {
+		isLowOrder |= subtle.ConstantTimeCompare(P[:], k[:])
+	}
+	return isLowOrder == 0
+}
+
+// KeyGen obtains a public key given a secret key.
+func KeyGen(public, secret *Key) {
+	ladderJoye(public.clamp(secret))
+}
+
+// Shared calculates Alice's shared key from Alice's secret key and Bob's
+// public key returning true on success. A failure case happens when the public
+// key is a low-order point, thus the shared key is all-zeros and the function
+// returns false.
+func Shared(shared, secret, public *Key) bool {
+	validPk := *public
+	validPk[31] &= (1 << (255 % 8)) - 1
+	ok := validPk.isValidPubKey()
+	ladderMontgomery(shared.clamp(secret), &validPk)
+	return ok
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x25519/table.go b/vendor/github.com/cloudflare/circl/dh/x25519/table.go
new file mode 100644
index 00000000..28c8c4ac
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x25519/table.go
@@ -0,0 +1,268 @@
+package x25519
+
+import "github.com/cloudflare/circl/math/fp25519"
+
+// tableGenerator contains the set of points:
+//
+//	t[i] = (xi+1)/(xi-1),
+//
+// where (xi,yi) = 2^iG and G is the generator point
+// Size = (256)*(256/8) = 8192 bytes.
+var tableGenerator = [256 * fp25519.Size]byte{
+	/* (2^  0)P */ 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5f,
+	/* (2^  1)P */ 0x96, 0xfe, 0xaa, 0x16, 0xf4, 0x20, 0x82, 0x6b, 0x34, 0x6a, 0x56, 0x4f, 0x2b, 0xeb, 0xeb, 0x82, 0x0f, 0x95, 0xa5, 0x75, 0xb0, 0xa5, 0xa9, 0xd5, 0xf4, 0x88, 0x24, 0x4b, 0xcf, 0xb2, 0x42, 0x51,
+	/* (2^  2)P */ 0x0c, 0x68, 0x69, 0x00, 0x75, 0xbc, 0xae, 0x6a, 0x41, 0x9c, 0xf9, 0xa0, 0x20, 0x78, 0xcf, 0x89, 0xf4, 0xd0, 0x56, 0x3b, 0x18, 0xd9, 0x58, 0x2a, 0xa4, 0x11, 0x60, 0xe3, 0x80, 0xca, 0x5a, 0x4b,
+	/* (2^  3)P */ 0x5d, 0x74, 0x29, 0x8c, 0x34, 0x32, 0x91, 0x32, 0xd7, 0x2f, 0x64, 0xe1, 0x16, 0xe6, 0xa2, 0xf4, 0x34, 0xbc, 0x67, 0xff, 0x03, 0xbb, 0x45, 0x1e, 0x4a, 0x9b, 0x2a, 0xf4, 0xd0, 0x12, 0x69, 0x30,
+	/* (2^  4)P */ 0x54, 0x71, 0xaf, 0xe6, 0x07, 0x65, 0x88, 0xff, 0x2f, 0xc8, 0xee, 0xdf, 0x13, 0x0e, 0xf5, 0x04, 0xce, 0xb5, 0xba, 0x2a, 0xe8, 0x2f, 0x51, 0xaa, 0x22, 0xf2, 0xd5, 0x68, 0x1a, 0x25, 0x4e, 0x17,
+	/* (2^  5)P */ 0x98, 0x88, 0x02, 0x82, 0x0d, 0x70, 0x96, 0xcf, 0xc5, 0x02, 0x2c, 0x0a, 0x37, 0xe3, 0x43, 0x17, 0xaa, 0x6e, 0xe8, 0xb4, 0x98, 0xec, 0x9e, 0x37, 0x2e, 0x48, 0xe0, 0x51, 0x8a, 0x88, 0x59, 0x0c,
+	/* (2^  6)P */ 0x89, 0xd1, 0xb5, 0x99, 0xd6, 0xf1, 0xcb, 0xfb, 0x84, 0xdc, 0x9f, 0x8e, 0xd5, 0xf0, 0xae, 0xac, 0x14, 0x76, 0x1f, 0x23, 0x06, 0x0d, 0xc2, 0xc1, 0x72, 0xf9, 0x74, 0xa2, 0x8d, 0x21, 0x38, 0x29,
+	/* (2^  7)P */ 0x18, 0x7f, 0x1d, 0xff, 0xbe, 0x49, 0xaf, 0xf6, 0xc2, 0xc9, 0x7a, 0x38, 0x22, 0x1c, 0x54, 0xcc, 0x6b, 0xc5, 0x15, 0x40, 0xef, 0xc9, 0xfc, 0x96, 0xa9, 0x13, 0x09, 0x69, 0x7c, 0x62, 0xc1, 0x69,
+	/* (2^  8)P */ 0x0e, 0xdb, 0x33, 0x47, 0x2f, 0xfd, 0x86, 0x7a, 0xe9, 0x7d, 0x08, 0x9e, 0xf2, 0xc4, 0xb8, 0xfd, 0x29, 0xa2, 0xa2, 0x8e, 0x1a, 0x4b, 0x5e, 0x09, 0x79, 0x7a, 0xb3, 0x29, 0xc8, 0xa7, 0xd7, 0x1a,
+	/* (2^  9)P */ 0xc0, 0xa0, 0x7e, 0xd1, 0xca, 0x89, 0x2d, 0x34, 0x51, 0x20, 0xed, 0xcc, 0xa6, 0xdd, 0xbe, 0x67, 0x74, 0x2f, 0xb4, 0x2b, 0xbf, 0x31, 0xca, 0x19, 0xbb, 0xac, 0x80, 0x49, 0xc8, 0xb4, 0xf7, 0x3d,
+	/* (2^ 10)P */ 0x83, 0xd8, 0x0a, 0xc8, 0x4d, 0x44, 0xc6, 0xa8, 0x85, 0xab, 0xe3, 0x66, 0x03, 0x44, 0x1e, 0xb9, 0xd8, 0xf6, 0x64, 0x01, 0xa0, 0xcd, 0x15, 0xc2, 0x68, 0xe6, 0x47, 0xf2, 0x6e, 0x7c, 0x86, 0x3d,
+	/* (2^ 11)P */ 0x8c, 0x65, 0x3e, 0xcc, 0x2b, 0x58, 0xdd, 0xc7, 0x28, 0x55, 0x0e, 0xee, 0x48, 0x47, 0x2c, 0xfd, 0x71, 0x4f, 0x9f, 0xcc, 0x95, 0x9b, 0xfd, 0xa0, 0xdf, 0x5d, 0x67, 0xb0, 0x71, 0xd8, 0x29, 0x75,
+	/* (2^ 12)P */ 0x78, 0xbd, 0x3c, 0x2d, 0xb4, 0x68, 0xf5, 0xb8, 0x82, 0xda, 0xf3, 0x91, 0x1b, 0x01, 0x33, 0x12, 0x62, 0x3b, 0x7c, 0x4a, 0xcd, 0x6c, 0xce, 0x2d, 0x03, 0x86, 0x49, 0x9e, 0x8e, 0xfc, 0xe7, 0x75,
+	/* (2^ 13)P */ 0xec, 0xb6, 0xd0, 0xfc, 0xf1, 0x13, 0x4f, 0x2f, 0x45, 0x7a, 0xff, 0x29, 0x1f, 0xca, 0xa8, 0xf1, 0x9b, 0xe2, 0x81, 0x29, 0xa7, 0xc1, 0x49, 0xc2, 0x6a, 0xb5, 0x83, 0x8c, 0xbb, 0x0d, 0xbe, 0x6e,
+	/* (2^ 14)P */ 0x22, 0xb2, 0x0b, 0x17, 0x8d, 0xfa, 0x14, 0x71, 0x5f, 0x93, 0x93, 0xbf, 0xd5, 0xdc, 0xa2, 0x65, 0x9a, 0x97, 0x9c, 0xb5, 0x68, 0x1f, 0xc4, 0xbd, 0x89, 0x92, 0xce, 0xa2, 0x79, 0xef, 0x0e, 0x2f,
+	/* (2^ 15)P */ 0xce, 0x37, 0x3c, 0x08, 0x0c, 0xbf, 0xec, 0x42, 0x22, 0x63, 0x49, 0xec, 0x09, 0xbc, 0x30, 0x29, 0x0d, 0xac, 0xfe, 0x9c, 0xc1, 0xb0, 0x94, 0xf2, 0x80, 0xbb, 0xfa, 0xed, 0x4b, 0xaa, 0x80, 0x37,
+	/* (2^ 16)P */ 0x29, 0xd9, 0xea, 0x7c, 0x3e, 0x7d, 0xc1, 0x56, 0xc5, 0x22, 0x57, 0x2e, 0xeb, 0x4b, 0xcb, 0xe7, 0x5a, 0xe1, 0xbf, 0x2d, 0x73, 0x31, 0xe9, 0x0c, 0xf8, 0x52, 0x10, 0x62, 0xc7, 0x83, 0xb8, 0x41,
+	/* (2^ 17)P */ 0x50, 0x53, 0xd2, 0xc3, 0xa0, 0x5c, 0xf7, 0xdb, 0x51, 0xe3, 0xb1, 0x6e, 0x08, 0xbe, 0x36, 0x29, 0x12, 0xb2, 0xa9, 0xb4, 0x3c, 0xe0, 0x36, 0xc9, 0xaa, 0x25, 0x22, 0x32, 0x82, 0xbf, 0x45, 0x1d,
+	/* (2^ 18)P */ 0xc5, 0x4c, 0x02, 0x6a, 0x03, 0xb1, 0x1a, 0xe8, 0x72, 0x9a, 0x4c, 0x30, 0x1c, 0x20, 0x12, 0xe2, 0xfc, 0xb1, 0x32, 0x68, 0xba, 0x3f, 0xd7, 0xc5, 0x81, 0x95, 0x83, 0x4d, 0x5a, 0xdb, 0xff, 0x20,
+	/* (2^ 19)P */ 0xad, 0x0f, 0x5d, 0xbe, 0x67, 0xd3, 0x83, 0xa2, 0x75, 0x44, 0x16, 0x8b, 0xca, 0x25, 0x2b, 0x6c, 0x2e, 0xf2, 0xaa, 0x7c, 0x46, 0x35, 0x49, 0x9d, 0x49, 0xff, 0x85, 0xee, 0x8e, 0x40, 0x66, 0x51,
+	/* (2^ 20)P */ 0x61, 0xe3, 0xb4, 0xfa, 0xa2, 0xba, 0x67, 0x3c, 0xef, 0x5c, 0xf3, 0x7e, 0xc6, 0x33, 0xe4, 0xb3, 0x1c, 0x9b, 0x15, 0x41, 0x92, 0x72, 0x59, 0x52, 0x33, 0xab, 0xb0, 0xd5, 0x92, 0x18, 0x62, 0x6a,
+	/* (2^ 21)P */ 0xcb, 0xcd, 0x55, 0x75, 0x38, 0x4a, 0xb7, 0x20, 0x3f, 0x92, 0x08, 0x12, 0x0e, 0xa1, 0x2a, 0x53, 0xd1, 0x1d, 0x28, 0x62, 0x77, 0x7b, 0xa1, 0xea, 0xbf, 0x44, 0x5c, 0xf0, 0x43, 0x34, 0xab, 0x61,
+	/* (2^ 22)P */ 0xf8, 0xde, 0x24, 0x23, 0x42, 0x6c, 0x7a, 0x25, 0x7f, 0xcf, 0xe3, 0x17, 0x10, 0x6c, 0x1c, 0x13, 0x57, 0xa2, 0x30, 0xf6, 0x39, 0x87, 0x75, 0x23, 0x80, 0x85, 0xa7, 0x01, 0x7a, 0x40, 0x5a, 0x29,
+	/* (2^ 23)P */ 0xd9, 0xa8, 0x5d, 0x6d, 0x24, 0x43, 0xc4, 0xf8, 0x5d, 0xfa, 0x52, 0x0c, 0x45, 0x75, 0xd7, 0x19, 0x3d, 0xf8, 0x1b, 0x73, 0x92, 0xfc, 0xfc, 0x2a, 0x00, 0x47, 0x2b, 0x1b, 0xe8, 0xc8, 0x10, 0x7d,
+	/* (2^ 24)P */ 0x0b, 0xa2, 0xba, 0x70, 0x1f, 0x27, 0xe0, 0xc8, 0x57, 0x39, 0xa6, 0x7c, 0x86, 0x48, 0x37, 0x99, 0xbb, 0xd4, 0x7e, 0xcb, 0xb3, 0xef, 0x12, 0x54, 0x75, 0x29, 0xe6, 0x73, 0x61, 0xd3, 0x96, 0x31,
+	/* (2^ 25)P */ 0xfc, 0xdf, 0xc7, 0x41, 0xd1, 0xca, 0x5b, 0xde, 0x48, 0xc8, 0x95, 0xb3, 0xd2, 0x8c, 0xcc, 0x47, 0xcb, 0xf3, 0x1a, 0xe1, 0x42, 0xd9, 0x4c, 0xa3, 0xc2, 0xce, 0x4e, 0xd0, 0xf2, 0xdb, 0x56, 0x02,
+	/* (2^ 26)P */ 0x7f, 0x66, 0x0e, 0x4b, 0xe9, 0xb7, 0x5a, 0x87, 0x10, 0x0d, 0x85, 0xc0, 0x83, 0xdd, 0xd4, 0xca, 0x9f, 0xc7, 0x72, 0x4e, 0x8f, 0x2e, 0xf1, 0x47, 0x9b, 0xb1, 0x85, 0x8c, 0xbb, 0x87, 0x1a, 0x5f,
+	/* (2^ 27)P */ 0xb8, 0x51, 0x7f, 0x43, 0xb6, 0xd0, 0xe9, 0x7a, 0x65, 0x90, 0x87, 0x18, 0x55, 0xce, 0xc7, 0x12, 0xee, 0x7a, 0xf7, 0x5c, 0xfe, 0x09, 0xde, 0x2a, 0x27, 0x56, 0x2c, 0x7d, 0x2f, 0x5a, 0xa0, 0x23,
+	/* (2^ 28)P */ 0x9a, 0x16, 0x7c, 0xf1, 0x28, 0xe1, 0x08, 0x59, 0x2d, 0x85, 0xd0, 0x8a, 0xdd, 0x98, 0x74, 0xf7, 0x64, 0x2f, 0x10, 0xab, 0xce, 0xc4, 0xb4, 0x74, 0x45, 0x98, 0x13, 0x10, 0xdd, 0xba, 0x3a, 0x18,
+	/* (2^ 29)P */ 0xac, 0xaa, 0x92, 0xaa, 0x8d, 0xba, 0x65, 0xb1, 0x05, 0x67, 0x38, 0x99, 0x95, 0xef, 0xc5, 0xd5, 0xd1, 0x40, 0xfc, 0xf8, 0x0c, 0x8f, 0x2f, 0xbe, 0x14, 0x45, 0x20, 0xee, 0x35, 0xe6, 0x01, 0x27,
+	/* (2^ 30)P */ 0x14, 0x65, 0x15, 0x20, 0x00, 0xa8, 0x9f, 0x62, 0xce, 0xc1, 0xa8, 0x64, 0x87, 0x86, 0x23, 0xf2, 0x0e, 0x06, 0x3f, 0x0b, 0xff, 0x4f, 0x89, 0x5b, 0xfa, 0xa3, 0x08, 0xf7, 0x4c, 0x94, 0xd9, 0x60,
+	/* (2^ 31)P */ 0x1f, 0x20, 0x7a, 0x1c, 0x1a, 0x00, 0xea, 0xae, 0x63, 0xce, 0xe2, 0x3e, 0x63, 0x6a, 0xf1, 0xeb, 0xe1, 0x07, 0x7a, 0x4c, 0x59, 0x09, 0x77, 0x6f, 0xcb, 0x08, 0x02, 0x0d, 0x15, 0x58, 0xb9, 0x79,
+	/* (2^ 32)P */ 0xe7, 0x10, 0xd4, 0x01, 0x53, 0x5e, 0xb5, 0x24, 0x4d, 0xc8, 0xfd, 0xf3, 0xdf, 0x4e, 0xa3, 0xe3, 0xd8, 0x32, 0x40, 0x90, 0xe4, 0x68, 0x87, 0xd8, 0xec, 0xae, 0x3a, 0x7b, 0x42, 0x84, 0x13, 0x13,
+	/* (2^ 33)P */ 0x14, 0x4f, 0x23, 0x86, 0x12, 0xe5, 0x05, 0x84, 0x29, 0xc5, 0xb4, 0xad, 0x39, 0x47, 0xdc, 0x14, 0xfd, 0x4f, 0x63, 0x50, 0xb2, 0xb5, 0xa2, 0xb8, 0x93, 0xff, 0xa7, 0xd8, 0x4a, 0xa9, 0xe2, 0x2f,
+	/* (2^ 34)P */ 0xdd, 0xfa, 0x43, 0xe8, 0xef, 0x57, 0x5c, 0xec, 0x18, 0x99, 0xbb, 0xf0, 0x40, 0xce, 0x43, 0x28, 0x05, 0x63, 0x3d, 0xcf, 0xd6, 0x61, 0xb5, 0xa4, 0x7e, 0x77, 0xfb, 0xe8, 0xbd, 0x29, 0x36, 0x74,
+	/* (2^ 35)P */ 0x8f, 0x73, 0xaf, 0xbb, 0x46, 0xdd, 0x3e, 0x34, 0x51, 0xa6, 0x01, 0xb1, 0x28, 0x18, 0x98, 0xed, 0x7a, 0x79, 0x2c, 0x88, 0x0b, 0x76, 0x01, 0xa4, 0x30, 0x87, 0xc8, 0x8d, 0xe2, 0x23, 0xc2, 0x1f,
+	/* (2^ 36)P */ 0x0e, 0xba, 0x0f, 0xfc, 0x91, 0x4e, 0x60, 0x48, 0xa4, 0x6f, 0x2c, 0x05, 0x8f, 0xf7, 0x37, 0xb6, 0x9c, 0x23, 0xe9, 0x09, 0x3d, 0xac, 0xcc, 0x91, 0x7c, 0x68, 0x7a, 0x43, 0xd4, 0xee, 0xf7, 0x23,
+	/* (2^ 37)P */ 0x00, 0xd8, 0x9b, 0x8d, 0x11, 0xb1, 0x73, 0x51, 0xa7, 0xd4, 0x89, 0x31, 0xb6, 0x41, 0xd6, 0x29, 0x86, 0xc5, 0xbb, 0x88, 0x79, 0x17, 0xbf, 0xfd, 0xf5, 0x1d, 0xd8, 0xca, 0x4f, 0x89, 0x59, 0x29,
+	/* (2^ 38)P */ 0x99, 0xc8, 0xbb, 0xb4, 0xf3, 0x8e, 0xbc, 0xae, 0xb9, 0x92, 0x69, 0xb2, 0x5a, 0x99, 0x48, 0x41, 0xfb, 0x2c, 0xf9, 0x34, 0x01, 0x0b, 0xe2, 0x24, 0xe8, 0xde, 0x05, 0x4a, 0x89, 0x58, 0xd1, 0x40,
+	/* (2^ 39)P */ 0xf6, 0x76, 0xaf, 0x85, 0x11, 0x0b, 0xb0, 0x46, 0x79, 0x7a, 0x18, 0x73, 0x78, 0xc7, 0xba, 0x26, 0x5f, 0xff, 0x8f, 0xab, 0x95, 0xbf, 0xc0, 0x3d, 0xd7, 0x24, 0x55, 0x94, 0xd8, 0x8b, 0x60, 0x2a,
+	/* (2^ 40)P */ 0x02, 0x63, 0x44, 0xbd, 0x88, 0x95, 0x44, 0x26, 0x9c, 0x43, 0x88, 0x03, 0x1c, 0xc2, 0x4b, 0x7c, 0xb2, 0x11, 0xbd, 0x83, 0xf3, 0xa4, 0x98, 0x8e, 0xb9, 0x76, 0xd8, 0xc9, 0x7b, 0x8d, 0x21, 0x26,
+	/* (2^ 41)P */ 0x8a, 0x17, 0x7c, 0x99, 0x42, 0x15, 0x08, 0xe3, 0x6f, 0x60, 0xb6, 0x6f, 0xa8, 0x29, 0x2d, 0x3c, 0x74, 0x93, 0x27, 0xfa, 0x36, 0x77, 0x21, 0x5c, 0xfa, 0xb1, 0xfe, 0x4a, 0x73, 0x05, 0xde, 0x7d,
+	/* (2^ 42)P */ 0xab, 0x2b, 0xd4, 0x06, 0x39, 0x0e, 0xf1, 0x3b, 0x9c, 0x64, 0x80, 0x19, 0x3e, 0x80, 0xf7, 0xe4, 0x7a, 0xbf, 0x95, 0x95, 0xf8, 0x3b, 0x05, 0xe6, 0x30, 0x55, 0x24, 0xda, 0x38, 0xaf, 0x4f, 0x39,
+	/* (2^ 43)P */ 0xf4, 0x28, 0x69, 0x89, 0x58, 0xfb, 0x8e, 0x7a, 0x3c, 0x11, 0x6a, 0xcc, 0xe9, 0x78, 0xc7, 0xfb, 0x6f, 0x59, 0xaf, 0x30, 0xe3, 0x0c, 0x67, 0x72, 0xf7, 0x6c, 0x3d, 0x1d, 0xa8, 0x22, 0xf2, 0x48,
+	/* (2^ 44)P */ 0xa7, 0xca, 0x72, 0x0d, 0x41, 0xce, 0x1f, 0xf0, 0x95, 0x55, 0x3b, 0x21, 0xc7, 0xec, 0x20, 0x5a, 0x83, 0x14, 0xfa, 0xc1, 0x65, 0x11, 0xc2, 0x7b, 0x41, 0xa7, 0xa8, 0x1d, 0xe3, 0x9a, 0xf8, 0x07,
+	/* (2^ 45)P */ 0xf9, 0x0f, 0x83, 0xc6, 0xb4, 0xc2, 0xd2, 0x05, 0x93, 0x62, 0x31, 0xc6, 0x0f, 0x33, 0x3e, 0xd4, 0x04, 0xa9, 0xd3, 0x96, 0x0a, 0x59, 0xa5, 0xa5, 0xb6, 0x33, 0x53, 0xa6, 0x91, 0xdb, 0x5e, 0x70,
+	/* (2^ 46)P */ 0xf7, 0xa5, 0xb9, 0x0b, 0x5e, 0xe1, 0x8e, 0x04, 0x5d, 0xaf, 0x0a, 0x9e, 0xca, 0xcf, 0x40, 0x32, 0x0b, 0xa4, 0xc4, 0xed, 0xce, 0x71, 0x4b, 0x8f, 0x6d, 0x4a, 0x54, 0xde, 0xa3, 0x0d, 0x1c, 0x62,
+	/* (2^ 47)P */ 0x91, 0x40, 0x8c, 0xa0, 0x36, 0x28, 0x87, 0x92, 0x45, 0x14, 0xc9, 0x10, 0xb0, 0x75, 0x83, 0xce, 0x94, 0x63, 0x27, 0x4f, 0x52, 0xeb, 0x72, 0x8a, 0x35, 0x36, 0xc8, 0x7e, 0xfa, 0xfc, 0x67, 0x26,
+	/* (2^ 48)P */ 0x2a, 0x75, 0xe8, 0x45, 0x33, 0x17, 0x4c, 0x7f, 0xa5, 0x79, 0x70, 0xee, 0xfe, 0x47, 0x1b, 0x06, 0x34, 0xff, 0x86, 0x9f, 0xfa, 0x9a, 0xdd, 0x25, 0x9c, 0xc8, 0x5d, 0x42, 0xf5, 0xce, 0x80, 0x37,
+	/* (2^ 49)P */ 0xe9, 0xb4, 0x3b, 0x51, 0x5a, 0x03, 0x46, 0x1a, 0xda, 0x5a, 0x57, 0xac, 0x79, 0xf3, 0x1e, 0x3e, 0x50, 0x4b, 0xa2, 0x5f, 0x1c, 0x5f, 0x8c, 0xc7, 0x22, 0x9f, 0xfd, 0x34, 0x76, 0x96, 0x1a, 0x32,
+	/* (2^ 50)P */ 0xfa, 0x27, 0x6e, 0x82, 0xb8, 0x07, 0x67, 0x94, 0xd0, 0x6f, 0x50, 0x4c, 0xd6, 0x84, 0xca, 0x3d, 0x36, 0x14, 0xe9, 0x75, 0x80, 0x21, 0x89, 0xc1, 0x84, 0x84, 0x3b, 0x9b, 0x16, 0x84, 0x92, 0x6d,
+	/* (2^ 51)P */ 0xdf, 0x2d, 0x3f, 0x38, 0x40, 0xe8, 0x67, 0x3a, 0x75, 0x9b, 0x4f, 0x0c, 0xa3, 0xc9, 0xee, 0x33, 0x47, 0xef, 0x83, 0xa7, 0x6f, 0xc8, 0xc7, 0x3e, 0xc4, 0xfb, 0xc9, 0xba, 0x9f, 0x44, 0xec, 0x26,
+	/* (2^ 52)P */ 0x7d, 0x9e, 0x9b, 0xa0, 0xcb, 0x38, 0x0f, 0x5c, 0x8c, 0x47, 0xa3, 0x62, 0xc7, 0x8c, 0x16, 0x81, 0x1c, 0x12, 0xfc, 0x06, 0xd3, 0xb0, 0x23, 0x3e, 0xdd, 0xdc, 0xef, 0xa5, 0xa0, 0x8a, 0x23, 0x5a,
+	/* (2^ 53)P */ 0xff, 0x43, 0xea, 0xc4, 0x21, 0x61, 0xa2, 0x1b, 0xb5, 0x32, 0x88, 0x7c, 0x7f, 0xc7, 0xf8, 0x36, 0x9a, 0xf9, 0xdc, 0x0a, 0x0b, 0xea, 0xfb, 0x88, 0xf9, 0xeb, 0x5b, 0xc2, 0x8e, 0x93, 0xa9, 0x5c,
+	/* (2^ 54)P */ 0xa0, 0xcd, 0xfc, 0x51, 0x5e, 0x6a, 0x43, 0xd5, 0x3b, 0x89, 0xcd, 0xc2, 0x97, 0x47, 0xbc, 0x1d, 0x08, 0x4a, 0x22, 0xd3, 0x65, 0x6a, 0x34, 0x19, 0x66, 0xf4, 0x9a, 0x9b, 0xe4, 0x34, 0x50, 0x0f,
+	/* (2^ 55)P */ 0x6e, 0xb9, 0xe0, 0xa1, 0x67, 0x39, 0x3c, 0xf2, 0x88, 0x4d, 0x7a, 0x86, 0xfa, 0x08, 0x8b, 0xe5, 0x79, 0x16, 0x34, 0xa7, 0xc6, 0xab, 0x2f, 0xfb, 0x46, 0x69, 0x02, 0xb6, 0x1e, 0x38, 0x75, 0x2a,
+	/* (2^ 56)P */ 0xac, 0x20, 0x94, 0xc1, 0xe4, 0x3b, 0x0a, 0xc8, 0xdc, 0xb6, 0xf2, 0x81, 0xc6, 0xf6, 0xb1, 0x66, 0x88, 0x33, 0xe9, 0x61, 0x67, 0x03, 0xf7, 0x7c, 0xc4, 0xa4, 0x60, 0xa6, 0xd8, 0xbb, 0xab, 0x25,
+	/* (2^ 57)P */ 0x98, 0x51, 0xfd, 0x14, 0xba, 0x12, 0xea, 0x91, 0xa9, 0xff, 0x3c, 0x4a, 0xfc, 0x50, 0x49, 0x68, 0x28, 0xad, 0xf5, 0x30, 0x21, 0x84, 0x26, 0xf8, 0x41, 0xa4, 0x01, 0x53, 0xf7, 0x88, 0xa9, 0x3e,
+	/* (2^ 58)P */ 0x6f, 0x8c, 0x5f, 0x69, 0x9a, 0x10, 0x78, 0xc9, 0xf3, 0xc3, 0x30, 0x05, 0x4a, 0xeb, 0x46, 0x17, 0x95, 0x99, 0x45, 0xb4, 0x77, 0x6d, 0x4d, 0x44, 0xc7, 0x5c, 0x4e, 0x05, 0x8c, 0x2b, 0x95, 0x75,
+	/* (2^ 59)P */ 0xaa, 0xd6, 0xf4, 0x15, 0x79, 0x3f, 0x70, 0xa3, 0xd8, 0x47, 0x26, 0x2f, 0x20, 0x46, 0xc3, 0x66, 0x4b, 0x64, 0x1d, 0x81, 0xdf, 0x69, 0x14, 0xd0, 0x1f, 0xd7, 0xa5, 0x81, 0x7d, 0xa4, 0xfe, 0x77,
+	/* (2^ 60)P */ 0x81, 0xa3, 0x7c, 0xf5, 0x9e, 0x52, 0xe9, 0xc5, 0x1a, 0x88, 0x2f, 0xce, 0xb9, 0xb4, 0xee, 0x6e, 0xd6, 0x9b, 0x00, 0xe8, 0x28, 0x1a, 0xe9, 0xb6, 0xec, 0x3f, 0xfc, 0x9a, 0x3e, 0xbe, 0x80, 0x4b,
+	/* (2^ 61)P */ 0xc5, 0xd2, 0xae, 0x26, 0xc5, 0x73, 0x37, 0x7e, 0x9d, 0xa4, 0xc9, 0x53, 0xb4, 0xfc, 0x4a, 0x1b, 0x4d, 0xb2, 0xff, 0xba, 0xd7, 0xbd, 0x20, 0xa9, 0x0e, 0x40, 0x2d, 0x12, 0x9f, 0x69, 0x54, 0x7c,
+	/* (2^ 62)P */ 0xc8, 0x4b, 0xa9, 0x4f, 0xe1, 0xc8, 0x46, 0xef, 0x5e, 0xed, 0x52, 0x29, 0xce, 0x74, 0xb0, 0xe0, 0xd5, 0x85, 0xd8, 0xdb, 0xe1, 0x50, 0xa4, 0xbe, 0x2c, 0x71, 0x0f, 0x32, 0x49, 0x86, 0xb6, 0x61,
+	/* (2^ 63)P */ 0xd1, 0xbd, 0xcc, 0x09, 0x73, 0x5f, 0x48, 0x8a, 0x2d, 0x1a, 0x4d, 0x7d, 0x0d, 0x32, 0x06, 0xbd, 0xf4, 0xbe, 0x2d, 0x32, 0x73, 0x29, 0x23, 0x25, 0x70, 0xf7, 0x17, 0x8c, 0x75, 0xc4, 0x5d, 0x44,
+	/* (2^ 64)P */ 0x3c, 0x93, 0xc8, 0x7c, 0x17, 0x34, 0x04, 0xdb, 0x9f, 0x05, 0xea, 0x75, 0x21, 0xe8, 0x6f, 0xed, 0x34, 0xdb, 0x53, 0xc0, 0xfd, 0xbe, 0xfe, 0x1e, 0x99, 0xaf, 0x5d, 0xc6, 0x67, 0xe8, 0xdb, 0x4a,
+	/* (2^ 65)P */ 0xdf, 0x09, 0x06, 0xa9, 0xa2, 0x71, 0xcd, 0x3a, 0x50, 0x40, 0xd0, 0x6d, 0x85, 0x91, 0xe9, 0xe5, 0x3c, 0xc2, 0x57, 0x81, 0x68, 0x9b, 0xc6, 0x1e, 0x4d, 0xfe, 0x5c, 0x88, 0xf6, 0x27, 0x74, 0x69,
+	/* (2^ 66)P */ 0x51, 0xa8, 0xe1, 0x65, 0x9b, 0x7b, 0xbe, 0xd7, 0xdd, 0x36, 0xc5, 0x22, 0xd5, 0x28, 0x3d, 0xa0, 0x45, 0xb6, 0xd2, 0x8f, 0x65, 0x9d, 0x39, 0x28, 0xe1, 0x41, 0x26, 0x7c, 0xe1, 0xb7, 0xe5, 0x49,
+	/* (2^ 67)P */ 0xa4, 0x57, 0x04, 0x70, 0x98, 0x3a, 0x8c, 0x6f, 0x78, 0x67, 0xbb, 0x5e, 0xa2, 0xf0, 0x78, 0x50, 0x0f, 0x96, 0x82, 0xc3, 0xcb, 0x3c, 0x3c, 0xd1, 0xb1, 0x84, 0xdf, 0xa7, 0x58, 0x32, 0x00, 0x2e,
+	/* (2^ 68)P */ 0x1c, 0x6a, 0x29, 0xe6, 0x9b, 0xf3, 0xd1, 0x8a, 0xb2, 0xbf, 0x5f, 0x2a, 0x65, 0xaa, 0xee, 0xc1, 0xcb, 0xf3, 0x26, 0xfd, 0x73, 0x06, 0xee, 0x33, 0xcc, 0x2c, 0x9d, 0xa6, 0x73, 0x61, 0x25, 0x59,
+	/* (2^ 69)P */ 0x41, 0xfc, 0x18, 0x4e, 0xaa, 0x07, 0xea, 0x41, 0x1e, 0xa5, 0x87, 0x7c, 0x52, 0x19, 0xfc, 0xd9, 0x6f, 0xca, 0x31, 0x58, 0x80, 0xcb, 0xaa, 0xbd, 0x4f, 0x69, 0x16, 0xc9, 0x2d, 0x65, 0x5b, 0x44,
+	/* (2^ 70)P */ 0x15, 0x23, 0x17, 0xf2, 0xa7, 0xa3, 0x92, 0xce, 0x64, 0x99, 0x1b, 0xe1, 0x2d, 0x28, 0xdc, 0x1e, 0x4a, 0x31, 0x4c, 0xe0, 0xaf, 0x3a, 0x82, 0xa1, 0x86, 0xf5, 0x7c, 0x43, 0x94, 0x2d, 0x0a, 0x79,
+	/* (2^ 71)P */ 0x09, 0xe0, 0xf6, 0x93, 0xfb, 0x47, 0xc4, 0x71, 0x76, 0x52, 0x84, 0x22, 0x67, 0xa5, 0x22, 0x89, 0x69, 0x51, 0x4f, 0x20, 0x3b, 0x90, 0x70, 0xbf, 0xfe, 0x19, 0xa3, 0x1b, 0x89, 0x89, 0x7a, 0x2f,
+	/* (2^ 72)P */ 0x0c, 0x14, 0xe2, 0x77, 0xb5, 0x8e, 0xa0, 0x02, 0xf4, 0xdc, 0x7b, 0x42, 0xd4, 0x4e, 0x9a, 0xed, 0xd1, 0x3c, 0x32, 0xe4, 0x44, 0xec, 0x53, 0x52, 0x5b, 0x35, 0xe9, 0x14, 0x3c, 0x36, 0x88, 0x3e,
+	/* (2^ 73)P */ 0x8c, 0x0b, 0x11, 0x77, 0x42, 0xc1, 0x66, 0xaa, 0x90, 0x33, 0xa2, 0x10, 0x16, 0x39, 0xe0, 0x1a, 0xa2, 0xc2, 0x3f, 0xc9, 0x12, 0xbd, 0x30, 0x20, 0xab, 0xc7, 0x55, 0x95, 0x57, 0x41, 0xe1, 0x3e,
+	/* (2^ 74)P */ 0x41, 0x7d, 0x6e, 0x6d, 0x3a, 0xde, 0x14, 0x92, 0xfe, 0x7e, 0xf1, 0x07, 0x86, 0xd8, 0xcd, 0x3c, 0x17, 0x12, 0xe1, 0xf8, 0x88, 0x12, 0x4f, 0x67, 0xd0, 0x93, 0x9f, 0x32, 0x0f, 0x25, 0x82, 0x56,
+	/* (2^ 75)P */ 0x6e, 0x39, 0x2e, 0x6d, 0x13, 0x0b, 0xf0, 0x6c, 0xbf, 0xde, 0x14, 0x10, 0x6f, 0xf8, 0x4c, 0x6e, 0x83, 0x4e, 0xcc, 0xbf, 0xb5, 0xb1, 0x30, 0x59, 0xb6, 0x16, 0xba, 0x8a, 0xb4, 0x69, 0x70, 0x04,
+	/* (2^ 76)P */ 0x93, 0x07, 0xb2, 0x69, 0xab, 0xe4, 0x4c, 0x0d, 0x9e, 0xfb, 0xd0, 0x97, 0x1a, 0xb9, 0x4d, 0xb2, 0x1d, 0xd0, 0x00, 0x4e, 0xf5, 0x50, 0xfa, 0xcd, 0xb5, 0xdd, 0x8b, 0x36, 0x85, 0x10, 0x1b, 0x22,
+	/* (2^ 77)P */ 0xd2, 0xd8, 0xe3, 0xb1, 0x68, 0x94, 0xe5, 0xe7, 0x93, 0x2f, 0x12, 0xbd, 0x63, 0x65, 0xc5, 0x53, 0x09, 0x3f, 0x66, 0xe0, 0x03, 0xa9, 0xe8, 0xee, 0x42, 0x3d, 0xbe, 0xcb, 0x62, 0xa6, 0xef, 0x61,
+	/* (2^ 78)P */ 0x2a, 0xab, 0x6e, 0xde, 0xdd, 0xdd, 0xf8, 0x2c, 0x31, 0xf2, 0x35, 0x14, 0xd5, 0x0a, 0xf8, 0x9b, 0x73, 0x49, 0xf0, 0xc9, 0xce, 0xda, 0xea, 0x5d, 0x27, 0x9b, 0xd2, 0x41, 0x5d, 0x5b, 0x27, 0x29,
+	/* (2^ 79)P */ 0x4f, 0xf1, 0xeb, 0x95, 0x08, 0x0f, 0xde, 0xcf, 0xa7, 0x05, 0x49, 0x05, 0x6b, 0xb9, 0xaa, 0xb9, 0xfd, 0x20, 0xc4, 0xa1, 0xd9, 0x0d, 0xe8, 0xca, 0xc7, 0xbb, 0x73, 0x16, 0x2f, 0xbf, 0x63, 0x0a,
+	/* (2^ 80)P */ 0x8c, 0xbc, 0x8f, 0x95, 0x11, 0x6e, 0x2f, 0x09, 0xad, 0x2f, 0x82, 0x04, 0xe8, 0x81, 0x2a, 0x67, 0x17, 0x25, 0xd5, 0x60, 0x15, 0x35, 0xc8, 0xca, 0xf8, 0x92, 0xf1, 0xc8, 0x22, 0x77, 0x3f, 0x6f,
+	/* (2^ 81)P */ 0xb7, 0x94, 0xe8, 0xc2, 0xcc, 0x90, 0xba, 0xf8, 0x0d, 0x9f, 0xff, 0x38, 0xa4, 0x57, 0x75, 0x2c, 0x59, 0x23, 0xe5, 0x5a, 0x85, 0x1d, 0x4d, 0x89, 0x69, 0x3d, 0x74, 0x7b, 0x15, 0x22, 0xe1, 0x68,
+	/* (2^ 82)P */ 0xf3, 0x19, 0xb9, 0xcf, 0x70, 0x55, 0x7e, 0xd8, 0xb9, 0x8d, 0x79, 0x95, 0xcd, 0xde, 0x2c, 0x3f, 0xce, 0xa2, 0xc0, 0x10, 0x47, 0x15, 0x21, 0x21, 0xb2, 0xc5, 0x6d, 0x24, 0x15, 0xa1, 0x66, 0x3c,
+	/* (2^ 83)P */ 0x72, 0xcb, 0x4e, 0x29, 0x62, 0xc5, 0xed, 0xcb, 0x16, 0x0b, 0x28, 0x6a, 0xc3, 0x43, 0x71, 0xba, 0x67, 0x8b, 0x07, 0xd4, 0xef, 0xc2, 0x10, 0x96, 0x1e, 0x4b, 0x6a, 0x94, 0x5d, 0x73, 0x44, 0x61,
+	/* (2^ 84)P */ 0x50, 0x33, 0x5b, 0xd7, 0x1e, 0x11, 0x6f, 0x53, 0x1b, 0xd8, 0x41, 0x20, 0x8c, 0xdb, 0x11, 0x02, 0x3c, 0x41, 0x10, 0x0e, 0x00, 0xb1, 0x3c, 0xf9, 0x76, 0x88, 0x9e, 0x03, 0x3c, 0xfd, 0x9d, 0x14,
+	/* (2^ 85)P */ 0x5b, 0x15, 0x63, 0x6b, 0xe4, 0xdd, 0x79, 0xd4, 0x76, 0x79, 0x83, 0x3c, 0xe9, 0x15, 0x6e, 0xb6, 0x38, 0xe0, 0x13, 0x1f, 0x3b, 0xe4, 0xfd, 0xda, 0x35, 0x0b, 0x4b, 0x2e, 0x1a, 0xda, 0xaf, 0x5f,
+	/* (2^ 86)P */ 0x81, 0x75, 0x19, 0x17, 0xdf, 0xbb, 0x00, 0x36, 0xc2, 0xd2, 0x3c, 0xbe, 0x0b, 0x05, 0x72, 0x39, 0x86, 0xbe, 0xd5, 0xbd, 0x6d, 0x90, 0x38, 0x59, 0x0f, 0x86, 0x9b, 0x3f, 0xe4, 0xe5, 0xfc, 0x34,
+	/* (2^ 87)P */ 0x02, 0x4d, 0xd1, 0x42, 0xcd, 0xa4, 0xa8, 0x75, 0x65, 0xdf, 0x41, 0x34, 0xc5, 0xab, 0x8d, 0x82, 0xd3, 0x31, 0xe1, 0xd2, 0xed, 0xab, 0xdc, 0x33, 0x5f, 0xd2, 0x14, 0xb8, 0x6f, 0xd7, 0xba, 0x3e,
+	/* (2^ 88)P */ 0x0f, 0xe1, 0x70, 0x6f, 0x56, 0x6f, 0x90, 0xd4, 0x5a, 0x0f, 0x69, 0x51, 0xaa, 0xf7, 0x12, 0x5d, 0xf2, 0xfc, 0xce, 0x76, 0x6e, 0xb1, 0xad, 0x45, 0x99, 0x29, 0x23, 0xad, 0xae, 0x68, 0xf7, 0x01,
+	/* (2^ 89)P */ 0xbd, 0xfe, 0x48, 0x62, 0x7b, 0xc7, 0x6c, 0x2b, 0xfd, 0xaf, 0x3a, 0xec, 0x28, 0x06, 0xd3, 0x3c, 0x6a, 0x48, 0xef, 0xd4, 0x80, 0x0b, 0x1c, 0xce, 0x23, 0x6c, 0xf6, 0xa6, 0x2e, 0xff, 0x3b, 0x4c,
+	/* (2^ 90)P */ 0x5f, 0xeb, 0xea, 0x4a, 0x09, 0xc4, 0x2e, 0x3f, 0xa7, 0x2c, 0x37, 0x6e, 0x28, 0x9b, 0xb1, 0x61, 0x1d, 0x70, 0x2a, 0xde, 0x66, 0xa9, 0xef, 0x5e, 0xef, 0xe3, 0x55, 0xde, 0x65, 0x05, 0xb2, 0x23,
+	/* (2^ 91)P */ 0x57, 0x85, 0xd5, 0x79, 0x52, 0xca, 0x01, 0xe3, 0x4f, 0x87, 0xc2, 0x27, 0xce, 0xd4, 0xb2, 0x07, 0x67, 0x1d, 0xcf, 0x9d, 0x8a, 0xcd, 0x32, 0xa5, 0x56, 0xff, 0x2b, 0x3f, 0xe2, 0xfe, 0x52, 0x2a,
+	/* (2^ 92)P */ 0x3d, 0x66, 0xd8, 0x7c, 0xb3, 0xef, 0x24, 0x86, 0x94, 0x75, 0xbd, 0xff, 0x20, 0xac, 0xc7, 0xbb, 0x45, 0x74, 0xd3, 0x82, 0x9c, 0x5e, 0xb8, 0x57, 0x66, 0xec, 0xa6, 0x86, 0xcb, 0x52, 0x30, 0x7b,
+	/* (2^ 93)P */ 0x1e, 0xe9, 0x25, 0x25, 0xad, 0xf0, 0x82, 0x34, 0xa0, 0xdc, 0x8e, 0xd2, 0x43, 0x80, 0xb6, 0x2c, 0x3a, 0x00, 0x1b, 0x2e, 0x05, 0x6d, 0x4f, 0xaf, 0x0a, 0x1b, 0x78, 0x29, 0x25, 0x8c, 0x5f, 0x18,
+	/* (2^ 94)P */ 0xd6, 0xe0, 0x0c, 0xd8, 0x5b, 0xde, 0x41, 0xaa, 0xd6, 0xe9, 0x53, 0x68, 0x41, 0xb2, 0x07, 0x94, 0x3a, 0x4c, 0x7f, 0x35, 0x6e, 0xc3, 0x3e, 0x56, 0xce, 0x7b, 0x29, 0x0e, 0xdd, 0xb8, 0xc4, 0x4c,
+	/* (2^ 95)P */ 0x0e, 0x73, 0xb8, 0xff, 0x52, 0x1a, 0xfc, 0xa2, 0x37, 0x8e, 0x05, 0x67, 0x6e, 0xf1, 0x11, 0x18, 0xe1, 0x4e, 0xdf, 0xcd, 0x66, 0xa3, 0xf9, 0x10, 0x99, 0xf0, 0xb9, 0xa0, 0xc4, 0xa0, 0xf4, 0x72,
+	/* (2^ 96)P */ 0xa7, 0x4e, 0x3f, 0x66, 0x6f, 0xc0, 0x16, 0x8c, 0xba, 0x0f, 0x97, 0x4e, 0xf7, 0x3a, 0x3b, 0x69, 0x45, 0xc3, 0x9e, 0xd6, 0xf1, 0xe7, 0x02, 0x21, 0x89, 0x80, 0x8a, 0x96, 0xbc, 0x3c, 0xa5, 0x0b,
+	/* (2^ 97)P */ 0x37, 0x55, 0xa1, 0xfe, 0xc7, 0x9d, 0x3d, 0xca, 0x93, 0x64, 0x53, 0x51, 0xbb, 0x24, 0x68, 0x4c, 0xb1, 0x06, 0x40, 0x84, 0x14, 0x63, 0x88, 0xb9, 0x60, 0xcc, 0x54, 0xb4, 0x2a, 0xa7, 0xd2, 0x40,
+	/* (2^ 98)P */ 0x75, 0x09, 0x57, 0x12, 0xb7, 0xa1, 0x36, 0x59, 0x57, 0xa6, 0xbd, 0xde, 0x48, 0xd6, 0xb9, 0x91, 0xea, 0x30, 0x43, 0xb6, 0x4b, 0x09, 0x44, 0x33, 0xd0, 0x51, 0xee, 0x12, 0x0d, 0xa1, 0x6b, 0x00,
+	/* (2^ 99)P */ 0x58, 0x5d, 0xde, 0xf5, 0x68, 0x84, 0x22, 0x19, 0xb0, 0x05, 0xcc, 0x38, 0x4c, 0x2f, 0xb1, 0x0e, 0x90, 0x19, 0x60, 0xd5, 0x9d, 0x9f, 0x03, 0xa1, 0x0b, 0x0e, 0xff, 0x4f, 0xce, 0xd4, 0x02, 0x45,
+	/* (2^100)P */ 0x89, 0xc1, 0x37, 0x68, 0x10, 0x54, 0x20, 0xeb, 0x3c, 0xb9, 0xd3, 0x6d, 0x4c, 0x54, 0xf6, 0xd0, 0x4f, 0xd7, 0x16, 0xc4, 0x64, 0x70, 0x72, 0x40, 0xf0, 0x2e, 0x50, 0x4b, 0x11, 0xc6, 0x15, 0x6e,
+	/* (2^101)P */ 0x6b, 0xa7, 0xb1, 0xcf, 0x98, 0xa3, 0xf2, 0x4d, 0xb1, 0xf6, 0xf2, 0x19, 0x74, 0x6c, 0x25, 0x11, 0x43, 0x60, 0x6e, 0x06, 0x62, 0x79, 0x49, 0x4a, 0x44, 0x5b, 0x35, 0x41, 0xab, 0x3a, 0x5b, 0x70,
+	/* (2^102)P */ 0xd8, 0xb1, 0x97, 0xd7, 0x36, 0xf5, 0x5e, 0x36, 0xdb, 0xf0, 0xdd, 0x22, 0xd6, 0x6b, 0x07, 0x00, 0x88, 0x5a, 0x57, 0xe0, 0xb0, 0x33, 0xbf, 0x3b, 0x4d, 0xca, 0xe4, 0xc8, 0x05, 0xaa, 0x77, 0x37,
+	/* (2^103)P */ 0x5f, 0xdb, 0x78, 0x55, 0xc8, 0x45, 0x27, 0x39, 0xe2, 0x5a, 0xae, 0xdb, 0x49, 0x41, 0xda, 0x6f, 0x67, 0x98, 0xdc, 0x8a, 0x0b, 0xb0, 0xf0, 0xb1, 0xa3, 0x1d, 0x6f, 0xd3, 0x37, 0x34, 0x96, 0x09,
+	/* (2^104)P */ 0x53, 0x38, 0xdc, 0xa5, 0x90, 0x4e, 0x82, 0x7e, 0xbd, 0x5c, 0x13, 0x1f, 0x64, 0xf6, 0xb5, 0xcc, 0xcc, 0x8f, 0xce, 0x87, 0x6c, 0xd8, 0x36, 0x67, 0x9f, 0x24, 0x04, 0x66, 0xe2, 0x3c, 0x5f, 0x62,
+	/* (2^105)P */ 0x3f, 0xf6, 0x02, 0x95, 0x05, 0xc8, 0x8a, 0xaf, 0x69, 0x14, 0x35, 0x2e, 0x0a, 0xe7, 0x05, 0x0c, 0x05, 0x63, 0x4b, 0x76, 0x9c, 0x2e, 0x29, 0x35, 0xc3, 0x3a, 0xe2, 0xc7, 0x60, 0x43, 0x39, 0x1a,
+	/* (2^106)P */ 0x64, 0x32, 0x18, 0x51, 0x32, 0xd5, 0xc6, 0xd5, 0x4f, 0xb7, 0xc2, 0x43, 0xbd, 0x5a, 0x06, 0x62, 0x9b, 0x3f, 0x97, 0x3b, 0xd0, 0xf5, 0xfb, 0xb5, 0x5e, 0x6e, 0x20, 0x61, 0x36, 0xda, 0xa3, 0x13,
+	/* (2^107)P */ 0xe5, 0x94, 0x5d, 0x72, 0x37, 0x58, 0xbd, 0xc6, 0xc5, 0x16, 0x50, 0x20, 0x12, 0x09, 0xe3, 0x18, 0x68, 0x3c, 0x03, 0x70, 0x15, 0xce, 0x88, 0x20, 0x87, 0x79, 0x83, 0x5c, 0x49, 0x1f, 0xba, 0x7f,
+	/* (2^108)P */ 0x9d, 0x07, 0xf9, 0xf2, 0x23, 0x74, 0x8c, 0x5a, 0xc5, 0x3f, 0x02, 0x34, 0x7b, 0x15, 0x35, 0x17, 0x51, 0xb3, 0xfa, 0xd2, 0x9a, 0xb4, 0xf9, 0xe4, 0x3c, 0xe3, 0x78, 0xc8, 0x72, 0xff, 0x91, 0x66,
+	/* (2^109)P */ 0x3e, 0xff, 0x5e, 0xdc, 0xde, 0x2a, 0x2c, 0x12, 0xf4, 0x6c, 0x95, 0xd8, 0xf1, 0x4b, 0xdd, 0xf8, 0xda, 0x5b, 0x9e, 0x9e, 0x5d, 0x20, 0x86, 0xeb, 0x43, 0xc7, 0x75, 0xd9, 0xb9, 0x92, 0x9b, 0x04,
+	/* (2^110)P */ 0x5a, 0xc0, 0xf6, 0xb0, 0x30, 0x97, 0x37, 0xa5, 0x53, 0xa5, 0xf3, 0xc6, 0xac, 0xff, 0xa0, 0x72, 0x6d, 0xcd, 0x0d, 0xb2, 0x34, 0x2c, 0x03, 0xb0, 0x4a, 0x16, 0xd5, 0x88, 0xbc, 0x9d, 0x0e, 0x47,
+	/* (2^111)P */ 0x47, 0xc0, 0x37, 0xa2, 0x0c, 0xf1, 0x9c, 0xb1, 0xa2, 0x81, 0x6c, 0x1f, 0x71, 0x66, 0x54, 0xb6, 0x43, 0x0b, 0xd8, 0x6d, 0xd1, 0x1b, 0x32, 0xb3, 0x8e, 0xbe, 0x5f, 0x0c, 0x60, 0x4f, 0xc1, 0x48,
+	/* (2^112)P */ 0x03, 0xc8, 0xa6, 0x4a, 0x26, 0x1c, 0x45, 0x66, 0xa6, 0x7d, 0xfa, 0xa4, 0x04, 0x39, 0x6e, 0xb6, 0x95, 0x83, 0x12, 0xb3, 0xb0, 0x19, 0x5f, 0xd4, 0x10, 0xbc, 0xc9, 0xc3, 0x27, 0x26, 0x60, 0x31,
+	/* (2^113)P */ 0x0d, 0xe1, 0xe4, 0x32, 0x48, 0xdc, 0x20, 0x31, 0xf7, 0x17, 0xc7, 0x56, 0x67, 0xc4, 0x20, 0xeb, 0x94, 0x02, 0x28, 0x67, 0x3f, 0x2e, 0xf5, 0x00, 0x09, 0xc5, 0x30, 0x47, 0xc1, 0x4f, 0x6d, 0x56,
+	/* (2^114)P */ 0x06, 0x72, 0x83, 0xfd, 0x40, 0x5d, 0x3a, 0x7e, 0x7a, 0x54, 0x59, 0x71, 0xdc, 0x26, 0xe9, 0xc1, 0x95, 0x60, 0x8d, 0xa6, 0xfb, 0x30, 0x67, 0x21, 0xa7, 0xce, 0x69, 0x3f, 0x84, 0xc3, 0xe8, 0x22,
+	/* (2^115)P */ 0x2b, 0x4b, 0x0e, 0x93, 0xe8, 0x74, 0xd0, 0x33, 0x16, 0x58, 0xd1, 0x84, 0x0e, 0x35, 0xe4, 0xb6, 0x65, 0x23, 0xba, 0xd6, 0x6a, 0xc2, 0x34, 0x55, 0xf3, 0xf3, 0xf1, 0x89, 0x2f, 0xc1, 0x73, 0x77,
+	/* (2^116)P */ 0xaa, 0x62, 0x79, 0xa5, 0x4d, 0x40, 0xba, 0x8c, 0x56, 0xce, 0x99, 0x19, 0xa8, 0x97, 0x98, 0x5b, 0xfc, 0x92, 0x16, 0x12, 0x2f, 0x86, 0x8e, 0x50, 0x91, 0xc2, 0x93, 0xa0, 0x7f, 0x90, 0x81, 0x3a,
+	/* (2^117)P */ 0x10, 0xa5, 0x25, 0x47, 0xff, 0xd0, 0xde, 0x0d, 0x03, 0xc5, 0x3f, 0x67, 0x10, 0xcc, 0xd8, 0x10, 0x89, 0x4e, 0x1f, 0x9f, 0x1c, 0x15, 0x9d, 0x5b, 0x4c, 0xa4, 0x09, 0xcb, 0xd5, 0xc1, 0xa5, 0x32,
+	/* (2^118)P */ 0xfb, 0x41, 0x05, 0xb9, 0x42, 0xa4, 0x0a, 0x1e, 0xdb, 0x85, 0xb4, 0xc1, 0x7c, 0xeb, 0x85, 0x5f, 0xe5, 0xf2, 0x9d, 0x8a, 0xce, 0x95, 0xe5, 0xbe, 0x36, 0x22, 0x42, 0x22, 0xc7, 0x96, 0xe4, 0x25,
+	/* (2^119)P */ 0xb9, 0xe5, 0x0f, 0xcd, 0x46, 0x3c, 0xdf, 0x5e, 0x88, 0x33, 0xa4, 0xd2, 0x7e, 0x5a, 0xe7, 0x34, 0x52, 0xe3, 0x61, 0xd7, 0x11, 0xde, 0x88, 0xe4, 0x5c, 0x54, 0x85, 0xa0, 0x01, 0x8a, 0x87, 0x0e,
+	/* (2^120)P */ 0x04, 0xbb, 0x21, 0xe0, 0x77, 0x3c, 0x49, 0xba, 0x9a, 0x89, 0xdf, 0xc7, 0x43, 0x18, 0x4d, 0x2b, 0x67, 0x0d, 0xe8, 0x7a, 0x48, 0x7a, 0xa3, 0x9e, 0x94, 0x17, 0xe4, 0x11, 0x80, 0x95, 0xa9, 0x67,
+	/* (2^121)P */ 0x65, 0xb0, 0x97, 0x66, 0x1a, 0x05, 0x58, 0x4b, 0xd4, 0xa6, 0x6b, 0x8d, 0x7d, 0x3f, 0xe3, 0x47, 0xc1, 0x46, 0xca, 0x83, 0xd4, 0xa8, 0x4d, 0xbb, 0x0d, 0xdb, 0xc2, 0x81, 0xa1, 0xca, 0xbe, 0x68,
+	/* (2^122)P */ 0xa5, 0x9a, 0x98, 0x0b, 0xe9, 0x80, 0x89, 0x8d, 0x9b, 0xc9, 0x93, 0x2c, 0x4a, 0xb1, 0x5e, 0xf9, 0xa2, 0x73, 0x6e, 0x79, 0xc4, 0xc7, 0xc6, 0x51, 0x69, 0xb5, 0xef, 0xb5, 0x63, 0x83, 0x22, 0x6e,
+	/* (2^123)P */ 0xc8, 0x24, 0xd6, 0x2d, 0xb0, 0xc0, 0xbb, 0xc6, 0xee, 0x70, 0x81, 0xec, 0x7d, 0xb4, 0x7e, 0x77, 0xa9, 0xaf, 0xcf, 0x04, 0xa0, 0x15, 0xde, 0x3c, 0x9b, 0xbf, 0x60, 0x71, 0x08, 0xbc, 0xc6, 0x1d,
+	/* (2^124)P */ 0x02, 0x40, 0xc3, 0xee, 0x43, 0xe0, 0x07, 0x2e, 0x7f, 0xdc, 0x68, 0x7a, 0x67, 0xfc, 0xe9, 0x18, 0x9a, 0x5b, 0xd1, 0x8b, 0x18, 0x03, 0xda, 0xd8, 0x53, 0x82, 0x56, 0x00, 0xbb, 0xc3, 0xfb, 0x48,
+	/* (2^125)P */ 0xe1, 0x4c, 0x65, 0xfb, 0x4c, 0x7d, 0x54, 0x57, 0xad, 0xe2, 0x58, 0xa0, 0x82, 0x5b, 0x56, 0xd3, 0x78, 0x44, 0x15, 0xbf, 0x0b, 0xaf, 0x3e, 0xf6, 0x18, 0xbb, 0xdf, 0x14, 0xf1, 0x1e, 0x53, 0x47,
+	/* (2^126)P */ 0x87, 0xc5, 0x78, 0x42, 0x0a, 0x63, 0xec, 0xe1, 0xf3, 0x83, 0x8e, 0xca, 0x46, 0xd5, 0x07, 0x55, 0x2b, 0x0c, 0xdc, 0x3a, 0xc6, 0x35, 0xe1, 0x85, 0x4e, 0x84, 0x82, 0x56, 0xa8, 0xef, 0xa7, 0x0a,
+	/* (2^127)P */ 0x15, 0xf6, 0xe1, 0xb3, 0xa8, 0x1b, 0x69, 0x72, 0xfa, 0x3f, 0xbe, 0x1f, 0x70, 0xe9, 0xb4, 0x32, 0x68, 0x78, 0xbb, 0x39, 0x2e, 0xd9, 0xb6, 0x97, 0xe8, 0x39, 0x2e, 0xa0, 0xde, 0x53, 0xfe, 0x2c,
+	/* (2^128)P */ 0xb0, 0x52, 0xcd, 0x85, 0xcd, 0x92, 0x73, 0x68, 0x31, 0x98, 0xe2, 0x10, 0xc9, 0x66, 0xff, 0x27, 0x06, 0x2d, 0x83, 0xa9, 0x56, 0x45, 0x13, 0x97, 0xa0, 0xf8, 0x84, 0x0a, 0x36, 0xb0, 0x9b, 0x26,
+	/* (2^129)P */ 0x5c, 0xf8, 0x43, 0x76, 0x45, 0x55, 0x6e, 0x70, 0x1b, 0x7d, 0x59, 0x9b, 0x8c, 0xa4, 0x34, 0x37, 0x72, 0xa4, 0xef, 0xc6, 0xe8, 0x91, 0xee, 0x7a, 0xe0, 0xd9, 0xa9, 0x98, 0xc1, 0xab, 0xd6, 0x5c,
+	/* (2^130)P */ 0x1a, 0xe4, 0x3c, 0xcb, 0x06, 0xde, 0x04, 0x0e, 0x38, 0xe1, 0x02, 0x34, 0x89, 0xeb, 0xc6, 0xd8, 0x72, 0x37, 0x6e, 0x68, 0xbb, 0x59, 0x46, 0x90, 0xc8, 0xa8, 0x6b, 0x74, 0x71, 0xc3, 0x15, 0x72,
+	/* (2^131)P */ 0xd9, 0xa2, 0xe4, 0xea, 0x7e, 0xa9, 0x12, 0xfd, 0xc5, 0xf2, 0x94, 0x63, 0x51, 0xb7, 0x14, 0x95, 0x94, 0xf2, 0x08, 0x92, 0x80, 0xd5, 0x6f, 0x26, 0xb9, 0x26, 0x9a, 0x61, 0x85, 0x70, 0x84, 0x5c,
+	/* (2^132)P */ 0xea, 0x94, 0xd6, 0xfe, 0x10, 0x54, 0x98, 0x52, 0x54, 0xd2, 0x2e, 0x4a, 0x93, 0x5b, 0x90, 0x3c, 0x67, 0xe4, 0x3b, 0x2d, 0x69, 0x47, 0xbb, 0x10, 0xe1, 0xe9, 0xe5, 0x69, 0x2d, 0x3d, 0x3b, 0x06,
+	/* (2^133)P */ 0xeb, 0x7d, 0xa5, 0xdd, 0xee, 0x26, 0x27, 0x47, 0x91, 0x18, 0xf4, 0x10, 0xae, 0xc4, 0xb6, 0xef, 0x14, 0x76, 0x30, 0x7b, 0x91, 0x41, 0x16, 0x2b, 0x7c, 0x5b, 0xf4, 0xc4, 0x4f, 0x55, 0x7c, 0x11,
+	/* (2^134)P */ 0x12, 0x88, 0x9d, 0x8f, 0x11, 0xf3, 0x7c, 0xc0, 0x39, 0x79, 0x01, 0x50, 0x20, 0xd8, 0xdb, 0x01, 0x27, 0x28, 0x1b, 0x17, 0xf4, 0x03, 0xe8, 0xd7, 0xea, 0x25, 0xd2, 0x87, 0x74, 0xe8, 0x15, 0x10,
+	/* (2^135)P */ 0x4d, 0xcc, 0x3a, 0xd2, 0xfe, 0xe3, 0x8d, 0xc5, 0x2d, 0xbe, 0xa7, 0x94, 0xc2, 0x91, 0xdb, 0x50, 0x57, 0xf4, 0x9c, 0x1c, 0x3d, 0xd4, 0x94, 0x0b, 0x4a, 0x52, 0x37, 0x6e, 0xfa, 0x40, 0x16, 0x6b,
+	/* (2^136)P */ 0x09, 0x0d, 0xda, 0x5f, 0x6c, 0x34, 0x2f, 0x69, 0x51, 0x31, 0x4d, 0xfa, 0x59, 0x1c, 0x0b, 0x20, 0x96, 0xa2, 0x77, 0x07, 0x76, 0x6f, 0xc4, 0xb8, 0xcf, 0xfb, 0xfd, 0x3f, 0x5f, 0x39, 0x38, 0x4b,
+	/* (2^137)P */ 0x71, 0xd6, 0x54, 0xbe, 0x00, 0x5e, 0xd2, 0x18, 0xa6, 0xab, 0xc8, 0xbe, 0x82, 0x05, 0xd5, 0x60, 0x82, 0xb9, 0x78, 0x3b, 0x26, 0x8f, 0xad, 0x87, 0x32, 0x04, 0xda, 0x9c, 0x4e, 0xf6, 0xfd, 0x50,
+	/* (2^138)P */ 0xf0, 0xdc, 0x78, 0xc5, 0xaa, 0x67, 0xf5, 0x90, 0x3b, 0x13, 0xa3, 0xf2, 0x0e, 0x9b, 0x1e, 0xef, 0x71, 0xde, 0xd9, 0x42, 0x92, 0xba, 0xeb, 0x0e, 0xc7, 0x01, 0x31, 0xf0, 0x9b, 0x3c, 0x47, 0x15,
+	/* (2^139)P */ 0x95, 0x80, 0xb7, 0x56, 0xae, 0xe8, 0x77, 0x7c, 0x8e, 0x07, 0x6f, 0x6e, 0x66, 0xe7, 0x78, 0xb6, 0x1f, 0xba, 0x48, 0x53, 0x61, 0xb9, 0xa0, 0x2d, 0x0b, 0x3f, 0x73, 0xff, 0xc1, 0x31, 0xf9, 0x7c,
+	/* (2^140)P */ 0x6c, 0x36, 0x0a, 0x0a, 0xf5, 0x57, 0xb3, 0x26, 0x32, 0xd7, 0x87, 0x2b, 0xf4, 0x8c, 0x70, 0xe9, 0xc0, 0xb2, 0x1c, 0xf9, 0xa5, 0xee, 0x3a, 0xc1, 0x4c, 0xbb, 0x43, 0x11, 0x99, 0x0c, 0xd9, 0x35,
+	/* (2^141)P */ 0xdc, 0xd9, 0xa0, 0xa9, 0x04, 0xc4, 0xc1, 0x47, 0x51, 0xd2, 0x72, 0x19, 0x45, 0x58, 0x9e, 0x65, 0x31, 0x8c, 0xb3, 0x73, 0xc4, 0xa8, 0x75, 0x38, 0x24, 0x1f, 0x56, 0x79, 0xd3, 0x9e, 0xbd, 0x1f,
+	/* (2^142)P */ 0x8d, 0xc2, 0x1e, 0xd4, 0x6f, 0xbc, 0xfa, 0x11, 0xca, 0x2d, 0x2a, 0xcd, 0xe3, 0xdf, 0xf8, 0x7e, 0x95, 0x45, 0x40, 0x8c, 0x5d, 0x3b, 0xe7, 0x72, 0x27, 0x2f, 0xb7, 0x54, 0x49, 0xfa, 0x35, 0x61,
+	/* (2^143)P */ 0x9c, 0xb6, 0x24, 0xde, 0xa2, 0x32, 0xfc, 0xcc, 0x88, 0x5d, 0x09, 0x1f, 0x8c, 0x69, 0x55, 0x3f, 0x29, 0xf9, 0xc3, 0x5a, 0xed, 0x50, 0x33, 0xbe, 0xeb, 0x7e, 0x47, 0xca, 0x06, 0xf8, 0x9b, 0x5e,
+	/* (2^144)P */ 0x68, 0x9f, 0x30, 0x3c, 0xb6, 0x8f, 0xce, 0xe9, 0xf4, 0xf9, 0xe1, 0x65, 0x35, 0xf6, 0x76, 0x53, 0xf1, 0x93, 0x63, 0x5a, 0xb3, 0xcf, 0xaf, 0xd1, 0x06, 0x35, 0x62, 0xe5, 0xed, 0xa1, 0x32, 0x66,
+	/* (2^145)P */ 0x4c, 0xed, 0x2d, 0x0c, 0x39, 0x6c, 0x7d, 0x0b, 0x1f, 0xcb, 0x04, 0xdf, 0x81, 0x32, 0xcb, 0x56, 0xc7, 0xc3, 0xec, 0x49, 0x12, 0x5a, 0x30, 0x66, 0x2a, 0xa7, 0x8c, 0xa3, 0x60, 0x8b, 0x58, 0x5d,
+	/* (2^146)P */ 0x2d, 0xf4, 0xe5, 0xe8, 0x78, 0xbf, 0xec, 0xa6, 0xec, 0x3e, 0x8a, 0x3c, 0x4b, 0xb4, 0xee, 0x86, 0x04, 0x16, 0xd2, 0xfb, 0x48, 0x9c, 0x21, 0xec, 0x31, 0x67, 0xc3, 0x17, 0xf5, 0x1a, 0xaf, 0x1a,
+	/* (2^147)P */ 0xe7, 0xbd, 0x69, 0x67, 0x83, 0xa2, 0x06, 0xc3, 0xdb, 0x2a, 0x1e, 0x2b, 0x62, 0x80, 0x82, 0x20, 0xa6, 0x94, 0xff, 0xfb, 0x1f, 0xf5, 0x27, 0x80, 0x6b, 0xf2, 0x24, 0x11, 0xce, 0xa1, 0xcf, 0x76,
+	/* (2^148)P */ 0xb6, 0xab, 0x22, 0x24, 0x56, 0x00, 0xeb, 0x18, 0xc3, 0x29, 0x8c, 0x8f, 0xd5, 0xc4, 0x77, 0xf3, 0x1a, 0x56, 0x31, 0xf5, 0x07, 0xc2, 0xbb, 0x4d, 0x27, 0x8a, 0x12, 0x82, 0xf0, 0xb7, 0x53, 0x02,
+	/* (2^149)P */ 0xe0, 0x17, 0x2c, 0xb6, 0x1c, 0x09, 0x1f, 0x3d, 0xa9, 0x28, 0x46, 0xd6, 0xab, 0xe1, 0x60, 0x48, 0x53, 0x42, 0x9d, 0x30, 0x36, 0x74, 0xd1, 0x52, 0x76, 0xe5, 0xfa, 0x3e, 0xe1, 0x97, 0x6f, 0x35,
+	/* (2^150)P */ 0x5b, 0x53, 0x50, 0xa1, 0x1a, 0xe1, 0x51, 0xd3, 0xcc, 0x78, 0xd8, 0x1d, 0xbb, 0x45, 0x6b, 0x3e, 0x98, 0x2c, 0xd9, 0xbe, 0x28, 0x61, 0x77, 0x0c, 0xb8, 0x85, 0x28, 0x03, 0x93, 0xae, 0x34, 0x1d,
+	/* (2^151)P */ 0xc3, 0xa4, 0x5b, 0xa8, 0x8c, 0x48, 0xa0, 0x4b, 0xce, 0xe6, 0x9c, 0x3c, 0xc3, 0x48, 0x53, 0x98, 0x70, 0xa7, 0xbd, 0x97, 0x6f, 0x4c, 0x12, 0x66, 0x4a, 0x12, 0x54, 0x06, 0x29, 0xa0, 0x81, 0x0f,
+	/* (2^152)P */ 0xfd, 0x86, 0x9b, 0x56, 0xa6, 0x9c, 0xd0, 0x9e, 0x2d, 0x9a, 0xaf, 0x18, 0xfd, 0x09, 0x10, 0x81, 0x0a, 0xc2, 0xd8, 0x93, 0x3f, 0xd0, 0x08, 0xff, 0x6b, 0xf2, 0xae, 0x9f, 0x19, 0x48, 0xa1, 0x52,
+	/* (2^153)P */ 0x73, 0x1b, 0x8d, 0x2d, 0xdc, 0xf9, 0x03, 0x3e, 0x70, 0x1a, 0x96, 0x73, 0x18, 0x80, 0x05, 0x42, 0x70, 0x59, 0xa3, 0x41, 0xf0, 0x87, 0xd9, 0xc0, 0x49, 0xd5, 0xc0, 0xa1, 0x15, 0x1f, 0xaa, 0x07,
+	/* (2^154)P */ 0x24, 0x72, 0xd2, 0x8c, 0xe0, 0x6c, 0xd4, 0xdf, 0x39, 0x42, 0x4e, 0x93, 0x4f, 0x02, 0x0a, 0x6d, 0x59, 0x7b, 0x89, 0x99, 0x63, 0x7a, 0x8a, 0x80, 0xa2, 0x95, 0x3d, 0xe1, 0xe9, 0x56, 0x45, 0x0a,
+	/* (2^155)P */ 0x45, 0x30, 0xc1, 0xe9, 0x1f, 0x99, 0x1a, 0xd2, 0xb8, 0x51, 0x77, 0xfe, 0x48, 0x85, 0x0e, 0x9b, 0x35, 0x00, 0xf3, 0x4b, 0xcb, 0x43, 0xa6, 0x5d, 0x21, 0xf7, 0x40, 0x39, 0xd6, 0x28, 0xdb, 0x77,
+	/* (2^156)P */ 0x11, 0x90, 0xdc, 0x4a, 0x61, 0xeb, 0x5e, 0xfc, 0xeb, 0x11, 0xc4, 0xe8, 0x9a, 0x41, 0x29, 0x52, 0x74, 0xcf, 0x1d, 0x7d, 0x78, 0xe7, 0xc3, 0x9e, 0xb5, 0x4c, 0x6e, 0x21, 0x3e, 0x05, 0x0d, 0x34,
+	/* (2^157)P */ 0xb4, 0xf2, 0x8d, 0xb4, 0x39, 0xaf, 0xc7, 0xca, 0x94, 0x0a, 0xa1, 0x71, 0x28, 0xec, 0xfa, 0xc0, 0xed, 0x75, 0xa5, 0x5c, 0x24, 0x69, 0x0a, 0x14, 0x4c, 0x3a, 0x27, 0x34, 0x71, 0xc3, 0xf1, 0x0c,
+	/* (2^158)P */ 0xa5, 0xb8, 0x24, 0xc2, 0x6a, 0x30, 0xee, 0xc8, 0xb0, 0x30, 0x49, 0xcb, 0x7c, 0xee, 0xea, 0x57, 0x4f, 0xe7, 0xcb, 0xaa, 0xbd, 0x06, 0xe8, 0xa1, 0x7d, 0x65, 0xeb, 0x2e, 0x74, 0x62, 0x9a, 0x7d,
+	/* (2^159)P */ 0x30, 0x48, 0x6c, 0x54, 0xef, 0xb6, 0xb6, 0x9e, 0x2e, 0x6e, 0xb3, 0xdd, 0x1f, 0xca, 0x5c, 0x88, 0x05, 0x71, 0x0d, 0xef, 0x83, 0xf3, 0xb9, 0xe6, 0x12, 0x04, 0x2e, 0x9d, 0xef, 0x4f, 0x65, 0x58,
+	/* (2^160)P */ 0x26, 0x8e, 0x0e, 0xbe, 0xff, 0xc4, 0x05, 0xa9, 0x6e, 0x81, 0x31, 0x9b, 0xdf, 0xe5, 0x2d, 0x94, 0xe1, 0x88, 0x2e, 0x80, 0x3f, 0x72, 0x7d, 0x49, 0x8d, 0x40, 0x2f, 0x60, 0xea, 0x4d, 0x68, 0x30,
+	/* (2^161)P */ 0x34, 0xcb, 0xe6, 0xa3, 0x78, 0xa2, 0xe5, 0x21, 0xc4, 0x1d, 0x15, 0x5b, 0x6f, 0x6e, 0xfb, 0xae, 0x15, 0xca, 0x77, 0x9d, 0x04, 0x8e, 0x0b, 0xb3, 0x81, 0x89, 0xb9, 0x53, 0xcf, 0xc9, 0xc3, 0x28,
+	/* (2^162)P */ 0x2a, 0xdd, 0x6c, 0x55, 0x21, 0xb7, 0x7f, 0x28, 0x74, 0x22, 0x02, 0x97, 0xa8, 0x7c, 0x31, 0x0d, 0x58, 0x32, 0x54, 0x3a, 0x42, 0xc7, 0x68, 0x74, 0x2f, 0x64, 0xb5, 0x4e, 0x46, 0x11, 0x7f, 0x4a,
+	/* (2^163)P */ 0xa6, 0x3a, 0x19, 0x4d, 0x77, 0xa4, 0x37, 0xa2, 0xa1, 0x29, 0x21, 0xa9, 0x6e, 0x98, 0x65, 0xd8, 0x88, 0x1a, 0x7c, 0xf8, 0xec, 0x15, 0xc5, 0x24, 0xeb, 0xf5, 0x39, 0x5f, 0x57, 0x03, 0x40, 0x60,
+	/* (2^164)P */ 0x27, 0x9b, 0x0a, 0x57, 0x89, 0xf1, 0xb9, 0x47, 0x78, 0x4b, 0x5e, 0x46, 0xde, 0xce, 0x98, 0x2b, 0x20, 0x5c, 0xb8, 0xdb, 0x51, 0xf5, 0x6d, 0x02, 0x01, 0x19, 0xe2, 0x47, 0x10, 0xd9, 0xfc, 0x74,
+	/* (2^165)P */ 0xa3, 0xbf, 0xc1, 0x23, 0x0a, 0xa9, 0xe2, 0x13, 0xf6, 0x19, 0x85, 0x47, 0x4e, 0x07, 0xb0, 0x0c, 0x44, 0xcf, 0xf6, 0x3a, 0xbe, 0xcb, 0xf1, 0x5f, 0xbe, 0x2d, 0x81, 0xbe, 0x38, 0x54, 0xfe, 0x67,
+	/* (2^166)P */ 0xb0, 0x05, 0x0f, 0xa4, 0x4f, 0xf6, 0x3c, 0xd1, 0x87, 0x37, 0x28, 0x32, 0x2f, 0xfb, 0x4d, 0x05, 0xea, 0x2a, 0x0d, 0x7f, 0x5b, 0x91, 0x73, 0x41, 0x4e, 0x0d, 0x61, 0x1f, 0x4f, 0x14, 0x2f, 0x48,
+	/* (2^167)P */ 0x34, 0x82, 0x7f, 0xb4, 0x01, 0x02, 0x21, 0xf6, 0x90, 0xb9, 0x70, 0x9e, 0x92, 0xe1, 0x0a, 0x5d, 0x7c, 0x56, 0x49, 0xb0, 0x55, 0xf4, 0xd7, 0xdc, 0x01, 0x6f, 0x91, 0xf0, 0xf1, 0xd0, 0x93, 0x7e,
+	/* (2^168)P */ 0xfa, 0xb4, 0x7d, 0x8a, 0xf1, 0xcb, 0x79, 0xdd, 0x2f, 0xc6, 0x74, 0x6f, 0xbf, 0x91, 0x83, 0xbe, 0xbd, 0x91, 0x82, 0x4b, 0xd1, 0x45, 0x71, 0x02, 0x05, 0x17, 0xbf, 0x2c, 0xea, 0x73, 0x5a, 0x58,
+	/* (2^169)P */ 0xb2, 0x0d, 0x8a, 0x92, 0x3e, 0xa0, 0x5c, 0x48, 0xe7, 0x57, 0x28, 0x74, 0xa5, 0x01, 0xfc, 0x10, 0xa7, 0x51, 0xd5, 0xd6, 0xdb, 0x2e, 0x48, 0x2f, 0x8a, 0xdb, 0x8f, 0x04, 0xb5, 0x33, 0x04, 0x0f,
+	/* (2^170)P */ 0x47, 0x62, 0xdc, 0xd7, 0x8d, 0x2e, 0xda, 0x60, 0x9a, 0x81, 0xd4, 0x8c, 0xd3, 0xc9, 0xb4, 0x88, 0x97, 0x66, 0xf6, 0x01, 0xc0, 0x3a, 0x03, 0x13, 0x75, 0x7d, 0x36, 0x3b, 0xfe, 0x24, 0x3b, 0x27,
+	/* (2^171)P */ 0xd4, 0xb9, 0xb3, 0x31, 0x6a, 0xf6, 0xe8, 0xc6, 0xd5, 0x49, 0xdf, 0x94, 0xa4, 0x14, 0x15, 0x28, 0xa7, 0x3d, 0xb2, 0xc8, 0xdf, 0x6f, 0x72, 0xd1, 0x48, 0xe5, 0xde, 0x03, 0xd1, 0xe7, 0x3a, 0x4b,
+	/* (2^172)P */ 0x7e, 0x9d, 0x4b, 0xce, 0x19, 0x6e, 0x25, 0xc6, 0x1c, 0xc6, 0xe3, 0x86, 0xf1, 0x5c, 0x5c, 0xff, 0x45, 0xc1, 0x8e, 0x4b, 0xa3, 0x3c, 0xc6, 0xac, 0x74, 0x65, 0xe6, 0xfe, 0x88, 0x18, 0x62, 0x74,
+	/* (2^173)P */ 0x1e, 0x0a, 0x29, 0x45, 0x96, 0x40, 0x6f, 0x95, 0x2e, 0x96, 0x3a, 0x26, 0xe3, 0xf8, 0x0b, 0xef, 0x7b, 0x64, 0xc2, 0x5e, 0xeb, 0x50, 0x6a, 0xed, 0x02, 0x75, 0xca, 0x9d, 0x3a, 0x28, 0x94, 0x06,
+	/* (2^174)P */ 0xd1, 0xdc, 0xa2, 0x43, 0x36, 0x96, 0x9b, 0x76, 0x53, 0x53, 0xfc, 0x09, 0xea, 0xc8, 0xb7, 0x42, 0xab, 0x7e, 0x39, 0x13, 0xee, 0x2a, 0x00, 0x4f, 0x3a, 0xd6, 0xb7, 0x19, 0x2c, 0x5e, 0x00, 0x63,
+	/* (2^175)P */ 0xea, 0x3b, 0x02, 0x63, 0xda, 0x36, 0x67, 0xca, 0xb7, 0x99, 0x2a, 0xb1, 0x6d, 0x7f, 0x6c, 0x96, 0xe1, 0xc5, 0x37, 0xc5, 0x90, 0x93, 0xe0, 0xac, 0xee, 0x89, 0xaa, 0xa1, 0x63, 0x60, 0x69, 0x0b,
+	/* (2^176)P */ 0xe5, 0x56, 0x8c, 0x28, 0x97, 0x3e, 0xb0, 0xeb, 0xe8, 0x8b, 0x8c, 0x93, 0x9f, 0x9f, 0x2a, 0x43, 0x71, 0x7f, 0x71, 0x5b, 0x3d, 0xa9, 0xa5, 0xa6, 0x97, 0x9d, 0x8f, 0xe1, 0xc3, 0xb4, 0x5f, 0x1a,
+	/* (2^177)P */ 0xce, 0xcd, 0x60, 0x1c, 0xad, 0xe7, 0x94, 0x1c, 0xa0, 0xc4, 0x02, 0xfc, 0x43, 0x2a, 0x20, 0xee, 0x20, 0x6a, 0xc4, 0x67, 0xd8, 0xe4, 0xaf, 0x8d, 0x58, 0x7b, 0xc2, 0x8a, 0x3c, 0x26, 0x10, 0x0a,
+	/* (2^178)P */ 0x4a, 0x2a, 0x43, 0xe4, 0xdf, 0xa9, 0xde, 0xd0, 0xc5, 0x77, 0x92, 0xbe, 0x7b, 0xf8, 0x6a, 0x85, 0x1a, 0xc7, 0x12, 0xc2, 0xac, 0x72, 0x84, 0xce, 0x91, 0x1e, 0xbb, 0x9b, 0x6d, 0x1b, 0x15, 0x6f,
+	/* (2^179)P */ 0x6a, 0xd5, 0xee, 0x7c, 0x52, 0x6c, 0x77, 0x26, 0xec, 0xfa, 0xf8, 0xfb, 0xb7, 0x1c, 0x21, 0x7d, 0xcc, 0x09, 0x46, 0xfd, 0xa6, 0x66, 0xae, 0x37, 0x42, 0x0c, 0x77, 0xd2, 0x02, 0xb7, 0x81, 0x1f,
+	/* (2^180)P */ 0x92, 0x83, 0xc5, 0xea, 0x57, 0xb0, 0xb0, 0x2f, 0x9d, 0x4e, 0x74, 0x29, 0xfe, 0x89, 0xdd, 0xe1, 0xf8, 0xb4, 0xbe, 0x17, 0xeb, 0xf8, 0x64, 0xc9, 0x1e, 0xd4, 0xa2, 0xc9, 0x73, 0x10, 0x57, 0x29,
+	/* (2^181)P */ 0x54, 0xe2, 0xc0, 0x81, 0x89, 0xa1, 0x48, 0xa9, 0x30, 0x28, 0xb2, 0x65, 0x9b, 0x36, 0xf6, 0x2d, 0xc6, 0xd3, 0xcf, 0x5f, 0xd7, 0xb2, 0x3e, 0xa3, 0x1f, 0xa0, 0x99, 0x41, 0xec, 0xd6, 0x8c, 0x07,
+	/* (2^182)P */ 0x2f, 0x0d, 0x90, 0xad, 0x41, 0x4a, 0x58, 0x4a, 0x52, 0x4c, 0xc7, 0xe2, 0x78, 0x2b, 0x14, 0x32, 0x78, 0xc9, 0x31, 0x84, 0x33, 0xe8, 0xc4, 0x68, 0xc2, 0x9f, 0x68, 0x08, 0x90, 0xea, 0x69, 0x7f,
+	/* (2^183)P */ 0x65, 0x82, 0xa3, 0x46, 0x1e, 0xc8, 0xf2, 0x52, 0xfd, 0x32, 0xa8, 0x04, 0x2d, 0x07, 0x78, 0xfd, 0x94, 0x9e, 0x35, 0x25, 0xfa, 0xd5, 0xd7, 0x8c, 0xd2, 0x29, 0xcc, 0x54, 0x74, 0x1b, 0xe7, 0x4d,
+	/* (2^184)P */ 0xc9, 0x6a, 0xda, 0x1e, 0xad, 0x60, 0xeb, 0x42, 0x3a, 0x9c, 0xc0, 0xdb, 0xdf, 0x37, 0xad, 0x0a, 0x91, 0xc1, 0x3c, 0xe3, 0x71, 0x4b, 0x00, 0x81, 0x3c, 0x80, 0x22, 0x51, 0x34, 0xbe, 0xe6, 0x44,
+	/* (2^185)P */ 0xdb, 0x20, 0x19, 0xba, 0x88, 0x83, 0xfe, 0x03, 0x08, 0xb0, 0x0d, 0x15, 0x32, 0x7c, 0xd5, 0xf5, 0x29, 0x0c, 0xf6, 0x1a, 0x28, 0xc4, 0xc8, 0x49, 0xee, 0x1a, 0x70, 0xde, 0x18, 0xb5, 0xed, 0x21,
+	/* (2^186)P */ 0x99, 0xdc, 0x06, 0x8f, 0x41, 0x3e, 0xb6, 0x7f, 0xb8, 0xd7, 0x66, 0xc1, 0x99, 0x0d, 0x46, 0xa4, 0x83, 0x0a, 0x52, 0xce, 0x48, 0x52, 0xdd, 0x24, 0x58, 0x83, 0x92, 0x2b, 0x71, 0xad, 0xc3, 0x5e,
+	/* (2^187)P */ 0x0f, 0x93, 0x17, 0xbd, 0x5f, 0x2a, 0x02, 0x15, 0xe3, 0x70, 0x25, 0xd8, 0x77, 0x4a, 0xf6, 0xa4, 0x12, 0x37, 0x78, 0x15, 0x69, 0x8d, 0xbc, 0x12, 0xbb, 0x0a, 0x62, 0xfc, 0xc0, 0x94, 0x81, 0x49,
+	/* (2^188)P */ 0x82, 0x6c, 0x68, 0x55, 0xd2, 0xd9, 0xa2, 0x38, 0xf0, 0x21, 0x3e, 0x19, 0xd9, 0x6b, 0x5c, 0x78, 0x84, 0x54, 0x4a, 0xb2, 0x1a, 0xc8, 0xd5, 0xe4, 0x89, 0x09, 0xe2, 0xb2, 0x60, 0x78, 0x30, 0x56,
+	/* (2^189)P */ 0xc4, 0x74, 0x4d, 0x8b, 0xf7, 0x55, 0x9d, 0x42, 0x31, 0x01, 0x35, 0x43, 0x46, 0x83, 0xf1, 0x22, 0xff, 0x1f, 0xc7, 0x98, 0x45, 0xc2, 0x60, 0x1e, 0xef, 0x83, 0x99, 0x97, 0x14, 0xf0, 0xf2, 0x59,
+	/* (2^190)P */ 0x44, 0x4a, 0x49, 0xeb, 0x56, 0x7d, 0xa4, 0x46, 0x8e, 0xa1, 0x36, 0xd6, 0x54, 0xa8, 0x22, 0x3e, 0x3b, 0x1c, 0x49, 0x74, 0x52, 0xe1, 0x46, 0xb3, 0xe7, 0xcd, 0x90, 0x53, 0x4e, 0xfd, 0xea, 0x2c,
+	/* (2^191)P */ 0x75, 0x66, 0x0d, 0xbe, 0x38, 0x85, 0x8a, 0xba, 0x23, 0x8e, 0x81, 0x50, 0xbb, 0x74, 0x90, 0x4b, 0xc3, 0x04, 0xd3, 0x85, 0x90, 0xb8, 0xda, 0xcb, 0xc4, 0x92, 0x61, 0xe5, 0xe0, 0x4f, 0xa2, 0x61,
+	/* (2^192)P */ 0xcb, 0x5b, 0x52, 0xdb, 0xe6, 0x15, 0x76, 0xcb, 0xca, 0xe4, 0x67, 0xa5, 0x35, 0x8c, 0x7d, 0xdd, 0x69, 0xdd, 0xfc, 0xca, 0x3a, 0x15, 0xb4, 0xe6, 0x66, 0x97, 0x3c, 0x7f, 0x09, 0x8e, 0x66, 0x2d,
+	/* (2^193)P */ 0xf0, 0x5e, 0xe5, 0x5c, 0x26, 0x7e, 0x7e, 0xa5, 0x67, 0xb9, 0xd4, 0x7c, 0x52, 0x4e, 0x9f, 0x5d, 0xe5, 0xd1, 0x2f, 0x49, 0x06, 0x36, 0xc8, 0xfb, 0xae, 0xf7, 0xc3, 0xb7, 0xbe, 0x52, 0x0d, 0x09,
+	/* (2^194)P */ 0x7c, 0x4d, 0x7b, 0x1e, 0x5a, 0x51, 0xb9, 0x09, 0xc0, 0x44, 0xda, 0x99, 0x25, 0x6a, 0x26, 0x1f, 0x04, 0x55, 0xc5, 0xe2, 0x48, 0x95, 0xc4, 0xa1, 0xcc, 0x15, 0x6f, 0x12, 0x87, 0x42, 0xf0, 0x7e,
+	/* (2^195)P */ 0x15, 0xef, 0x30, 0xbd, 0x9d, 0x65, 0xd1, 0xfe, 0x7b, 0x27, 0xe0, 0xc4, 0xee, 0xb9, 0x4a, 0x8b, 0x91, 0x32, 0xdf, 0xa5, 0x36, 0x62, 0x4d, 0x88, 0x88, 0xf7, 0x5c, 0xbf, 0xa6, 0x6e, 0xd9, 0x1f,
+	/* (2^196)P */ 0x9a, 0x0d, 0x19, 0x1f, 0x98, 0x61, 0xa1, 0x42, 0xc1, 0x52, 0x60, 0x7e, 0x50, 0x49, 0xd8, 0x61, 0xd5, 0x2c, 0x5a, 0x28, 0xbf, 0x13, 0xe1, 0x9f, 0xd8, 0x85, 0xad, 0xdb, 0x76, 0xd6, 0x22, 0x7c,
+	/* (2^197)P */ 0x7d, 0xd2, 0xfb, 0x2b, 0xed, 0x70, 0xe7, 0x82, 0xa5, 0xf5, 0x96, 0xe9, 0xec, 0xb2, 0x05, 0x4c, 0x50, 0x01, 0x90, 0xb0, 0xc2, 0xa9, 0x40, 0xcd, 0x64, 0xbf, 0xd9, 0x13, 0x92, 0x31, 0x95, 0x58,
+	/* (2^198)P */ 0x08, 0x2e, 0xea, 0x3f, 0x70, 0x5d, 0xcc, 0xe7, 0x8c, 0x18, 0xe2, 0x58, 0x12, 0x49, 0x0c, 0xb5, 0xf0, 0x5b, 0x20, 0x48, 0xaa, 0x0b, 0xe3, 0xcc, 0x62, 0x2d, 0xa3, 0xcf, 0x9c, 0x65, 0x7c, 0x53,
+	/* (2^199)P */ 0x88, 0xc0, 0xcf, 0x98, 0x3a, 0x62, 0xb6, 0x37, 0xa4, 0xac, 0xd6, 0xa4, 0x1f, 0xed, 0x9b, 0xfe, 0xb0, 0xd1, 0xa8, 0x56, 0x8e, 0x9b, 0xd2, 0x04, 0x75, 0x95, 0x51, 0x0b, 0xc4, 0x71, 0x5f, 0x72,
+	/* (2^200)P */ 0xe6, 0x9c, 0x33, 0xd0, 0x9c, 0xf8, 0xc7, 0x28, 0x8b, 0xc1, 0xdd, 0x69, 0x44, 0xb1, 0x67, 0x83, 0x2c, 0x65, 0xa1, 0xa6, 0x83, 0xda, 0x3a, 0x88, 0x17, 0x6c, 0x4d, 0x03, 0x74, 0x19, 0x5f, 0x58,
+	/* (2^201)P */ 0x88, 0x91, 0xb1, 0xf1, 0x66, 0xb2, 0xcf, 0x89, 0x17, 0x52, 0xc3, 0xe7, 0x63, 0x48, 0x3b, 0xe6, 0x6a, 0x52, 0xc0, 0xb4, 0xa6, 0x9d, 0x8c, 0xd8, 0x35, 0x46, 0x95, 0xf0, 0x9d, 0x5c, 0x03, 0x3e,
+	/* (2^202)P */ 0x9d, 0xde, 0x45, 0xfb, 0x12, 0x54, 0x9d, 0xdd, 0x0d, 0xf4, 0xcf, 0xe4, 0x32, 0x45, 0x68, 0xdd, 0x1c, 0x67, 0x1d, 0x15, 0x9b, 0x99, 0x5c, 0x4b, 0x90, 0xf6, 0xe7, 0x11, 0xc8, 0x2c, 0x8c, 0x2d,
+	/* (2^203)P */ 0x40, 0x5d, 0x05, 0x90, 0x1d, 0xbe, 0x54, 0x7f, 0x40, 0xaf, 0x4a, 0x46, 0xdf, 0xc5, 0x64, 0xa4, 0xbe, 0x17, 0xe9, 0xf0, 0x24, 0x96, 0x97, 0x33, 0x30, 0x6b, 0x35, 0x27, 0xc5, 0x8d, 0x01, 0x2c,
+	/* (2^204)P */ 0xd4, 0xb3, 0x30, 0xe3, 0x24, 0x50, 0x41, 0xa5, 0xd3, 0x52, 0x16, 0x69, 0x96, 0x3d, 0xff, 0x73, 0xf1, 0x59, 0x9b, 0xef, 0xc4, 0x42, 0xec, 0x94, 0x5a, 0x8e, 0xd0, 0x18, 0x16, 0x20, 0x47, 0x07,
+	/* (2^205)P */ 0x53, 0x1c, 0x41, 0xca, 0x8a, 0xa4, 0x6c, 0x4d, 0x19, 0x61, 0xa6, 0xcf, 0x2f, 0x5f, 0x41, 0x66, 0xff, 0x27, 0xe2, 0x51, 0x00, 0xd4, 0x4d, 0x9c, 0xeb, 0xf7, 0x02, 0x9a, 0xc0, 0x0b, 0x81, 0x59,
+	/* (2^206)P */ 0x1d, 0x10, 0xdc, 0xb3, 0x71, 0xb1, 0x7e, 0x2a, 0x8e, 0xf6, 0xfe, 0x9f, 0xb9, 0x5a, 0x1c, 0x44, 0xea, 0x59, 0xb3, 0x93, 0x9b, 0x5c, 0x02, 0x32, 0x2f, 0x11, 0x9d, 0x1e, 0xa7, 0xe0, 0x8c, 0x5e,
+	/* (2^207)P */ 0xfd, 0x03, 0x95, 0x42, 0x92, 0xcb, 0xcc, 0xbf, 0x55, 0x5d, 0x09, 0x2f, 0x75, 0xba, 0x71, 0xd2, 0x1e, 0x09, 0x2d, 0x97, 0x5e, 0xad, 0x5e, 0x34, 0xba, 0x03, 0x31, 0xa8, 0x11, 0xdf, 0xc8, 0x18,
+	/* (2^208)P */ 0x4c, 0x0f, 0xed, 0x9a, 0x9a, 0x94, 0xcd, 0x90, 0x7e, 0xe3, 0x60, 0x66, 0xcb, 0xf4, 0xd1, 0xc5, 0x0b, 0x2e, 0xc5, 0x56, 0x2d, 0xc5, 0xca, 0xb8, 0x0d, 0x8e, 0x80, 0xc5, 0x00, 0xe4, 0x42, 0x6e,
+	/* (2^209)P */ 0x23, 0xfd, 0xae, 0xee, 0x66, 0x69, 0xb4, 0xa3, 0xca, 0xcd, 0x9e, 0xe3, 0x0b, 0x1f, 0x4f, 0x0c, 0x1d, 0xa5, 0x83, 0xd6, 0xc9, 0xc8, 0x9d, 0x18, 0x1b, 0x35, 0x09, 0x4c, 0x05, 0x7f, 0xf2, 0x51,
+	/* (2^210)P */ 0x82, 0x06, 0x32, 0x2a, 0xcd, 0x7c, 0x48, 0x4c, 0x96, 0x1c, 0xdf, 0xb3, 0x5b, 0xa9, 0x7e, 0x58, 0xe8, 0xb8, 0x5c, 0x55, 0x9e, 0xf7, 0xcc, 0xc8, 0x3d, 0xd7, 0x06, 0xa2, 0x29, 0xc8, 0x7d, 0x54,
+	/* (2^211)P */ 0x06, 0x9b, 0xc3, 0x80, 0xcd, 0xa6, 0x22, 0xb8, 0xc6, 0xd4, 0x00, 0x20, 0x73, 0x54, 0x6d, 0xe9, 0x4d, 0x3b, 0x46, 0x91, 0x6f, 0x5b, 0x53, 0x28, 0x1d, 0x6e, 0x48, 0xe2, 0x60, 0x46, 0x8f, 0x22,
+	/* (2^212)P */ 0xbf, 0x3a, 0x8d, 0xde, 0x38, 0x95, 0x79, 0x98, 0x6e, 0xca, 0xeb, 0x45, 0x00, 0x33, 0xd8, 0x8c, 0x38, 0xe7, 0x21, 0x82, 0x00, 0x2a, 0x95, 0x79, 0xbb, 0xd2, 0x5c, 0x53, 0xa7, 0xe1, 0x22, 0x43,
+	/* (2^213)P */ 0x1c, 0x80, 0xd1, 0x19, 0x18, 0xc1, 0x14, 0xb1, 0xc7, 0x5e, 0x3f, 0x4f, 0xd8, 0xe4, 0x16, 0x20, 0x4c, 0x0f, 0x26, 0x09, 0xf4, 0x2d, 0x0e, 0xdd, 0x66, 0x72, 0x5f, 0xae, 0xc0, 0x62, 0xc3, 0x5e,
+	/* (2^214)P */ 0xee, 0xb4, 0xb2, 0xb8, 0x18, 0x2b, 0x46, 0xc0, 0xfb, 0x1a, 0x4d, 0x27, 0x50, 0xd9, 0xc8, 0x7c, 0xd2, 0x02, 0x6b, 0x43, 0x05, 0x71, 0x5f, 0xf2, 0xd3, 0xcc, 0xf9, 0xbf, 0xdc, 0xf8, 0xbb, 0x43,
+	/* (2^215)P */ 0xdf, 0xe9, 0x39, 0xa0, 0x67, 0x17, 0xad, 0xb6, 0x83, 0x35, 0x9d, 0xf6, 0xa8, 0x4d, 0x71, 0xb0, 0xf5, 0x31, 0x29, 0xb4, 0x18, 0xfa, 0x55, 0x5e, 0x61, 0x09, 0xc6, 0x33, 0x8f, 0x55, 0xd5, 0x4e,
+	/* (2^216)P */ 0xdd, 0xa5, 0x47, 0xc6, 0x01, 0x79, 0xe3, 0x1f, 0x57, 0xd3, 0x81, 0x80, 0x1f, 0xdf, 0x3d, 0x59, 0xa6, 0xd7, 0x3f, 0x81, 0xfd, 0xa4, 0x49, 0x02, 0x61, 0xaf, 0x9c, 0x4e, 0x27, 0xca, 0xac, 0x69,
+	/* (2^217)P */ 0xc9, 0x21, 0x07, 0x33, 0xea, 0xa3, 0x7b, 0x04, 0xa0, 0x1e, 0x7e, 0x0e, 0xc2, 0x3f, 0x42, 0x83, 0x60, 0x4a, 0x31, 0x01, 0xaf, 0xc0, 0xf4, 0x1d, 0x27, 0x95, 0x28, 0x89, 0xab, 0x2d, 0xa6, 0x09,
+	/* (2^218)P */ 0x00, 0xcb, 0xc6, 0x9c, 0xa4, 0x25, 0xb3, 0xa5, 0xb6, 0x6c, 0xb5, 0x54, 0xc6, 0x5d, 0x4b, 0xe9, 0xa0, 0x94, 0xc9, 0xad, 0x79, 0x87, 0xe2, 0x3b, 0xad, 0x4a, 0x3a, 0xba, 0xf8, 0xe8, 0x96, 0x42,
+	/* (2^219)P */ 0xab, 0x1e, 0x45, 0x1e, 0x76, 0x89, 0x86, 0x32, 0x4a, 0x59, 0x59, 0xff, 0x8b, 0x59, 0x4d, 0x2e, 0x4a, 0x08, 0xa7, 0xd7, 0x53, 0x68, 0xb9, 0x49, 0xa8, 0x20, 0x14, 0x60, 0x19, 0xa3, 0x80, 0x49,
+	/* (2^220)P */ 0x42, 0x2c, 0x55, 0x2f, 0xe1, 0xb9, 0x65, 0x95, 0x96, 0xfe, 0x00, 0x71, 0xdb, 0x18, 0x53, 0x8a, 0xd7, 0xd0, 0xad, 0x43, 0x4d, 0x0b, 0xc9, 0x05, 0xda, 0x4e, 0x5d, 0x6a, 0xd6, 0x4c, 0x8b, 0x53,
+	/* (2^221)P */ 0x9f, 0x03, 0x9f, 0xe8, 0xc3, 0x4f, 0xe9, 0xf4, 0x45, 0x80, 0x61, 0x6f, 0xf2, 0x9a, 0x2c, 0x59, 0x50, 0x95, 0x4b, 0xfd, 0xb5, 0x6e, 0xa3, 0x08, 0x19, 0x14, 0xed, 0xc2, 0xf6, 0xfa, 0xff, 0x25,
+	/* (2^222)P */ 0x54, 0xd3, 0x79, 0xcc, 0x59, 0x44, 0x43, 0x34, 0x6b, 0x47, 0xd5, 0xb1, 0xb4, 0xbf, 0xec, 0xee, 0x99, 0x5d, 0x61, 0x61, 0xa0, 0x34, 0xeb, 0xdd, 0x73, 0xb7, 0x64, 0xeb, 0xcc, 0xce, 0x29, 0x51,
+	/* (2^223)P */ 0x20, 0x35, 0x99, 0x94, 0x58, 0x21, 0x43, 0xee, 0x3b, 0x0b, 0x4c, 0xf1, 0x7c, 0x9c, 0x2f, 0x77, 0xd5, 0xda, 0xbe, 0x06, 0xe3, 0xfc, 0xe2, 0xd2, 0x97, 0x6a, 0xf0, 0x46, 0xb5, 0x42, 0x5f, 0x71,
+	/* (2^224)P */ 0x1a, 0x5f, 0x5b, 0xda, 0xce, 0xcd, 0x4e, 0x43, 0xa9, 0x41, 0x97, 0xa4, 0x15, 0x71, 0xa1, 0x0d, 0x2e, 0xad, 0xed, 0x73, 0x7c, 0xd7, 0x0b, 0x68, 0x41, 0x90, 0xdd, 0x4e, 0x35, 0x02, 0x7c, 0x48,
+	/* (2^225)P */ 0xc4, 0xd9, 0x0e, 0xa7, 0xf3, 0xef, 0xef, 0xb8, 0x02, 0xe3, 0x57, 0xe8, 0xa3, 0x2a, 0xa3, 0x56, 0xa0, 0xa5, 0xa2, 0x48, 0xbd, 0x68, 0x3a, 0xdf, 0x44, 0xc4, 0x76, 0x31, 0xb7, 0x50, 0xf6, 0x07,
+	/* (2^226)P */ 0xb1, 0xcc, 0xe0, 0x26, 0x16, 0x9b, 0x8b, 0xe3, 0x36, 0xfb, 0x09, 0x8b, 0xc1, 0x53, 0xe0, 0x79, 0x64, 0x49, 0xf9, 0xc9, 0x19, 0x03, 0xd9, 0x56, 0xc4, 0xf5, 0x9f, 0xac, 0xe7, 0x41, 0xa9, 0x1c,
+	/* (2^227)P */ 0xbb, 0xa0, 0x2f, 0x16, 0x29, 0xdf, 0xc4, 0x49, 0x05, 0x33, 0xb3, 0x82, 0x32, 0xcf, 0x88, 0x84, 0x7d, 0x43, 0xbb, 0xca, 0x14, 0xda, 0xdf, 0x95, 0x86, 0xad, 0xd5, 0x64, 0x82, 0xf7, 0x91, 0x33,
+	/* (2^228)P */ 0x5d, 0x09, 0xb5, 0xe2, 0x6a, 0xe0, 0x9a, 0x72, 0x46, 0xa9, 0x59, 0x32, 0xd7, 0x58, 0x8a, 0xd5, 0xed, 0x21, 0x39, 0xd1, 0x62, 0x42, 0x83, 0xe9, 0x92, 0xb5, 0x4b, 0xa5, 0xfa, 0xda, 0xfe, 0x27,
+	/* (2^229)P */ 0xbb, 0x48, 0xad, 0x29, 0xb8, 0xc5, 0x9d, 0xa9, 0x60, 0xe2, 0x9e, 0x49, 0x42, 0x57, 0x02, 0x5f, 0xfd, 0x13, 0x75, 0x5d, 0xcd, 0x8e, 0x2c, 0x80, 0x38, 0xd9, 0x6d, 0x3f, 0xef, 0xb3, 0xce, 0x78,
+	/* (2^230)P */ 0x94, 0x5d, 0x13, 0x8a, 0x4f, 0xf4, 0x42, 0xc3, 0xa3, 0xdd, 0x8c, 0x82, 0x44, 0xdb, 0x9e, 0x7b, 0xe7, 0xcf, 0x37, 0x05, 0x1a, 0xd1, 0x36, 0x94, 0xc8, 0xb4, 0x1a, 0xec, 0x64, 0xb1, 0x64, 0x50,
+	/* (2^231)P */ 0xfc, 0xb2, 0x7e, 0xd3, 0xcf, 0xec, 0x20, 0x70, 0xfc, 0x25, 0x0d, 0xd9, 0x3e, 0xea, 0x31, 0x1f, 0x34, 0xbb, 0xa1, 0xdf, 0x7b, 0x0d, 0x93, 0x1b, 0x44, 0x30, 0x11, 0x48, 0x7a, 0x46, 0x44, 0x53,
+	/* (2^232)P */ 0xfb, 0x6d, 0x5e, 0xf2, 0x70, 0x31, 0x07, 0x70, 0xc8, 0x4c, 0x11, 0x50, 0x1a, 0xdc, 0x85, 0xe3, 0x00, 0x4f, 0xfc, 0xc8, 0x8a, 0x69, 0x48, 0x23, 0xd8, 0x40, 0xdd, 0x84, 0x52, 0xa5, 0x77, 0x2a,
+	/* (2^233)P */ 0xe4, 0x6c, 0x8c, 0xc9, 0xe0, 0xaf, 0x06, 0xfe, 0xe4, 0xd6, 0xdf, 0xdd, 0x96, 0xdf, 0x35, 0xc2, 0xd3, 0x1e, 0xbf, 0x33, 0x1e, 0xd0, 0x28, 0x14, 0xaf, 0xbd, 0x00, 0x93, 0xec, 0x68, 0x57, 0x78,
+	/* (2^234)P */ 0x3b, 0xb6, 0xde, 0x91, 0x7a, 0xe5, 0x02, 0x97, 0x80, 0x8b, 0xce, 0xe5, 0xbf, 0xb8, 0xbd, 0x61, 0xac, 0x58, 0x1d, 0x3d, 0x6f, 0x42, 0x5b, 0x64, 0xbc, 0x57, 0xa5, 0x27, 0x22, 0xa8, 0x04, 0x48,
+	/* (2^235)P */ 0x01, 0x26, 0x4d, 0xb4, 0x8a, 0x04, 0x57, 0x8e, 0x35, 0x69, 0x3a, 0x4b, 0x1a, 0x50, 0xd6, 0x68, 0x93, 0xc2, 0xe1, 0xf9, 0xc3, 0x9e, 0x9c, 0xc3, 0xe2, 0x63, 0xde, 0xd4, 0x57, 0xf2, 0x72, 0x41,
+	/* (2^236)P */ 0x01, 0x64, 0x0c, 0x33, 0x50, 0xb4, 0x68, 0xd3, 0x91, 0x23, 0x8f, 0x41, 0x17, 0x30, 0x0d, 0x04, 0x0d, 0xd9, 0xb7, 0x90, 0x60, 0xbb, 0x34, 0x2c, 0x1f, 0xd5, 0xdf, 0x8f, 0x22, 0x49, 0xf6, 0x16,
+	/* (2^237)P */ 0xf5, 0x8e, 0x92, 0x2b, 0x8e, 0x81, 0xa6, 0xbe, 0x72, 0x1e, 0xc1, 0xcd, 0x91, 0xcf, 0x8c, 0xe2, 0xcd, 0x36, 0x7a, 0xe7, 0x68, 0xaa, 0x4a, 0x59, 0x0f, 0xfd, 0x7f, 0x6c, 0x80, 0x34, 0x30, 0x31,
+	/* (2^238)P */ 0x65, 0xbd, 0x49, 0x22, 0xac, 0x27, 0x9d, 0x8a, 0x12, 0x95, 0x8e, 0x01, 0x64, 0xb4, 0xa3, 0x19, 0xc7, 0x7e, 0xb3, 0x52, 0xf3, 0xcf, 0x6c, 0xc2, 0x21, 0x7b, 0x79, 0x1d, 0x34, 0x68, 0x6f, 0x05,
+	/* (2^239)P */ 0x27, 0x23, 0xfd, 0x7e, 0x75, 0xd6, 0x79, 0x5e, 0x15, 0xfe, 0x3a, 0x55, 0xb6, 0xbc, 0xbd, 0xfa, 0x60, 0x5a, 0xaf, 0x6e, 0x2c, 0x22, 0xe7, 0xd3, 0x3b, 0x74, 0xae, 0x4d, 0x6d, 0xc7, 0x46, 0x70,
+	/* (2^240)P */ 0x55, 0x4a, 0x8d, 0xb1, 0x72, 0xe8, 0x0b, 0x66, 0x96, 0x14, 0x4e, 0x57, 0x18, 0x25, 0x99, 0x19, 0xbb, 0xdc, 0x2b, 0x30, 0x3a, 0x05, 0x03, 0xc1, 0x8e, 0x8e, 0x21, 0x0b, 0x80, 0xe9, 0xd8, 0x3e,
+	/* (2^241)P */ 0x3e, 0xe0, 0x75, 0xfa, 0x39, 0x92, 0x0b, 0x7b, 0x83, 0xc0, 0x33, 0x46, 0x68, 0xfb, 0xe9, 0xef, 0x93, 0x77, 0x1a, 0x39, 0xbe, 0x5f, 0xa3, 0x98, 0x34, 0xfe, 0xd0, 0xe2, 0x0f, 0x51, 0x65, 0x60,
+	/* (2^242)P */ 0x0c, 0xad, 0xab, 0x48, 0x85, 0x66, 0xcb, 0x55, 0x27, 0xe5, 0x87, 0xda, 0x48, 0x45, 0x58, 0xb4, 0xdd, 0xc1, 0x07, 0x01, 0xea, 0xec, 0x43, 0x2c, 0x35, 0xde, 0x72, 0x93, 0x80, 0x28, 0x60, 0x52,
+	/* (2^243)P */ 0x1f, 0x3b, 0x21, 0xf9, 0x6a, 0xc5, 0x15, 0x34, 0xdb, 0x98, 0x7e, 0x01, 0x4d, 0x1a, 0xee, 0x5b, 0x9b, 0x70, 0xcf, 0xb5, 0x05, 0xb1, 0xf6, 0x13, 0xb6, 0x9a, 0xb2, 0x82, 0x34, 0x0e, 0xf2, 0x5f,
+	/* (2^244)P */ 0x90, 0x6c, 0x2e, 0xcc, 0x75, 0x9c, 0xa2, 0x0a, 0x06, 0xe2, 0x70, 0x3a, 0xca, 0x73, 0x7d, 0xfc, 0x15, 0xc5, 0xb5, 0xc4, 0x8f, 0xc3, 0x9f, 0x89, 0x07, 0xc2, 0xff, 0x24, 0xb1, 0x86, 0x03, 0x25,
+	/* (2^245)P */ 0x56, 0x2b, 0x3d, 0xae, 0xd5, 0x28, 0xea, 0x54, 0xce, 0x60, 0xde, 0xd6, 0x9d, 0x14, 0x13, 0x99, 0xc1, 0xd6, 0x06, 0x8f, 0xc5, 0x4f, 0x69, 0x16, 0xc7, 0x8f, 0x01, 0xeb, 0x75, 0x39, 0xb2, 0x46,
+	/* (2^246)P */ 0xe2, 0xb4, 0xb7, 0xb4, 0x0f, 0x6a, 0x0a, 0x47, 0xde, 0x53, 0x72, 0x8f, 0x5a, 0x47, 0x92, 0x5d, 0xdb, 0x3a, 0xbd, 0x2f, 0xb5, 0xe5, 0xee, 0xab, 0x68, 0x69, 0x80, 0xa0, 0x01, 0x08, 0xa2, 0x7f,
+	/* (2^247)P */ 0xd2, 0x14, 0x77, 0x9f, 0xf1, 0xfa, 0xf3, 0x76, 0xc3, 0x60, 0x46, 0x2f, 0xc1, 0x40, 0xe8, 0xb3, 0x4e, 0x74, 0x12, 0xf2, 0x8d, 0xcd, 0xb4, 0x0f, 0xd2, 0x2d, 0x3a, 0x1d, 0x25, 0x5a, 0x06, 0x4b,
+	/* (2^248)P */ 0x4a, 0xcd, 0x77, 0x3d, 0x38, 0xde, 0xeb, 0x5c, 0xb1, 0x9c, 0x2c, 0x88, 0xdf, 0x39, 0xdf, 0x6a, 0x59, 0xf7, 0x9a, 0xb0, 0x2e, 0x24, 0xdd, 0xa2, 0x22, 0x64, 0x5f, 0x0e, 0xe5, 0xc0, 0x47, 0x31,
+	/* (2^249)P */ 0xdb, 0x50, 0x13, 0x1d, 0x10, 0xa5, 0x4c, 0x16, 0x62, 0xc9, 0x3f, 0xc3, 0x79, 0x34, 0xd1, 0xf8, 0x08, 0xda, 0xe5, 0x13, 0x4d, 0xce, 0x40, 0xe6, 0xba, 0xf8, 0x61, 0x50, 0xc4, 0xe0, 0xde, 0x4b,
+	/* (2^250)P */ 0xc9, 0xb1, 0xed, 0xa4, 0xc1, 0x6d, 0xc4, 0xd7, 0x8a, 0xd9, 0x7f, 0x43, 0xb6, 0xd7, 0x14, 0x55, 0x0b, 0xc0, 0xa1, 0xb2, 0x6b, 0x2f, 0x94, 0x58, 0x0e, 0x71, 0x70, 0x1d, 0xab, 0xb2, 0xff, 0x2d,
+	/* (2^251)P */ 0x68, 0x6d, 0x8b, 0xc1, 0x2f, 0xcf, 0xdf, 0xcc, 0x67, 0x61, 0x80, 0xb7, 0xa8, 0xcb, 0xeb, 0xa8, 0xe3, 0x37, 0x29, 0x5e, 0xf9, 0x97, 0x06, 0x98, 0x8c, 0x6e, 0x12, 0xd0, 0x1c, 0xba, 0xfb, 0x02,
+	/* (2^252)P */ 0x65, 0x45, 0xff, 0xad, 0x60, 0xc3, 0x98, 0xcb, 0x19, 0x15, 0xdb, 0x4b, 0xd2, 0x01, 0x71, 0x44, 0xd5, 0x15, 0xfb, 0x75, 0x74, 0xc8, 0xc4, 0x98, 0x7d, 0xa2, 0x22, 0x6e, 0x6d, 0xc7, 0xf8, 0x05,
+	/* (2^253)P */ 0x94, 0xf4, 0xb9, 0xfe, 0xdf, 0xe5, 0x69, 0xab, 0x75, 0x6b, 0x40, 0x18, 0x9d, 0xc7, 0x09, 0xae, 0x1d, 0x2d, 0xa4, 0x94, 0xfb, 0x45, 0x9b, 0x19, 0x84, 0xfa, 0x2a, 0xae, 0xeb, 0x0a, 0x71, 0x79,
+	/* (2^254)P */ 0xdf, 0xd2, 0x34, 0xf3, 0xa7, 0xed, 0xad, 0xa6, 0xb4, 0x57, 0x2a, 0xaf, 0x51, 0x9c, 0xde, 0x7b, 0xa8, 0xea, 0xdc, 0x86, 0x4f, 0xc6, 0x8f, 0xa9, 0x7b, 0xd0, 0x0e, 0xc2, 0x35, 0x03, 0xbe, 0x6b,
+	/* (2^255)P */ 0x44, 0x43, 0x98, 0x53, 0xbe, 0xdc, 0x7f, 0x66, 0xa8, 0x49, 0x59, 0x00, 0x1c, 0xbc, 0x72, 0x07, 0x8e, 0xd6, 0xbe, 0x4e, 0x9f, 0xa4, 0x07, 0xba, 0xbf, 0x30, 0xdf, 0xba, 0x85, 0xb0, 0xa7, 0x1f,
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/curve.go b/vendor/github.com/cloudflare/circl/dh/x448/curve.go
new file mode 100644
index 00000000..d59564e4
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve.go
@@ -0,0 +1,104 @@
+package x448
+
+import (
+	fp "github.com/cloudflare/circl/math/fp448"
+)
+
+// ladderJoye calculates a fixed-point multiplication with the generator point.
+// The algorithm is the right-to-left Joye's ladder as described
+// in "How to precompute a ladder" in SAC'2017.
+func ladderJoye(k *Key) {
+	w := [5]fp.Elt{} // [mu,x1,z1,x2,z2] order must be preserved.
+	w[1] = fp.Elt{   // x1 = S
+		0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	}
+	fp.SetOne(&w[2]) // z1 = 1
+	w[3] = fp.Elt{   // x2 = G-S
+		0x20, 0x27, 0x9d, 0xc9, 0x7d, 0x19, 0xb1, 0xac,
+		0xf8, 0xba, 0x69, 0x1c, 0xff, 0x33, 0xac, 0x23,
+		0x51, 0x1b, 0xce, 0x3a, 0x64, 0x65, 0xbd, 0xf1,
+		0x23, 0xf8, 0xc1, 0x84, 0x9d, 0x45, 0x54, 0x29,
+		0x67, 0xb9, 0x81, 0x1c, 0x03, 0xd1, 0xcd, 0xda,
+		0x7b, 0xeb, 0xff, 0x1a, 0x88, 0x03, 0xcf, 0x3a,
+		0x42, 0x44, 0x32, 0x01, 0x25, 0xb7, 0xfa, 0xf0,
+	}
+	fp.SetOne(&w[4]) // z2 = 1
+
+	const n = 448
+	const h = 2
+	swap := uint(1)
+	for s := 0; s < n-h; s++ {
+		i := (s + h) / 8
+		j := (s + h) % 8
+		bit := uint((k[i] >> uint(j)) & 1)
+		copy(w[0][:], tableGenerator[s*Size:(s+1)*Size])
+		diffAdd(&w, swap^bit)
+		swap = bit
+	}
+	for s := 0; s < h; s++ {
+		double(&w[1], &w[2])
+	}
+	toAffine((*[fp.Size]byte)(k), &w[1], &w[2])
+}
+
+// ladderMontgomery calculates a generic scalar point multiplication
+// The algorithm implemented is the left-to-right Montgomery's ladder.
+func ladderMontgomery(k, xP *Key) {
+	w := [5]fp.Elt{}      // [x1, x2, z2, x3, z3] order must be preserved.
+	w[0] = *(*fp.Elt)(xP) // x1 = xP
+	fp.SetOne(&w[1])      // x2 = 1
+	w[3] = *(*fp.Elt)(xP) // x3 = xP
+	fp.SetOne(&w[4])      // z3 = 1
+
+	move := uint(0)
+	for s := 448 - 1; s >= 0; s-- {
+		i := s / 8
+		j := s % 8
+		bit := uint((k[i] >> uint(j)) & 1)
+		ladderStep(&w, move^bit)
+		move = bit
+	}
+	toAffine((*[fp.Size]byte)(k), &w[1], &w[2])
+}
+
+func toAffine(k *[fp.Size]byte, x, z *fp.Elt) {
+	fp.Inv(z, z)
+	fp.Mul(x, x, z)
+	_ = fp.ToBytes(k[:], x)
+}
+
+var lowOrderPoints = [3]fp.Elt{
+	{ /* (0,_,1) point of order 2 on Curve448 */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	},
+	{ /* (1,_,1) a point of order 4 on the twist of Curve448 */
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	},
+	{ /* (-1,_,1) point of order 4 on Curve448 */
+		0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	},
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.go b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.go
new file mode 100644
index 00000000..a0622666
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.go
@@ -0,0 +1,30 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+package x448
+
+import (
+	fp "github.com/cloudflare/circl/math/fp448"
+	"golang.org/x/sys/cpu"
+)
+
+var hasBmi2Adx = cpu.X86.HasBMI2 && cpu.X86.HasADX
+
+var _ = hasBmi2Adx
+
+func double(x, z *fp.Elt)             { doubleAmd64(x, z) }
+func diffAdd(w *[5]fp.Elt, b uint)    { diffAddAmd64(w, b) }
+func ladderStep(w *[5]fp.Elt, b uint) { ladderStepAmd64(w, b) }
+func mulA24(z, x *fp.Elt)             { mulA24Amd64(z, x) }
+
+//go:noescape
+func doubleAmd64(x, z *fp.Elt)
+
+//go:noescape
+func diffAddAmd64(w *[5]fp.Elt, b uint)
+
+//go:noescape
+func ladderStepAmd64(w *[5]fp.Elt, b uint)
+
+//go:noescape
+func mulA24Amd64(z, x *fp.Elt)
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.h b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.h
new file mode 100644
index 00000000..8c1ae4d0
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.h
@@ -0,0 +1,111 @@
+#define ladderStepLeg          \
+    addSub(x2,z2)              \
+    addSub(x3,z3)              \
+    integerMulLeg(b0,x2,z3)    \
+    integerMulLeg(b1,x3,z2)    \
+    reduceFromDoubleLeg(t0,b0) \
+    reduceFromDoubleLeg(t1,b1) \
+    addSub(t0,t1)              \
+    cselect(x2,x3,regMove)     \
+    cselect(z2,z3,regMove)     \
+    integerSqrLeg(b0,t0)       \
+    integerSqrLeg(b1,t1)       \
+    reduceFromDoubleLeg(x3,b0) \
+    reduceFromDoubleLeg(z3,b1) \
+    integerMulLeg(b0,x1,z3)    \
+    reduceFromDoubleLeg(z3,b0) \
+    integerSqrLeg(b0,x2)       \
+    integerSqrLeg(b1,z2)       \
+    reduceFromDoubleLeg(x2,b0) \
+    reduceFromDoubleLeg(z2,b1) \
+    subtraction(t0,x2,z2)      \
+    multiplyA24Leg(t1,t0)      \
+    additionLeg(t1,t1,z2)      \
+    integerMulLeg(b0,x2,z2)    \
+    integerMulLeg(b1,t0,t1)    \
+    reduceFromDoubleLeg(x2,b0) \
+    reduceFromDoubleLeg(z2,b1)
+
+#define ladderStepBmi2Adx      \
+    addSub(x2,z2)              \
+    addSub(x3,z3)              \
+    integerMulAdx(b0,x2,z3)    \
+    integerMulAdx(b1,x3,z2)    \
+    reduceFromDoubleAdx(t0,b0) \
+    reduceFromDoubleAdx(t1,b1) \
+    addSub(t0,t1)              \
+    cselect(x2,x3,regMove)     \
+    cselect(z2,z3,regMove)     \
+    integerSqrAdx(b0,t0)       \
+    integerSqrAdx(b1,t1)       \
+    reduceFromDoubleAdx(x3,b0) \
+    reduceFromDoubleAdx(z3,b1) \
+    integerMulAdx(b0,x1,z3)    \
+    reduceFromDoubleAdx(z3,b0) \
+    integerSqrAdx(b0,x2)       \
+    integerSqrAdx(b1,z2)       \
+    reduceFromDoubleAdx(x2,b0) \
+    reduceFromDoubleAdx(z2,b1) \
+    subtraction(t0,x2,z2)      \
+    multiplyA24Adx(t1,t0)      \
+    additionAdx(t1,t1,z2)      \
+    integerMulAdx(b0,x2,z2)    \
+    integerMulAdx(b1,t0,t1)    \
+    reduceFromDoubleAdx(x2,b0) \
+    reduceFromDoubleAdx(z2,b1)
+
+#define difAddLeg              \
+    addSub(x1,z1)              \
+    integerMulLeg(b0,z1,ui)    \
+    reduceFromDoubleLeg(z1,b0) \
+    addSub(x1,z1)              \
+    integerSqrLeg(b0,x1)       \
+    integerSqrLeg(b1,z1)       \
+    reduceFromDoubleLeg(x1,b0) \
+    reduceFromDoubleLeg(z1,b1) \
+    integerMulLeg(b0,x1,z2)    \
+    integerMulLeg(b1,z1,x2)    \
+    reduceFromDoubleLeg(x1,b0) \
+    reduceFromDoubleLeg(z1,b1)
+
+#define difAddBmi2Adx          \
+    addSub(x1,z1)              \
+    integerMulAdx(b0,z1,ui)    \
+    reduceFromDoubleAdx(z1,b0) \
+    addSub(x1,z1)              \
+    integerSqrAdx(b0,x1)       \
+    integerSqrAdx(b1,z1)       \
+    reduceFromDoubleAdx(x1,b0) \
+    reduceFromDoubleAdx(z1,b1) \
+    integerMulAdx(b0,x1,z2)    \
+    integerMulAdx(b1,z1,x2)    \
+    reduceFromDoubleAdx(x1,b0) \
+    reduceFromDoubleAdx(z1,b1)
+
+#define doubleLeg              \
+    addSub(x1,z1)              \
+    integerSqrLeg(b0,x1)       \
+    integerSqrLeg(b1,z1)       \
+    reduceFromDoubleLeg(x1,b0) \
+    reduceFromDoubleLeg(z1,b1) \
+    subtraction(t0,x1,z1)      \
+    multiplyA24Leg(t1,t0)      \
+    additionLeg(t1,t1,z1)      \
+    integerMulLeg(b0,x1,z1)    \
+    integerMulLeg(b1,t0,t1)    \
+    reduceFromDoubleLeg(x1,b0) \
+    reduceFromDoubleLeg(z1,b1)
+
+#define doubleBmi2Adx          \
+    addSub(x1,z1)              \
+    integerSqrAdx(b0,x1)       \
+    integerSqrAdx(b1,z1)       \
+    reduceFromDoubleAdx(x1,b0) \
+    reduceFromDoubleAdx(z1,b1) \
+    subtraction(t0,x1,z1)      \
+    multiplyA24Adx(t1,t0)      \
+    additionAdx(t1,t1,z1)      \
+    integerMulAdx(b0,x1,z1)    \
+    integerMulAdx(b1,t0,t1)    \
+    reduceFromDoubleAdx(x1,b0) \
+    reduceFromDoubleAdx(z1,b1)
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s
new file mode 100644
index 00000000..ed33ba3d
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve_amd64.s
@@ -0,0 +1,194 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+#include "textflag.h"
+
+// Depends on circl/math/fp448 package
+#include "../../math/fp448/fp_amd64.h"
+#include "curve_amd64.h"
+
+// CTE_A24 is (A+2)/4 from Curve448
+#define CTE_A24 39082
+
+#define Size 56
+
+// multiplyA24Leg multiplies x times CTE_A24 and stores in z
+// Uses: AX, DX, R8-R15, FLAGS
+// Instr: x86_64, cmov, adx
+#define multiplyA24Leg(z,x) \
+    MOVQ $CTE_A24, R15; \
+    MOVQ  0+x, AX; MULQ R15; MOVQ AX,  R8; ;;;;;;;;;;;;  MOVQ DX,  R9; \
+    MOVQ  8+x, AX; MULQ R15; ADDQ AX,  R9; ADCQ $0, DX;  MOVQ DX, R10; \
+    MOVQ 16+x, AX; MULQ R15; ADDQ AX, R10; ADCQ $0, DX;  MOVQ DX, R11; \
+    MOVQ 24+x, AX; MULQ R15; ADDQ AX, R11; ADCQ $0, DX;  MOVQ DX, R12; \
+    MOVQ 32+x, AX; MULQ R15; ADDQ AX, R12; ADCQ $0, DX;  MOVQ DX, R13; \
+    MOVQ 40+x, AX; MULQ R15; ADDQ AX, R13; ADCQ $0, DX;  MOVQ DX, R14; \
+    MOVQ 48+x, AX; MULQ R15; ADDQ AX, R14; ADCQ $0, DX; \
+    MOVQ DX,  AX; \
+    SHLQ $32, AX; \
+    ADDQ DX,  R8; MOVQ $0, DX; \
+    ADCQ $0,  R9; \
+    ADCQ $0, R10; \
+    ADCQ AX, R11; \
+    ADCQ $0, R12; \
+    ADCQ $0, R13; \
+    ADCQ $0, R14; \
+    ADCQ $0,  DX; \
+    MOVQ DX,  AX; \
+    SHLQ $32, AX; \
+    ADDQ DX,  R8; \
+    ADCQ $0,  R9; \
+    ADCQ $0, R10; \
+    ADCQ AX, R11; \
+    ADCQ $0, R12; \
+    ADCQ $0, R13; \
+    ADCQ $0, R14; \
+    MOVQ  R8,  0+z; \
+    MOVQ  R9,  8+z; \
+    MOVQ R10, 16+z; \
+    MOVQ R11, 24+z; \
+    MOVQ R12, 32+z; \
+    MOVQ R13, 40+z; \
+    MOVQ R14, 48+z;
+
+// multiplyA24Adx multiplies x times CTE_A24 and stores in z
+// Uses: AX, DX, R8-R14, FLAGS
+// Instr: x86_64, bmi2
+#define multiplyA24Adx(z,x) \
+    MOVQ $CTE_A24, DX; \
+    MULXQ  0+x, R8,  R9; \
+    MULXQ  8+x, AX, R10;  ADDQ AX,  R9; \
+    MULXQ 16+x, AX, R11;  ADCQ AX, R10; \
+    MULXQ 24+x, AX, R12;  ADCQ AX, R11; \
+    MULXQ 32+x, AX, R13;  ADCQ AX, R12; \
+    MULXQ 40+x, AX, R14;  ADCQ AX, R13; \
+    MULXQ 48+x, AX,  DX;  ADCQ AX, R14; \
+    ;;;;;;;;;;;;;;;;;;;;  ADCQ $0,  DX; \
+    MOVQ DX,  AX; \
+    SHLQ $32, AX; \
+    ADDQ DX,  R8; MOVQ $0, DX; \
+    ADCQ $0,  R9; \
+    ADCQ $0, R10; \
+    ADCQ AX, R11; \
+    ADCQ $0, R12; \
+    ADCQ $0, R13; \
+    ADCQ $0, R14; \
+    ADCQ $0,  DX; \
+    MOVQ DX,  AX; \
+    SHLQ $32, AX; \
+    ADDQ DX,  R8; \
+    ADCQ $0,  R9; \
+    ADCQ $0, R10; \
+    ADCQ AX, R11; \
+    ADCQ $0, R12; \
+    ADCQ $0, R13; \
+    ADCQ $0, R14; \
+    MOVQ  R8,  0+z; \
+    MOVQ  R9,  8+z; \
+    MOVQ R10, 16+z; \
+    MOVQ R11, 24+z; \
+    MOVQ R12, 32+z; \
+    MOVQ R13, 40+z; \
+    MOVQ R14, 48+z;
+
+#define mulA24Legacy \
+    multiplyA24Leg(0(DI),0(SI))
+#define mulA24Bmi2Adx \
+    multiplyA24Adx(0(DI),0(SI))
+
+// func mulA24Amd64(z, x *fp448.Elt)
+TEXT ·mulA24Amd64(SB),NOSPLIT,$0-16
+    MOVQ z+0(FP), DI
+    MOVQ x+8(FP), SI
+    CHECK_BMI2ADX(LMA24, mulA24Legacy, mulA24Bmi2Adx)
+
+// func ladderStepAmd64(w *[5]fp448.Elt, b uint)
+// ladderStepAmd64 calculates a point addition and doubling as follows:
+// (x2,z2) = 2*(x2,z2) and (x3,z3) = (x2,z2)+(x3,z3) using as a difference (x1,-).
+//    w    = {x1,x2,z2,x3,z4} are five fp255.Elt of 56 bytes.
+//  stack  = (t0,t1) are two fp.Elt of fp.Size bytes, and
+//           (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
+TEXT ·ladderStepAmd64(SB),NOSPLIT,$336-16
+    // Parameters
+    #define regWork DI
+    #define regMove SI
+    #define x1 0*Size(regWork)
+    #define x2 1*Size(regWork)
+    #define z2 2*Size(regWork)
+    #define x3 3*Size(regWork)
+    #define z3 4*Size(regWork)
+    // Local variables
+    #define t0 0*Size(SP)
+    #define t1 1*Size(SP)
+    #define b0 2*Size(SP)
+    #define b1 4*Size(SP)
+    MOVQ w+0(FP), regWork
+    MOVQ b+8(FP), regMove
+    CHECK_BMI2ADX(LLADSTEP, ladderStepLeg, ladderStepBmi2Adx)
+    #undef regWork
+    #undef regMove
+    #undef x1
+    #undef x2
+    #undef z2
+    #undef x3
+    #undef z3
+    #undef t0
+    #undef t1
+    #undef b0
+    #undef b1
+
+// func diffAddAmd64(work *[5]fp.Elt, swap uint)
+// diffAddAmd64 calculates a differential point addition using a precomputed point.
+// (x1,z1) = (x1,z1)+(mu) using a difference point (x2,z2)
+//    work = {mu,x1,z1,x2,z2} are five fp448.Elt of 56 bytes, and
+//   stack = (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
+// This is Equation 7 at https://eprint.iacr.org/2017/264.
+TEXT ·diffAddAmd64(SB),NOSPLIT,$224-16
+    // Parameters
+    #define regWork DI
+    #define regSwap SI
+    #define ui 0*Size(regWork)
+    #define x1 1*Size(regWork)
+    #define z1 2*Size(regWork)
+    #define x2 3*Size(regWork)
+    #define z2 4*Size(regWork)
+    // Local variables
+    #define b0 0*Size(SP)
+    #define b1 2*Size(SP)
+    MOVQ w+0(FP), regWork
+    MOVQ b+8(FP), regSwap
+    cswap(x1,x2,regSwap)
+    cswap(z1,z2,regSwap)
+    CHECK_BMI2ADX(LDIFADD, difAddLeg, difAddBmi2Adx)
+    #undef regWork
+    #undef regSwap
+    #undef ui
+    #undef x1
+    #undef z1
+    #undef x2
+    #undef z2
+    #undef b0
+    #undef b1
+
+// func doubleAmd64(x, z *fp448.Elt)
+// doubleAmd64 calculates a point doubling (x1,z1) = 2*(x1,z1).
+//  stack = (t0,t1) are two fp.Elt of fp.Size bytes, and
+//          (b0,b1) are two-double precision fp.Elt of 2*fp.Size bytes.
+TEXT ·doubleAmd64(SB),NOSPLIT,$336-16
+    // Parameters
+    #define x1 0(DI)
+    #define z1 0(SI)
+    // Local variables
+    #define t0 0*Size(SP)
+    #define t1 1*Size(SP)
+    #define b0 2*Size(SP)
+    #define b1 4*Size(SP)
+    MOVQ x+0(FP), DI
+    MOVQ z+8(FP), SI
+    CHECK_BMI2ADX(LDOUB,doubleLeg,doubleBmi2Adx)
+    #undef x1
+    #undef z1
+    #undef t0
+    #undef t1
+    #undef b0
+    #undef b1
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/curve_generic.go b/vendor/github.com/cloudflare/circl/dh/x448/curve_generic.go
new file mode 100644
index 00000000..b0b65ccf
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve_generic.go
@@ -0,0 +1,100 @@
+package x448
+
+import (
+	"encoding/binary"
+	"math/bits"
+
+	"github.com/cloudflare/circl/math/fp448"
+)
+
+func doubleGeneric(x, z *fp448.Elt) {
+	t0, t1 := &fp448.Elt{}, &fp448.Elt{}
+	fp448.AddSub(x, z)
+	fp448.Sqr(x, x)
+	fp448.Sqr(z, z)
+	fp448.Sub(t0, x, z)
+	mulA24Generic(t1, t0)
+	fp448.Add(t1, t1, z)
+	fp448.Mul(x, x, z)
+	fp448.Mul(z, t0, t1)
+}
+
+func diffAddGeneric(w *[5]fp448.Elt, b uint) {
+	mu, x1, z1, x2, z2 := &w[0], &w[1], &w[2], &w[3], &w[4]
+	fp448.Cswap(x1, x2, b)
+	fp448.Cswap(z1, z2, b)
+	fp448.AddSub(x1, z1)
+	fp448.Mul(z1, z1, mu)
+	fp448.AddSub(x1, z1)
+	fp448.Sqr(x1, x1)
+	fp448.Sqr(z1, z1)
+	fp448.Mul(x1, x1, z2)
+	fp448.Mul(z1, z1, x2)
+}
+
+func ladderStepGeneric(w *[5]fp448.Elt, b uint) {
+	x1, x2, z2, x3, z3 := &w[0], &w[1], &w[2], &w[3], &w[4]
+	t0 := &fp448.Elt{}
+	t1 := &fp448.Elt{}
+	fp448.AddSub(x2, z2)
+	fp448.AddSub(x3, z3)
+	fp448.Mul(t0, x2, z3)
+	fp448.Mul(t1, x3, z2)
+	fp448.AddSub(t0, t1)
+	fp448.Cmov(x2, x3, b)
+	fp448.Cmov(z2, z3, b)
+	fp448.Sqr(x3, t0)
+	fp448.Sqr(z3, t1)
+	fp448.Mul(z3, x1, z3)
+	fp448.Sqr(x2, x2)
+	fp448.Sqr(z2, z2)
+	fp448.Sub(t0, x2, z2)
+	mulA24Generic(t1, t0)
+	fp448.Add(t1, t1, z2)
+	fp448.Mul(x2, x2, z2)
+	fp448.Mul(z2, t0, t1)
+}
+
+func mulA24Generic(z, x *fp448.Elt) {
+	const A24 = 39082
+	const n = 8
+	var xx [7]uint64
+	for i := range xx {
+		xx[i] = binary.LittleEndian.Uint64(x[i*n : (i+1)*n])
+	}
+	h0, l0 := bits.Mul64(xx[0], A24)
+	h1, l1 := bits.Mul64(xx[1], A24)
+	h2, l2 := bits.Mul64(xx[2], A24)
+	h3, l3 := bits.Mul64(xx[3], A24)
+	h4, l4 := bits.Mul64(xx[4], A24)
+	h5, l5 := bits.Mul64(xx[5], A24)
+	h6, l6 := bits.Mul64(xx[6], A24)
+
+	l1, c0 := bits.Add64(h0, l1, 0)
+	l2, c1 := bits.Add64(h1, l2, c0)
+	l3, c2 := bits.Add64(h2, l3, c1)
+	l4, c3 := bits.Add64(h3, l4, c2)
+	l5, c4 := bits.Add64(h4, l5, c3)
+	l6, c5 := bits.Add64(h5, l6, c4)
+	l7, _ := bits.Add64(h6, 0, c5)
+
+	l0, c0 = bits.Add64(l0, l7, 0)
+	l1, c1 = bits.Add64(l1, 0, c0)
+	l2, c2 = bits.Add64(l2, 0, c1)
+	l3, c3 = bits.Add64(l3, l7<<32, c2)
+	l4, c4 = bits.Add64(l4, 0, c3)
+	l5, c5 = bits.Add64(l5, 0, c4)
+	l6, l7 = bits.Add64(l6, 0, c5)
+
+	xx[0], c0 = bits.Add64(l0, l7, 0)
+	xx[1], c1 = bits.Add64(l1, 0, c0)
+	xx[2], c2 = bits.Add64(l2, 0, c1)
+	xx[3], c3 = bits.Add64(l3, l7<<32, c2)
+	xx[4], c4 = bits.Add64(l4, 0, c3)
+	xx[5], c5 = bits.Add64(l5, 0, c4)
+	xx[6], _ = bits.Add64(l6, 0, c5)
+
+	for i := range xx {
+		binary.LittleEndian.PutUint64(z[i*n:(i+1)*n], xx[i])
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/curve_noasm.go b/vendor/github.com/cloudflare/circl/dh/x448/curve_noasm.go
new file mode 100644
index 00000000..3755b7c8
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/curve_noasm.go
@@ -0,0 +1,11 @@
+//go:build !amd64 || purego
+// +build !amd64 purego
+
+package x448
+
+import fp "github.com/cloudflare/circl/math/fp448"
+
+func double(x, z *fp.Elt)             { doubleGeneric(x, z) }
+func diffAdd(w *[5]fp.Elt, b uint)    { diffAddGeneric(w, b) }
+func ladderStep(w *[5]fp.Elt, b uint) { ladderStepGeneric(w, b) }
+func mulA24(z, x *fp.Elt)             { mulA24Generic(z, x) }
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/doc.go b/vendor/github.com/cloudflare/circl/dh/x448/doc.go
new file mode 100644
index 00000000..c02904fe
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/doc.go
@@ -0,0 +1,19 @@
+/*
+Package x448 provides Diffie-Hellman functions as specified in RFC-7748.
+
+Validation of public keys.
+
+The Diffie-Hellman function, as described in RFC-7748 [1], works for any
+public key. However, if a different protocol requires contributory
+behaviour [2,3], then the public keys must be validated against low-order
+points [3,4]. To do that, the Shared function performs this validation
+internally and returns false when the public key is invalid (i.e., it
+is a low-order point).
+
+References:
+  - [1] RFC7748 by Langley, Hamburg, Turner (https://rfc-editor.org/rfc/rfc7748.txt)
+  - [2] Curve25519 by Bernstein (https://cr.yp.to/ecdh.html)
+  - [3] Bernstein (https://cr.yp.to/ecdh.html#validate)
+  - [4] Cremers&Jackson (https://eprint.iacr.org/2019/526)
+*/
+package x448
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/key.go b/vendor/github.com/cloudflare/circl/dh/x448/key.go
new file mode 100644
index 00000000..2fdde511
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/key.go
@@ -0,0 +1,46 @@
+package x448
+
+import (
+	"crypto/subtle"
+
+	fp "github.com/cloudflare/circl/math/fp448"
+)
+
+// Size is the length in bytes of a X448 key.
+const Size = 56
+
+// Key represents a X448 key.
+type Key [Size]byte
+
+func (k *Key) clamp(in *Key) *Key {
+	*k = *in
+	k[0] &= 252
+	k[55] |= 128
+	return k
+}
+
+// isValidPubKey verifies if the public key is not a low-order point.
+func (k *Key) isValidPubKey() bool {
+	fp.Modp((*fp.Elt)(k))
+	var isLowOrder int
+	for _, P := range lowOrderPoints {
+		isLowOrder |= subtle.ConstantTimeCompare(P[:], k[:])
+	}
+	return isLowOrder == 0
+}
+
+// KeyGen obtains a public key given a secret key.
+func KeyGen(public, secret *Key) {
+	ladderJoye(public.clamp(secret))
+}
+
+// Shared calculates Alice's shared key from Alice's secret key and Bob's
+// public key returning true on success. A failure case happens when the public
+// key is a low-order point, thus the shared key is all-zeros and the function
+// returns false.
+func Shared(shared, secret, public *Key) bool {
+	validPk := *public
+	ok := validPk.isValidPubKey()
+	ladderMontgomery(shared.clamp(secret), &validPk)
+	return ok
+}
diff --git a/vendor/github.com/cloudflare/circl/dh/x448/table.go b/vendor/github.com/cloudflare/circl/dh/x448/table.go
new file mode 100644
index 00000000..eef53c30
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/dh/x448/table.go
@@ -0,0 +1,460 @@
+package x448
+
+import fp "github.com/cloudflare/circl/math/fp448"
+
+// tableGenerator contains the set of points:
+//
+//	t[i] = (xi+1)/(xi-1),
+//
+// where (xi,yi) = 2^iG and G is the generator point
+// Size = (448)*(448/8) = 25088 bytes.
+var tableGenerator = [448 * fp.Size]byte{
+	/* (2^  0)P */ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
+	/* (2^  1)P */ 0x37, 0xfa, 0xaa, 0x0d, 0x86, 0xa6, 0x24, 0xe9, 0x6c, 0x95, 0x08, 0x34, 0xba, 0x1a, 0x81, 0x3a, 0xae, 0x01, 0xa5, 0xa7, 0x05, 0x85, 0x96, 0x00, 0x06, 0x5a, 0xd7, 0xff, 0xee, 0x8e, 0x8f, 0x94, 0xd2, 0xdc, 0xd7, 0xfc, 0xe7, 0xe5, 0x99, 0x1d, 0x05, 0x46, 0x43, 0xe8, 0xbc, 0x12, 0xb7, 0xeb, 0x30, 0x5e, 0x7a, 0x85, 0x68, 0xed, 0x9d, 0x28,
+	/* (2^  2)P */ 0xf1, 0x7d, 0x08, 0x2b, 0x32, 0x4a, 0x62, 0x80, 0x36, 0xe7, 0xa4, 0x76, 0x5a, 0x2a, 0x1e, 0xf7, 0x9e, 0x3c, 0x40, 0x46, 0x9a, 0x1b, 0x61, 0xc1, 0xbf, 0x1a, 0x1b, 0xae, 0x91, 0x80, 0xa3, 0x76, 0x6c, 0xd4, 0x8f, 0xa4, 0xee, 0x26, 0x39, 0x23, 0xa4, 0x80, 0xf4, 0x66, 0x92, 0xe4, 0xe1, 0x18, 0x76, 0xc5, 0xe2, 0x19, 0x87, 0xd5, 0xc3, 0xe8,
+	/* (2^  3)P */ 0xfb, 0xc9, 0xf0, 0x07, 0xf2, 0x93, 0xd8, 0x50, 0x36, 0xed, 0xfb, 0xbd, 0xb2, 0xd3, 0xfc, 0xdf, 0xd5, 0x2a, 0x6e, 0x26, 0x09, 0xce, 0xd4, 0x07, 0x64, 0x9f, 0x40, 0x74, 0xad, 0x98, 0x2f, 0x1c, 0xb6, 0xdc, 0x2d, 0x42, 0xff, 0xbf, 0x97, 0xd8, 0xdb, 0xef, 0x99, 0xca, 0x73, 0x99, 0x1a, 0x04, 0x3b, 0x56, 0x2c, 0x1f, 0x87, 0x9d, 0x9f, 0x03,
+	/* (2^  4)P */ 0x4c, 0x35, 0x97, 0xf7, 0x81, 0x2c, 0x84, 0xa6, 0xe0, 0xcb, 0xce, 0x37, 0x4c, 0x21, 0x1c, 0x67, 0xfa, 0xab, 0x18, 0x4d, 0xef, 0xd0, 0xf0, 0x44, 0xa9, 0xfb, 0xc0, 0x8e, 0xda, 0x57, 0xa1, 0xd8, 0xeb, 0x87, 0xf4, 0x17, 0xea, 0x66, 0x0f, 0x16, 0xea, 0xcd, 0x5f, 0x3e, 0x88, 0xea, 0x09, 0x68, 0x40, 0xdf, 0x43, 0xcc, 0x54, 0x61, 0x58, 0xaa,
+	/* (2^  5)P */ 0x8d, 0xe7, 0x59, 0xd7, 0x5e, 0x63, 0x37, 0xa7, 0x3f, 0xd1, 0x49, 0x85, 0x01, 0xdd, 0x5e, 0xb3, 0xe6, 0x29, 0xcb, 0x25, 0x93, 0xdd, 0x08, 0x96, 0x83, 0x52, 0x76, 0x85, 0xf5, 0x5d, 0x02, 0xbf, 0xe9, 0x6d, 0x15, 0x27, 0xc1, 0x09, 0xd1, 0x14, 0x4d, 0x6e, 0xe8, 0xaf, 0x59, 0x58, 0x34, 0x9d, 0x2a, 0x99, 0x85, 0x26, 0xbe, 0x4b, 0x1e, 0xb9,
+	/* (2^  6)P */ 0x8d, 0xce, 0x94, 0xe2, 0x18, 0x56, 0x0d, 0x82, 0x8e, 0xdf, 0x85, 0x01, 0x8f, 0x93, 0x3c, 0xc6, 0xbd, 0x61, 0xfb, 0xf4, 0x22, 0xc5, 0x16, 0x87, 0xd1, 0xb1, 0x9e, 0x09, 0xc5, 0x83, 0x2e, 0x4a, 0x07, 0x88, 0xee, 0xe0, 0x29, 0x8d, 0x2e, 0x1f, 0x88, 0xad, 0xfd, 0x18, 0x93, 0xb7, 0xed, 0x42, 0x86, 0x78, 0xf0, 0xb8, 0x70, 0xbe, 0x01, 0x67,
+	/* (2^  7)P */ 0xdf, 0x62, 0x2d, 0x94, 0xc7, 0x35, 0x23, 0xda, 0x27, 0xbb, 0x2b, 0xdb, 0x30, 0x80, 0x68, 0x16, 0xa3, 0xae, 0xd7, 0xd2, 0xa7, 0x7c, 0xbf, 0x6a, 0x1d, 0x83, 0xde, 0x96, 0x0a, 0x43, 0xb6, 0x30, 0x37, 0xd6, 0xee, 0x63, 0x59, 0x9a, 0xbf, 0xa3, 0x30, 0x6c, 0xaf, 0x0c, 0xee, 0x3d, 0xcb, 0x35, 0x4b, 0x55, 0x5f, 0x84, 0x85, 0xcb, 0x4f, 0x1e,
+	/* (2^  8)P */ 0x9d, 0x04, 0x68, 0x89, 0xa4, 0xa9, 0x0d, 0x87, 0xc1, 0x70, 0xf1, 0xeb, 0xfb, 0x47, 0x0a, 0xf0, 0xde, 0x67, 0xb7, 0x94, 0xcd, 0x36, 0x43, 0xa5, 0x49, 0x43, 0x67, 0xc3, 0xee, 0x3c, 0x6b, 0xec, 0xd0, 0x1a, 0xf4, 0xad, 0xef, 0x06, 0x4a, 0xe8, 0x46, 0x24, 0xd7, 0x93, 0xbf, 0xf0, 0xe3, 0x81, 0x61, 0xec, 0xea, 0x64, 0xfe, 0x67, 0xeb, 0xc7,
+	/* (2^  9)P */ 0x95, 0x45, 0x79, 0xcf, 0x2c, 0xfd, 0x9b, 0xfe, 0x84, 0x46, 0x4b, 0x8f, 0xa1, 0xcf, 0xc3, 0x04, 0x94, 0x78, 0xdb, 0xc9, 0xa6, 0x01, 0x75, 0xa4, 0xb4, 0x93, 0x72, 0x43, 0xa7, 0x7d, 0xda, 0x31, 0x38, 0x54, 0xab, 0x4e, 0x3f, 0x89, 0xa6, 0xab, 0x57, 0xc0, 0x16, 0x65, 0xdb, 0x92, 0x96, 0xe4, 0xc8, 0xae, 0xe7, 0x4c, 0x7a, 0xeb, 0xbb, 0x5a,
+	/* (2^ 10)P */ 0xbe, 0xfe, 0x86, 0xc3, 0x97, 0xe0, 0x6a, 0x18, 0x20, 0x21, 0xca, 0x22, 0x55, 0xa1, 0xeb, 0xf5, 0x74, 0xe5, 0xc9, 0x59, 0xa7, 0x92, 0x65, 0x15, 0x08, 0x71, 0xd1, 0x09, 0x7e, 0x83, 0xfc, 0xbc, 0x5a, 0x93, 0x38, 0x0d, 0x43, 0x42, 0xfd, 0x76, 0x30, 0xe8, 0x63, 0x60, 0x09, 0x8d, 0x6c, 0xd3, 0xf8, 0x56, 0x3d, 0x68, 0x47, 0xab, 0xa0, 0x1d,
+	/* (2^ 11)P */ 0x38, 0x50, 0x1c, 0xb1, 0xac, 0x88, 0x8f, 0x38, 0xe3, 0x69, 0xe6, 0xfc, 0x4f, 0x8f, 0xe1, 0x9b, 0xb1, 0x1a, 0x09, 0x39, 0x19, 0xdf, 0xcd, 0x98, 0x7b, 0x64, 0x42, 0xf6, 0x11, 0xea, 0xc7, 0xe8, 0x92, 0x65, 0x00, 0x2c, 0x75, 0xb5, 0x94, 0x1e, 0x5b, 0xa6, 0x66, 0x81, 0x77, 0xf3, 0x39, 0x94, 0xac, 0xbd, 0xe4, 0x2a, 0x66, 0x84, 0x9c, 0x60,
+	/* (2^ 12)P */ 0xb5, 0xb6, 0xd9, 0x03, 0x67, 0xa4, 0xa8, 0x0a, 0x4a, 0x2b, 0x9d, 0xfa, 0x13, 0xe1, 0x99, 0x25, 0x4a, 0x5c, 0x67, 0xb9, 0xb2, 0xb7, 0xdd, 0x1e, 0xaf, 0xeb, 0x63, 0x41, 0xb6, 0xb9, 0xa0, 0x87, 0x0a, 0xe0, 0x06, 0x07, 0xaa, 0x97, 0xf8, 0xf9, 0x38, 0x4f, 0xdf, 0x0c, 0x40, 0x7c, 0xc3, 0x98, 0xa9, 0x74, 0xf1, 0x5d, 0xda, 0xd1, 0xc0, 0x0a,
+	/* (2^ 13)P */ 0xf2, 0x0a, 0xab, 0xab, 0x94, 0x50, 0xf0, 0xa3, 0x6f, 0xc6, 0x66, 0xba, 0xa6, 0xdc, 0x44, 0xdd, 0xd6, 0x08, 0xf4, 0xd3, 0xed, 0xb1, 0x40, 0x93, 0xee, 0xf6, 0xb8, 0x8e, 0xb4, 0x7c, 0xb9, 0x82, 0xc9, 0x9d, 0x45, 0x3b, 0x8e, 0x10, 0xcb, 0x70, 0x1e, 0xba, 0x3c, 0x62, 0x50, 0xda, 0xa9, 0x93, 0xb5, 0xd7, 0xd0, 0x6f, 0x29, 0x52, 0x95, 0xae,
+	/* (2^ 14)P */ 0x14, 0x68, 0x69, 0x23, 0xa8, 0x44, 0x87, 0x9e, 0x22, 0x91, 0xe8, 0x92, 0xdf, 0xf7, 0xae, 0xba, 0x1c, 0x96, 0xe1, 0xc3, 0x94, 0xed, 0x6c, 0x95, 0xae, 0x96, 0xa7, 0x15, 0x9f, 0xf1, 0x17, 0x11, 0x92, 0x42, 0xd5, 0xcd, 0x18, 0xe7, 0xa9, 0xb5, 0x2f, 0xcd, 0xde, 0x6c, 0xc9, 0x7d, 0xfc, 0x7e, 0xbd, 0x7f, 0x10, 0x3d, 0x01, 0x00, 0x8d, 0x95,
+	/* (2^ 15)P */ 0x3b, 0x76, 0x72, 0xae, 0xaf, 0x84, 0xf2, 0xf7, 0xd1, 0x6d, 0x13, 0x9c, 0x47, 0xe1, 0xb7, 0xa3, 0x19, 0x16, 0xee, 0x75, 0x45, 0xf6, 0x1a, 0x7b, 0x78, 0x49, 0x79, 0x05, 0x86, 0xf0, 0x7f, 0x9f, 0xfc, 0xc4, 0xbd, 0x86, 0xf3, 0x41, 0xa7, 0xfe, 0x01, 0xd5, 0x67, 0x16, 0x10, 0x5b, 0xa5, 0x16, 0xf3, 0x7f, 0x60, 0xce, 0xd2, 0x0c, 0x8e, 0x4b,
+	/* (2^ 16)P */ 0x4a, 0x07, 0x99, 0x4a, 0x0f, 0x74, 0x91, 0x14, 0x68, 0xb9, 0x48, 0xb7, 0x44, 0x77, 0x9b, 0x4a, 0xe0, 0x68, 0x0e, 0x43, 0x4d, 0x98, 0x98, 0xbf, 0xa8, 0x3a, 0xb7, 0x6d, 0x2a, 0x9a, 0x77, 0x5f, 0x62, 0xf5, 0x6b, 0x4a, 0xb7, 0x7d, 0xe5, 0x09, 0x6b, 0xc0, 0x8b, 0x9c, 0x88, 0x37, 0x33, 0xf2, 0x41, 0xac, 0x22, 0x1f, 0xcf, 0x3b, 0x82, 0x34,
+	/* (2^ 17)P */ 0x00, 0xc3, 0x78, 0x42, 0x32, 0x2e, 0xdc, 0xda, 0xb1, 0x96, 0x21, 0xa4, 0xe4, 0xbb, 0xe9, 0x9d, 0xbb, 0x0f, 0x93, 0xed, 0x26, 0x3d, 0xb5, 0xdb, 0x94, 0x31, 0x37, 0x07, 0xa2, 0xb2, 0xd5, 0x99, 0x0d, 0x93, 0xe1, 0xce, 0x3f, 0x0b, 0x96, 0x82, 0x47, 0xfe, 0x60, 0x6f, 0x8f, 0x61, 0x88, 0xd7, 0x05, 0x95, 0x0b, 0x46, 0x06, 0xb7, 0x32, 0x06,
+	/* (2^ 18)P */ 0x44, 0xf5, 0x34, 0xdf, 0x2f, 0x9c, 0x5d, 0x9f, 0x53, 0x5c, 0x42, 0x8f, 0xc9, 0xdc, 0xd8, 0x40, 0xa2, 0xe7, 0x6a, 0x4a, 0x05, 0xf7, 0x86, 0x77, 0x2b, 0xae, 0x37, 0xed, 0x48, 0xfb, 0xf7, 0x62, 0x7c, 0x17, 0x59, 0x92, 0x41, 0x61, 0x93, 0x38, 0x30, 0xd1, 0xef, 0x54, 0x54, 0x03, 0x17, 0x57, 0x91, 0x15, 0x11, 0x33, 0xb5, 0xfa, 0xfb, 0x17,
+	/* (2^ 19)P */ 0x29, 0xbb, 0xd4, 0xb4, 0x9c, 0xf1, 0x72, 0x94, 0xce, 0x6a, 0x29, 0xa8, 0x89, 0x18, 0x19, 0xf7, 0xb7, 0xcc, 0xee, 0x9a, 0x02, 0xe3, 0xc0, 0xb1, 0xe0, 0xee, 0x83, 0x78, 0xb4, 0x9e, 0x07, 0x87, 0xdf, 0xb0, 0x82, 0x26, 0x4e, 0xa4, 0x0c, 0x33, 0xaf, 0x40, 0x59, 0xb6, 0xdd, 0x52, 0x45, 0xf0, 0xb4, 0xf6, 0xe8, 0x4e, 0x4e, 0x79, 0x1a, 0x5d,
+	/* (2^ 20)P */ 0x27, 0x33, 0x4d, 0x4c, 0x6b, 0x4f, 0x75, 0xb1, 0xbc, 0x1f, 0xab, 0x5b, 0x2b, 0xf0, 0x1c, 0x57, 0x86, 0xdd, 0xfd, 0x60, 0xb0, 0x8c, 0xe7, 0x9a, 0xe5, 0x5c, 0xeb, 0x11, 0x3a, 0xda, 0x22, 0x25, 0x99, 0x06, 0x8d, 0xf4, 0xaf, 0x29, 0x7a, 0xc9, 0xe5, 0xd2, 0x16, 0x9e, 0xd4, 0x63, 0x1d, 0x64, 0xa6, 0x47, 0x96, 0x37, 0x6f, 0x93, 0x2c, 0xcc,
+	/* (2^ 21)P */ 0xc1, 0x94, 0x74, 0x86, 0x75, 0xf2, 0x91, 0x58, 0x23, 0x85, 0x63, 0x76, 0x54, 0xc7, 0xb4, 0x8c, 0xbc, 0x4e, 0xc4, 0xa7, 0xba, 0xa0, 0x55, 0x26, 0x71, 0xd5, 0x33, 0x72, 0xc9, 0xad, 0x1e, 0xf9, 0x5d, 0x78, 0x70, 0x93, 0x4e, 0x85, 0xfc, 0x39, 0x06, 0x73, 0x76, 0xff, 0xe8, 0x64, 0x69, 0x42, 0x45, 0xb2, 0x69, 0xb5, 0x32, 0xe7, 0x2c, 0xde,
+	/* (2^ 22)P */ 0xde, 0x16, 0xd8, 0x33, 0x49, 0x32, 0xe9, 0x0e, 0x3a, 0x60, 0xee, 0x2e, 0x24, 0x75, 0xe3, 0x9c, 0x92, 0x07, 0xdb, 0xad, 0x92, 0xf5, 0x11, 0xdf, 0xdb, 0xb0, 0x17, 0x5c, 0xd6, 0x1a, 0x70, 0x00, 0xb7, 0xe2, 0x18, 0xec, 0xdc, 0xc2, 0x02, 0x93, 0xb3, 0xc8, 0x3f, 0x4f, 0x1b, 0x96, 0xe6, 0x33, 0x8c, 0xfb, 0xcc, 0xa5, 0x4e, 0xe8, 0xe7, 0x11,
+	/* (2^ 23)P */ 0x05, 0x7a, 0x74, 0x52, 0xf8, 0xdf, 0x0d, 0x7c, 0x6a, 0x1a, 0x4e, 0x9a, 0x02, 0x1d, 0xae, 0x77, 0xf8, 0x8e, 0xf9, 0xa2, 0x38, 0x54, 0x50, 0xb2, 0x2c, 0x08, 0x9d, 0x9b, 0x9f, 0xfb, 0x2b, 0x06, 0xde, 0x9d, 0xc2, 0x03, 0x0b, 0x22, 0x2b, 0x10, 0x5b, 0x3a, 0x73, 0x29, 0x8e, 0x3e, 0x37, 0x08, 0x2c, 0x3b, 0xf8, 0x80, 0xc1, 0x66, 0x1e, 0x98,
+	/* (2^ 24)P */ 0xd8, 0xd6, 0x3e, 0xcd, 0x63, 0x8c, 0x2b, 0x41, 0x81, 0xc0, 0x0c, 0x06, 0x87, 0xd6, 0xe7, 0x92, 0xfe, 0xf1, 0x0c, 0x4a, 0x84, 0x5b, 0xaf, 0x40, 0x53, 0x6f, 0x60, 0xd6, 0x6b, 0x76, 0x4b, 0xc2, 0xad, 0xc9, 0xb6, 0xb6, 0x6a, 0xa2, 0xb3, 0xf5, 0xf5, 0xc2, 0x55, 0x83, 0xb2, 0xd3, 0xe9, 0x41, 0x6c, 0x63, 0x51, 0xb8, 0x81, 0x74, 0xc8, 0x2c,
+	/* (2^ 25)P */ 0xb2, 0xaf, 0x1c, 0xee, 0x07, 0xb0, 0x58, 0xa8, 0x2c, 0x6a, 0xc9, 0x2d, 0x62, 0x28, 0x75, 0x0c, 0x40, 0xb6, 0x11, 0x33, 0x96, 0x80, 0x28, 0x6d, 0xd5, 0x9e, 0x87, 0x90, 0x01, 0x66, 0x1d, 0x1c, 0xf8, 0xb4, 0x92, 0xac, 0x38, 0x18, 0x05, 0xc2, 0x4c, 0x4b, 0x54, 0x7d, 0x80, 0x46, 0x87, 0x2d, 0x99, 0x8e, 0x70, 0x80, 0x69, 0x71, 0x8b, 0xed,
+	/* (2^ 26)P */ 0x37, 0xa7, 0x6b, 0x71, 0x36, 0x75, 0x8e, 0xff, 0x0f, 0x42, 0xda, 0x5a, 0x46, 0xa6, 0x97, 0x79, 0x7e, 0x30, 0xb3, 0x8f, 0xc7, 0x3a, 0xa0, 0xcb, 0x1d, 0x9c, 0x78, 0x77, 0x36, 0xc2, 0xe7, 0xf4, 0x2f, 0x29, 0x07, 0xb1, 0x07, 0xfd, 0xed, 0x1b, 0x39, 0x77, 0x06, 0x38, 0x77, 0x0f, 0x50, 0x31, 0x12, 0xbf, 0x92, 0xbf, 0x72, 0x79, 0x54, 0xa9,
+	/* (2^ 27)P */ 0xbd, 0x4d, 0x46, 0x6b, 0x1a, 0x80, 0x46, 0x2d, 0xed, 0xfd, 0x64, 0x6d, 0x94, 0xbc, 0x4a, 0x6e, 0x0c, 0x12, 0xf6, 0x12, 0xab, 0x54, 0x88, 0xd3, 0x85, 0xac, 0x51, 0xae, 0x6f, 0xca, 0xc4, 0xb7, 0xec, 0x22, 0x54, 0x6d, 0x80, 0xb2, 0x1c, 0x63, 0x33, 0x76, 0x6b, 0x8e, 0x6d, 0x59, 0xcd, 0x73, 0x92, 0x5f, 0xff, 0xad, 0x10, 0x35, 0x70, 0x5f,
+	/* (2^ 28)P */ 0xb3, 0x84, 0xde, 0xc8, 0x04, 0x43, 0x63, 0xfa, 0x29, 0xd9, 0xf0, 0x69, 0x65, 0x5a, 0x0c, 0xe8, 0x2e, 0x0b, 0xfe, 0xb0, 0x7a, 0x42, 0xb3, 0xc3, 0xfc, 0xe6, 0xb8, 0x92, 0x29, 0xae, 0xed, 0xec, 0xd5, 0xe8, 0x4a, 0xa1, 0xbd, 0x3b, 0xd3, 0xc0, 0x07, 0xab, 0x65, 0x65, 0x35, 0x9a, 0xa6, 0x5e, 0x78, 0x18, 0x76, 0x1c, 0x15, 0x49, 0xe6, 0x75,
+	/* (2^ 29)P */ 0x45, 0xb3, 0x92, 0xa9, 0xc3, 0xb8, 0x11, 0x68, 0x64, 0x3a, 0x83, 0x5d, 0xa8, 0x94, 0x6a, 0x9d, 0xaa, 0x27, 0x9f, 0x98, 0x5d, 0xc0, 0x29, 0xf0, 0xc0, 0x4b, 0x14, 0x3c, 0x05, 0xe7, 0xf8, 0xbd, 0x38, 0x22, 0x96, 0x75, 0x65, 0x5e, 0x0d, 0x3f, 0xbb, 0x6f, 0xe8, 0x3f, 0x96, 0x76, 0x9f, 0xba, 0xd9, 0x44, 0x92, 0x96, 0x22, 0xe7, 0x52, 0xe7,
+	/* (2^ 30)P */ 0xf4, 0xa3, 0x95, 0x90, 0x47, 0xdf, 0x7d, 0xdc, 0xf4, 0x13, 0x87, 0x67, 0x7d, 0x4f, 0x9d, 0xa0, 0x00, 0x46, 0x72, 0x08, 0xc3, 0xa2, 0x7a, 0x3e, 0xe7, 0x6d, 0x52, 0x7c, 0x11, 0x36, 0x50, 0x83, 0x89, 0x64, 0xcb, 0x1f, 0x08, 0x83, 0x46, 0xcb, 0xac, 0xa6, 0xd8, 0x9c, 0x1b, 0xe8, 0x05, 0x47, 0xc7, 0x26, 0x06, 0x83, 0x39, 0xe9, 0xb1, 0x1c,
+	/* (2^ 31)P */ 0x11, 0xe8, 0xc8, 0x42, 0xbf, 0x30, 0x9c, 0xa3, 0xf1, 0x85, 0x96, 0x95, 0x4f, 0x4f, 0x52, 0xa2, 0xf5, 0x8b, 0x68, 0x24, 0x16, 0xac, 0x9b, 0xa9, 0x27, 0x28, 0x0e, 0x84, 0x03, 0x46, 0x22, 0x5f, 0xf7, 0x0d, 0xa6, 0x85, 0x88, 0xc1, 0x45, 0x4b, 0x85, 0x1a, 0x10, 0x7f, 0xc9, 0x94, 0x20, 0xb0, 0x04, 0x28, 0x12, 0x30, 0xb9, 0xe6, 0x40, 0x6b,
+	/* (2^ 32)P */ 0xac, 0x1b, 0x57, 0xb6, 0x42, 0xdb, 0x81, 0x8d, 0x76, 0xfd, 0x9b, 0x1c, 0x29, 0x30, 0xd5, 0x3a, 0xcc, 0x53, 0xd9, 0x26, 0x7a, 0x0f, 0x9c, 0x2e, 0x79, 0xf5, 0x62, 0xeb, 0x61, 0x9d, 0x9b, 0x80, 0x39, 0xcd, 0x60, 0x2e, 0x1f, 0x08, 0x22, 0xbc, 0x19, 0xb3, 0x2a, 0x43, 0x44, 0xf2, 0x4e, 0x66, 0xf4, 0x36, 0xa6, 0xa7, 0xbc, 0xa4, 0x15, 0x7e,
+	/* (2^ 33)P */ 0xc1, 0x90, 0x8a, 0xde, 0xff, 0x78, 0xc3, 0x73, 0x16, 0xee, 0x76, 0xa0, 0x84, 0x60, 0x8d, 0xe6, 0x82, 0x0f, 0xde, 0x4e, 0xc5, 0x99, 0x34, 0x06, 0x90, 0x44, 0x55, 0xf8, 0x91, 0xd8, 0xe1, 0xe4, 0x2c, 0x8a, 0xde, 0x94, 0x1e, 0x78, 0x25, 0x3d, 0xfd, 0xd8, 0x59, 0x7d, 0xaf, 0x6e, 0xbe, 0x96, 0xbe, 0x3c, 0x16, 0x23, 0x0f, 0x4c, 0xa4, 0x28,
+	/* (2^ 34)P */ 0xba, 0x11, 0x35, 0x57, 0x03, 0xb6, 0xf4, 0x24, 0x89, 0xb8, 0x5a, 0x0d, 0x50, 0x9c, 0xaa, 0x51, 0x7f, 0xa4, 0x0e, 0xfc, 0x71, 0xb3, 0x3b, 0xf1, 0x96, 0x50, 0x23, 0x15, 0xf5, 0xf5, 0xd4, 0x23, 0xdc, 0x8b, 0x26, 0x9e, 0xae, 0xb7, 0x50, 0xcd, 0xc4, 0x25, 0xf6, 0x75, 0x40, 0x9c, 0x37, 0x79, 0x33, 0x60, 0xd4, 0x4b, 0x13, 0x32, 0xee, 0xe2,
+	/* (2^ 35)P */ 0x43, 0xb8, 0x56, 0x59, 0xf0, 0x68, 0x23, 0xb3, 0xea, 0x70, 0x58, 0x4c, 0x1e, 0x5a, 0x16, 0x54, 0x03, 0xb2, 0xf4, 0x73, 0xb6, 0xd9, 0x5c, 0x9c, 0x6f, 0xcf, 0x82, 0x2e, 0x54, 0x15, 0x46, 0x2c, 0xa3, 0xda, 0x4e, 0x87, 0xf5, 0x2b, 0xba, 0x91, 0xa3, 0xa0, 0x89, 0xba, 0x48, 0x2b, 0xfa, 0x64, 0x02, 0x7f, 0x78, 0x03, 0xd1, 0xe8, 0x3b, 0xe9,
+	/* (2^ 36)P */ 0x15, 0xa4, 0x71, 0xd4, 0x0c, 0x24, 0xe9, 0x07, 0xa1, 0x43, 0xf4, 0x7f, 0xbb, 0xa2, 0xa6, 0x6b, 0xfa, 0xb7, 0xea, 0x58, 0xd1, 0x96, 0xb0, 0x24, 0x5c, 0xc7, 0x37, 0x4e, 0x60, 0x0f, 0x40, 0xf2, 0x2f, 0x44, 0x70, 0xea, 0x80, 0x63, 0xfe, 0xfc, 0x46, 0x59, 0x12, 0x27, 0xb5, 0x27, 0xfd, 0xb7, 0x73, 0x0b, 0xca, 0x8b, 0xc2, 0xd3, 0x71, 0x08,
+	/* (2^ 37)P */ 0x26, 0x0e, 0xd7, 0x52, 0x6f, 0xf1, 0xf2, 0x9d, 0xb8, 0x3d, 0xbd, 0xd4, 0x75, 0x97, 0xd8, 0xbf, 0xa8, 0x86, 0x96, 0xa5, 0x80, 0xa0, 0x45, 0x75, 0xf6, 0x77, 0x71, 0xdb, 0x77, 0x96, 0x55, 0x99, 0x31, 0xd0, 0x4f, 0x34, 0xf4, 0x35, 0x39, 0x41, 0xd3, 0x7d, 0xf7, 0xe2, 0x74, 0xde, 0xbe, 0x5b, 0x1f, 0x39, 0x10, 0x21, 0xa3, 0x4d, 0x3b, 0xc8,
+	/* (2^ 38)P */ 0x04, 0x00, 0x2a, 0x45, 0xb2, 0xaf, 0x9b, 0x18, 0x6a, 0xeb, 0x96, 0x28, 0xa4, 0x77, 0xd0, 0x13, 0xcf, 0x17, 0x65, 0xe8, 0xc5, 0x81, 0x28, 0xad, 0x39, 0x7a, 0x0b, 0xaa, 0x55, 0x2b, 0xf3, 0xfc, 0x86, 0x40, 0xad, 0x0d, 0x1e, 0x28, 0xa2, 0x2d, 0xc5, 0xd6, 0x04, 0x15, 0xa2, 0x30, 0x3d, 0x12, 0x8e, 0xd6, 0xb5, 0xf7, 0x69, 0xbb, 0x84, 0x20,
+	/* (2^ 39)P */ 0xd7, 0x7a, 0x77, 0x2c, 0xfb, 0x81, 0x80, 0xe9, 0x1e, 0xc6, 0x36, 0x31, 0x79, 0xc3, 0x7c, 0xa9, 0x57, 0x6b, 0xb5, 0x70, 0xfb, 0xe4, 0xa1, 0xff, 0xfd, 0x21, 0xa5, 0x7c, 0xfa, 0x44, 0xba, 0x0d, 0x96, 0x3d, 0xc4, 0x5c, 0x39, 0x52, 0x87, 0xd7, 0x22, 0x0f, 0x52, 0x88, 0x91, 0x87, 0x96, 0xac, 0xfa, 0x3b, 0xdf, 0xdc, 0x83, 0x8c, 0x99, 0x29,
+	/* (2^ 40)P */ 0x98, 0x6b, 0x3a, 0x8d, 0x83, 0x17, 0xe1, 0x62, 0xd8, 0x80, 0x4c, 0x97, 0xce, 0x6b, 0xaa, 0x10, 0xa7, 0xc4, 0xe9, 0xeb, 0xa5, 0xfb, 0xc9, 0xdd, 0x2d, 0xeb, 0xfc, 0x9a, 0x71, 0xcd, 0x68, 0x6e, 0xc0, 0x35, 0x64, 0x62, 0x1b, 0x95, 0x12, 0xe8, 0x53, 0xec, 0xf0, 0xf4, 0x86, 0x86, 0x78, 0x18, 0xc4, 0xc6, 0xbc, 0x5a, 0x59, 0x8f, 0x7c, 0x7e,
+	/* (2^ 41)P */ 0x7f, 0xd7, 0x1e, 0xc5, 0x83, 0xdc, 0x1f, 0xbe, 0x0b, 0xcf, 0x2e, 0x01, 0x01, 0xed, 0xac, 0x17, 0x3b, 0xed, 0xa4, 0x30, 0x96, 0x0e, 0x14, 0x7e, 0x19, 0x2b, 0xa5, 0x67, 0x1e, 0xb3, 0x34, 0x03, 0xa8, 0xbb, 0x0a, 0x7d, 0x08, 0x2d, 0xd5, 0x53, 0x19, 0x6f, 0x13, 0xd5, 0xc0, 0x90, 0x8a, 0xcc, 0xc9, 0x5c, 0xab, 0x24, 0xd7, 0x03, 0xf6, 0x57,
+	/* (2^ 42)P */ 0x49, 0xcb, 0xb4, 0x96, 0x5f, 0xa6, 0xf8, 0x71, 0x6f, 0x59, 0xad, 0x05, 0x24, 0x2d, 0xaf, 0x67, 0xa8, 0xbe, 0x95, 0xdf, 0x0d, 0x28, 0x5a, 0x7f, 0x6e, 0x87, 0x8c, 0x6e, 0x67, 0x0c, 0xf4, 0xe0, 0x1c, 0x30, 0xc2, 0x66, 0xae, 0x20, 0xa1, 0x34, 0xec, 0x9c, 0xbc, 0xae, 0x3d, 0xa1, 0x28, 0x28, 0x95, 0x1d, 0xc9, 0x3a, 0xa8, 0xfd, 0xfc, 0xa1,
+	/* (2^ 43)P */ 0xe2, 0x2b, 0x9d, 0xed, 0x02, 0x99, 0x67, 0xbb, 0x2e, 0x16, 0x62, 0x05, 0x70, 0xc7, 0x27, 0xb9, 0x1c, 0x3f, 0xf2, 0x11, 0x01, 0xd8, 0x51, 0xa4, 0x18, 0x92, 0xa9, 0x5d, 0xfb, 0xa9, 0xe4, 0x42, 0xba, 0x38, 0x34, 0x1a, 0x4a, 0xc5, 0x6a, 0x37, 0xde, 0xa7, 0x0c, 0xb4, 0x7e, 0x7f, 0xde, 0xa6, 0xee, 0xcd, 0x55, 0x57, 0x05, 0x06, 0xfd, 0x5d,
+	/* (2^ 44)P */ 0x2f, 0x32, 0xcf, 0x2e, 0x2c, 0x7b, 0xbe, 0x9a, 0x0c, 0x57, 0x35, 0xf8, 0x87, 0xda, 0x9c, 0xec, 0x48, 0xf2, 0xbb, 0xe2, 0xda, 0x10, 0x58, 0x20, 0xc6, 0xd3, 0x87, 0xe9, 0xc7, 0x26, 0xd1, 0x9a, 0x46, 0x87, 0x90, 0xda, 0xdc, 0xde, 0xc3, 0xb3, 0xf2, 0xe8, 0x6f, 0x4a, 0xe6, 0xe8, 0x9d, 0x98, 0x36, 0x20, 0x03, 0x47, 0x15, 0x3f, 0x64, 0x59,
+	/* (2^ 45)P */ 0xd4, 0x71, 0x49, 0x0a, 0x67, 0x97, 0xaa, 0x3f, 0xf4, 0x1b, 0x3a, 0x6e, 0x5e, 0x17, 0xcc, 0x0a, 0x8f, 0x81, 0x6a, 0x41, 0x38, 0x77, 0x40, 0x8a, 0x11, 0x42, 0x62, 0xd2, 0x50, 0x32, 0x79, 0x78, 0x28, 0xc2, 0x2e, 0x10, 0x01, 0x94, 0x30, 0x4f, 0x7f, 0x18, 0x17, 0x56, 0x85, 0x4e, 0xad, 0xf7, 0xcb, 0x87, 0x3c, 0x3f, 0x50, 0x2c, 0xc0, 0xba,
+	/* (2^ 46)P */ 0xbc, 0x30, 0x8e, 0x65, 0x8e, 0x57, 0x5b, 0x38, 0x7a, 0xd4, 0x95, 0x52, 0x7a, 0x32, 0x59, 0x69, 0xcd, 0x9d, 0x47, 0x34, 0x5b, 0x55, 0xa5, 0x24, 0x60, 0xdd, 0xc0, 0xc1, 0x62, 0x73, 0x44, 0xae, 0x4c, 0x9c, 0x65, 0x55, 0x1b, 0x9d, 0x8a, 0x29, 0xb0, 0x1a, 0x52, 0xa8, 0xf1, 0xe6, 0x9a, 0xb3, 0xf6, 0xa3, 0xc9, 0x0a, 0x70, 0x7d, 0x0f, 0xee,
+	/* (2^ 47)P */ 0x77, 0xd3, 0xe5, 0x8e, 0xfa, 0x00, 0xeb, 0x1b, 0x7f, 0xdc, 0x68, 0x3f, 0x92, 0xbd, 0xb7, 0x0b, 0xb7, 0xb5, 0x24, 0xdf, 0xc5, 0x67, 0x53, 0xd4, 0x36, 0x79, 0xc4, 0x7b, 0x57, 0xbc, 0x99, 0x97, 0x60, 0xef, 0xe4, 0x01, 0xa1, 0xa7, 0xaa, 0x12, 0x36, 0x29, 0xb1, 0x03, 0xc2, 0x83, 0x1c, 0x2b, 0x83, 0xef, 0x2e, 0x2c, 0x23, 0x92, 0xfd, 0xd1,
+	/* (2^ 48)P */ 0x94, 0xef, 0x03, 0x59, 0xfa, 0x8a, 0x18, 0x76, 0xee, 0x58, 0x08, 0x4d, 0x44, 0xce, 0xf1, 0x52, 0x33, 0x49, 0xf6, 0x69, 0x71, 0xe3, 0xa9, 0xbc, 0x86, 0xe3, 0x43, 0xde, 0x33, 0x7b, 0x90, 0x8b, 0x3e, 0x7d, 0xd5, 0x4a, 0xf0, 0x23, 0x99, 0xa6, 0xea, 0x5f, 0x08, 0xe5, 0xb9, 0x49, 0x8b, 0x0d, 0x6a, 0x21, 0xab, 0x07, 0x62, 0xcd, 0xc4, 0xbe,
+	/* (2^ 49)P */ 0x61, 0xbf, 0x70, 0x14, 0xfa, 0x4e, 0x9e, 0x7c, 0x0c, 0xf8, 0xb2, 0x48, 0x71, 0x62, 0x83, 0xd6, 0xd1, 0xdc, 0x9c, 0x29, 0x66, 0xb1, 0x34, 0x9c, 0x8d, 0xe6, 0x88, 0xaf, 0xbe, 0xdc, 0x4d, 0xeb, 0xb0, 0xe7, 0x28, 0xae, 0xb2, 0x05, 0x56, 0xc6, 0x0e, 0x10, 0x26, 0xab, 0x2c, 0x59, 0x72, 0x03, 0x66, 0xfe, 0x8f, 0x2c, 0x51, 0x2d, 0xdc, 0xae,
+	/* (2^ 50)P */ 0xdc, 0x63, 0xf1, 0x8b, 0x5c, 0x65, 0x0b, 0xf1, 0xa6, 0x22, 0xe2, 0xd9, 0xdb, 0x49, 0xb1, 0x3c, 0x47, 0xc2, 0xfe, 0xac, 0x86, 0x07, 0x52, 0xec, 0xb0, 0x08, 0x69, 0xfb, 0xd1, 0x06, 0xdc, 0x48, 0x5c, 0x3d, 0xb2, 0x4d, 0xb8, 0x1a, 0x4e, 0xda, 0xb9, 0xc1, 0x2b, 0xab, 0x4b, 0x62, 0x81, 0x21, 0x9a, 0xfc, 0x3d, 0x39, 0x83, 0x11, 0x36, 0xeb,
+	/* (2^ 51)P */ 0x94, 0xf3, 0x17, 0xef, 0xf9, 0x60, 0x54, 0xc3, 0xd7, 0x27, 0x35, 0xc5, 0x98, 0x5e, 0xf6, 0x63, 0x6c, 0xa0, 0x4a, 0xd3, 0xa3, 0x98, 0xd9, 0x42, 0xe3, 0xf1, 0xf8, 0x81, 0x96, 0xa9, 0xea, 0x6d, 0x4b, 0x8e, 0x33, 0xca, 0x94, 0x0d, 0xa0, 0xf7, 0xbb, 0x64, 0xa3, 0x36, 0x6f, 0xdc, 0x5a, 0x94, 0x42, 0xca, 0x06, 0xb2, 0x2b, 0x9a, 0x9f, 0x71,
+	/* (2^ 52)P */ 0xec, 0xdb, 0xa6, 0x1f, 0xdf, 0x15, 0x36, 0xa3, 0xda, 0x8a, 0x7a, 0xb6, 0xa7, 0xe3, 0xaf, 0x52, 0xe0, 0x8d, 0xe8, 0xf2, 0x44, 0x20, 0xeb, 0xa1, 0x20, 0xc4, 0x65, 0x3c, 0x7c, 0x6c, 0x49, 0xed, 0x2f, 0x66, 0x23, 0x68, 0x61, 0x91, 0x40, 0x9f, 0x50, 0x19, 0xd1, 0x84, 0xa7, 0xe2, 0xed, 0x34, 0x37, 0xe3, 0xe4, 0x11, 0x7f, 0x87, 0x55, 0x0f,
+	/* (2^ 53)P */ 0xb3, 0xa1, 0x0f, 0xb0, 0x48, 0xc0, 0x4d, 0x96, 0xa7, 0xcf, 0x5a, 0x81, 0xb8, 0x4a, 0x46, 0xef, 0x0a, 0xd3, 0x40, 0x7e, 0x02, 0xe3, 0x63, 0xaa, 0x50, 0xd1, 0x2a, 0x37, 0x22, 0x4a, 0x7f, 0x4f, 0xb6, 0xf9, 0x01, 0x82, 0x78, 0x3d, 0x93, 0x14, 0x11, 0x8a, 0x90, 0x60, 0xcd, 0x45, 0x4e, 0x7b, 0x42, 0xb9, 0x3e, 0x6e, 0x68, 0x1f, 0x36, 0x41,
+	/* (2^ 54)P */ 0x13, 0x73, 0x0e, 0x4f, 0x79, 0x93, 0x9e, 0x29, 0x70, 0x7b, 0x4a, 0x59, 0x1a, 0x9a, 0xf4, 0x55, 0x08, 0xf0, 0xdb, 0x17, 0x58, 0xec, 0x64, 0xad, 0x7f, 0x29, 0xeb, 0x3f, 0x85, 0x4e, 0x60, 0x28, 0x98, 0x1f, 0x73, 0x4e, 0xe6, 0xa8, 0xab, 0xd5, 0xd6, 0xfc, 0xa1, 0x36, 0x6d, 0x15, 0xc6, 0x13, 0x83, 0xa0, 0xc2, 0x6e, 0xd9, 0xdb, 0xc9, 0xcc,
+	/* (2^ 55)P */ 0xff, 0xd8, 0x52, 0xa3, 0xdc, 0x99, 0xcf, 0x3e, 0x19, 0xb3, 0x68, 0xd0, 0xb5, 0x0d, 0xb8, 0xee, 0x3f, 0xef, 0x6e, 0xc0, 0x38, 0x28, 0x44, 0x92, 0x78, 0x91, 0x1a, 0x08, 0x78, 0x6c, 0x65, 0x24, 0xf3, 0xa2, 0x3d, 0xf2, 0xe5, 0x79, 0x62, 0x69, 0x29, 0xf4, 0x22, 0xc5, 0xdb, 0x6a, 0xae, 0xf4, 0x44, 0xa3, 0x6f, 0xc7, 0x86, 0xab, 0xef, 0xef,
+	/* (2^ 56)P */ 0xbf, 0x54, 0x9a, 0x09, 0x5d, 0x17, 0xd0, 0xde, 0xfb, 0xf5, 0xca, 0xff, 0x13, 0x20, 0x88, 0x82, 0x3a, 0xe2, 0xd0, 0x3b, 0xfb, 0x05, 0x76, 0xd1, 0xc0, 0x02, 0x71, 0x3b, 0x94, 0xe8, 0xc9, 0x84, 0xcf, 0xa4, 0xe9, 0x28, 0x7b, 0xf5, 0x09, 0xc3, 0x2b, 0x22, 0x40, 0xf1, 0x68, 0x24, 0x24, 0x7d, 0x9f, 0x6e, 0xcd, 0xfe, 0xb0, 0x19, 0x61, 0xf5,
+	/* (2^ 57)P */ 0xe8, 0x63, 0x51, 0xb3, 0x95, 0x6b, 0x7b, 0x74, 0x92, 0x52, 0x45, 0xa4, 0xed, 0xea, 0x0e, 0x0d, 0x2b, 0x01, 0x1e, 0x2c, 0xbc, 0x91, 0x06, 0x69, 0xdb, 0x1f, 0xb5, 0x77, 0x1d, 0x56, 0xf5, 0xb4, 0x02, 0x80, 0x49, 0x56, 0x12, 0xce, 0x86, 0x05, 0xc9, 0xd9, 0xae, 0xf3, 0x6d, 0xe6, 0x3f, 0x40, 0x52, 0xe9, 0x49, 0x2b, 0x31, 0x06, 0x86, 0x14,
+	/* (2^ 58)P */ 0xf5, 0x09, 0x3b, 0xd2, 0xff, 0xdf, 0x11, 0xa5, 0x1c, 0x99, 0xe8, 0x1b, 0xa4, 0x2c, 0x7d, 0x8e, 0xc8, 0xf7, 0x03, 0x46, 0xfa, 0xb6, 0xde, 0x73, 0x91, 0x7e, 0x5a, 0x7a, 0xd7, 0x9a, 0x5b, 0x80, 0x24, 0x62, 0x5e, 0x92, 0xf1, 0xa3, 0x45, 0xa3, 0x43, 0x92, 0x8a, 0x2a, 0x5b, 0x0c, 0xb4, 0xc8, 0xad, 0x1c, 0xb6, 0x6c, 0x5e, 0x81, 0x18, 0x91,
+	/* (2^ 59)P */ 0x96, 0xb3, 0xca, 0x2b, 0xe3, 0x7a, 0x59, 0x72, 0x17, 0x74, 0x29, 0x21, 0xe7, 0x78, 0x07, 0xad, 0xda, 0xb6, 0xcd, 0xf9, 0x27, 0x4d, 0xc8, 0xf2, 0x98, 0x22, 0xca, 0xf2, 0x33, 0x74, 0x7a, 0xdd, 0x1e, 0x71, 0xec, 0xe3, 0x3f, 0xe2, 0xa2, 0xd2, 0x38, 0x75, 0xb0, 0xd0, 0x0a, 0xcf, 0x7d, 0x36, 0xdc, 0x49, 0x38, 0x25, 0x34, 0x4f, 0x20, 0x9a,
+	/* (2^ 60)P */ 0x2b, 0x6e, 0x04, 0x0d, 0x4f, 0x3d, 0x3b, 0x24, 0xf6, 0x4e, 0x5e, 0x0a, 0xbd, 0x48, 0x96, 0xba, 0x81, 0x8f, 0x39, 0x82, 0x13, 0xe6, 0x72, 0xf3, 0x0f, 0xb6, 0x94, 0xf4, 0xc5, 0x90, 0x74, 0x91, 0xa8, 0xf2, 0xc9, 0xca, 0x9a, 0x4d, 0x98, 0xf2, 0xdf, 0x52, 0x4e, 0x97, 0x2f, 0xeb, 0x84, 0xd3, 0xaf, 0xc2, 0xcc, 0xfb, 0x4c, 0x26, 0x4b, 0xe4,
+	/* (2^ 61)P */ 0x12, 0x9e, 0xfb, 0x9d, 0x78, 0x79, 0x99, 0xdd, 0xb3, 0x0b, 0x2e, 0x56, 0x41, 0x8e, 0x3f, 0x39, 0xb8, 0x97, 0x89, 0x53, 0x9b, 0x8a, 0x3c, 0x40, 0x9d, 0xa4, 0x6c, 0x2e, 0x31, 0x71, 0xc6, 0x0a, 0x41, 0xd4, 0x95, 0x06, 0x5e, 0xc1, 0xab, 0xc2, 0x14, 0xc4, 0xc7, 0x15, 0x08, 0x3a, 0xad, 0x7a, 0xb4, 0x62, 0xa3, 0x0c, 0x90, 0xf4, 0x47, 0x08,
+	/* (2^ 62)P */ 0x7f, 0xec, 0x09, 0x82, 0xf5, 0x94, 0x09, 0x93, 0x32, 0xd3, 0xdc, 0x56, 0x80, 0x7b, 0x5b, 0x22, 0x80, 0x6a, 0x96, 0x72, 0xb1, 0xc2, 0xd9, 0xa1, 0x8b, 0x66, 0x42, 0x16, 0xe2, 0x07, 0xb3, 0x2d, 0xf1, 0x75, 0x35, 0x72, 0xc7, 0x98, 0xbe, 0x63, 0x3b, 0x20, 0x75, 0x05, 0xc1, 0x3e, 0x31, 0x5a, 0xf7, 0xaa, 0xae, 0x4b, 0xdb, 0x1d, 0xd0, 0x74,
+	/* (2^ 63)P */ 0x36, 0x5c, 0x74, 0xe6, 0x5d, 0x59, 0x3f, 0x15, 0x4b, 0x4d, 0x4e, 0x67, 0x41, 0xfe, 0x98, 0x1f, 0x49, 0x76, 0x91, 0x0f, 0x9b, 0xf4, 0xaf, 0x86, 0xaf, 0x66, 0x19, 0xed, 0x46, 0xf1, 0x05, 0x9a, 0xcc, 0xd1, 0x14, 0x1f, 0x82, 0x12, 0x8e, 0xe6, 0xf4, 0xc3, 0x42, 0x5c, 0x4e, 0x33, 0x93, 0xbe, 0x30, 0xe7, 0x64, 0xa9, 0x35, 0x00, 0x4d, 0xf9,
+	/* (2^ 64)P */ 0x1f, 0xc1, 0x1e, 0xb7, 0xe3, 0x7c, 0xfa, 0xa3, 0x6b, 0x76, 0xaf, 0x9c, 0x05, 0x85, 0x4a, 0xa9, 0xfb, 0xe3, 0x7e, 0xf2, 0x49, 0x56, 0xdc, 0x2f, 0x57, 0x10, 0xba, 0x37, 0xb2, 0x62, 0xf5, 0x6b, 0xe5, 0x8f, 0x0a, 0x87, 0xd1, 0x6a, 0xcb, 0x9d, 0x07, 0xd0, 0xf6, 0x38, 0x99, 0x2c, 0x61, 0x4a, 0x4e, 0xd8, 0xd2, 0x88, 0x29, 0x99, 0x11, 0x95,
+	/* (2^ 65)P */ 0x6f, 0xdc, 0xd5, 0xd6, 0xd6, 0xa7, 0x4c, 0x46, 0x93, 0x65, 0x62, 0x23, 0x95, 0x32, 0x9c, 0xde, 0x40, 0x41, 0x68, 0x2c, 0x18, 0x4e, 0x5a, 0x8c, 0xc0, 0xc5, 0xc5, 0xea, 0x5c, 0x45, 0x0f, 0x60, 0x78, 0x39, 0xb6, 0x36, 0x23, 0x12, 0xbc, 0x21, 0x9a, 0xf8, 0x91, 0xac, 0xc4, 0x70, 0xdf, 0x85, 0x8e, 0x3c, 0xec, 0x22, 0x04, 0x98, 0xa8, 0xaa,
+	/* (2^ 66)P */ 0xcc, 0x52, 0x10, 0x5b, 0x4b, 0x6c, 0xc5, 0xfa, 0x3e, 0xd4, 0xf8, 0x1c, 0x04, 0x14, 0x48, 0x33, 0xd9, 0xfc, 0x5f, 0xb0, 0xa5, 0x48, 0x8c, 0x45, 0x8a, 0xee, 0x3e, 0xa7, 0xc1, 0x2e, 0x34, 0xca, 0xf6, 0xc9, 0xeb, 0x10, 0xbb, 0xe1, 0x59, 0x84, 0x25, 0xe8, 0x81, 0x70, 0xc0, 0x09, 0x42, 0xa7, 0x3b, 0x0d, 0x33, 0x00, 0xb5, 0x77, 0xbe, 0x25,
+	/* (2^ 67)P */ 0xcd, 0x1f, 0xbc, 0x7d, 0xef, 0xe5, 0xca, 0x91, 0xaf, 0xa9, 0x59, 0x6a, 0x09, 0xca, 0xd6, 0x1b, 0x3d, 0x55, 0xde, 0xa2, 0x6a, 0x80, 0xd6, 0x95, 0x47, 0xe4, 0x5f, 0x68, 0x54, 0x08, 0xdf, 0x29, 0xba, 0x2a, 0x02, 0x84, 0xe8, 0xe9, 0x00, 0x77, 0x99, 0x36, 0x03, 0xf6, 0x4a, 0x3e, 0x21, 0x81, 0x7d, 0xb8, 0xa4, 0x8a, 0xa2, 0x05, 0xef, 0xbc,
+	/* (2^ 68)P */ 0x7c, 0x59, 0x5f, 0x66, 0xd9, 0xb7, 0x83, 0x43, 0x8a, 0xa1, 0x8d, 0x51, 0x70, 0xba, 0xf2, 0x9b, 0x95, 0xc0, 0x4b, 0x4c, 0xa0, 0x14, 0xd3, 0xa4, 0x5d, 0x4a, 0x37, 0x36, 0x97, 0x31, 0x1e, 0x12, 0xe7, 0xbb, 0x08, 0x67, 0xa5, 0x23, 0xd7, 0xfb, 0x97, 0xd8, 0x6a, 0x03, 0xb1, 0xf8, 0x7f, 0xda, 0x58, 0xd9, 0x3f, 0x73, 0x4a, 0x53, 0xe1, 0x7b,
+	/* (2^ 69)P */ 0x55, 0x83, 0x98, 0x78, 0x6c, 0x56, 0x5e, 0xed, 0xf7, 0x23, 0x3e, 0x4c, 0x7d, 0x09, 0x2d, 0x09, 0x9c, 0x58, 0x8b, 0x32, 0xca, 0xfe, 0xbf, 0x47, 0x03, 0xeb, 0x4d, 0xe7, 0xeb, 0x9c, 0x83, 0x05, 0x68, 0xaa, 0x80, 0x89, 0x44, 0xf9, 0xd4, 0xdc, 0xdb, 0xb1, 0xdb, 0x77, 0xac, 0xf9, 0x2a, 0xae, 0x35, 0xac, 0x74, 0xb5, 0x95, 0x62, 0x18, 0x85,
+	/* (2^ 70)P */ 0xab, 0x82, 0x7e, 0x10, 0xd7, 0xe6, 0x57, 0xd1, 0x66, 0x12, 0x31, 0x9c, 0x9c, 0xa6, 0x27, 0x59, 0x71, 0x2e, 0xeb, 0xa0, 0x68, 0xc5, 0x87, 0x51, 0xf4, 0xca, 0x3f, 0x98, 0x56, 0xb0, 0x89, 0xb1, 0xc7, 0x7b, 0x46, 0xb3, 0xae, 0x36, 0xf2, 0xee, 0x15, 0x1a, 0x60, 0xf4, 0x50, 0x76, 0x4f, 0xc4, 0x53, 0x0d, 0x36, 0x4d, 0x31, 0xb1, 0x20, 0x51,
+	/* (2^ 71)P */ 0xf7, 0x1d, 0x8c, 0x1b, 0x5e, 0xe5, 0x02, 0x6f, 0xc5, 0xa5, 0xe0, 0x5f, 0xc6, 0xb6, 0x63, 0x43, 0xaf, 0x3c, 0x19, 0x6c, 0xf4, 0xaf, 0xa4, 0x33, 0xb1, 0x0a, 0x37, 0x3d, 0xd9, 0x4d, 0xe2, 0x29, 0x24, 0x26, 0x94, 0x7c, 0x02, 0xe4, 0xe2, 0xf2, 0xbe, 0xbd, 0xac, 0x1b, 0x48, 0xb8, 0xdd, 0xe9, 0x0d, 0x9a, 0x50, 0x1a, 0x98, 0x71, 0x6e, 0xdc,
+	/* (2^ 72)P */ 0x9f, 0x40, 0xb1, 0xb3, 0x66, 0x28, 0x6c, 0xfe, 0xa6, 0x7d, 0xf8, 0x3e, 0xb8, 0xf3, 0xde, 0x52, 0x76, 0x52, 0xa3, 0x92, 0x98, 0x23, 0xab, 0x4f, 0x88, 0x97, 0xfc, 0x22, 0xe1, 0x6b, 0x67, 0xcd, 0x13, 0x95, 0xda, 0x65, 0xdd, 0x3b, 0x67, 0x3f, 0x5f, 0x4c, 0xf2, 0x8a, 0xad, 0x98, 0xa7, 0x94, 0x24, 0x45, 0x87, 0x11, 0x7c, 0x75, 0x79, 0x85,
+	/* (2^ 73)P */ 0x70, 0xbf, 0xf9, 0x3b, 0xa9, 0x44, 0x57, 0x72, 0x96, 0xc9, 0xa4, 0x98, 0x65, 0xbf, 0x87, 0xb3, 0x3a, 0x39, 0x12, 0xde, 0xe5, 0x39, 0x01, 0x4f, 0xf7, 0xc0, 0x71, 0x52, 0x36, 0x85, 0xb3, 0x18, 0xf8, 0x14, 0xc0, 0x6d, 0xae, 0x9e, 0x4f, 0xb0, 0x72, 0x87, 0xac, 0x5c, 0xd1, 0x6c, 0x41, 0x6c, 0x90, 0x9d, 0x22, 0x81, 0xe4, 0x2b, 0xea, 0xe5,
+	/* (2^ 74)P */ 0xfc, 0xea, 0x1a, 0x65, 0xd9, 0x49, 0x6a, 0x39, 0xb5, 0x96, 0x72, 0x7b, 0x32, 0xf1, 0xd0, 0xe9, 0x45, 0xd9, 0x31, 0x55, 0xc7, 0x34, 0xe9, 0x5a, 0xec, 0x73, 0x0b, 0x03, 0xc4, 0xb3, 0xe6, 0xc9, 0x5e, 0x0a, 0x17, 0xfe, 0x53, 0x66, 0x7f, 0x21, 0x18, 0x74, 0x54, 0x1b, 0xc9, 0x49, 0x16, 0xd2, 0x48, 0xaf, 0x5b, 0x47, 0x7b, 0xeb, 0xaa, 0xc9,
+	/* (2^ 75)P */ 0x47, 0x04, 0xf5, 0x5a, 0x87, 0x77, 0x9e, 0x21, 0x34, 0x4e, 0x83, 0x88, 0xaf, 0x02, 0x1d, 0xb0, 0x5a, 0x1d, 0x1d, 0x7d, 0x8d, 0x2c, 0xd3, 0x8d, 0x63, 0xa9, 0x45, 0xfb, 0x15, 0x6d, 0x86, 0x45, 0xcd, 0x38, 0x0e, 0xf7, 0x37, 0x79, 0xed, 0x6d, 0x5a, 0xbc, 0x32, 0xcc, 0x66, 0xf1, 0x3a, 0xb2, 0x87, 0x6f, 0x70, 0x71, 0xd9, 0xf2, 0xfa, 0x7b,
+	/* (2^ 76)P */ 0x68, 0x07, 0xdc, 0x61, 0x40, 0xe4, 0xec, 0x32, 0xc8, 0xbe, 0x66, 0x30, 0x54, 0x80, 0xfd, 0x13, 0x7a, 0xef, 0xae, 0xed, 0x2e, 0x00, 0x6d, 0x3f, 0xbd, 0xfc, 0x91, 0x24, 0x53, 0x7f, 0x63, 0x9d, 0x2e, 0xe3, 0x76, 0xe0, 0xf3, 0xe1, 0x8f, 0x7a, 0xc4, 0x77, 0x0c, 0x91, 0xc0, 0xc2, 0x18, 0x6b, 0x04, 0xad, 0xb6, 0x70, 0x9a, 0x64, 0xc5, 0x82,
+	/* (2^ 77)P */ 0x7f, 0xea, 0x13, 0xd8, 0x9e, 0xfc, 0x5b, 0x06, 0xb5, 0x4f, 0xda, 0x38, 0xe0, 0x9c, 0xd2, 0x3a, 0xc1, 0x1c, 0x62, 0x70, 0x7f, 0xc6, 0x24, 0x0a, 0x47, 0x04, 0x01, 0xc4, 0x55, 0x09, 0xd1, 0x7a, 0x07, 0xba, 0xa3, 0x80, 0x4f, 0xc1, 0x65, 0x36, 0x6d, 0xc0, 0x10, 0xcf, 0x94, 0xa9, 0xa2, 0x01, 0x44, 0xd1, 0xf9, 0x1c, 0x4c, 0xfb, 0xf8, 0x99,
+	/* (2^ 78)P */ 0x6c, 0xb9, 0x6b, 0xee, 0x43, 0x5b, 0xb9, 0xbb, 0xee, 0x2e, 0x52, 0xc1, 0xc6, 0xb9, 0x61, 0xd2, 0x93, 0xa5, 0xaf, 0x52, 0xf4, 0xa4, 0x1a, 0x51, 0x61, 0xa7, 0xcb, 0x9e, 0xbb, 0x56, 0x65, 0xe2, 0xbf, 0x75, 0xb9, 0x9c, 0x50, 0x96, 0x60, 0x81, 0x74, 0x47, 0xc0, 0x04, 0x88, 0x71, 0x76, 0x39, 0x9a, 0xa7, 0xb1, 0x4e, 0x43, 0x15, 0xe0, 0xbb,
+	/* (2^ 79)P */ 0xbb, 0xce, 0xe2, 0xbb, 0xf9, 0x17, 0x0f, 0x82, 0x40, 0xad, 0x73, 0xe3, 0xeb, 0x3b, 0x06, 0x1a, 0xcf, 0x8e, 0x6e, 0x28, 0xb8, 0x26, 0xd9, 0x5b, 0xb7, 0xb3, 0xcf, 0xb4, 0x6a, 0x1c, 0xbf, 0x7f, 0xb8, 0xb5, 0x79, 0xcf, 0x45, 0x68, 0x7d, 0xc5, 0xeb, 0xf3, 0xbe, 0x39, 0x40, 0xfc, 0x07, 0x90, 0x7a, 0x62, 0xad, 0x86, 0x08, 0x71, 0x25, 0xe1,
+	/* (2^ 80)P */ 0x9b, 0x46, 0xac, 0xef, 0xc1, 0x4e, 0xa1, 0x97, 0x95, 0x76, 0xf9, 0x1b, 0xc2, 0xb2, 0x6a, 0x41, 0xea, 0x80, 0x3d, 0xe9, 0x08, 0x52, 0x5a, 0xe3, 0xf2, 0x08, 0xc5, 0xea, 0x39, 0x3f, 0x44, 0x71, 0x4d, 0xea, 0x0d, 0x05, 0x23, 0xe4, 0x2e, 0x3c, 0x89, 0xfe, 0x12, 0x8a, 0x95, 0x42, 0x0a, 0x68, 0xea, 0x5a, 0x28, 0x06, 0x9e, 0xe3, 0x5f, 0xe0,
+	/* (2^ 81)P */ 0x00, 0x61, 0x6c, 0x98, 0x9b, 0xe7, 0xb9, 0x06, 0x1c, 0xc5, 0x1b, 0xed, 0xbe, 0xc8, 0xb3, 0xea, 0x87, 0xf0, 0xc4, 0x24, 0x7d, 0xbb, 0x5d, 0xa4, 0x1d, 0x7a, 0x16, 0x00, 0x55, 0x94, 0x67, 0x78, 0xbd, 0x58, 0x02, 0x82, 0x90, 0x53, 0x76, 0xd4, 0x72, 0x99, 0x51, 0x6f, 0x7b, 0xcf, 0x80, 0x30, 0x31, 0x3b, 0x01, 0xc7, 0xc1, 0xef, 0xe6, 0x42,
+	/* (2^ 82)P */ 0xe2, 0x35, 0xaf, 0x4b, 0x79, 0xc6, 0x12, 0x24, 0x99, 0xc0, 0x68, 0xb0, 0x43, 0x3e, 0xe5, 0xef, 0xe2, 0x29, 0xea, 0xb8, 0xb3, 0xbc, 0x6a, 0x53, 0x2c, 0x69, 0x18, 0x5a, 0xf9, 0x15, 0xae, 0x66, 0x58, 0x18, 0xd3, 0x2d, 0x4b, 0x00, 0xfd, 0x84, 0xab, 0x4f, 0xae, 0x70, 0x6b, 0x9e, 0x9a, 0xdf, 0x83, 0xfd, 0x2e, 0x3c, 0xcf, 0xf8, 0x88, 0x5b,
+	/* (2^ 83)P */ 0xa4, 0x90, 0x31, 0x85, 0x13, 0xcd, 0xdf, 0x64, 0xc9, 0xa1, 0x0b, 0xe7, 0xb6, 0x73, 0x8a, 0x1b, 0x22, 0x78, 0x4c, 0xd4, 0xae, 0x48, 0x18, 0x00, 0x00, 0xa8, 0x9f, 0x06, 0xf9, 0xfb, 0x2d, 0xc3, 0xb1, 0x2a, 0xbc, 0x13, 0x99, 0x57, 0xaf, 0xf0, 0x8d, 0x61, 0x54, 0x29, 0xd5, 0xf2, 0x72, 0x00, 0x96, 0xd1, 0x85, 0x12, 0x8a, 0xf0, 0x23, 0xfb,
+	/* (2^ 84)P */ 0x69, 0xc7, 0xdb, 0xd9, 0x92, 0x75, 0x08, 0x9b, 0xeb, 0xa5, 0x93, 0xd1, 0x1a, 0xf4, 0xf5, 0xaf, 0xe6, 0xc4, 0x4a, 0x0d, 0x35, 0x26, 0x39, 0x9d, 0xd3, 0x17, 0x3e, 0xae, 0x2d, 0xbf, 0x73, 0x9f, 0xb7, 0x74, 0x91, 0xd1, 0xd8, 0x5c, 0x14, 0xf9, 0x75, 0xdf, 0xeb, 0xc2, 0x22, 0xd8, 0x14, 0x8d, 0x86, 0x23, 0x4d, 0xd1, 0x2d, 0xdb, 0x6b, 0x42,
+	/* (2^ 85)P */ 0x8c, 0xda, 0xc6, 0xf8, 0x71, 0xba, 0x2b, 0x06, 0x78, 0xae, 0xcc, 0x3a, 0xe3, 0xe3, 0xa1, 0x8b, 0xe2, 0x34, 0x6d, 0x28, 0x9e, 0x46, 0x13, 0x4d, 0x9e, 0xa6, 0x73, 0x49, 0x65, 0x79, 0x88, 0xb9, 0x3a, 0xd1, 0x6d, 0x2f, 0x48, 0x2b, 0x0a, 0x7f, 0x58, 0x20, 0x37, 0xf4, 0x0e, 0xbb, 0x4a, 0x95, 0x58, 0x0c, 0x88, 0x30, 0xc4, 0x74, 0xdd, 0xfd,
+	/* (2^ 86)P */ 0x6d, 0x13, 0x4e, 0x89, 0x2d, 0xa9, 0xa3, 0xed, 0x09, 0xe3, 0x0e, 0x71, 0x3e, 0x4a, 0xab, 0x90, 0xde, 0x03, 0xeb, 0x56, 0x46, 0x60, 0x06, 0xf5, 0x71, 0xe5, 0xee, 0x9b, 0xef, 0xff, 0xc4, 0x2c, 0x9f, 0x37, 0x48, 0x45, 0x94, 0x12, 0x41, 0x81, 0x15, 0x70, 0x91, 0x99, 0x5e, 0x56, 0x6b, 0xf4, 0xa6, 0xc9, 0xf5, 0x69, 0x9d, 0x78, 0x37, 0x57,
+	/* (2^ 87)P */ 0xf3, 0x51, 0x57, 0x7e, 0x43, 0x6f, 0xc6, 0x67, 0x59, 0x0c, 0xcf, 0x94, 0xe6, 0x3d, 0xb5, 0x07, 0xc9, 0x77, 0x48, 0xc9, 0x68, 0x0d, 0x98, 0x36, 0x62, 0x35, 0x38, 0x1c, 0xf5, 0xc5, 0xec, 0x66, 0x78, 0xfe, 0x47, 0xab, 0x26, 0xd6, 0x44, 0xb6, 0x06, 0x0f, 0x89, 0xe3, 0x19, 0x40, 0x1a, 0xe7, 0xd8, 0x65, 0x55, 0xf7, 0x1a, 0xfc, 0xa3, 0x0e,
+	/* (2^ 88)P */ 0x0e, 0x30, 0xa6, 0xb7, 0x58, 0x60, 0x62, 0x2a, 0x6c, 0x13, 0xa8, 0x14, 0x9b, 0xb8, 0xf2, 0x70, 0xd8, 0xb1, 0x71, 0x88, 0x8c, 0x18, 0x31, 0x25, 0x93, 0x90, 0xb4, 0xc7, 0x49, 0xd8, 0xd4, 0xdb, 0x1e, 0x1e, 0x7f, 0xaa, 0xba, 0xc9, 0xf2, 0x5d, 0xa9, 0x3a, 0x43, 0xb4, 0x5c, 0xee, 0x7b, 0xc7, 0x97, 0xb7, 0x66, 0xd7, 0x23, 0xd9, 0x22, 0x59,
+	/* (2^ 89)P */ 0x28, 0x19, 0xa6, 0xf9, 0x89, 0x20, 0x78, 0xd4, 0x6d, 0xcb, 0x79, 0x8f, 0x61, 0x6f, 0xb2, 0x5c, 0x4f, 0xa6, 0x54, 0x84, 0x95, 0x24, 0x36, 0x64, 0xcb, 0x39, 0xe7, 0x8f, 0x97, 0x9c, 0x5c, 0x3c, 0xfb, 0x51, 0x11, 0x01, 0x17, 0xdb, 0xc9, 0x9b, 0x51, 0x03, 0x9a, 0xe9, 0xe5, 0x24, 0x1e, 0xf5, 0xda, 0xe0, 0x48, 0x02, 0x23, 0xd0, 0x2c, 0x81,
+	/* (2^ 90)P */ 0x42, 0x1b, 0xe4, 0x91, 0x85, 0x2a, 0x0c, 0xd2, 0x28, 0x66, 0x57, 0x9e, 0x33, 0x8d, 0x25, 0x71, 0x10, 0x65, 0x76, 0xa2, 0x8c, 0x21, 0x86, 0x81, 0x15, 0xc2, 0x27, 0xeb, 0x54, 0x2d, 0x4f, 0x6c, 0xe6, 0xd6, 0x24, 0x9c, 0x1a, 0x12, 0xb8, 0x81, 0xe2, 0x0a, 0xf3, 0xd3, 0xf0, 0xd3, 0xe1, 0x74, 0x1f, 0x9b, 0x11, 0x47, 0xd0, 0xcf, 0xb6, 0x54,
+	/* (2^ 91)P */ 0x26, 0x45, 0xa2, 0x10, 0xd4, 0x2d, 0xae, 0xc0, 0xb0, 0xe8, 0x86, 0xb3, 0xc7, 0xea, 0x70, 0x87, 0x61, 0xb5, 0xa5, 0x55, 0xbe, 0x88, 0x1d, 0x7a, 0xd9, 0x6f, 0xeb, 0x83, 0xe2, 0x44, 0x7f, 0x98, 0x04, 0xd6, 0x50, 0x9d, 0xa7, 0x86, 0x66, 0x09, 0x63, 0xe1, 0xed, 0x72, 0xb1, 0xe4, 0x1d, 0x3a, 0xfd, 0x47, 0xce, 0x1c, 0xaa, 0x3b, 0x8f, 0x1b,
+	/* (2^ 92)P */ 0xf4, 0x3c, 0x4a, 0xb6, 0xc2, 0x9c, 0xe0, 0x2e, 0xb7, 0x38, 0xea, 0x61, 0x35, 0x97, 0x10, 0x90, 0xae, 0x22, 0x48, 0xb3, 0xa9, 0xc6, 0x7a, 0xbb, 0x23, 0xf2, 0xf8, 0x1b, 0xa7, 0xa1, 0x79, 0xcc, 0xc4, 0xf8, 0x08, 0x76, 0x8a, 0x5a, 0x1c, 0x1b, 0xc5, 0x33, 0x91, 0xa9, 0xb8, 0xb9, 0xd3, 0xf8, 0x49, 0xcd, 0xe5, 0x82, 0x43, 0xf7, 0xca, 0x68,
+	/* (2^ 93)P */ 0x38, 0xba, 0xae, 0x44, 0xfe, 0x57, 0x64, 0x56, 0x7c, 0x0e, 0x9c, 0xca, 0xff, 0xa9, 0x82, 0xbb, 0x38, 0x4a, 0xa7, 0xf7, 0x47, 0xab, 0xbe, 0x6d, 0x23, 0x0b, 0x8a, 0xed, 0xc2, 0xb9, 0x8f, 0xf1, 0xec, 0x91, 0x44, 0x73, 0x64, 0xba, 0xd5, 0x8f, 0x37, 0x38, 0x0d, 0xd5, 0xf8, 0x73, 0x57, 0xb6, 0xc2, 0x45, 0xdc, 0x25, 0xb2, 0xb6, 0xea, 0xd9,
+	/* (2^ 94)P */ 0xbf, 0xe9, 0x1a, 0x40, 0x4d, 0xcc, 0xe6, 0x1d, 0x70, 0x1a, 0x65, 0xcc, 0x34, 0x2c, 0x37, 0x2c, 0x2d, 0x6b, 0x6d, 0xe5, 0x2f, 0x19, 0x9e, 0xe4, 0xe1, 0xaa, 0xd4, 0xab, 0x54, 0xf4, 0xa8, 0xe4, 0x69, 0x2d, 0x8e, 0x4d, 0xd7, 0xac, 0xb0, 0x5b, 0xfe, 0xe3, 0x26, 0x07, 0xc3, 0xf8, 0x1b, 0x43, 0xa8, 0x1d, 0x64, 0xa5, 0x25, 0x88, 0xbb, 0x77,
+	/* (2^ 95)P */ 0x92, 0xcd, 0x6e, 0xa0, 0x79, 0x04, 0x18, 0xf4, 0x11, 0x58, 0x48, 0xb5, 0x3c, 0x7b, 0xd1, 0xcc, 0xd3, 0x14, 0x2c, 0xa0, 0xdd, 0x04, 0x44, 0x11, 0xb3, 0x6d, 0x2f, 0x0d, 0xf5, 0x2a, 0x75, 0x5d, 0x1d, 0xda, 0x86, 0x8d, 0x7d, 0x6b, 0x32, 0x68, 0xb6, 0x6c, 0x64, 0x9e, 0xde, 0x80, 0x88, 0xce, 0x08, 0xbf, 0x0b, 0xe5, 0x8e, 0x4f, 0x1d, 0xfb,
+	/* (2^ 96)P */ 0xaf, 0xe8, 0x85, 0xbf, 0x7f, 0x37, 0x8d, 0x66, 0x7c, 0xd5, 0xd3, 0x96, 0xa5, 0x81, 0x67, 0x95, 0xff, 0x48, 0xde, 0xde, 0xd7, 0x7a, 0x46, 0x34, 0xb1, 0x13, 0x70, 0x29, 0xed, 0x87, 0x90, 0xb0, 0x40, 0x2c, 0xa6, 0x43, 0x6e, 0xb6, 0xbc, 0x48, 0x8a, 0xc1, 0xae, 0xb8, 0xd4, 0xe2, 0xc0, 0x32, 0xb2, 0xa6, 0x2a, 0x8f, 0xb5, 0x16, 0x9e, 0xc3,
+	/* (2^ 97)P */ 0xff, 0x4d, 0xd2, 0xd6, 0x74, 0xef, 0x2c, 0x96, 0xc1, 0x11, 0xa8, 0xb8, 0xfe, 0x94, 0x87, 0x3e, 0xa0, 0xfb, 0x57, 0xa3, 0xfc, 0x7a, 0x7e, 0x6a, 0x59, 0x6c, 0x54, 0xbb, 0xbb, 0xa2, 0x25, 0x38, 0x1b, 0xdf, 0x5d, 0x7b, 0x94, 0x14, 0xde, 0x07, 0x6e, 0xd3, 0xab, 0x02, 0x26, 0x74, 0x16, 0x12, 0xdf, 0x2e, 0x2a, 0xa7, 0xb0, 0xe8, 0x29, 0xc0,
+	/* (2^ 98)P */ 0x6a, 0x38, 0x0b, 0xd3, 0xba, 0x45, 0x23, 0xe0, 0x04, 0x3b, 0x83, 0x39, 0xc5, 0x11, 0xe6, 0xcf, 0x39, 0x0a, 0xb3, 0xb0, 0x3b, 0x27, 0x29, 0x63, 0x1c, 0xf3, 0x00, 0xe6, 0xd2, 0x55, 0x21, 0x1f, 0x84, 0x97, 0x9f, 0x01, 0x49, 0x43, 0x30, 0x5f, 0xe0, 0x1d, 0x24, 0xc4, 0x4e, 0xa0, 0x2b, 0x0b, 0x12, 0x55, 0xc3, 0x27, 0xae, 0x08, 0x83, 0x7c,
+	/* (2^ 99)P */ 0x5d, 0x1a, 0xb7, 0xa9, 0xf5, 0xfd, 0xec, 0xad, 0xb7, 0x87, 0x02, 0x5f, 0x0d, 0x30, 0x4d, 0xe2, 0x65, 0x87, 0xa4, 0x41, 0x45, 0x1d, 0x67, 0xe0, 0x30, 0x5c, 0x13, 0x87, 0xf6, 0x2e, 0x08, 0xc1, 0xc7, 0x12, 0x45, 0xc8, 0x9b, 0xad, 0xb8, 0xd5, 0x57, 0xbb, 0x5c, 0x48, 0x3a, 0xe1, 0x91, 0x5e, 0xf6, 0x4d, 0x8a, 0x63, 0x75, 0x69, 0x0c, 0x01,
+	/* (2^100)P */ 0x8f, 0x53, 0x2d, 0xa0, 0x71, 0x3d, 0xfc, 0x45, 0x10, 0x96, 0xcf, 0x56, 0xf9, 0xbb, 0x40, 0x3c, 0x86, 0x52, 0x76, 0xbe, 0x84, 0xf9, 0xa6, 0x9d, 0x3d, 0x27, 0xbe, 0xb4, 0x00, 0x49, 0x94, 0xf5, 0x5d, 0xe1, 0x62, 0x85, 0x66, 0xe5, 0xb8, 0x20, 0x2c, 0x09, 0x7d, 0x9d, 0x3d, 0x6e, 0x74, 0x39, 0xab, 0xad, 0xa0, 0x90, 0x97, 0x5f, 0xbb, 0xa7,
+	/* (2^101)P */ 0xdb, 0x2d, 0x99, 0x08, 0x16, 0x46, 0x83, 0x7a, 0xa8, 0xea, 0x3d, 0x28, 0x5b, 0x49, 0xfc, 0xb9, 0x6d, 0x00, 0x9e, 0x54, 0x4f, 0x47, 0x64, 0x9b, 0x58, 0x4d, 0x07, 0x0c, 0x6f, 0x29, 0x56, 0x0b, 0x00, 0x14, 0x85, 0x96, 0x41, 0x04, 0xb9, 0x5c, 0xa4, 0xf6, 0x16, 0x73, 0x6a, 0xc7, 0x62, 0x0c, 0x65, 0x2f, 0x93, 0xbf, 0xf7, 0xb9, 0xb7, 0xf1,
+	/* (2^102)P */ 0xeb, 0x6d, 0xb3, 0x46, 0x32, 0xd2, 0xcb, 0x08, 0x94, 0x14, 0xbf, 0x3f, 0xc5, 0xcb, 0x5f, 0x9f, 0x8a, 0x89, 0x0c, 0x1b, 0x45, 0xad, 0x4c, 0x50, 0xb4, 0xe1, 0xa0, 0x6b, 0x11, 0x92, 0xaf, 0x1f, 0x00, 0xcc, 0xe5, 0x13, 0x7e, 0xe4, 0x2e, 0xa0, 0x57, 0xf3, 0xa7, 0x84, 0x79, 0x7a, 0xc2, 0xb7, 0xb7, 0xfc, 0x5d, 0xa5, 0xa9, 0x64, 0xcc, 0xd8,
+	/* (2^103)P */ 0xa9, 0xc4, 0x12, 0x8b, 0x34, 0x78, 0x3e, 0x38, 0xfd, 0x3f, 0x87, 0xfa, 0x88, 0x94, 0xd5, 0xd9, 0x7f, 0xeb, 0x58, 0xff, 0xb9, 0x45, 0xdb, 0xa1, 0xed, 0x22, 0x28, 0x1d, 0x00, 0x6d, 0x79, 0x85, 0x7a, 0x75, 0x5d, 0xf0, 0xb1, 0x9e, 0x47, 0x28, 0x8c, 0x62, 0xdf, 0xfb, 0x4c, 0x7b, 0xc5, 0x1a, 0x42, 0x95, 0xef, 0x9a, 0xb7, 0x27, 0x7e, 0xda,
+	/* (2^104)P */ 0xca, 0xd5, 0xc0, 0x17, 0xa1, 0x66, 0x79, 0x9c, 0x2a, 0xb7, 0x0a, 0xfe, 0x62, 0xe4, 0x26, 0x78, 0x90, 0xa7, 0xcb, 0xb0, 0x4f, 0x6d, 0xf9, 0x8f, 0xf7, 0x7d, 0xac, 0xb8, 0x78, 0x1f, 0x41, 0xea, 0x97, 0x1e, 0x62, 0x97, 0x43, 0x80, 0x58, 0x80, 0xb6, 0x69, 0x7d, 0xee, 0x16, 0xd2, 0xa1, 0x81, 0xd7, 0xb1, 0x27, 0x03, 0x48, 0xda, 0xab, 0xec,
+	/* (2^105)P */ 0x5b, 0xed, 0x40, 0x8e, 0x8c, 0xc1, 0x66, 0x90, 0x7f, 0x0c, 0xb2, 0xfc, 0xbd, 0x16, 0xac, 0x7d, 0x4c, 0x6a, 0xf9, 0xae, 0xe7, 0x4e, 0x11, 0x12, 0xe9, 0xbe, 0x17, 0x09, 0xc6, 0xc1, 0x5e, 0xb5, 0x7b, 0x50, 0x5c, 0x27, 0xfb, 0x80, 0xab, 0x01, 0xfa, 0x5b, 0x9b, 0x75, 0x16, 0x6e, 0xb2, 0x5c, 0x8c, 0x2f, 0xa5, 0x6a, 0x1a, 0x68, 0xa6, 0x90,
+	/* (2^106)P */ 0x75, 0xfe, 0xb6, 0x96, 0x96, 0x87, 0x4c, 0x12, 0xa9, 0xd1, 0xd8, 0x03, 0xa3, 0xc1, 0x15, 0x96, 0xe8, 0xa0, 0x75, 0x82, 0xa0, 0x6d, 0xea, 0x54, 0xdc, 0x5f, 0x0d, 0x7e, 0xf6, 0x70, 0xb5, 0xdc, 0x7a, 0xf6, 0xc4, 0xd4, 0x21, 0x49, 0xf5, 0xd4, 0x14, 0x6d, 0x48, 0x1d, 0x7c, 0x99, 0x42, 0xdf, 0x78, 0x6b, 0x9d, 0xb9, 0x30, 0x3c, 0xd0, 0x29,
+	/* (2^107)P */ 0x85, 0xd6, 0xd8, 0xf3, 0x91, 0x74, 0xdd, 0xbd, 0x72, 0x96, 0x10, 0xe4, 0x76, 0x02, 0x5a, 0x72, 0x67, 0xd3, 0x17, 0x72, 0x14, 0x9a, 0x20, 0x5b, 0x0f, 0x8d, 0xed, 0x6d, 0x4e, 0xe3, 0xd9, 0x82, 0xc2, 0x99, 0xee, 0x39, 0x61, 0x69, 0x8a, 0x24, 0x01, 0x92, 0x15, 0xe7, 0xfc, 0xf9, 0x4d, 0xac, 0xf1, 0x30, 0x49, 0x01, 0x0b, 0x6e, 0x0f, 0x20,
+	/* (2^108)P */ 0xd8, 0x25, 0x94, 0x5e, 0x43, 0x29, 0xf5, 0xcc, 0xe8, 0xe3, 0x55, 0x41, 0x3c, 0x9f, 0x58, 0x5b, 0x00, 0xeb, 0xc5, 0xdf, 0xcf, 0xfb, 0xfd, 0x6e, 0x92, 0xec, 0x99, 0x30, 0xd6, 0x05, 0xdd, 0x80, 0x7a, 0x5d, 0x6d, 0x16, 0x85, 0xd8, 0x9d, 0x43, 0x65, 0xd8, 0x2c, 0x33, 0x2f, 0x5c, 0x41, 0xea, 0xb7, 0x95, 0x77, 0xf2, 0x9e, 0x59, 0x09, 0xe8,
+	/* (2^109)P */ 0x00, 0xa0, 0x03, 0x80, 0xcd, 0x60, 0xe5, 0x17, 0xd4, 0x15, 0x99, 0xdd, 0x4f, 0xbf, 0x66, 0xb8, 0xc0, 0xf5, 0xf9, 0xfc, 0x6d, 0x42, 0x18, 0x34, 0x1c, 0x7d, 0x5b, 0xb5, 0x09, 0xd0, 0x99, 0x57, 0x81, 0x0b, 0x62, 0xb3, 0xa2, 0xf9, 0x0b, 0xae, 0x95, 0xb8, 0xc2, 0x3b, 0x0d, 0x5b, 0x00, 0xf1, 0xed, 0xbc, 0x05, 0x9d, 0x61, 0xbc, 0x73, 0x9d,
+	/* (2^110)P */ 0xd4, 0xdb, 0x29, 0xe5, 0x85, 0xe9, 0xc6, 0x89, 0x2a, 0xa8, 0x54, 0xab, 0xb3, 0x7f, 0x88, 0xc0, 0x4d, 0xe0, 0xd1, 0x74, 0x6e, 0xa3, 0xa7, 0x39, 0xd5, 0xcc, 0xa1, 0x8a, 0xcb, 0x5b, 0x34, 0xad, 0x92, 0xb4, 0xd8, 0xd5, 0x17, 0xf6, 0x77, 0x18, 0x9e, 0xaf, 0x45, 0x3b, 0x03, 0xe2, 0xf8, 0x52, 0x60, 0xdc, 0x15, 0x20, 0x9e, 0xdf, 0xd8, 0x5d,
+	/* (2^111)P */ 0x02, 0xc1, 0xac, 0x1a, 0x15, 0x8e, 0x6c, 0xf5, 0x1e, 0x1e, 0xba, 0x7e, 0xc2, 0xda, 0x7d, 0x02, 0xda, 0x43, 0xae, 0x04, 0x70, 0x28, 0x54, 0x78, 0x94, 0xf5, 0x4f, 0x07, 0x84, 0x8f, 0xed, 0xaa, 0xc0, 0xb8, 0xcd, 0x7f, 0x7e, 0x33, 0xa3, 0xbe, 0x21, 0x29, 0xc8, 0x56, 0x34, 0xc0, 0x76, 0x87, 0x8f, 0xc7, 0x73, 0x58, 0x90, 0x16, 0xfc, 0xd6,
+	/* (2^112)P */ 0xb8, 0x3f, 0xe1, 0xdf, 0x3a, 0x91, 0x25, 0x0c, 0xf6, 0x47, 0xa8, 0x89, 0xc4, 0xc6, 0x61, 0xec, 0x86, 0x2c, 0xfd, 0xbe, 0xa4, 0x6f, 0xc2, 0xd4, 0x46, 0x19, 0x70, 0x5d, 0x09, 0x02, 0x86, 0xd3, 0x4b, 0xe9, 0x16, 0x7b, 0xf0, 0x0d, 0x6c, 0xff, 0x91, 0x05, 0xbf, 0x55, 0xb4, 0x00, 0x8d, 0xe5, 0x6d, 0x68, 0x20, 0x90, 0x12, 0xb5, 0x5c, 0x32,
+	/* (2^113)P */ 0x80, 0x45, 0xc8, 0x51, 0x87, 0xba, 0x1c, 0x5c, 0xcf, 0x5f, 0x4b, 0x3c, 0x9e, 0x3b, 0x36, 0xd2, 0x26, 0xa2, 0x7f, 0xab, 0xb7, 0xbf, 0xda, 0x68, 0x23, 0x8f, 0xc3, 0xa0, 0xfd, 0xad, 0xf1, 0x56, 0x3b, 0xd0, 0x75, 0x2b, 0x44, 0x61, 0xd8, 0xf4, 0xf1, 0x05, 0x49, 0x53, 0x07, 0xee, 0x47, 0xef, 0xc0, 0x7c, 0x9d, 0xe4, 0x15, 0x88, 0xc5, 0x47,
+	/* (2^114)P */ 0x2d, 0xb5, 0x09, 0x80, 0xb9, 0xd3, 0xd8, 0xfe, 0x4c, 0xd2, 0xa6, 0x6e, 0xd3, 0x75, 0xcf, 0xb0, 0x99, 0xcb, 0x50, 0x8d, 0xe9, 0x67, 0x9b, 0x20, 0xe8, 0x57, 0xd8, 0x14, 0x85, 0x73, 0x6a, 0x74, 0xe0, 0x99, 0xf0, 0x6b, 0x6e, 0x59, 0x30, 0x31, 0x33, 0x96, 0x5f, 0xa1, 0x0c, 0x1b, 0xf4, 0xca, 0x09, 0xe1, 0x9b, 0xb5, 0xcf, 0x6d, 0x0b, 0xeb,
+	/* (2^115)P */ 0x1a, 0xde, 0x50, 0xa9, 0xac, 0x3e, 0x10, 0x43, 0x4f, 0x82, 0x4f, 0xc0, 0xfe, 0x3f, 0x33, 0xd2, 0x64, 0x86, 0x50, 0xa9, 0x51, 0x76, 0x5e, 0x50, 0x97, 0x6c, 0x73, 0x8d, 0x77, 0xa3, 0x75, 0x03, 0xbc, 0xc9, 0xfb, 0x50, 0xd9, 0x6d, 0x16, 0xad, 0x5d, 0x32, 0x3d, 0xac, 0x44, 0xdf, 0x51, 0xf7, 0x19, 0xd4, 0x0b, 0x57, 0x78, 0x0b, 0x81, 0x4e,
+	/* (2^116)P */ 0x32, 0x24, 0xf1, 0x6c, 0x55, 0x62, 0x1d, 0xb3, 0x1f, 0xda, 0xfa, 0x6a, 0x8f, 0x98, 0x01, 0x16, 0xde, 0x44, 0x50, 0x0d, 0x2e, 0x6c, 0x0b, 0xa2, 0xd3, 0x74, 0x0e, 0xa9, 0xbf, 0x8d, 0xa9, 0xc8, 0xc8, 0x2f, 0x62, 0xc1, 0x35, 0x5e, 0xfd, 0x3a, 0xb3, 0x83, 0x2d, 0xee, 0x4e, 0xfd, 0x5c, 0x5e, 0xad, 0x85, 0xa5, 0x10, 0xb5, 0x4f, 0x34, 0xa7,
+	/* (2^117)P */ 0xd1, 0x58, 0x6f, 0xe6, 0x54, 0x2c, 0xc2, 0xcd, 0xcf, 0x83, 0xdc, 0x88, 0x0c, 0xb9, 0xb4, 0x62, 0x18, 0x89, 0x65, 0x28, 0xe9, 0x72, 0x4b, 0x65, 0xcf, 0xd6, 0x90, 0x88, 0xd7, 0x76, 0x17, 0x4f, 0x74, 0x64, 0x1e, 0xcb, 0xd3, 0xf5, 0x4b, 0xaa, 0x2e, 0x4d, 0x2d, 0x7c, 0x13, 0x1f, 0xfd, 0xd9, 0x60, 0x83, 0x7e, 0xda, 0x64, 0x1c, 0xdc, 0x9f,
+	/* (2^118)P */ 0xad, 0xef, 0xac, 0x1b, 0xc1, 0x30, 0x5a, 0x15, 0xc9, 0x1f, 0xac, 0xf1, 0xca, 0x44, 0x95, 0x95, 0xea, 0xf2, 0x22, 0xe7, 0x8d, 0x25, 0xf0, 0xff, 0xd8, 0x71, 0xf7, 0xf8, 0x8f, 0x8f, 0xcd, 0xf4, 0x1e, 0xfe, 0x6c, 0x68, 0x04, 0xb8, 0x78, 0xa1, 0x5f, 0xa6, 0x5d, 0x5e, 0xf9, 0x8d, 0xea, 0x80, 0xcb, 0xf3, 0x17, 0xa6, 0x03, 0xc9, 0x38, 0xd5,
+	/* (2^119)P */ 0x79, 0x14, 0x31, 0xc3, 0x38, 0xe5, 0xaa, 0xbf, 0x17, 0xa3, 0x04, 0x4e, 0x80, 0x59, 0x9c, 0x9f, 0x19, 0x39, 0xe4, 0x2d, 0x23, 0x54, 0x4a, 0x7f, 0x3e, 0xf3, 0xd9, 0xc7, 0xba, 0x6c, 0x8f, 0x6b, 0xfa, 0x34, 0xb5, 0x23, 0x17, 0x1d, 0xff, 0x1d, 0xea, 0x1f, 0xd7, 0xba, 0x61, 0xb2, 0xe0, 0x38, 0x6a, 0xe9, 0xcf, 0x48, 0x5d, 0x6a, 0x10, 0x9c,
+	/* (2^120)P */ 0xc8, 0xbb, 0x13, 0x1c, 0x3f, 0x3c, 0x34, 0xfd, 0xac, 0x37, 0x52, 0x44, 0x25, 0xa8, 0xde, 0x1d, 0x63, 0xf4, 0x81, 0x9a, 0xbe, 0x0b, 0x74, 0x2e, 0xc8, 0x51, 0x16, 0xd3, 0xac, 0x4a, 0xaf, 0xe2, 0x5f, 0x3a, 0x89, 0x32, 0xd1, 0x9b, 0x7c, 0x90, 0x0d, 0xac, 0xdc, 0x8b, 0x73, 0x45, 0x45, 0x97, 0xb1, 0x90, 0x2c, 0x1b, 0x31, 0xca, 0xb1, 0x94,
+	/* (2^121)P */ 0x07, 0x28, 0xdd, 0x10, 0x14, 0xa5, 0x95, 0x7e, 0xf3, 0xe4, 0xd4, 0x14, 0xb4, 0x7e, 0x76, 0xdb, 0x42, 0xd6, 0x94, 0x3e, 0xeb, 0x44, 0x64, 0x88, 0x0d, 0xec, 0xc1, 0x21, 0xf0, 0x79, 0xe0, 0x83, 0x67, 0x55, 0x53, 0xc2, 0xf6, 0xc5, 0xc5, 0x89, 0x39, 0xe8, 0x42, 0xd0, 0x17, 0xbd, 0xff, 0x35, 0x59, 0x0e, 0xc3, 0x06, 0x86, 0xd4, 0x64, 0xcf,
+	/* (2^122)P */ 0x91, 0xa8, 0xdb, 0x57, 0x9b, 0xe2, 0x96, 0x31, 0x10, 0x6e, 0xd7, 0x9a, 0x97, 0xb3, 0xab, 0xb5, 0x15, 0x66, 0xbe, 0xcc, 0x6d, 0x9a, 0xac, 0x06, 0xb3, 0x0d, 0xaa, 0x4b, 0x9c, 0x96, 0x79, 0x6c, 0x34, 0xee, 0x9e, 0x53, 0x4d, 0x6e, 0xbd, 0x88, 0x02, 0xbf, 0x50, 0x54, 0x12, 0x5d, 0x01, 0x02, 0x46, 0xc6, 0x74, 0x02, 0x8c, 0x24, 0xae, 0xb1,
+	/* (2^123)P */ 0xf5, 0x22, 0xea, 0xac, 0x7d, 0x9c, 0x33, 0x8a, 0xa5, 0x36, 0x79, 0x6a, 0x4f, 0xa4, 0xdc, 0xa5, 0x73, 0x64, 0xc4, 0x6f, 0x43, 0x02, 0x3b, 0x94, 0x66, 0xd2, 0x4b, 0x4f, 0xf6, 0x45, 0x33, 0x5d, 0x10, 0x33, 0x18, 0x1e, 0xa3, 0xfc, 0xf7, 0xd2, 0xb8, 0xc8, 0xa7, 0xe0, 0x76, 0x8a, 0xcd, 0xff, 0x4f, 0x99, 0x34, 0x47, 0x84, 0x91, 0x96, 0x9f,
+	/* (2^124)P */ 0x8a, 0x48, 0x3b, 0x48, 0x4a, 0xbc, 0xac, 0xe2, 0x80, 0xd6, 0xd2, 0x35, 0xde, 0xd0, 0x56, 0x42, 0x33, 0xb3, 0x56, 0x5a, 0xcd, 0xb8, 0x3d, 0xb5, 0x25, 0xc1, 0xed, 0xff, 0x87, 0x0b, 0x79, 0xff, 0xf2, 0x62, 0xe1, 0x76, 0xc6, 0xa2, 0x0f, 0xa8, 0x9b, 0x0d, 0xcc, 0x3f, 0x3d, 0x35, 0x27, 0x8d, 0x0b, 0x74, 0xb0, 0xc3, 0x78, 0x8c, 0xcc, 0xc8,
+	/* (2^125)P */ 0xfc, 0x9a, 0x0c, 0xa8, 0x49, 0x42, 0xb8, 0xdf, 0xcf, 0xb3, 0x19, 0xa6, 0x64, 0x57, 0xfe, 0xe8, 0xf8, 0xa6, 0x4b, 0x86, 0xa1, 0xd5, 0x83, 0x7f, 0x14, 0x99, 0x18, 0x0c, 0x7d, 0x5b, 0xf7, 0x3d, 0xf9, 0x4b, 0x79, 0xb1, 0x86, 0x30, 0xb4, 0x5e, 0x6a, 0xe8, 0x9d, 0xfa, 0x8a, 0x41, 0xc4, 0x30, 0xfc, 0x56, 0x74, 0x14, 0x42, 0xc8, 0x96, 0x0e,
+	/* (2^126)P */ 0xdf, 0x66, 0xec, 0xbc, 0x44, 0xdb, 0x19, 0xce, 0xd4, 0xb5, 0x49, 0x40, 0x07, 0x49, 0xe0, 0x3a, 0x61, 0x10, 0xfb, 0x7d, 0xba, 0xb1, 0xe0, 0x28, 0x5b, 0x99, 0x59, 0x96, 0xa2, 0xee, 0xe0, 0x23, 0x37, 0x39, 0x1f, 0xe6, 0x57, 0x9f, 0xf8, 0xf8, 0xdc, 0x74, 0xf6, 0x8f, 0x4f, 0x5e, 0x51, 0xa4, 0x12, 0xac, 0xbe, 0xe4, 0xf3, 0xd1, 0xf0, 0x24,
+	/* (2^127)P */ 0x1e, 0x3e, 0x9a, 0x5f, 0xdf, 0x9f, 0xd6, 0x4e, 0x8a, 0x28, 0xc3, 0xcd, 0x96, 0x9d, 0x57, 0xc7, 0x61, 0x81, 0x90, 0xff, 0xae, 0xb1, 0x4f, 0xc2, 0x96, 0x8b, 0x1a, 0x18, 0xf4, 0x50, 0xcb, 0x31, 0xe1, 0x57, 0xf4, 0x90, 0xa8, 0xea, 0xac, 0xe7, 0x61, 0x98, 0xb6, 0x15, 0xc1, 0x7b, 0x29, 0xa4, 0xc3, 0x18, 0xef, 0xb9, 0xd8, 0xdf, 0xf6, 0xac,
+	/* (2^128)P */ 0xca, 0xa8, 0x6c, 0xf1, 0xb4, 0xca, 0xfe, 0x31, 0xee, 0x48, 0x38, 0x8b, 0x0e, 0xbb, 0x7a, 0x30, 0xaa, 0xf9, 0xee, 0x27, 0x53, 0x24, 0xdc, 0x2e, 0x15, 0xa6, 0x48, 0x8f, 0xa0, 0x7e, 0xf1, 0xdc, 0x93, 0x87, 0x39, 0xeb, 0x7f, 0x38, 0x92, 0x92, 0x4c, 0x29, 0xe9, 0x57, 0xd8, 0x59, 0xfc, 0xe9, 0x9c, 0x44, 0xc0, 0x65, 0xcf, 0xac, 0x4b, 0xdc,
+	/* (2^129)P */ 0xa3, 0xd0, 0x37, 0x8f, 0x86, 0x2f, 0xc6, 0x47, 0x55, 0x46, 0x65, 0x26, 0x4b, 0x91, 0xe2, 0x18, 0x5c, 0x4f, 0x23, 0xc1, 0x37, 0x29, 0xb9, 0xc1, 0x27, 0xc5, 0x3c, 0xbf, 0x7e, 0x23, 0xdb, 0x73, 0x99, 0xbd, 0x1b, 0xb2, 0x31, 0x68, 0x3a, 0xad, 0xb7, 0xb0, 0x10, 0xc5, 0xe5, 0x11, 0x51, 0xba, 0xa7, 0x60, 0x66, 0x54, 0xf0, 0x08, 0xd7, 0x69,
+	/* (2^130)P */ 0x89, 0x41, 0x79, 0xcc, 0xeb, 0x0a, 0xf5, 0x4b, 0xa3, 0x4c, 0xce, 0x52, 0xb0, 0xa7, 0xe4, 0x41, 0x75, 0x7d, 0x04, 0xbb, 0x09, 0x4c, 0x50, 0x9f, 0xdf, 0xea, 0x74, 0x61, 0x02, 0xad, 0xb4, 0x9d, 0xb7, 0x05, 0xb9, 0xea, 0xeb, 0x91, 0x35, 0xe7, 0x49, 0xea, 0xd3, 0x4f, 0x3c, 0x60, 0x21, 0x7a, 0xde, 0xc7, 0xe2, 0x5a, 0xee, 0x8e, 0x93, 0xc7,
+	/* (2^131)P */ 0x00, 0xe8, 0xed, 0xd0, 0xb3, 0x0d, 0xaf, 0xb2, 0xde, 0x2c, 0xf6, 0x00, 0xe2, 0xea, 0x6d, 0xf8, 0x0e, 0xd9, 0x67, 0x59, 0xa9, 0x50, 0xbb, 0x17, 0x8f, 0xff, 0xb1, 0x9f, 0x17, 0xb6, 0xf2, 0xb5, 0xba, 0x80, 0xf7, 0x0f, 0xba, 0xd5, 0x09, 0x43, 0xaa, 0x4e, 0x3a, 0x67, 0x6a, 0x89, 0x9b, 0x18, 0x65, 0x35, 0xf8, 0x3a, 0x49, 0x91, 0x30, 0x51,
+	/* (2^132)P */ 0x8d, 0x25, 0xe9, 0x0e, 0x7d, 0x50, 0x76, 0xe4, 0x58, 0x7e, 0xb9, 0x33, 0xe6, 0x65, 0x90, 0xc2, 0x50, 0x9d, 0x50, 0x2e, 0x11, 0xad, 0xd5, 0x43, 0x52, 0x32, 0x41, 0x4f, 0x7b, 0xb6, 0xa0, 0xec, 0x81, 0x75, 0x36, 0x7c, 0x77, 0x85, 0x59, 0x70, 0xe4, 0xf9, 0xef, 0x66, 0x8d, 0x35, 0xc8, 0x2a, 0x6e, 0x5b, 0xc6, 0x0d, 0x0b, 0x29, 0x60, 0x68,
+	/* (2^133)P */ 0xf8, 0xce, 0xb0, 0x3a, 0x56, 0x7d, 0x51, 0x9a, 0x25, 0x73, 0xea, 0xdd, 0xe4, 0xe0, 0x0e, 0xf0, 0x07, 0xc0, 0x31, 0x00, 0x73, 0x35, 0xd0, 0x39, 0xc4, 0x9b, 0xb7, 0x95, 0xe0, 0x62, 0x70, 0x36, 0x0b, 0xcb, 0xa0, 0x42, 0xde, 0x51, 0xcf, 0x41, 0xe0, 0xb8, 0xb4, 0xc0, 0xe5, 0x46, 0x99, 0x9f, 0x02, 0x7f, 0x14, 0x8c, 0xc1, 0x4e, 0xef, 0xe8,
+	/* (2^134)P */ 0x10, 0x01, 0x57, 0x0a, 0xbe, 0x8b, 0x18, 0xc8, 0xca, 0x00, 0x28, 0x77, 0x4a, 0x9a, 0xc7, 0x55, 0x2a, 0xcc, 0x0c, 0x7b, 0xb9, 0xe9, 0xc8, 0x97, 0x7c, 0x02, 0xe3, 0x09, 0x2f, 0x62, 0x30, 0xb8, 0x40, 0x09, 0x65, 0xe9, 0x55, 0x63, 0xb5, 0x07, 0xca, 0x9f, 0x00, 0xdf, 0x9d, 0x5c, 0xc7, 0xee, 0x57, 0xa5, 0x90, 0x15, 0x1e, 0x22, 0xa0, 0x12,
+	/* (2^135)P */ 0x71, 0x2d, 0xc9, 0xef, 0x27, 0xb9, 0xd8, 0x12, 0x43, 0x6b, 0xa8, 0xce, 0x3b, 0x6d, 0x6e, 0x91, 0x43, 0x23, 0xbc, 0x32, 0xb3, 0xbf, 0xe1, 0xc7, 0x39, 0xcf, 0x7c, 0x42, 0x4c, 0xb1, 0x30, 0xe2, 0xdd, 0x69, 0x06, 0xe5, 0xea, 0xf0, 0x2a, 0x16, 0x50, 0x71, 0xca, 0x92, 0xdf, 0xc1, 0xcc, 0xec, 0xe6, 0x54, 0x07, 0xf3, 0x18, 0x8d, 0xd8, 0x29,
+	/* (2^136)P */ 0x98, 0x51, 0x48, 0x8f, 0xfa, 0x2e, 0x5e, 0x67, 0xb0, 0xc6, 0x17, 0x12, 0xb6, 0x7d, 0xc9, 0xad, 0x81, 0x11, 0xad, 0x0c, 0x1c, 0x2d, 0x45, 0xdf, 0xac, 0x66, 0xbd, 0x08, 0x6f, 0x7c, 0xc7, 0x06, 0x6e, 0x19, 0x08, 0x39, 0x64, 0xd7, 0xe4, 0xd1, 0x11, 0x5f, 0x1c, 0xf4, 0x67, 0xc3, 0x88, 0x6a, 0xe6, 0x07, 0xa3, 0x83, 0xd7, 0xfd, 0x2a, 0xf9,
+	/* (2^137)P */ 0x87, 0xed, 0xeb, 0xd9, 0xdf, 0xff, 0x43, 0x8b, 0xaa, 0x20, 0x58, 0xb0, 0xb4, 0x6b, 0x14, 0xb8, 0x02, 0xc5, 0x40, 0x20, 0x22, 0xbb, 0xf7, 0xb4, 0xf3, 0x05, 0x1e, 0x4d, 0x94, 0xff, 0xe3, 0xc5, 0x22, 0x82, 0xfe, 0xaf, 0x90, 0x42, 0x98, 0x6b, 0x76, 0x8b, 0x3e, 0x89, 0x3f, 0x42, 0x2a, 0xa7, 0x26, 0x00, 0xda, 0x5c, 0xa2, 0x2b, 0xec, 0xdd,
+	/* (2^138)P */ 0x5c, 0x21, 0x16, 0x0d, 0x46, 0xb8, 0xd0, 0xa7, 0x88, 0xe7, 0x25, 0xcb, 0x3e, 0x50, 0x73, 0x61, 0xe7, 0xaf, 0x5a, 0x3f, 0x47, 0x8b, 0x3d, 0x97, 0x79, 0x2c, 0xe6, 0x6d, 0x95, 0x74, 0x65, 0x70, 0x36, 0xfd, 0xd1, 0x9e, 0x13, 0x18, 0x63, 0xb1, 0x2d, 0x0b, 0xb5, 0x36, 0x3e, 0xe7, 0x35, 0x42, 0x3b, 0xe6, 0x1f, 0x4d, 0x9d, 0x59, 0xa2, 0x43,
+	/* (2^139)P */ 0x8c, 0x0c, 0x7c, 0x24, 0x9e, 0xe0, 0xf8, 0x05, 0x1c, 0x9e, 0x1f, 0x31, 0xc0, 0x70, 0xb3, 0xfb, 0x4e, 0xf8, 0x0a, 0x57, 0xb7, 0x49, 0xb5, 0x73, 0xa1, 0x5f, 0x9b, 0x6a, 0x07, 0x6c, 0x87, 0x71, 0x87, 0xd4, 0xbe, 0x98, 0x1e, 0x98, 0xee, 0x52, 0xc1, 0x7b, 0x95, 0x0f, 0x28, 0x32, 0x36, 0x28, 0xd0, 0x3a, 0x0f, 0x7d, 0x2a, 0xa9, 0x62, 0xb9,
+	/* (2^140)P */ 0x97, 0xe6, 0x18, 0x77, 0xf9, 0x34, 0xac, 0xbc, 0xe0, 0x62, 0x9f, 0x42, 0xde, 0xbd, 0x2f, 0xf7, 0x1f, 0xb7, 0x14, 0x52, 0x8a, 0x79, 0xb2, 0x3f, 0xd2, 0x95, 0x71, 0x01, 0xe8, 0xaf, 0x8c, 0xa4, 0xa4, 0xa7, 0x27, 0xf3, 0x5c, 0xdf, 0x3e, 0x57, 0x7a, 0xf1, 0x76, 0x49, 0xe6, 0x42, 0x3f, 0x8f, 0x1e, 0x63, 0x4a, 0x65, 0xb5, 0x41, 0xf5, 0x02,
+	/* (2^141)P */ 0x72, 0x85, 0xc5, 0x0b, 0xe1, 0x47, 0x64, 0x02, 0xc5, 0x4d, 0x81, 0x69, 0xb2, 0xcf, 0x0f, 0x6c, 0xd4, 0x6d, 0xd0, 0xc7, 0xb4, 0x1c, 0xd0, 0x32, 0x59, 0x89, 0xe2, 0xe0, 0x96, 0x8b, 0x12, 0x98, 0xbf, 0x63, 0x7a, 0x4c, 0x76, 0x7e, 0x58, 0x17, 0x8f, 0x5b, 0x0a, 0x59, 0x65, 0x75, 0xbc, 0x61, 0x1f, 0xbe, 0xc5, 0x6e, 0x0a, 0x57, 0x52, 0x70,
+	/* (2^142)P */ 0x92, 0x1c, 0x77, 0xbb, 0x62, 0x02, 0x6c, 0x25, 0x9c, 0x66, 0x07, 0x83, 0xab, 0xcc, 0x80, 0x5d, 0xd2, 0x76, 0x0c, 0xa4, 0xc5, 0xb4, 0x8a, 0x68, 0x23, 0x31, 0x32, 0x29, 0x8a, 0x47, 0x92, 0x12, 0x80, 0xb3, 0xfa, 0x18, 0xe4, 0x8d, 0xc0, 0x4d, 0xfe, 0x97, 0x5f, 0x72, 0x41, 0xb5, 0x5c, 0x7a, 0xbd, 0xf0, 0xcf, 0x5e, 0x97, 0xaa, 0x64, 0x32,
+	/* (2^143)P */ 0x35, 0x3f, 0x75, 0xc1, 0x7a, 0x75, 0x7e, 0xa9, 0xc6, 0x0b, 0x4e, 0x32, 0x62, 0xec, 0xe3, 0x5c, 0xfb, 0x01, 0x43, 0xb6, 0xd4, 0x5b, 0x75, 0xd2, 0xee, 0x7f, 0x5d, 0x23, 0x2b, 0xb3, 0x54, 0x34, 0x4c, 0xd3, 0xb4, 0x32, 0x84, 0x81, 0xb5, 0x09, 0x76, 0x19, 0xda, 0x58, 0xda, 0x7c, 0xdb, 0x2e, 0xdd, 0x4c, 0x8e, 0xdd, 0x5d, 0x89, 0x10, 0x10,
+	/* (2^144)P */ 0x57, 0x25, 0x6a, 0x08, 0x37, 0x92, 0xa8, 0xdf, 0x24, 0xef, 0x8f, 0x33, 0x34, 0x52, 0xa4, 0x4c, 0xf0, 0x77, 0x9f, 0x69, 0x77, 0xd5, 0x8f, 0xd2, 0x9a, 0xb3, 0xb6, 0x1d, 0x2d, 0xa6, 0xf7, 0x1f, 0xda, 0xd7, 0xcb, 0x75, 0x11, 0xc3, 0x6b, 0xc0, 0x38, 0xb1, 0xd5, 0x2d, 0x96, 0x84, 0x16, 0xfa, 0x26, 0xb9, 0xcc, 0x3f, 0x16, 0x47, 0x23, 0x74,
+	/* (2^145)P */ 0x9b, 0x61, 0x2a, 0x1c, 0xdd, 0x39, 0xa5, 0xfa, 0x1c, 0x7d, 0x63, 0x50, 0xca, 0xe6, 0x9d, 0xfa, 0xb7, 0xc4, 0x4c, 0x6a, 0x97, 0x5f, 0x36, 0x4e, 0x47, 0xdd, 0x17, 0xf7, 0xf9, 0x19, 0xce, 0x75, 0x17, 0xad, 0xce, 0x2a, 0xf3, 0xfe, 0x27, 0x8f, 0x3e, 0x48, 0xc0, 0x60, 0x87, 0x24, 0x19, 0xae, 0x59, 0xe4, 0x5a, 0x00, 0x2a, 0xba, 0xa2, 0x1f,
+	/* (2^146)P */ 0x26, 0x88, 0x42, 0x60, 0x9f, 0x6e, 0x2c, 0x7c, 0x39, 0x0f, 0x47, 0x6a, 0x0e, 0x02, 0xbb, 0x4b, 0x34, 0x29, 0x55, 0x18, 0x36, 0xcf, 0x3b, 0x47, 0xf1, 0x2e, 0xfc, 0x6e, 0x94, 0xff, 0xe8, 0x6b, 0x06, 0xd2, 0xba, 0x77, 0x5e, 0x60, 0xd7, 0x19, 0xef, 0x02, 0x9d, 0x3a, 0xc2, 0xb7, 0xa9, 0xd8, 0x57, 0xee, 0x7e, 0x2b, 0xf2, 0x6d, 0x28, 0xda,
+	/* (2^147)P */ 0xdf, 0xd9, 0x92, 0x11, 0x98, 0x23, 0xe2, 0x45, 0x2f, 0x74, 0x70, 0xee, 0x0e, 0x55, 0x65, 0x79, 0x86, 0x38, 0x17, 0x92, 0x85, 0x87, 0x99, 0x50, 0xd9, 0x7c, 0xdb, 0xa1, 0x10, 0xec, 0x30, 0xb7, 0x40, 0xa3, 0x23, 0x9b, 0x0e, 0x27, 0x49, 0x29, 0x03, 0x94, 0xff, 0x53, 0xdc, 0xd7, 0xed, 0x49, 0xa9, 0x5a, 0x3b, 0xee, 0xd7, 0xc7, 0x65, 0xaf,
+	/* (2^148)P */ 0xa0, 0xbd, 0xbe, 0x03, 0xee, 0x0c, 0xbe, 0x32, 0x00, 0x7b, 0x52, 0xcb, 0x92, 0x29, 0xbf, 0xa0, 0xc6, 0xd9, 0xd2, 0xd6, 0x15, 0xe8, 0x3a, 0x75, 0x61, 0x65, 0x56, 0xae, 0xad, 0x3c, 0x2a, 0x64, 0x14, 0x3f, 0x8e, 0xc1, 0x2d, 0x0c, 0x8d, 0x20, 0xdb, 0x58, 0x4b, 0xe5, 0x40, 0x15, 0x4b, 0xdc, 0xa8, 0xbd, 0xef, 0x08, 0xa7, 0xd1, 0xf4, 0xb0,
+	/* (2^149)P */ 0xa9, 0x0f, 0x05, 0x94, 0x66, 0xac, 0x1f, 0x65, 0x3f, 0xe1, 0xb8, 0xe1, 0x34, 0x5e, 0x1d, 0x8f, 0xe3, 0x93, 0x03, 0x15, 0xff, 0xb6, 0x65, 0xb6, 0x6e, 0xc0, 0x2f, 0xd4, 0x2e, 0xb9, 0x2c, 0x13, 0x3c, 0x99, 0x1c, 0xb5, 0x87, 0xba, 0x79, 0xcb, 0xf0, 0x18, 0x06, 0x86, 0x04, 0x14, 0x25, 0x09, 0xcd, 0x1c, 0x14, 0xda, 0x35, 0xd0, 0x38, 0x3b,
+	/* (2^150)P */ 0x1b, 0x04, 0xa3, 0x27, 0xb4, 0xd3, 0x37, 0x48, 0x1e, 0x8f, 0x69, 0xd3, 0x5a, 0x2f, 0x20, 0x02, 0x36, 0xbe, 0x06, 0x7b, 0x6b, 0x6c, 0x12, 0x5b, 0x80, 0x74, 0x44, 0xe6, 0xf8, 0xf5, 0x95, 0x59, 0x29, 0xab, 0x51, 0x47, 0x83, 0x28, 0xe0, 0xad, 0xde, 0xaa, 0xd3, 0xb1, 0x1a, 0xcb, 0xa3, 0xcd, 0x8b, 0x6a, 0xb1, 0xa7, 0x0a, 0xd1, 0xf9, 0xbe,
+	/* (2^151)P */ 0xce, 0x2f, 0x85, 0xca, 0x74, 0x6d, 0x49, 0xb8, 0xce, 0x80, 0x44, 0xe0, 0xda, 0x5b, 0xcf, 0x2f, 0x79, 0x74, 0xfe, 0xb4, 0x2c, 0x99, 0x20, 0x6e, 0x09, 0x04, 0xfb, 0x6d, 0x57, 0x5b, 0x95, 0x0c, 0x45, 0xda, 0x4f, 0x7f, 0x63, 0xcc, 0x85, 0x5a, 0x67, 0x50, 0x68, 0x71, 0xb4, 0x67, 0xb1, 0x2e, 0xc1, 0x1c, 0xdc, 0xff, 0x2a, 0x7c, 0x10, 0x5e,
+	/* (2^152)P */ 0xa6, 0xde, 0xf3, 0xd4, 0x22, 0x30, 0x24, 0x9e, 0x0b, 0x30, 0x54, 0x59, 0x7e, 0xa2, 0xeb, 0x89, 0x54, 0x65, 0x3e, 0x40, 0xd1, 0xde, 0xe6, 0xee, 0x4d, 0xbf, 0x5e, 0x40, 0x1d, 0xee, 0x4f, 0x68, 0xd9, 0xa7, 0x2f, 0xb3, 0x64, 0xb3, 0xf5, 0xc8, 0xd3, 0xaa, 0x70, 0x70, 0x3d, 0xef, 0xd3, 0x95, 0x54, 0xdb, 0x3e, 0x94, 0x95, 0x92, 0x1f, 0x45,
+	/* (2^153)P */ 0x22, 0x80, 0x1d, 0x9d, 0x96, 0xa5, 0x78, 0x6f, 0xe0, 0x1e, 0x1b, 0x66, 0x42, 0xc8, 0xae, 0x9e, 0x46, 0x45, 0x08, 0x41, 0xdf, 0x80, 0xae, 0x6f, 0xdb, 0x15, 0x5a, 0x21, 0x31, 0x7a, 0xd0, 0xf2, 0x54, 0x15, 0x88, 0xd3, 0x0f, 0x7f, 0x14, 0x5a, 0x14, 0x97, 0xab, 0xf4, 0x58, 0x6a, 0x9f, 0xea, 0x74, 0xe5, 0x6b, 0x90, 0x59, 0x2b, 0x48, 0xd9,
+	/* (2^154)P */ 0x12, 0x24, 0x04, 0xf5, 0x50, 0xc2, 0x8c, 0xb0, 0x7c, 0x46, 0x98, 0xd5, 0x24, 0xad, 0xf6, 0x72, 0xdc, 0x82, 0x1a, 0x60, 0xc1, 0xeb, 0x48, 0xef, 0x7f, 0x6e, 0xe6, 0xcc, 0xdb, 0x7b, 0xae, 0xbe, 0x5e, 0x1e, 0x5c, 0xe6, 0x0a, 0x70, 0xdf, 0xa4, 0xa3, 0x85, 0x1b, 0x1b, 0x7f, 0x72, 0xb9, 0x96, 0x6f, 0xdc, 0x03, 0x76, 0x66, 0xfb, 0xa0, 0x33,
+	/* (2^155)P */ 0x37, 0x40, 0xbb, 0xbc, 0x68, 0x58, 0x86, 0xca, 0xbb, 0xa5, 0x24, 0x76, 0x3d, 0x48, 0xd1, 0xad, 0xb4, 0xa8, 0xcf, 0xc3, 0xb6, 0xa8, 0xba, 0x1a, 0x3a, 0xbe, 0x33, 0x75, 0x04, 0x5c, 0x13, 0x8c, 0x0d, 0x70, 0x8d, 0xa6, 0x4e, 0x2a, 0xeb, 0x17, 0x3c, 0x22, 0xdd, 0x3e, 0x96, 0x40, 0x11, 0x9e, 0x4e, 0xae, 0x3d, 0xf8, 0x91, 0xd7, 0x50, 0xc8,
+	/* (2^156)P */ 0xd8, 0xca, 0xde, 0x19, 0xcf, 0x00, 0xe4, 0x73, 0x18, 0x7f, 0x9b, 0x9f, 0xf4, 0x5b, 0x49, 0x49, 0x99, 0xdc, 0xa4, 0x46, 0x21, 0xb5, 0xd7, 0x3e, 0xb7, 0x47, 0x1b, 0xa9, 0x9f, 0x4c, 0x69, 0x7d, 0xec, 0x33, 0xd6, 0x1c, 0x51, 0x7f, 0x47, 0x74, 0x7a, 0x6c, 0xf3, 0xd2, 0x2e, 0xbf, 0xdf, 0x6c, 0x9e, 0x77, 0x3b, 0x34, 0xf6, 0x73, 0x80, 0xed,
+	/* (2^157)P */ 0x16, 0xfb, 0x16, 0xc3, 0xc2, 0x83, 0xe4, 0xf4, 0x03, 0x7f, 0x52, 0xb0, 0x67, 0x51, 0x7b, 0x24, 0x5a, 0x51, 0xd3, 0xb6, 0x4e, 0x59, 0x76, 0xcd, 0x08, 0x7b, 0x1d, 0x7a, 0x9c, 0x65, 0xae, 0xce, 0xaa, 0xd2, 0x1c, 0x85, 0x66, 0x68, 0x06, 0x15, 0xa8, 0x06, 0xe6, 0x16, 0x37, 0xf4, 0x49, 0x9e, 0x0f, 0x50, 0x37, 0xb1, 0xb2, 0x93, 0x70, 0x43,
+	/* (2^158)P */ 0x18, 0x3a, 0x16, 0xe5, 0x8d, 0xc8, 0x35, 0xd6, 0x7b, 0x09, 0xec, 0x61, 0x5f, 0x5c, 0x2a, 0x19, 0x96, 0x2e, 0xc3, 0xfd, 0xab, 0xe6, 0x23, 0xae, 0xab, 0xc5, 0xcb, 0xb9, 0x7b, 0x2d, 0x34, 0x51, 0xb9, 0x41, 0x9e, 0x7d, 0xca, 0xda, 0x25, 0x45, 0x14, 0xb0, 0xc7, 0x4d, 0x26, 0x2b, 0xfe, 0x43, 0xb0, 0x21, 0x5e, 0xfa, 0xdc, 0x7c, 0xf9, 0x5a,
+	/* (2^159)P */ 0x94, 0xad, 0x42, 0x17, 0xf5, 0xcd, 0x1c, 0x0d, 0xf6, 0x41, 0xd2, 0x55, 0xbb, 0x50, 0xf1, 0xc6, 0xbc, 0xa6, 0xc5, 0x3a, 0xfd, 0x9b, 0x75, 0x3e, 0xf6, 0x1a, 0xa7, 0xb2, 0x6e, 0x64, 0x12, 0xdc, 0x3c, 0xe5, 0xf6, 0xfc, 0x3b, 0xfa, 0x43, 0x81, 0xd4, 0xa5, 0xee, 0xf5, 0x9c, 0x47, 0x2f, 0xd0, 0x9c, 0xde, 0xa1, 0x48, 0x91, 0x9a, 0x34, 0xc1,
+	/* (2^160)P */ 0x37, 0x1b, 0xb3, 0x88, 0xc9, 0x98, 0x4e, 0xfb, 0x84, 0x4f, 0x2b, 0x0a, 0xb6, 0x8f, 0x35, 0x15, 0xcd, 0x61, 0x7a, 0x5f, 0x5c, 0xa0, 0xca, 0x23, 0xa0, 0x93, 0x1f, 0xcc, 0x3c, 0x39, 0x3a, 0x24, 0xa7, 0x49, 0xad, 0x8d, 0x59, 0xcc, 0x94, 0x5a, 0x16, 0xf5, 0x70, 0xe8, 0x52, 0x1e, 0xee, 0x20, 0x30, 0x17, 0x7e, 0xf0, 0x4c, 0x93, 0x06, 0x5a,
+	/* (2^161)P */ 0x81, 0xba, 0x3b, 0xd7, 0x3e, 0xb4, 0x32, 0x3a, 0x22, 0x39, 0x2a, 0xfc, 0x19, 0xd9, 0xd2, 0xf6, 0xc5, 0x79, 0x6c, 0x0e, 0xde, 0xda, 0x01, 0xff, 0x52, 0xfb, 0xb6, 0x95, 0x4e, 0x7a, 0x10, 0xb8, 0x06, 0x86, 0x3c, 0xcd, 0x56, 0xd6, 0x15, 0xbf, 0x6e, 0x3e, 0x4f, 0x35, 0x5e, 0xca, 0xbc, 0xa5, 0x95, 0xa2, 0xdf, 0x2d, 0x1d, 0xaf, 0x59, 0xf9,
+	/* (2^162)P */ 0x69, 0xe5, 0xe2, 0xfa, 0xc9, 0x7f, 0xdd, 0x09, 0xf5, 0x6b, 0x4e, 0x2e, 0xbe, 0xb4, 0xbf, 0x3e, 0xb2, 0xf2, 0x81, 0x30, 0xe1, 0x07, 0xa8, 0x0d, 0x2b, 0xd2, 0x5a, 0x55, 0xbe, 0x4b, 0x86, 0x5d, 0xb0, 0x5e, 0x7c, 0x8f, 0xc1, 0x3c, 0x81, 0x4c, 0xf7, 0x6d, 0x7d, 0xe6, 0x4f, 0x8a, 0x85, 0xc2, 0x2f, 0x28, 0xef, 0x8c, 0x69, 0xc2, 0xc2, 0x1a,
+	/* (2^163)P */ 0xd9, 0xe4, 0x0e, 0x1e, 0xc2, 0xf7, 0x2f, 0x9f, 0xa1, 0x40, 0xfe, 0x46, 0x16, 0xaf, 0x2e, 0xd1, 0xec, 0x15, 0x9b, 0x61, 0x92, 0xce, 0xfc, 0x10, 0x43, 0x1d, 0x00, 0xf6, 0xbe, 0x20, 0x80, 0x80, 0x6f, 0x3c, 0x16, 0x94, 0x59, 0xba, 0x03, 0x53, 0x6e, 0xb6, 0xdd, 0x25, 0x7b, 0x86, 0xbf, 0x96, 0xf4, 0x2f, 0xa1, 0x96, 0x8d, 0xf9, 0xb3, 0x29,
+	/* (2^164)P */ 0x3b, 0x04, 0x60, 0x6e, 0xce, 0xab, 0xd2, 0x63, 0x18, 0x53, 0x88, 0x16, 0x4a, 0x6a, 0xab, 0x72, 0x03, 0x68, 0xa5, 0xd4, 0x0d, 0xb2, 0x82, 0x81, 0x1f, 0x2b, 0x5c, 0x75, 0xe8, 0xd2, 0x1d, 0x7f, 0xe7, 0x1b, 0x35, 0x02, 0xde, 0xec, 0xbd, 0xcb, 0xc7, 0x01, 0xd3, 0x95, 0x61, 0xfe, 0xb2, 0x7a, 0x66, 0x09, 0x4c, 0x6d, 0xfd, 0x39, 0xf7, 0x52,
+	/* (2^165)P */ 0x42, 0xc1, 0x5f, 0xf8, 0x35, 0x52, 0xc1, 0xfe, 0xc5, 0x11, 0x80, 0x1c, 0x11, 0x46, 0x31, 0x11, 0xbe, 0xd0, 0xc4, 0xb6, 0x07, 0x13, 0x38, 0xa0, 0x8d, 0x65, 0xf0, 0x56, 0x9e, 0x16, 0xbf, 0x9d, 0xcd, 0x51, 0x34, 0xf9, 0x08, 0x48, 0x7b, 0x76, 0x0c, 0x7b, 0x30, 0x07, 0xa8, 0x76, 0xaf, 0xa3, 0x29, 0x38, 0xb0, 0x58, 0xde, 0x72, 0x4b, 0x45,
+	/* (2^166)P */ 0xd4, 0x16, 0xa7, 0xc0, 0xb4, 0x9f, 0xdf, 0x1a, 0x37, 0xc8, 0x35, 0xed, 0xc5, 0x85, 0x74, 0x64, 0x09, 0x22, 0xef, 0xe9, 0x0c, 0xaf, 0x12, 0x4c, 0x9e, 0xf8, 0x47, 0x56, 0xe0, 0x7f, 0x4e, 0x24, 0x6b, 0x0c, 0xe7, 0xad, 0xc6, 0x47, 0x1d, 0xa4, 0x0d, 0x86, 0x89, 0x65, 0xe8, 0x5f, 0x71, 0xc7, 0xe9, 0xcd, 0xec, 0x6c, 0x62, 0xc7, 0xe3, 0xb3,
+	/* (2^167)P */ 0xb5, 0xea, 0x86, 0xe3, 0x15, 0x18, 0x3f, 0x6d, 0x7b, 0x05, 0x95, 0x15, 0x53, 0x26, 0x1c, 0xeb, 0xbe, 0x7e, 0x16, 0x42, 0x4b, 0xa2, 0x3d, 0xdd, 0x0e, 0xff, 0xba, 0x67, 0xb5, 0xae, 0x7a, 0x17, 0xde, 0x23, 0xad, 0x14, 0xcc, 0xd7, 0xaf, 0x57, 0x01, 0xe0, 0xdd, 0x48, 0xdd, 0xd7, 0xe3, 0xdf, 0xe9, 0x2d, 0xda, 0x67, 0xa4, 0x9f, 0x29, 0x04,
+	/* (2^168)P */ 0x16, 0x53, 0xe6, 0x9c, 0x4e, 0xe5, 0x1e, 0x70, 0x81, 0x25, 0x02, 0x9b, 0x47, 0x6d, 0xd2, 0x08, 0x73, 0xbe, 0x0a, 0xf1, 0x7b, 0xeb, 0x24, 0xeb, 0x38, 0x23, 0x5c, 0xb6, 0x3e, 0xce, 0x1e, 0xe3, 0xbc, 0x82, 0x35, 0x1f, 0xaf, 0x3a, 0x3a, 0xe5, 0x4e, 0xc1, 0xca, 0xbf, 0x47, 0xb4, 0xbb, 0xbc, 0x5f, 0xea, 0xc6, 0xca, 0xf3, 0xa0, 0xa2, 0x73,
+	/* (2^169)P */ 0xef, 0xa4, 0x7a, 0x4e, 0xe4, 0xc7, 0xb6, 0x43, 0x2e, 0xa5, 0xe4, 0xa5, 0xba, 0x1e, 0xa5, 0xfe, 0x9e, 0xce, 0xa9, 0x80, 0x04, 0xcb, 0x4f, 0xd8, 0x74, 0x05, 0x48, 0xfa, 0x99, 0x11, 0x5d, 0x97, 0x3b, 0x07, 0x0d, 0xdd, 0xe6, 0xb1, 0x74, 0x87, 0x1a, 0xd3, 0x26, 0xb7, 0x8f, 0xe1, 0x63, 0x3d, 0xec, 0x53, 0x93, 0xb0, 0x81, 0x78, 0x34, 0xa4,
+	/* (2^170)P */ 0xe1, 0xe7, 0xd4, 0x58, 0x9d, 0x0e, 0x8b, 0x65, 0x66, 0x37, 0x16, 0x48, 0x6f, 0xaa, 0x42, 0x37, 0x77, 0xad, 0xb1, 0x56, 0x48, 0xdf, 0x65, 0x36, 0x30, 0xb8, 0x00, 0x12, 0xd8, 0x32, 0x28, 0x7f, 0xc1, 0x71, 0xeb, 0x93, 0x0f, 0x48, 0x04, 0xe1, 0x5a, 0x6a, 0x96, 0xc1, 0xca, 0x89, 0x6d, 0x1b, 0x82, 0x4c, 0x18, 0x6d, 0x55, 0x4b, 0xea, 0xfd,
+	/* (2^171)P */ 0x62, 0x1a, 0x53, 0xb4, 0xb1, 0xbe, 0x6f, 0x15, 0x18, 0x88, 0xd4, 0x66, 0x61, 0xc7, 0x12, 0x69, 0x02, 0xbd, 0x03, 0x23, 0x2b, 0xef, 0xf9, 0x54, 0xa4, 0x85, 0xa8, 0xe3, 0xb7, 0xbd, 0xa9, 0xa3, 0xf3, 0x2a, 0xdd, 0xf1, 0xd4, 0x03, 0x0f, 0xa9, 0xa1, 0xd8, 0xa3, 0xcd, 0xb2, 0x71, 0x90, 0x4b, 0x35, 0x62, 0xf2, 0x2f, 0xce, 0x67, 0x1f, 0xaa,
+	/* (2^172)P */ 0x9e, 0x1e, 0xcd, 0x43, 0x7e, 0x87, 0x37, 0x94, 0x3a, 0x97, 0x4c, 0x7e, 0xee, 0xc9, 0x37, 0x85, 0xf1, 0xd9, 0x4f, 0xbf, 0xf9, 0x6f, 0x39, 0x9a, 0x39, 0x87, 0x2e, 0x25, 0x84, 0x42, 0xc3, 0x80, 0xcb, 0x07, 0x22, 0xae, 0x30, 0xd5, 0x50, 0xa1, 0x23, 0xcc, 0x31, 0x81, 0x9d, 0xf1, 0x30, 0xd9, 0x2b, 0x73, 0x41, 0x16, 0x50, 0xab, 0x2d, 0xa2,
+	/* (2^173)P */ 0xa4, 0x69, 0x4f, 0xa1, 0x4e, 0xb9, 0xbf, 0x14, 0xe8, 0x2b, 0x04, 0x93, 0xb7, 0x6e, 0x9f, 0x7d, 0x73, 0x0a, 0xc5, 0x14, 0xb8, 0xde, 0x8c, 0xc1, 0xfe, 0xc0, 0xa7, 0xa4, 0xcc, 0x42, 0x42, 0x81, 0x15, 0x65, 0x8a, 0x80, 0xb9, 0xde, 0x1f, 0x60, 0x33, 0x0e, 0xcb, 0xfc, 0xe0, 0xdb, 0x83, 0xa1, 0xe5, 0xd0, 0x16, 0x86, 0x2c, 0xe2, 0x87, 0xed,
+	/* (2^174)P */ 0x7a, 0xc0, 0xeb, 0x6b, 0xf6, 0x0d, 0x4c, 0x6d, 0x1e, 0xdb, 0xab, 0xe7, 0x19, 0x45, 0xc6, 0xe3, 0xb2, 0x06, 0xbb, 0xbc, 0x70, 0x99, 0x83, 0x33, 0xeb, 0x28, 0xc8, 0x77, 0xf6, 0x4d, 0x01, 0xb7, 0x59, 0xa0, 0xd2, 0xb3, 0x2a, 0x72, 0x30, 0xe7, 0x11, 0x39, 0xb6, 0x41, 0x29, 0x65, 0x5a, 0x14, 0xb9, 0x86, 0x08, 0xe0, 0x7d, 0x32, 0x8c, 0xf0,
+	/* (2^175)P */ 0x5c, 0x11, 0x30, 0x9e, 0x05, 0x27, 0xf5, 0x45, 0x0f, 0xb3, 0xc9, 0x75, 0xc3, 0xd7, 0xe1, 0x82, 0x3b, 0x8e, 0x87, 0x23, 0x00, 0x15, 0x19, 0x07, 0xd9, 0x21, 0x53, 0xc7, 0xf1, 0xa3, 0xbf, 0x70, 0x64, 0x15, 0x18, 0xca, 0x23, 0x9e, 0xd3, 0x08, 0xc3, 0x2a, 0x8b, 0xe5, 0x83, 0x04, 0x89, 0x14, 0xfd, 0x28, 0x25, 0x1c, 0xe3, 0x26, 0xa7, 0x22,
+	/* (2^176)P */ 0xdc, 0xd4, 0x75, 0x60, 0x99, 0x94, 0xea, 0x09, 0x8e, 0x8a, 0x3c, 0x1b, 0xf9, 0xbd, 0x33, 0x0d, 0x51, 0x3d, 0x12, 0x6f, 0x4e, 0x72, 0xe0, 0x17, 0x20, 0xe9, 0x75, 0xe6, 0x3a, 0xb2, 0x13, 0x83, 0x4e, 0x7a, 0x08, 0x9e, 0xd1, 0x04, 0x5f, 0x6b, 0x42, 0x0b, 0x76, 0x2a, 0x2d, 0x77, 0x53, 0x6c, 0x65, 0x6d, 0x8e, 0x25, 0x3c, 0xb6, 0x8b, 0x69,
+	/* (2^177)P */ 0xb9, 0x49, 0x28, 0xd0, 0xdc, 0x6c, 0x8f, 0x4c, 0xc9, 0x14, 0x8a, 0x38, 0xa3, 0xcb, 0xc4, 0x9d, 0x53, 0xcf, 0xe9, 0xe3, 0xcf, 0xe0, 0xb1, 0xf2, 0x1b, 0x4c, 0x7f, 0x83, 0x2a, 0x7a, 0xe9, 0x8b, 0x3b, 0x86, 0x61, 0x30, 0xe9, 0x99, 0xbd, 0xba, 0x19, 0x6e, 0x65, 0x2a, 0x12, 0x3e, 0x9c, 0xa8, 0xaf, 0xc3, 0xcf, 0xf8, 0x1f, 0x77, 0x86, 0xea,
+	/* (2^178)P */ 0x30, 0xde, 0xe7, 0xff, 0x54, 0xf7, 0xa2, 0x59, 0xf6, 0x0b, 0xfb, 0x7a, 0xf2, 0x39, 0xf0, 0xdb, 0x39, 0xbc, 0xf0, 0xfa, 0x60, 0xeb, 0x6b, 0x4f, 0x47, 0x17, 0xc8, 0x00, 0x65, 0x6d, 0x25, 0x1c, 0xd0, 0x48, 0x56, 0x53, 0x45, 0x11, 0x30, 0x02, 0x49, 0x20, 0x27, 0xac, 0xf2, 0x4c, 0xac, 0x64, 0x3d, 0x52, 0xb8, 0x89, 0xe0, 0x93, 0x16, 0x0f,
+	/* (2^179)P */ 0x84, 0x09, 0xba, 0x40, 0xb2, 0x2f, 0xa3, 0xa8, 0xc2, 0xba, 0x46, 0x33, 0x05, 0x9d, 0x62, 0xad, 0xa1, 0x3c, 0x33, 0xef, 0x0d, 0xeb, 0xf0, 0x77, 0x11, 0x5a, 0xb0, 0x21, 0x9c, 0xdf, 0x55, 0x24, 0x25, 0x35, 0x51, 0x61, 0x92, 0xf0, 0xb1, 0xce, 0xf5, 0xd4, 0x7b, 0x6c, 0x21, 0x9d, 0x56, 0x52, 0xf8, 0xa1, 0x4c, 0xe9, 0x27, 0x55, 0xac, 0x91,
+	/* (2^180)P */ 0x03, 0x3e, 0x30, 0xd2, 0x0a, 0xfa, 0x7d, 0x82, 0x3d, 0x1f, 0x8b, 0xcb, 0xb6, 0x04, 0x5c, 0xcc, 0x8b, 0xda, 0xe2, 0x68, 0x74, 0x08, 0x8c, 0x44, 0x83, 0x57, 0x6d, 0x6f, 0x80, 0xb0, 0x7e, 0xa9, 0x82, 0x91, 0x7b, 0x4c, 0x37, 0x97, 0xd1, 0x63, 0xd1, 0xbd, 0x45, 0xe6, 0x8a, 0x86, 0xd6, 0x89, 0x54, 0xfd, 0xd2, 0xb1, 0xd7, 0x54, 0xad, 0xaf,
+	/* (2^181)P */ 0x8b, 0x33, 0x62, 0x49, 0x9f, 0x63, 0xf9, 0x87, 0x42, 0x58, 0xbf, 0xb3, 0xe6, 0x68, 0x02, 0x60, 0x5c, 0x76, 0x62, 0xf7, 0x61, 0xd7, 0x36, 0x31, 0xf7, 0x9c, 0xb5, 0xe5, 0x13, 0x6c, 0xea, 0x78, 0xae, 0xcf, 0xde, 0xbf, 0xb6, 0xeb, 0x4f, 0xc8, 0x2a, 0xb4, 0x9a, 0x9f, 0xf3, 0xd1, 0x6a, 0xec, 0x0c, 0xbd, 0x85, 0x98, 0x40, 0x06, 0x1c, 0x2a,
+	/* (2^182)P */ 0x74, 0x3b, 0xe7, 0x81, 0xd5, 0xae, 0x54, 0x56, 0x03, 0xe8, 0x97, 0x16, 0x76, 0xcf, 0x24, 0x96, 0x96, 0x5b, 0xcc, 0x09, 0xab, 0x23, 0x6f, 0x54, 0xae, 0x8f, 0xe4, 0x12, 0xcb, 0xfd, 0xbc, 0xac, 0x93, 0x45, 0x3d, 0x68, 0x08, 0x22, 0x59, 0xc6, 0xf0, 0x47, 0x19, 0x8c, 0x79, 0x93, 0x1e, 0x0e, 0x30, 0xb0, 0x94, 0xfb, 0x17, 0x1d, 0x5a, 0x12,
+	/* (2^183)P */ 0x85, 0xff, 0x40, 0x18, 0x85, 0xff, 0x44, 0x37, 0x69, 0x23, 0x4d, 0x34, 0xe1, 0xeb, 0xa3, 0x1b, 0x55, 0x40, 0xc1, 0x64, 0xf4, 0xd4, 0x13, 0x0a, 0x9f, 0xb9, 0x19, 0xfc, 0x88, 0x7d, 0xc0, 0x72, 0xcf, 0x69, 0x2f, 0xd2, 0x0c, 0x82, 0x0f, 0xda, 0x08, 0xba, 0x0f, 0xaa, 0x3b, 0xe9, 0xe5, 0x83, 0x7a, 0x06, 0xe8, 0x1b, 0x38, 0x43, 0xc3, 0x54,
+	/* (2^184)P */ 0x14, 0xaa, 0xb3, 0x6e, 0xe6, 0x28, 0xee, 0xc5, 0x22, 0x6c, 0x7c, 0xf9, 0xa8, 0x71, 0xcc, 0xfe, 0x68, 0x7e, 0xd3, 0xb8, 0x37, 0x96, 0xca, 0x0b, 0xd9, 0xb6, 0x06, 0xa9, 0xf6, 0x71, 0xe8, 0x31, 0xf7, 0xd8, 0xf1, 0x5d, 0xab, 0xb9, 0xf0, 0x5c, 0x98, 0xcf, 0x22, 0xa2, 0x2a, 0xf6, 0xd0, 0x59, 0xf0, 0x9d, 0xd9, 0x6a, 0x4f, 0x59, 0x57, 0xad,
+	/* (2^185)P */ 0xd7, 0x2b, 0x3d, 0x38, 0x4c, 0x2e, 0x23, 0x4d, 0x49, 0xa2, 0x62, 0x62, 0xf9, 0x0f, 0xde, 0x08, 0xf3, 0x86, 0x71, 0xb6, 0xc7, 0xf9, 0x85, 0x9c, 0x33, 0xa1, 0xcf, 0x16, 0xaa, 0x60, 0xb9, 0xb7, 0xea, 0xed, 0x01, 0x1c, 0x59, 0xdb, 0x3f, 0x3f, 0x97, 0x2e, 0xf0, 0x09, 0x9f, 0x10, 0x85, 0x5f, 0x53, 0x39, 0xf3, 0x13, 0x40, 0x56, 0x95, 0xf9,
+	/* (2^186)P */ 0xb4, 0xe3, 0xda, 0xc6, 0x1f, 0x78, 0x8e, 0xac, 0xd4, 0x20, 0x1d, 0xa0, 0xbf, 0x4c, 0x09, 0x16, 0xa7, 0x30, 0xb5, 0x8d, 0x9e, 0xa1, 0x5f, 0x6d, 0x52, 0xf4, 0x71, 0xb6, 0x32, 0x2d, 0x21, 0x51, 0xc6, 0xfc, 0x2f, 0x08, 0xf4, 0x13, 0x6c, 0x55, 0xba, 0x72, 0x81, 0x24, 0x49, 0x0e, 0x4f, 0x06, 0x36, 0x39, 0x6a, 0xc5, 0x81, 0xfc, 0xeb, 0xb2,
+	/* (2^187)P */ 0x7d, 0x8d, 0xc8, 0x6c, 0xea, 0xb4, 0xb9, 0xe8, 0x40, 0xc9, 0x69, 0xc9, 0x30, 0x05, 0xfd, 0x34, 0x46, 0xfd, 0x94, 0x05, 0x16, 0xf5, 0x4b, 0x13, 0x3d, 0x24, 0x1a, 0xd6, 0x64, 0x2b, 0x9c, 0xe2, 0xa5, 0xd9, 0x98, 0xe0, 0xe8, 0xf4, 0xbc, 0x2c, 0xbd, 0xa2, 0x56, 0xe3, 0x9e, 0x14, 0xdb, 0xbf, 0x05, 0xbf, 0x9a, 0x13, 0x5d, 0xf7, 0x91, 0xa3,
+	/* (2^188)P */ 0x8b, 0xcb, 0x27, 0xf3, 0x15, 0x26, 0x05, 0x40, 0x0f, 0xa6, 0x15, 0x13, 0x71, 0x95, 0xa2, 0xc6, 0x38, 0x04, 0x67, 0xf8, 0x9a, 0x83, 0x06, 0xaa, 0x25, 0x36, 0x72, 0x01, 0x6f, 0x74, 0x5f, 0xe5, 0x6e, 0x44, 0x99, 0xce, 0x13, 0xbc, 0x82, 0xc2, 0x0d, 0xa4, 0x98, 0x50, 0x38, 0xf3, 0xa2, 0xc5, 0xe5, 0x24, 0x1f, 0x6f, 0x56, 0x3e, 0x07, 0xb2,
+	/* (2^189)P */ 0xbd, 0x0f, 0x32, 0x60, 0x07, 0xb1, 0xd7, 0x0b, 0x11, 0x07, 0x57, 0x02, 0x89, 0xe8, 0x8b, 0xe8, 0x5a, 0x1f, 0xee, 0x54, 0x6b, 0xff, 0xb3, 0x04, 0x07, 0x57, 0x13, 0x0b, 0x94, 0xa8, 0x4d, 0x81, 0xe2, 0x17, 0x16, 0x45, 0xd4, 0x4b, 0xf7, 0x7e, 0x64, 0x66, 0x20, 0xe8, 0x0b, 0x26, 0xfd, 0xa9, 0x8a, 0x47, 0x52, 0x89, 0x14, 0xd0, 0xd1, 0xa1,
+	/* (2^190)P */ 0xdc, 0x03, 0xe6, 0x20, 0x44, 0x47, 0x8f, 0x04, 0x16, 0x24, 0x22, 0xc1, 0x55, 0x5c, 0xbe, 0x43, 0xc3, 0x92, 0xc5, 0x54, 0x3d, 0x5d, 0xd1, 0x05, 0x9c, 0xc6, 0x7c, 0xbf, 0x23, 0x84, 0x1a, 0xba, 0x4f, 0x1f, 0xfc, 0xa1, 0xae, 0x1a, 0x64, 0x02, 0x51, 0xf1, 0xcb, 0x7a, 0x20, 0xce, 0xb2, 0x34, 0x3c, 0xca, 0xe0, 0xe4, 0xba, 0x22, 0xd4, 0x7b,
+	/* (2^191)P */ 0xca, 0xfd, 0xca, 0xd7, 0xde, 0x61, 0xae, 0xf0, 0x79, 0x0c, 0x20, 0xab, 0xbc, 0x6f, 0x4d, 0x61, 0xf0, 0xc7, 0x9c, 0x8d, 0x4b, 0x52, 0xf3, 0xb9, 0x48, 0x63, 0x0b, 0xb6, 0xd2, 0x25, 0x9a, 0x96, 0x72, 0xc1, 0x6b, 0x0c, 0xb5, 0xfb, 0x71, 0xaa, 0xad, 0x47, 0x5b, 0xe7, 0xc0, 0x0a, 0x55, 0xb2, 0xd4, 0x16, 0x2f, 0xb1, 0x01, 0xfd, 0xce, 0x27,
+	/* (2^192)P */ 0x64, 0x11, 0x4b, 0xab, 0x57, 0x09, 0xc6, 0x49, 0x4a, 0x37, 0xc3, 0x36, 0xc4, 0x7b, 0x81, 0x1f, 0x42, 0xed, 0xbb, 0xe0, 0xa0, 0x8d, 0x51, 0xe6, 0xca, 0x8b, 0xb9, 0xcd, 0x99, 0x2d, 0x91, 0x53, 0xa9, 0x47, 0xcb, 0x32, 0xc7, 0xa4, 0x92, 0xec, 0x46, 0x74, 0x44, 0x6d, 0x71, 0x9f, 0x6d, 0x0c, 0x69, 0xa4, 0xf8, 0xbe, 0x9f, 0x7f, 0xa0, 0xd7,
+	/* (2^193)P */ 0x5f, 0x33, 0xb6, 0x91, 0xc8, 0xa5, 0x3f, 0x5d, 0x7f, 0x38, 0x6e, 0x74, 0x20, 0x4a, 0xd6, 0x2b, 0x98, 0x2a, 0x41, 0x4b, 0x83, 0x64, 0x0b, 0x92, 0x7a, 0x06, 0x1e, 0xc6, 0x2c, 0xf6, 0xe4, 0x91, 0xe5, 0xb1, 0x2e, 0x6e, 0x4e, 0xa8, 0xc8, 0x14, 0x32, 0x57, 0x44, 0x1c, 0xe4, 0xb9, 0x7f, 0x54, 0x51, 0x08, 0x81, 0xaa, 0x4e, 0xce, 0xa1, 0x5d,
+	/* (2^194)P */ 0x5c, 0xd5, 0x9b, 0x5e, 0x7c, 0xb5, 0xb1, 0x52, 0x73, 0x00, 0x41, 0x56, 0x79, 0x08, 0x7e, 0x07, 0x28, 0x06, 0xa6, 0xfb, 0x7f, 0x69, 0xbd, 0x7a, 0x3c, 0xae, 0x9f, 0x39, 0xbb, 0x54, 0xa2, 0x79, 0xb9, 0x0e, 0x7f, 0xbb, 0xe0, 0xe6, 0xb7, 0x27, 0x64, 0x38, 0x45, 0xdb, 0x84, 0xe4, 0x61, 0x72, 0x3f, 0xe2, 0x24, 0xfe, 0x7a, 0x31, 0x9a, 0xc9,
+	/* (2^195)P */ 0xa1, 0xd2, 0xa4, 0xee, 0x24, 0x96, 0xe5, 0x5b, 0x79, 0x78, 0x3c, 0x7b, 0x82, 0x3b, 0x8b, 0x58, 0x0b, 0xa3, 0x63, 0x2d, 0xbc, 0x75, 0x46, 0xe8, 0x83, 0x1a, 0xc0, 0x2a, 0x92, 0x61, 0xa8, 0x75, 0x37, 0x3c, 0xbf, 0x0f, 0xef, 0x8f, 0x6c, 0x97, 0x75, 0x10, 0x05, 0x7a, 0xde, 0x23, 0xe8, 0x2a, 0x35, 0xeb, 0x41, 0x64, 0x7d, 0xcf, 0xe0, 0x52,
+	/* (2^196)P */ 0x4a, 0xd0, 0x49, 0x93, 0xae, 0xf3, 0x24, 0x8c, 0xe1, 0x09, 0x98, 0x45, 0xd8, 0xb9, 0xfe, 0x8e, 0x8c, 0xa8, 0x2c, 0xc9, 0x9f, 0xce, 0x01, 0xdc, 0x38, 0x11, 0xab, 0x85, 0xb9, 0xe8, 0x00, 0x51, 0xfd, 0x82, 0xe1, 0x9b, 0x4e, 0xfc, 0xb5, 0x2a, 0x0f, 0x8b, 0xda, 0x4e, 0x02, 0xca, 0xcc, 0xe3, 0x91, 0xc4, 0xe0, 0xcf, 0x7b, 0xd6, 0xe6, 0x6a,
+	/* (2^197)P */ 0xfe, 0x11, 0xd7, 0xaa, 0xe3, 0x0c, 0x52, 0x2e, 0x04, 0xe0, 0xe0, 0x61, 0xc8, 0x05, 0xd7, 0x31, 0x4c, 0xc3, 0x9b, 0x2d, 0xce, 0x59, 0xbe, 0x12, 0xb7, 0x30, 0x21, 0xfc, 0x81, 0xb8, 0x5e, 0x57, 0x73, 0xd0, 0xad, 0x8e, 0x9e, 0xe4, 0xeb, 0xcd, 0xcf, 0xd2, 0x0f, 0x01, 0x35, 0x16, 0xed, 0x7a, 0x43, 0x8e, 0x42, 0xdc, 0xea, 0x4c, 0xa8, 0x7c,
+	/* (2^198)P */ 0x37, 0x26, 0xcc, 0x76, 0x0b, 0xe5, 0x76, 0xdd, 0x3e, 0x19, 0x3c, 0xc4, 0x6c, 0x7f, 0xd0, 0x03, 0xc1, 0xb8, 0x59, 0x82, 0xca, 0x36, 0xc1, 0xe4, 0xc8, 0xb2, 0x83, 0x69, 0x9c, 0xc5, 0x9d, 0x12, 0x82, 0x1c, 0xea, 0xb2, 0x84, 0x9f, 0xf3, 0x52, 0x6b, 0xbb, 0xd8, 0x81, 0x56, 0x83, 0x04, 0x66, 0x05, 0x22, 0x49, 0x37, 0x93, 0xb1, 0xfd, 0xd5,
+	/* (2^199)P */ 0xaf, 0x96, 0xbf, 0x03, 0xbe, 0xe6, 0x5d, 0x78, 0x19, 0xba, 0x37, 0x46, 0x0a, 0x2b, 0x52, 0x7c, 0xd8, 0x51, 0x9e, 0x3d, 0x29, 0x42, 0xdb, 0x0e, 0x31, 0x20, 0x94, 0xf8, 0x43, 0x9a, 0x2d, 0x22, 0xd3, 0xe3, 0xa1, 0x79, 0x68, 0xfb, 0x2d, 0x7e, 0xd6, 0x79, 0xda, 0x0b, 0xc6, 0x5b, 0x76, 0x68, 0xf0, 0xfe, 0x72, 0x59, 0xbb, 0xa1, 0x9c, 0x74,
+	/* (2^200)P */ 0x0a, 0xd9, 0xec, 0xc5, 0xbd, 0xf0, 0xda, 0xcf, 0x82, 0xab, 0x46, 0xc5, 0x32, 0x13, 0xdc, 0x5b, 0xac, 0xc3, 0x53, 0x9a, 0x7f, 0xef, 0xa5, 0x40, 0x5a, 0x1f, 0xc1, 0x12, 0x91, 0x54, 0x83, 0x6a, 0xb0, 0x9a, 0x85, 0x4d, 0xbf, 0x36, 0x8e, 0xd3, 0xa2, 0x2b, 0xe5, 0xd6, 0xc6, 0xe1, 0x58, 0x5b, 0x82, 0x9b, 0xc8, 0xf2, 0x03, 0xba, 0xf5, 0x92,
+	/* (2^201)P */ 0xfb, 0x21, 0x7e, 0xde, 0xe7, 0xb4, 0xc0, 0x56, 0x86, 0x3a, 0x5b, 0x78, 0xf8, 0xf0, 0xf4, 0xe7, 0x5c, 0x00, 0xd2, 0xd7, 0xd6, 0xf8, 0x75, 0x5e, 0x0f, 0x3e, 0xd1, 0x4b, 0x77, 0xd8, 0xad, 0xb0, 0xc9, 0x8b, 0x59, 0x7d, 0x30, 0x76, 0x64, 0x7a, 0x76, 0xd9, 0x51, 0x69, 0xfc, 0xbd, 0x8e, 0xb5, 0x55, 0xe0, 0xd2, 0x07, 0x15, 0xa9, 0xf7, 0xa4,
+	/* (2^202)P */ 0xaa, 0x2d, 0x2f, 0x2b, 0x3c, 0x15, 0xdd, 0xcd, 0xe9, 0x28, 0x82, 0x4f, 0xa2, 0xaa, 0x31, 0x48, 0xcc, 0xfa, 0x07, 0x73, 0x8a, 0x34, 0x74, 0x0d, 0xab, 0x1a, 0xca, 0xd2, 0xbf, 0x3a, 0xdb, 0x1a, 0x5f, 0x50, 0x62, 0xf4, 0x6b, 0x83, 0x38, 0x43, 0x96, 0xee, 0x6b, 0x39, 0x1e, 0xf0, 0x17, 0x80, 0x1e, 0x9b, 0xed, 0x2b, 0x2f, 0xcc, 0x65, 0xf7,
+	/* (2^203)P */ 0x03, 0xb3, 0x23, 0x9c, 0x0d, 0xd1, 0xeb, 0x7e, 0x34, 0x17, 0x8a, 0x4c, 0xde, 0x54, 0x39, 0xc4, 0x11, 0x82, 0xd3, 0xa4, 0x00, 0x32, 0x95, 0x9c, 0xa6, 0x64, 0x76, 0x6e, 0xd6, 0x53, 0x27, 0xb4, 0x6a, 0x14, 0x8c, 0x54, 0xf6, 0x58, 0x9e, 0x22, 0x4a, 0x55, 0x18, 0x77, 0xd0, 0x08, 0x6b, 0x19, 0x8a, 0xb5, 0xe7, 0x19, 0xb8, 0x60, 0x92, 0xb1,
+	/* (2^204)P */ 0x66, 0xec, 0xf3, 0x12, 0xde, 0x67, 0x7f, 0xd4, 0x5b, 0xf6, 0x70, 0x64, 0x0a, 0xb5, 0xc2, 0xf9, 0xb3, 0x64, 0xab, 0x56, 0x46, 0xc7, 0x93, 0xc2, 0x8b, 0x2d, 0xd0, 0xd6, 0x39, 0x3b, 0x1f, 0xcd, 0xb3, 0xac, 0xcc, 0x2c, 0x27, 0x6a, 0xbc, 0xb3, 0x4b, 0xa8, 0x3c, 0x69, 0x20, 0xe2, 0x18, 0x35, 0x17, 0xe1, 0x8a, 0xd3, 0x11, 0x74, 0xaa, 0x4d,
+	/* (2^205)P */ 0x96, 0xc4, 0x16, 0x7e, 0xfd, 0xf5, 0xd0, 0x7d, 0x1f, 0x32, 0x1b, 0xdb, 0xa6, 0xfd, 0x51, 0x75, 0x4d, 0xd7, 0x00, 0xe5, 0x7f, 0x58, 0x5b, 0xeb, 0x4b, 0x6a, 0x78, 0xfe, 0xe5, 0xd6, 0x8f, 0x99, 0x17, 0xca, 0x96, 0x45, 0xf7, 0x52, 0xdf, 0x84, 0x06, 0x77, 0xb9, 0x05, 0x63, 0x5d, 0xe9, 0x91, 0xb1, 0x4b, 0x82, 0x5a, 0xdb, 0xd7, 0xca, 0x69,
+	/* (2^206)P */ 0x02, 0xd3, 0x38, 0x38, 0x87, 0xea, 0xbd, 0x9f, 0x11, 0xca, 0xf3, 0x21, 0xf1, 0x9b, 0x35, 0x97, 0x98, 0xff, 0x8e, 0x6d, 0x3d, 0xd6, 0xb2, 0xfa, 0x68, 0xcb, 0x7e, 0x62, 0x85, 0xbb, 0xc7, 0x5d, 0xee, 0x32, 0x30, 0x2e, 0x71, 0x96, 0x63, 0x43, 0x98, 0xc4, 0xa7, 0xde, 0x60, 0xb2, 0xd9, 0x43, 0x4a, 0xfa, 0x97, 0x2d, 0x5f, 0x21, 0xd4, 0xfe,
+	/* (2^207)P */ 0x3b, 0x20, 0x29, 0x07, 0x07, 0xb5, 0x78, 0xc3, 0xc7, 0xab, 0x56, 0xba, 0x40, 0xde, 0x1d, 0xcf, 0xc3, 0x00, 0x56, 0x21, 0x0c, 0xc8, 0x42, 0xd9, 0x0e, 0xcd, 0x02, 0x7c, 0x07, 0xb9, 0x11, 0xd7, 0x96, 0xaf, 0xff, 0xad, 0xc5, 0xba, 0x30, 0x6d, 0x82, 0x3a, 0xbf, 0xef, 0x7b, 0xf7, 0x0a, 0x74, 0xbd, 0x31, 0x0c, 0xe4, 0xec, 0x1a, 0xe5, 0xc5,
+	/* (2^208)P */ 0xcc, 0xf2, 0x28, 0x16, 0x12, 0xbf, 0xef, 0x85, 0xbc, 0xf7, 0xcb, 0x9f, 0xdb, 0xa8, 0xb2, 0x49, 0x53, 0x48, 0xa8, 0x24, 0xa8, 0x68, 0x8d, 0xbb, 0x21, 0x0a, 0x5a, 0xbd, 0xb2, 0x91, 0x61, 0x47, 0xc4, 0x43, 0x08, 0xa6, 0x19, 0xef, 0x8e, 0x88, 0x39, 0xc6, 0x33, 0x30, 0xf3, 0x0e, 0xc5, 0x92, 0x66, 0xd6, 0xfe, 0xc5, 0x12, 0xd9, 0x4c, 0x2d,
+	/* (2^209)P */ 0x30, 0x34, 0x07, 0xbf, 0x9c, 0x5a, 0x4e, 0x65, 0xf1, 0x39, 0x35, 0x38, 0xae, 0x7b, 0x55, 0xac, 0x6a, 0x92, 0x24, 0x7e, 0x50, 0xd3, 0xba, 0x78, 0x51, 0xfe, 0x4d, 0x32, 0x05, 0x11, 0xf5, 0x52, 0xf1, 0x31, 0x45, 0x39, 0x98, 0x7b, 0x28, 0x56, 0xc3, 0x5d, 0x4f, 0x07, 0x6f, 0x84, 0xb8, 0x1a, 0x58, 0x0b, 0xc4, 0x7c, 0xc4, 0x8d, 0x32, 0x8e,
+	/* (2^210)P */ 0x7e, 0xaf, 0x98, 0xce, 0xc5, 0x2b, 0x9d, 0xf6, 0xfa, 0x2c, 0xb6, 0x2a, 0x5a, 0x1d, 0xc0, 0x24, 0x8d, 0xa4, 0xce, 0xb1, 0x12, 0x01, 0xf9, 0x79, 0xc6, 0x79, 0x38, 0x0c, 0xd4, 0x07, 0xc9, 0xf7, 0x37, 0xa1, 0x0b, 0xfe, 0x72, 0xec, 0x5d, 0xd6, 0xb0, 0x1c, 0x70, 0xbe, 0x70, 0x01, 0x13, 0xe0, 0x86, 0x95, 0xc7, 0x2e, 0x12, 0x3b, 0xe6, 0xa6,
+	/* (2^211)P */ 0x24, 0x82, 0x67, 0xe0, 0x14, 0x7b, 0x56, 0x08, 0x38, 0x44, 0xdb, 0xa0, 0x3a, 0x05, 0x47, 0xb2, 0xc0, 0xac, 0xd1, 0xcc, 0x3f, 0x82, 0xb8, 0x8a, 0x88, 0xbc, 0xf5, 0x33, 0xa1, 0x35, 0x0f, 0xf6, 0xe2, 0xef, 0x6c, 0xf7, 0x37, 0x9e, 0xe8, 0x10, 0xca, 0xb0, 0x8e, 0x80, 0x86, 0x00, 0x23, 0xd0, 0x4a, 0x76, 0x9f, 0xf7, 0x2c, 0x52, 0x15, 0x0e,
+	/* (2^212)P */ 0x5e, 0x49, 0xe1, 0x2c, 0x9a, 0x01, 0x76, 0xa6, 0xb3, 0x07, 0x5b, 0xa4, 0x07, 0xef, 0x1d, 0xc3, 0x6a, 0xbb, 0x64, 0xbe, 0x71, 0x15, 0x6e, 0x32, 0x31, 0x46, 0x9a, 0x9e, 0x8f, 0x45, 0x73, 0xce, 0x0b, 0x94, 0x1a, 0x52, 0x07, 0xf4, 0x50, 0x30, 0x49, 0x53, 0x50, 0xfb, 0x71, 0x1f, 0x5a, 0x03, 0xa9, 0x76, 0xf2, 0x8f, 0x42, 0xff, 0xed, 0xed,
+	/* (2^213)P */ 0xed, 0x08, 0xdb, 0x91, 0x1c, 0xee, 0xa2, 0xb4, 0x47, 0xa2, 0xfa, 0xcb, 0x03, 0xd1, 0xff, 0x8c, 0xad, 0x64, 0x50, 0x61, 0xcd, 0xfc, 0x88, 0xa0, 0x31, 0x95, 0x30, 0xb9, 0x58, 0xdd, 0xd7, 0x43, 0xe4, 0x46, 0xc2, 0x16, 0xd9, 0x72, 0x4a, 0x56, 0x51, 0x70, 0x85, 0xf1, 0xa1, 0x80, 0x40, 0xd5, 0xba, 0x67, 0x81, 0xda, 0xcd, 0x03, 0xea, 0x51,
+	/* (2^214)P */ 0x42, 0x50, 0xf0, 0xef, 0x37, 0x61, 0x72, 0x85, 0xe1, 0xf1, 0xff, 0x6f, 0x3d, 0xe8, 0x7b, 0x21, 0x5c, 0xe5, 0x50, 0x03, 0xde, 0x00, 0xc1, 0xf7, 0x3a, 0x55, 0x12, 0x1c, 0x9e, 0x1e, 0xce, 0xd1, 0x2f, 0xaf, 0x05, 0x70, 0x5b, 0x47, 0xf2, 0x04, 0x7a, 0x89, 0xbc, 0x78, 0xa6, 0x65, 0x6c, 0xaa, 0x3c, 0xa2, 0x3c, 0x8b, 0x5c, 0xa9, 0x22, 0x48,
+	/* (2^215)P */ 0x7e, 0x8c, 0x8f, 0x2f, 0x60, 0xe3, 0x5a, 0x94, 0xd4, 0xce, 0xdd, 0x9d, 0x83, 0x3b, 0x77, 0x78, 0x43, 0x1d, 0xfd, 0x8f, 0xc8, 0xe8, 0x02, 0x90, 0xab, 0xf6, 0xc9, 0xfc, 0xf1, 0x63, 0xaa, 0x5f, 0x42, 0xf1, 0x78, 0x34, 0x64, 0x16, 0x75, 0x9c, 0x7d, 0xd0, 0xe4, 0x74, 0x5a, 0xa8, 0xfb, 0xcb, 0xac, 0x20, 0xa3, 0xc2, 0xa6, 0x20, 0xf8, 0x1b,
+	/* (2^216)P */ 0x00, 0x4f, 0x1e, 0x56, 0xb5, 0x34, 0xb2, 0x87, 0x31, 0xe5, 0xee, 0x8d, 0xf1, 0x41, 0x67, 0xb7, 0x67, 0x3a, 0x54, 0x86, 0x5c, 0xf0, 0x0b, 0x37, 0x2f, 0x1b, 0x92, 0x5d, 0x58, 0x93, 0xdc, 0xd8, 0x58, 0xcc, 0x9e, 0x67, 0xd0, 0x97, 0x3a, 0xaf, 0x49, 0x39, 0x2d, 0x3b, 0xd8, 0x98, 0xfb, 0x76, 0x6b, 0xe7, 0xaf, 0xc3, 0x45, 0x44, 0x53, 0x94,
+	/* (2^217)P */ 0x30, 0xbd, 0x90, 0x75, 0xd3, 0xbd, 0x3b, 0x58, 0x27, 0x14, 0x9f, 0x6b, 0xd4, 0x31, 0x99, 0xcd, 0xde, 0x3a, 0x21, 0x1e, 0xb4, 0x02, 0xe4, 0x33, 0x04, 0x02, 0xb0, 0x50, 0x66, 0x68, 0x90, 0xdd, 0x7b, 0x69, 0x31, 0xd9, 0xcf, 0x68, 0x73, 0xf1, 0x60, 0xdd, 0xc8, 0x1d, 0x5d, 0xe3, 0xd6, 0x5b, 0x2a, 0xa4, 0xea, 0xc4, 0x3f, 0x08, 0xcd, 0x9c,
+	/* (2^218)P */ 0x6b, 0x1a, 0xbf, 0x55, 0xc1, 0x1b, 0x0c, 0x05, 0x09, 0xdf, 0xf5, 0x5e, 0xa3, 0x77, 0x95, 0xe9, 0xdf, 0x19, 0xdd, 0xc7, 0x94, 0xcb, 0x06, 0x73, 0xd0, 0x88, 0x02, 0x33, 0x94, 0xca, 0x7a, 0x2f, 0x8e, 0x3d, 0x72, 0x61, 0x2d, 0x4d, 0xa6, 0x61, 0x1f, 0x32, 0x5e, 0x87, 0x53, 0x36, 0x11, 0x15, 0x20, 0xb3, 0x5a, 0x57, 0x51, 0x93, 0x20, 0xd8,
+	/* (2^219)P */ 0xb7, 0x56, 0xf4, 0xab, 0x7d, 0x0c, 0xfb, 0x99, 0x1a, 0x30, 0x29, 0xb0, 0x75, 0x2a, 0xf8, 0x53, 0x71, 0x23, 0xbd, 0xa7, 0xd8, 0x0a, 0xe2, 0x27, 0x65, 0xe9, 0x74, 0x26, 0x98, 0x4a, 0x69, 0x19, 0xb2, 0x4d, 0x0a, 0x17, 0x98, 0xb2, 0xa9, 0x57, 0x4e, 0xf6, 0x86, 0xc8, 0x01, 0xa4, 0xc6, 0x98, 0xad, 0x5a, 0x90, 0x2c, 0x05, 0x46, 0x64, 0xb7,
+	/* (2^220)P */ 0x7b, 0x91, 0xdf, 0xfc, 0xf8, 0x1c, 0x8c, 0x15, 0x9e, 0xf7, 0xd5, 0xa8, 0xe8, 0xe7, 0xe3, 0xa3, 0xb0, 0x04, 0x74, 0xfa, 0x78, 0xfb, 0x26, 0xbf, 0x67, 0x42, 0xf9, 0x8c, 0x9b, 0xb4, 0x69, 0x5b, 0x02, 0x13, 0x6d, 0x09, 0x6c, 0xd6, 0x99, 0x61, 0x7b, 0x89, 0x4a, 0x67, 0x75, 0xa3, 0x98, 0x13, 0x23, 0x1d, 0x18, 0x24, 0x0e, 0xef, 0x41, 0x79,
+	/* (2^221)P */ 0x86, 0x33, 0xab, 0x08, 0xcb, 0xbf, 0x1e, 0x76, 0x3c, 0x0b, 0xbd, 0x30, 0xdb, 0xe9, 0xa3, 0x35, 0x87, 0x1b, 0xe9, 0x07, 0x00, 0x66, 0x7f, 0x3b, 0x35, 0x0c, 0x8a, 0x3f, 0x61, 0xbc, 0xe0, 0xae, 0xf6, 0xcc, 0x54, 0xe1, 0x72, 0x36, 0x2d, 0xee, 0x93, 0x24, 0xf8, 0xd7, 0xc5, 0xf9, 0xcb, 0xb0, 0xe5, 0x88, 0x0d, 0x23, 0x4b, 0x76, 0x15, 0xa2,
+	/* (2^222)P */ 0x37, 0xdb, 0x83, 0xd5, 0x6d, 0x06, 0x24, 0x37, 0x1b, 0x15, 0x85, 0x15, 0xe2, 0xc0, 0x4e, 0x02, 0xa9, 0x6d, 0x0a, 0x3a, 0x94, 0x4a, 0x6f, 0x49, 0x00, 0x01, 0x72, 0xbb, 0x60, 0x14, 0x35, 0xae, 0xb4, 0xc6, 0x01, 0x0a, 0x00, 0x9e, 0xc3, 0x58, 0xc5, 0xd1, 0x5e, 0x30, 0x73, 0x96, 0x24, 0x85, 0x9d, 0xf0, 0xf9, 0xec, 0x09, 0xd3, 0xe7, 0x70,
+	/* (2^223)P */ 0xf3, 0xbd, 0x96, 0x87, 0xe9, 0x71, 0xbd, 0xd6, 0xa2, 0x45, 0xeb, 0x0a, 0xcd, 0x2c, 0xf1, 0x72, 0xa6, 0x31, 0xa9, 0x6f, 0x09, 0xa1, 0x5e, 0xdd, 0xc8, 0x8d, 0x0d, 0xbc, 0x5a, 0x8d, 0xb1, 0x2c, 0x9a, 0xcc, 0x37, 0x74, 0xc2, 0xa9, 0x4e, 0xd6, 0xc0, 0x3c, 0xa0, 0x23, 0xb0, 0xa0, 0x77, 0x14, 0x80, 0x45, 0x71, 0x6a, 0x2d, 0x41, 0xc3, 0x82,
+	/* (2^224)P */ 0x37, 0x44, 0xec, 0x8a, 0x3e, 0xc1, 0x0c, 0xa9, 0x12, 0x9c, 0x08, 0x88, 0xcb, 0xd9, 0xf8, 0xba, 0x00, 0xd6, 0xc3, 0xdf, 0xef, 0x7a, 0x44, 0x7e, 0x25, 0x69, 0xc9, 0xc1, 0x46, 0xe5, 0x20, 0x9e, 0xcc, 0x0b, 0x05, 0x3e, 0xf4, 0x78, 0x43, 0x0c, 0xa6, 0x2f, 0xc1, 0xfa, 0x70, 0xb2, 0x3c, 0x31, 0x7a, 0x63, 0x58, 0xab, 0x17, 0xcf, 0x4c, 0x4f,
+	/* (2^225)P */ 0x2b, 0x08, 0x31, 0x59, 0x75, 0x8b, 0xec, 0x0a, 0xa9, 0x79, 0x70, 0xdd, 0xf1, 0x11, 0xc3, 0x11, 0x1f, 0xab, 0x37, 0xaa, 0x26, 0xea, 0x53, 0xc4, 0x79, 0xa7, 0x91, 0x00, 0xaa, 0x08, 0x42, 0xeb, 0x8b, 0x8b, 0xe8, 0xc3, 0x2f, 0xb8, 0x78, 0x90, 0x38, 0x0e, 0x8a, 0x42, 0x0c, 0x0f, 0xbf, 0x3e, 0xf8, 0xd8, 0x07, 0xcf, 0x6a, 0x34, 0xc9, 0xfa,
+	/* (2^226)P */ 0x11, 0xe0, 0x76, 0x4d, 0x23, 0xc5, 0xa6, 0xcc, 0x9f, 0x9a, 0x2a, 0xde, 0x3a, 0xb5, 0x92, 0x39, 0x19, 0x8a, 0xf1, 0x8d, 0xf9, 0x4d, 0xc9, 0xb4, 0x39, 0x9f, 0x57, 0xd8, 0x72, 0xab, 0x1d, 0x61, 0x6a, 0xb2, 0xff, 0x52, 0xba, 0x54, 0x0e, 0xfb, 0x83, 0x30, 0x8a, 0xf7, 0x3b, 0xf4, 0xd8, 0xae, 0x1a, 0x94, 0x3a, 0xec, 0x63, 0xfe, 0x6e, 0x7c,
+	/* (2^227)P */ 0xdc, 0x70, 0x8e, 0x55, 0x44, 0xbf, 0xd2, 0x6a, 0xa0, 0x14, 0x61, 0x89, 0xd5, 0x55, 0x45, 0x3c, 0xf6, 0x40, 0x0d, 0x83, 0x85, 0x44, 0xb4, 0x62, 0x56, 0xfe, 0x60, 0xd7, 0x07, 0x1d, 0x47, 0x30, 0x3b, 0x73, 0xa4, 0xb5, 0xb7, 0xea, 0xac, 0xda, 0xf1, 0x17, 0xaa, 0x60, 0xdf, 0xe9, 0x84, 0xda, 0x31, 0x32, 0x61, 0xbf, 0xd0, 0x7e, 0x8a, 0x02,
+	/* (2^228)P */ 0xb9, 0x51, 0xb3, 0x89, 0x21, 0x5d, 0xa2, 0xfe, 0x79, 0x2a, 0xb3, 0x2a, 0x3b, 0xe6, 0x6f, 0x2b, 0x22, 0x03, 0xea, 0x7b, 0x1f, 0xaf, 0x85, 0xc3, 0x38, 0x55, 0x5b, 0x8e, 0xb4, 0xaa, 0x77, 0xfe, 0x03, 0x6e, 0xda, 0x91, 0x24, 0x0c, 0x48, 0x39, 0x27, 0x43, 0x16, 0xd2, 0x0a, 0x0d, 0x43, 0xa3, 0x0e, 0xca, 0x45, 0xd1, 0x7f, 0xf5, 0xd3, 0x16,
+	/* (2^229)P */ 0x3d, 0x32, 0x9b, 0x38, 0xf8, 0x06, 0x93, 0x78, 0x5b, 0x50, 0x2b, 0x06, 0xd8, 0x66, 0xfe, 0xab, 0x9b, 0x58, 0xc7, 0xd1, 0x4d, 0xd5, 0xf8, 0x3b, 0x10, 0x7e, 0x85, 0xde, 0x58, 0x4e, 0xdf, 0x53, 0xd9, 0x58, 0xe0, 0x15, 0x81, 0x9f, 0x1a, 0x78, 0xfc, 0x9f, 0x10, 0xc2, 0x23, 0xd6, 0x78, 0xd1, 0x9d, 0xd2, 0xd5, 0x1c, 0x53, 0xe2, 0xc9, 0x76,
+	/* (2^230)P */ 0x98, 0x1e, 0x38, 0x7b, 0x71, 0x18, 0x4b, 0x15, 0xaf, 0xa1, 0xa6, 0x98, 0xcb, 0x26, 0xa3, 0xc8, 0x07, 0x46, 0xda, 0x3b, 0x70, 0x65, 0xec, 0x7a, 0x2b, 0x34, 0x94, 0xa8, 0xb6, 0x14, 0xf8, 0x1a, 0xce, 0xf7, 0xc8, 0x60, 0xf3, 0x88, 0xf4, 0x33, 0x60, 0x7b, 0xd1, 0x02, 0xe7, 0xda, 0x00, 0x4a, 0xea, 0xd2, 0xfd, 0x88, 0xd2, 0x99, 0x28, 0xf3,
+	/* (2^231)P */ 0x28, 0x24, 0x1d, 0x26, 0xc2, 0xeb, 0x8b, 0x3b, 0xb4, 0x6b, 0xbe, 0x6b, 0x77, 0xff, 0xf3, 0x21, 0x3b, 0x26, 0x6a, 0x8c, 0x8e, 0x2a, 0x44, 0xa8, 0x01, 0x2b, 0x71, 0xea, 0x64, 0x30, 0xfd, 0xfd, 0x95, 0xcb, 0x39, 0x38, 0x48, 0xfa, 0x96, 0x97, 0x8c, 0x2f, 0x33, 0xca, 0x03, 0xe6, 0xd7, 0x94, 0x55, 0x6c, 0xc3, 0xb3, 0xa8, 0xf7, 0xae, 0x8c,
+	/* (2^232)P */ 0xea, 0x62, 0x8a, 0xb4, 0xeb, 0x74, 0xf7, 0xb8, 0xae, 0xc5, 0x20, 0x71, 0x06, 0xd6, 0x7c, 0x62, 0x9b, 0x69, 0x74, 0xef, 0xa7, 0x6d, 0xd6, 0x8c, 0x37, 0xb9, 0xbf, 0xcf, 0xeb, 0xe4, 0x2f, 0x04, 0x02, 0x21, 0x7d, 0x75, 0x6b, 0x92, 0x48, 0xf8, 0x70, 0xad, 0x69, 0xe2, 0xea, 0x0e, 0x88, 0x67, 0x72, 0xcc, 0x2d, 0x10, 0xce, 0x2d, 0xcf, 0x65,
+	/* (2^233)P */ 0x49, 0xf3, 0x57, 0x64, 0xe5, 0x5c, 0xc5, 0x65, 0x49, 0x97, 0xc4, 0x8a, 0xcc, 0xa9, 0xca, 0x94, 0x7b, 0x86, 0x88, 0xb6, 0x51, 0x27, 0x69, 0xa5, 0x0f, 0x8b, 0x06, 0x59, 0xa0, 0x94, 0xef, 0x63, 0x1a, 0x01, 0x9e, 0x4f, 0xd2, 0x5a, 0x93, 0xc0, 0x7c, 0xe6, 0x61, 0x77, 0xb6, 0xf5, 0x40, 0xd9, 0x98, 0x43, 0x5b, 0x56, 0x68, 0xe9, 0x37, 0x8f,
+	/* (2^234)P */ 0xee, 0x87, 0xd2, 0x05, 0x1b, 0x39, 0x89, 0x10, 0x07, 0x6d, 0xe8, 0xfd, 0x8b, 0x4d, 0xb2, 0xa7, 0x7b, 0x1e, 0xa0, 0x6c, 0x0d, 0x3d, 0x3d, 0x49, 0xba, 0x61, 0x36, 0x1f, 0xc2, 0x84, 0x4a, 0xcc, 0x87, 0xa9, 0x1b, 0x23, 0x04, 0xe2, 0x3e, 0x97, 0xe1, 0xdb, 0xd5, 0x5a, 0xe8, 0x41, 0x6b, 0xe5, 0x5a, 0xa1, 0x99, 0xe5, 0x7b, 0xa7, 0xe0, 0x3b,
+	/* (2^235)P */ 0xea, 0xa3, 0x6a, 0xdd, 0x77, 0x7f, 0x77, 0x41, 0xc5, 0x6a, 0xe4, 0xaf, 0x11, 0x5f, 0x88, 0xa5, 0x10, 0xee, 0xd0, 0x8c, 0x0c, 0xb4, 0xa5, 0x2a, 0xd0, 0xd8, 0x1d, 0x47, 0x06, 0xc0, 0xd5, 0xce, 0x51, 0x54, 0x9b, 0x2b, 0xe6, 0x2f, 0xe7, 0xe7, 0x31, 0x5f, 0x5c, 0x23, 0x81, 0x3e, 0x03, 0x93, 0xaa, 0x2d, 0x71, 0x84, 0xa0, 0x89, 0x32, 0xa6,
+	/* (2^236)P */ 0x55, 0xa3, 0x13, 0x92, 0x4e, 0x93, 0x7d, 0xec, 0xca, 0x57, 0xfb, 0x37, 0xae, 0xd2, 0x18, 0x2e, 0x54, 0x05, 0x6c, 0xd1, 0x28, 0xca, 0x90, 0x40, 0x82, 0x2e, 0x79, 0xc6, 0x5a, 0xc7, 0xdd, 0x84, 0x93, 0xdf, 0x15, 0xb8, 0x1f, 0xb1, 0xf9, 0xaf, 0x2c, 0xe5, 0x32, 0xcd, 0xc2, 0x99, 0x6d, 0xac, 0x85, 0x5c, 0x63, 0xd3, 0xe2, 0xff, 0x24, 0xda,
+	/* (2^237)P */ 0x2d, 0x8d, 0xfd, 0x65, 0xcc, 0xe5, 0x02, 0xa0, 0xe5, 0xb9, 0xec, 0x59, 0x09, 0x50, 0x27, 0xb7, 0x3d, 0x2a, 0x79, 0xb2, 0x76, 0x5d, 0x64, 0x95, 0xf8, 0xc5, 0xaf, 0x8a, 0x62, 0x11, 0x5c, 0x56, 0x1c, 0x05, 0x64, 0x9e, 0x5e, 0xbd, 0x54, 0x04, 0xe6, 0x9e, 0xab, 0xe6, 0x22, 0x7e, 0x42, 0x54, 0xb5, 0xa5, 0xd0, 0x8d, 0x28, 0x6b, 0x0f, 0x0b,
+	/* (2^238)P */ 0x2d, 0xb2, 0x8c, 0x59, 0x10, 0x37, 0x84, 0x3b, 0x9b, 0x65, 0x1b, 0x0f, 0x10, 0xf9, 0xea, 0x60, 0x1b, 0x02, 0xf5, 0xee, 0x8b, 0xe6, 0x32, 0x7d, 0x10, 0x7f, 0x5f, 0x8c, 0x72, 0x09, 0x4e, 0x1f, 0x29, 0xff, 0x65, 0xcb, 0x3e, 0x3a, 0xd2, 0x96, 0x50, 0x1e, 0xea, 0x64, 0x99, 0xb5, 0x4c, 0x7a, 0x69, 0xb8, 0x95, 0xae, 0x48, 0xc0, 0x7c, 0xb1,
+	/* (2^239)P */ 0xcd, 0x7c, 0x4f, 0x3e, 0xea, 0xf3, 0x90, 0xcb, 0x12, 0x76, 0xd1, 0x17, 0xdc, 0x0d, 0x13, 0x0f, 0xfd, 0x4d, 0xb5, 0x1f, 0xe4, 0xdd, 0xf2, 0x4d, 0x58, 0xea, 0xa5, 0x66, 0x92, 0xcf, 0xe5, 0x54, 0xea, 0x9b, 0x35, 0x83, 0x1a, 0x44, 0x8e, 0x62, 0x73, 0x45, 0x98, 0xa3, 0x89, 0x95, 0x52, 0x93, 0x1a, 0x8d, 0x63, 0x0f, 0xc2, 0x57, 0x3c, 0xb1,
+	/* (2^240)P */ 0x72, 0xb4, 0xdf, 0x51, 0xb7, 0xf6, 0x52, 0xa2, 0x14, 0x56, 0xe5, 0x0a, 0x2e, 0x75, 0x81, 0x02, 0xee, 0x93, 0x48, 0x0a, 0x92, 0x4e, 0x0c, 0x0f, 0xdf, 0x09, 0x89, 0x99, 0xf6, 0xf9, 0x22, 0xa2, 0x32, 0xf8, 0xb0, 0x76, 0x0c, 0xb2, 0x4d, 0x6e, 0xbe, 0x83, 0x35, 0x61, 0x44, 0xd2, 0x58, 0xc7, 0xdd, 0x14, 0xcf, 0xc3, 0x4b, 0x7c, 0x07, 0xee,
+	/* (2^241)P */ 0x8b, 0x03, 0xee, 0xcb, 0xa7, 0x2e, 0x28, 0xbd, 0x97, 0xd1, 0x4c, 0x2b, 0xd1, 0x92, 0x67, 0x5b, 0x5a, 0x12, 0xbf, 0x29, 0x17, 0xfc, 0x50, 0x09, 0x74, 0x76, 0xa2, 0xd4, 0x82, 0xfd, 0x2c, 0x0c, 0x90, 0xf7, 0xe7, 0xe5, 0x9a, 0x2c, 0x16, 0x40, 0xb9, 0x6c, 0xd9, 0xe0, 0x22, 0x9e, 0xf8, 0xdd, 0x73, 0xe4, 0x7b, 0x9e, 0xbe, 0x4f, 0x66, 0x22,
+	/* (2^242)P */ 0xa4, 0x10, 0xbe, 0xb8, 0x83, 0x3a, 0x77, 0x8e, 0xea, 0x0a, 0xc4, 0x97, 0x3e, 0xb6, 0x6c, 0x81, 0xd7, 0x65, 0xd9, 0xf7, 0xae, 0xe6, 0xbe, 0xab, 0x59, 0x81, 0x29, 0x4b, 0xff, 0xe1, 0x0f, 0xc3, 0x2b, 0xad, 0x4b, 0xef, 0xc4, 0x50, 0x9f, 0x88, 0x31, 0xf2, 0xde, 0x80, 0xd6, 0xf4, 0x20, 0x9c, 0x77, 0x9b, 0xbe, 0xbe, 0x08, 0xf5, 0xf0, 0x95,
+	/* (2^243)P */ 0x0e, 0x7c, 0x7b, 0x7c, 0xb3, 0xd8, 0x83, 0xfc, 0x8c, 0x75, 0x51, 0x74, 0x1b, 0xe1, 0x6d, 0x11, 0x05, 0x46, 0x24, 0x0d, 0xa4, 0x2b, 0x32, 0xfd, 0x2c, 0x4e, 0x21, 0xdf, 0x39, 0x6b, 0x96, 0xfc, 0xff, 0x92, 0xfc, 0x35, 0x0d, 0x9a, 0x4b, 0xc0, 0x70, 0x46, 0x32, 0x7d, 0xc0, 0xc4, 0x04, 0xe0, 0x2d, 0x83, 0xa7, 0x00, 0xc7, 0xcb, 0xb4, 0x8f,
+	/* (2^244)P */ 0xa9, 0x5a, 0x7f, 0x0e, 0xdd, 0x2c, 0x85, 0xaa, 0x4d, 0xac, 0xde, 0xb3, 0xb6, 0xaf, 0xe6, 0xd1, 0x06, 0x7b, 0x2c, 0xa4, 0x01, 0x19, 0x22, 0x7d, 0x78, 0xf0, 0x3a, 0xea, 0x89, 0xfe, 0x21, 0x61, 0x6d, 0xb8, 0xfe, 0xa5, 0x2a, 0xab, 0x0d, 0x7b, 0x51, 0x39, 0xb6, 0xde, 0xbc, 0xf0, 0xc5, 0x48, 0xd7, 0x09, 0x82, 0x6e, 0x66, 0x75, 0xc5, 0xcd,
+	/* (2^245)P */ 0xee, 0xdf, 0x2b, 0x6c, 0xa8, 0xde, 0x61, 0xe1, 0x27, 0xfa, 0x2a, 0x0f, 0x68, 0xe7, 0x7a, 0x9b, 0x13, 0xe9, 0x56, 0xd2, 0x1c, 0x3d, 0x2f, 0x3c, 0x7a, 0xf6, 0x6f, 0x45, 0xee, 0xe8, 0xf4, 0xa0, 0xa6, 0xe8, 0xa5, 0x27, 0xee, 0xf2, 0x85, 0xa9, 0xd5, 0x0e, 0xa9, 0x26, 0x60, 0xfe, 0xee, 0xc7, 0x59, 0x99, 0x5e, 0xa3, 0xdf, 0x23, 0x36, 0xd5,
+	/* (2^246)P */ 0x15, 0x66, 0x6f, 0xd5, 0x78, 0xa4, 0x0a, 0xf7, 0xb1, 0xe8, 0x75, 0x6b, 0x48, 0x7d, 0xa6, 0x4d, 0x3d, 0x36, 0x9b, 0xc7, 0xcc, 0x68, 0x9a, 0xfe, 0x2f, 0x39, 0x2a, 0x51, 0x31, 0x39, 0x7d, 0x73, 0x6f, 0xc8, 0x74, 0x72, 0x6f, 0x6e, 0xda, 0x5f, 0xad, 0x48, 0xc8, 0x40, 0xe1, 0x06, 0x01, 0x36, 0xa1, 0x88, 0xc8, 0x99, 0x9c, 0xd1, 0x11, 0x8f,
+	/* (2^247)P */ 0xab, 0xc5, 0xcb, 0xcf, 0xbd, 0x73, 0x21, 0xd0, 0x82, 0xb1, 0x2e, 0x2d, 0xd4, 0x36, 0x1b, 0xed, 0xa9, 0x8a, 0x26, 0x79, 0xc4, 0x17, 0xae, 0xe5, 0x09, 0x0a, 0x0c, 0xa4, 0x21, 0xa0, 0x6e, 0xdd, 0x62, 0x8e, 0x44, 0x62, 0xcc, 0x50, 0xff, 0x93, 0xb3, 0x9a, 0x72, 0x8c, 0x3f, 0xa1, 0xa6, 0x4d, 0x87, 0xd5, 0x1c, 0x5a, 0xc0, 0x0b, 0x1a, 0xd6,
+	/* (2^248)P */ 0x67, 0x36, 0x6a, 0x1f, 0x96, 0xe5, 0x80, 0x20, 0xa9, 0xe8, 0x0b, 0x0e, 0x21, 0x29, 0x3f, 0xc8, 0x0a, 0x6d, 0x27, 0x47, 0xca, 0xd9, 0x05, 0x55, 0xbf, 0x11, 0xcf, 0x31, 0x7a, 0x37, 0xc7, 0x90, 0xa9, 0xf4, 0x07, 0x5e, 0xd5, 0xc3, 0x92, 0xaa, 0x95, 0xc8, 0x23, 0x2a, 0x53, 0x45, 0xe3, 0x3a, 0x24, 0xe9, 0x67, 0x97, 0x3a, 0x82, 0xf9, 0xa6,
+	/* (2^249)P */ 0x92, 0x9e, 0x6d, 0x82, 0x67, 0xe9, 0xf9, 0x17, 0x96, 0x2c, 0xa7, 0xd3, 0x89, 0xf9, 0xdb, 0xd8, 0x20, 0xc6, 0x2e, 0xec, 0x4a, 0x76, 0x64, 0xbf, 0x27, 0x40, 0xe2, 0xb4, 0xdf, 0x1f, 0xa0, 0xef, 0x07, 0x80, 0xfb, 0x8e, 0x12, 0xf8, 0xb8, 0xe1, 0xc6, 0xdf, 0x7c, 0x69, 0x35, 0x5a, 0xe1, 0x8e, 0x5d, 0x69, 0x84, 0x56, 0xb6, 0x31, 0x1c, 0x0b,
+	/* (2^250)P */ 0xd6, 0x94, 0x5c, 0xef, 0xbb, 0x46, 0x45, 0x44, 0x5b, 0xa1, 0xae, 0x03, 0x65, 0xdd, 0xb5, 0x66, 0x88, 0x35, 0x29, 0x95, 0x16, 0x54, 0xa6, 0xf5, 0xc9, 0x78, 0x34, 0xe6, 0x0f, 0xc4, 0x2b, 0x5b, 0x79, 0x51, 0x68, 0x48, 0x3a, 0x26, 0x87, 0x05, 0x70, 0xaf, 0x8b, 0xa6, 0xc7, 0x2e, 0xb3, 0xa9, 0x10, 0x01, 0xb0, 0xb9, 0x31, 0xfd, 0xdc, 0x80,
+	/* (2^251)P */ 0x25, 0xf2, 0xad, 0xd6, 0x75, 0xa3, 0x04, 0x05, 0x64, 0x8a, 0x97, 0x60, 0x27, 0x2a, 0xe5, 0x6d, 0xb0, 0x73, 0xf4, 0x07, 0x2a, 0x9d, 0xe9, 0x46, 0xb4, 0x1c, 0x51, 0xf8, 0x63, 0x98, 0x7e, 0xe5, 0x13, 0x51, 0xed, 0x98, 0x65, 0x98, 0x4f, 0x8f, 0xe7, 0x7e, 0x72, 0xd7, 0x64, 0x11, 0x2f, 0xcd, 0x12, 0xf8, 0xc4, 0x63, 0x52, 0x0f, 0x7f, 0xc4,
+	/* (2^252)P */ 0x5c, 0xd9, 0x85, 0x63, 0xc7, 0x8a, 0x65, 0x9a, 0x25, 0x83, 0x31, 0x73, 0x49, 0xf0, 0x93, 0x96, 0x70, 0x67, 0x6d, 0xb1, 0xff, 0x95, 0x54, 0xe4, 0xf8, 0x15, 0x6c, 0x5f, 0xbd, 0xf6, 0x0f, 0x38, 0x7b, 0x68, 0x7d, 0xd9, 0x3d, 0xf0, 0xa9, 0xa0, 0xe4, 0xd1, 0xb6, 0x34, 0x6d, 0x14, 0x16, 0xc2, 0x4c, 0x30, 0x0e, 0x67, 0xd3, 0xbe, 0x2e, 0xc0,
+	/* (2^253)P */ 0x06, 0x6b, 0x52, 0xc8, 0x14, 0xcd, 0xae, 0x03, 0x93, 0xea, 0xc1, 0xf2, 0xf6, 0x8b, 0xc5, 0xb6, 0xdc, 0x82, 0x42, 0x29, 0x94, 0xe0, 0x25, 0x6c, 0x3f, 0x9f, 0x5d, 0xe4, 0x96, 0xf6, 0x8e, 0x3f, 0xf9, 0x72, 0xc4, 0x77, 0x60, 0x8b, 0xa4, 0xf9, 0xa8, 0xc3, 0x0a, 0x81, 0xb1, 0x97, 0x70, 0x18, 0xab, 0xea, 0x37, 0x8a, 0x08, 0xc7, 0xe2, 0x95,
+	/* (2^254)P */ 0x94, 0x49, 0xd9, 0x5f, 0x76, 0x72, 0x82, 0xad, 0x2d, 0x50, 0x1a, 0x7a, 0x5b, 0xe6, 0x95, 0x1e, 0x95, 0x65, 0x87, 0x1c, 0x52, 0xd7, 0x44, 0xe6, 0x9b, 0x56, 0xcd, 0x6f, 0x05, 0xff, 0x67, 0xc5, 0xdb, 0xa2, 0xac, 0xe4, 0xa2, 0x28, 0x63, 0x5f, 0xfb, 0x0c, 0x3b, 0xf1, 0x87, 0xc3, 0x36, 0x78, 0x3f, 0x77, 0xfa, 0x50, 0x85, 0xf9, 0xd7, 0x82,
+	/* (2^255)P */ 0x64, 0xc0, 0xe0, 0xd8, 0x2d, 0xed, 0xcb, 0x6a, 0xfd, 0xcd, 0xbc, 0x7e, 0x9f, 0xc8, 0x85, 0xe9, 0xc1, 0x7c, 0x0f, 0xe5, 0x18, 0xea, 0xd4, 0x51, 0xad, 0x59, 0x13, 0x75, 0xd9, 0x3d, 0xd4, 0x8a, 0xb2, 0xbe, 0x78, 0x52, 0x2b, 0x52, 0x94, 0x37, 0x41, 0xd6, 0xb4, 0xb6, 0x45, 0x20, 0x76, 0xe0, 0x1f, 0x31, 0xdb, 0xb1, 0xa1, 0x43, 0xf0, 0x18,
+	/* (2^256)P */ 0x74, 0xa9, 0xa4, 0xa9, 0xdd, 0x6e, 0x3e, 0x68, 0xe5, 0xc3, 0x2e, 0x92, 0x17, 0xa4, 0xcb, 0x80, 0xb1, 0xf0, 0x06, 0x93, 0xef, 0xe6, 0x00, 0xe6, 0x3b, 0xb1, 0x32, 0x65, 0x7b, 0x83, 0xb6, 0x8a, 0x49, 0x1b, 0x14, 0x89, 0xee, 0xba, 0xf5, 0x6a, 0x8d, 0x36, 0xef, 0xb0, 0xd8, 0xb2, 0x16, 0x99, 0x17, 0x35, 0x02, 0x16, 0x55, 0x58, 0xdd, 0x82,
+	/* (2^257)P */ 0x36, 0x95, 0xe8, 0xf4, 0x36, 0x42, 0xbb, 0xc5, 0x3e, 0xfa, 0x30, 0x84, 0x9e, 0x59, 0xfd, 0xd2, 0x95, 0x42, 0xf8, 0x64, 0xd9, 0xb9, 0x0e, 0x9f, 0xfa, 0xd0, 0x7b, 0x20, 0x31, 0x77, 0x48, 0x29, 0x4d, 0xd0, 0x32, 0x57, 0x56, 0x30, 0xa6, 0x17, 0x53, 0x04, 0xbf, 0x08, 0x28, 0xec, 0xb8, 0x46, 0xc1, 0x03, 0x89, 0xdc, 0xed, 0xa0, 0x35, 0x53,
+	/* (2^258)P */ 0xc5, 0x7f, 0x9e, 0xd8, 0xc5, 0xba, 0x5f, 0x68, 0xc8, 0x23, 0x75, 0xea, 0x0d, 0xd9, 0x5a, 0xfd, 0x61, 0x1a, 0xa3, 0x2e, 0x45, 0x63, 0x14, 0x55, 0x86, 0x21, 0x29, 0xbe, 0xef, 0x5e, 0x50, 0xe5, 0x18, 0x59, 0xe7, 0xe3, 0xce, 0x4d, 0x8c, 0x15, 0x8f, 0x89, 0x66, 0x44, 0x52, 0x3d, 0xfa, 0xc7, 0x9a, 0x59, 0x90, 0x8e, 0xc0, 0x06, 0x3f, 0xc9,
+	/* (2^259)P */ 0x8e, 0x04, 0xd9, 0x16, 0x50, 0x1d, 0x8c, 0x9f, 0xd5, 0xe3, 0xce, 0xfd, 0x47, 0x04, 0x27, 0x4d, 0xc2, 0xfa, 0x71, 0xd9, 0x0b, 0xb8, 0x65, 0xf4, 0x11, 0xf3, 0x08, 0xee, 0x81, 0xc8, 0x67, 0x99, 0x0b, 0x8d, 0x77, 0xa3, 0x4f, 0xb5, 0x9b, 0xdb, 0x26, 0xf1, 0x97, 0xeb, 0x04, 0x54, 0xeb, 0x80, 0x08, 0x1d, 0x1d, 0xf6, 0x3d, 0x1f, 0x5a, 0xb8,
+	/* (2^260)P */ 0xb7, 0x9c, 0x9d, 0xee, 0xb9, 0x5c, 0xad, 0x0d, 0x9e, 0xfd, 0x60, 0x3c, 0x27, 0x4e, 0xa2, 0x95, 0xfb, 0x64, 0x7e, 0x79, 0x64, 0x87, 0x10, 0xb4, 0x73, 0xe0, 0x9d, 0x46, 0x4d, 0x3d, 0xee, 0x83, 0xe4, 0x16, 0x88, 0x97, 0xe6, 0x4d, 0xba, 0x70, 0xb6, 0x96, 0x7b, 0xff, 0x4b, 0xc8, 0xcf, 0x72, 0x83, 0x3e, 0x5b, 0x24, 0x2e, 0x57, 0xf1, 0x82,
+	/* (2^261)P */ 0x30, 0x71, 0x40, 0x51, 0x4f, 0x44, 0xbb, 0xc7, 0xf0, 0x54, 0x6e, 0x9d, 0xeb, 0x15, 0xad, 0xf8, 0x61, 0x43, 0x5a, 0xef, 0xc0, 0xb1, 0x57, 0xae, 0x03, 0x40, 0xe8, 0x68, 0x6f, 0x03, 0x20, 0x4f, 0x8a, 0x51, 0x2a, 0x9e, 0xd2, 0x45, 0xaf, 0xb4, 0xf5, 0xd4, 0x95, 0x7f, 0x3d, 0x3d, 0xb7, 0xb6, 0x28, 0xc5, 0x08, 0x8b, 0x44, 0xd6, 0x3f, 0xe7,
+	/* (2^262)P */ 0xa9, 0x52, 0x04, 0x67, 0xcb, 0x20, 0x63, 0xf8, 0x18, 0x01, 0x44, 0x21, 0x6a, 0x8a, 0x83, 0x48, 0xd4, 0xaf, 0x23, 0x0f, 0x35, 0x8d, 0xe5, 0x5a, 0xc4, 0x7c, 0x55, 0x46, 0x19, 0x5f, 0x35, 0xe0, 0x5d, 0x97, 0x4c, 0x2d, 0x04, 0xed, 0x59, 0xd4, 0xb0, 0xb2, 0xc6, 0xe3, 0x51, 0xe1, 0x38, 0xc6, 0x30, 0x49, 0x8f, 0xae, 0x61, 0x64, 0xce, 0xa8,
+	/* (2^263)P */ 0x9b, 0x64, 0x83, 0x3c, 0xd3, 0xdf, 0xb9, 0x27, 0xe7, 0x5b, 0x7f, 0xeb, 0xf3, 0x26, 0xcf, 0xb1, 0x8f, 0xaf, 0x26, 0xc8, 0x48, 0xce, 0xa1, 0xac, 0x7d, 0x10, 0x34, 0x28, 0xe1, 0x1f, 0x69, 0x03, 0x64, 0x77, 0x61, 0xdd, 0x4a, 0x9b, 0x18, 0x47, 0xf8, 0xca, 0x63, 0xc9, 0x03, 0x2d, 0x20, 0x2a, 0x69, 0x6e, 0x42, 0xd0, 0xe7, 0xaa, 0xb5, 0xf3,
+	/* (2^264)P */ 0xea, 0x31, 0x0c, 0x57, 0x0f, 0x3e, 0xe3, 0x35, 0xd8, 0x30, 0xa5, 0x6f, 0xdd, 0x95, 0x43, 0xc6, 0x66, 0x07, 0x4f, 0x34, 0xc3, 0x7e, 0x04, 0x10, 0x2d, 0xc4, 0x1c, 0x94, 0x52, 0x2e, 0x5b, 0x9a, 0x65, 0x2f, 0x91, 0xaa, 0x4f, 0x3c, 0xdc, 0x23, 0x18, 0xe1, 0x4f, 0x85, 0xcd, 0xf4, 0x8c, 0x51, 0xf7, 0xab, 0x4f, 0xdc, 0x15, 0x5c, 0x9e, 0xc5,
+	/* (2^265)P */ 0x54, 0x57, 0x23, 0x17, 0xe7, 0x82, 0x2f, 0x04, 0x7d, 0xfe, 0xe7, 0x1f, 0xa2, 0x57, 0x79, 0xe9, 0x58, 0x9b, 0xbe, 0xc6, 0x16, 0x4a, 0x17, 0x50, 0x90, 0x4a, 0x34, 0x70, 0x87, 0x37, 0x01, 0x26, 0xd8, 0xa3, 0x5f, 0x07, 0x7c, 0xd0, 0x7d, 0x05, 0x8a, 0x93, 0x51, 0x2f, 0x99, 0xea, 0xcf, 0x00, 0xd8, 0xc7, 0xe6, 0x9b, 0x8c, 0x62, 0x45, 0x87,
+	/* (2^266)P */ 0xc3, 0xfd, 0x29, 0x66, 0xe7, 0x30, 0x29, 0x77, 0xe0, 0x0d, 0x63, 0x5b, 0xe6, 0x90, 0x1a, 0x1e, 0x99, 0xc2, 0xa7, 0xab, 0xff, 0xa7, 0xbd, 0x79, 0x01, 0x97, 0xfd, 0x27, 0x1b, 0x43, 0x2b, 0xe6, 0xfe, 0x5e, 0xf1, 0xb9, 0x35, 0x38, 0x08, 0x25, 0x55, 0x90, 0x68, 0x2e, 0xc3, 0x67, 0x39, 0x9f, 0x2b, 0x2c, 0x70, 0x48, 0x8c, 0x47, 0xee, 0x56,
+	/* (2^267)P */ 0xf7, 0x32, 0x70, 0xb5, 0xe6, 0x42, 0xfd, 0x0a, 0x39, 0x9b, 0x07, 0xfe, 0x0e, 0xf4, 0x47, 0xba, 0x6a, 0x3f, 0xf5, 0x2c, 0x15, 0xf3, 0x60, 0x3f, 0xb1, 0x83, 0x7b, 0x2e, 0x34, 0x58, 0x1a, 0x6e, 0x4a, 0x49, 0x05, 0x45, 0xca, 0xdb, 0x00, 0x01, 0x0c, 0x42, 0x5e, 0x60, 0x40, 0x5f, 0xd9, 0xc7, 0x3a, 0x9e, 0x1c, 0x8d, 0xab, 0x11, 0x55, 0x65,
+	/* (2^268)P */ 0x87, 0x40, 0xb7, 0x0d, 0xaa, 0x34, 0x89, 0x90, 0x75, 0x6d, 0xa2, 0xfe, 0x3b, 0x6d, 0x5c, 0x39, 0x98, 0x10, 0x9e, 0x15, 0xc5, 0x35, 0xa2, 0x27, 0x23, 0x0a, 0x2d, 0x60, 0xe2, 0xa8, 0x7f, 0x3e, 0x77, 0x8f, 0xcc, 0x44, 0xcc, 0x30, 0x28, 0xe2, 0xf0, 0x04, 0x8c, 0xee, 0xe4, 0x5f, 0x68, 0x8c, 0xdf, 0x70, 0xbf, 0x31, 0xee, 0x2a, 0xfc, 0xce,
+	/* (2^269)P */ 0x92, 0xf2, 0xa0, 0xd9, 0x58, 0x3b, 0x7c, 0x1a, 0x99, 0x46, 0x59, 0x54, 0x60, 0x06, 0x8d, 0x5e, 0xf0, 0x22, 0xa1, 0xed, 0x92, 0x8a, 0x4d, 0x76, 0x95, 0x05, 0x0b, 0xff, 0xfc, 0x9a, 0xd1, 0xcc, 0x05, 0xb9, 0x5e, 0x99, 0xe8, 0x2a, 0x76, 0x7b, 0xfd, 0xa6, 0xe2, 0xd1, 0x1a, 0xd6, 0x76, 0x9f, 0x2f, 0x0e, 0xd1, 0xa8, 0x77, 0x5a, 0x40, 0x5a,
+	/* (2^270)P */ 0xff, 0xf9, 0x3f, 0xa9, 0xa6, 0x6c, 0x6d, 0x03, 0x8b, 0xa7, 0x10, 0x5d, 0x3f, 0xec, 0x3e, 0x1c, 0x0b, 0x6b, 0xa2, 0x6a, 0x22, 0xa9, 0x28, 0xd0, 0x66, 0xc9, 0xc2, 0x3d, 0x47, 0x20, 0x7d, 0xa6, 0x1d, 0xd8, 0x25, 0xb5, 0xf2, 0xf9, 0x70, 0x19, 0x6b, 0xf8, 0x43, 0x36, 0xc5, 0x1f, 0xe4, 0x5a, 0x4c, 0x13, 0xe4, 0x6d, 0x08, 0x0b, 0x1d, 0xb1,
+	/* (2^271)P */ 0x3f, 0x20, 0x9b, 0xfb, 0xec, 0x7d, 0x31, 0xc5, 0xfc, 0x88, 0x0b, 0x30, 0xed, 0x36, 0xc0, 0x63, 0xb1, 0x7d, 0x10, 0xda, 0xb6, 0x2e, 0xad, 0xf3, 0xec, 0x94, 0xe7, 0xec, 0xb5, 0x9c, 0xfe, 0xf5, 0x35, 0xf0, 0xa2, 0x2d, 0x7f, 0xca, 0x6b, 0x67, 0x1a, 0xf6, 0xb3, 0xda, 0x09, 0x2a, 0xaa, 0xdf, 0xb1, 0xca, 0x9b, 0xfb, 0xeb, 0xb3, 0xcd, 0xc0,
+	/* (2^272)P */ 0xcd, 0x4d, 0x89, 0x00, 0xa4, 0x3b, 0x48, 0xf0, 0x76, 0x91, 0x35, 0xa5, 0xf8, 0xc9, 0xb6, 0x46, 0xbc, 0xf6, 0x9a, 0x45, 0x47, 0x17, 0x96, 0x80, 0x5b, 0x3a, 0x28, 0x33, 0xf9, 0x5a, 0xef, 0x43, 0x07, 0xfe, 0x3b, 0xf4, 0x8e, 0x19, 0xce, 0xd2, 0x94, 0x4b, 0x6d, 0x8e, 0x67, 0x20, 0xc7, 0x4f, 0x2f, 0x59, 0x8e, 0xe1, 0xa1, 0xa9, 0xf9, 0x0e,
+	/* (2^273)P */ 0xdc, 0x7b, 0xb5, 0x50, 0x2e, 0xe9, 0x7e, 0x8b, 0x78, 0xa1, 0x38, 0x96, 0x22, 0xc3, 0x61, 0x67, 0x6d, 0xc8, 0x58, 0xed, 0x41, 0x1d, 0x5d, 0x86, 0x98, 0x7f, 0x2f, 0x1b, 0x8d, 0x3e, 0xaa, 0xc1, 0xd2, 0x0a, 0xf3, 0xbf, 0x95, 0x04, 0xf3, 0x10, 0x3c, 0x2b, 0x7f, 0x90, 0x46, 0x04, 0xaa, 0x6a, 0xa9, 0x35, 0x76, 0xac, 0x49, 0xb5, 0x00, 0x45,
+	/* (2^274)P */ 0xb1, 0x93, 0x79, 0x84, 0x4a, 0x2a, 0x30, 0x78, 0x16, 0xaa, 0xc5, 0x74, 0x06, 0xce, 0xa5, 0xa7, 0x32, 0x86, 0xe0, 0xf9, 0x10, 0xd2, 0x58, 0x76, 0xfb, 0x66, 0x49, 0x76, 0x3a, 0x90, 0xba, 0xb5, 0xcc, 0x99, 0xcd, 0x09, 0xc1, 0x9a, 0x74, 0x23, 0xdf, 0x0c, 0xfe, 0x99, 0x52, 0x80, 0xa3, 0x7c, 0x1c, 0x71, 0x5f, 0x2c, 0x49, 0x57, 0xf4, 0xf9,
+	/* (2^275)P */ 0x6d, 0xbf, 0x52, 0xe6, 0x25, 0x98, 0xed, 0xcf, 0xe3, 0xbc, 0x08, 0xa2, 0x1a, 0x90, 0xae, 0xa0, 0xbf, 0x07, 0x15, 0xad, 0x0a, 0x9f, 0x3e, 0x47, 0x44, 0xc2, 0x10, 0x46, 0xa6, 0x7a, 0x9e, 0x2f, 0x57, 0xbc, 0xe2, 0xf0, 0x1d, 0xd6, 0x9a, 0x06, 0xed, 0xfc, 0x54, 0x95, 0x92, 0x15, 0xa2, 0xf7, 0x8d, 0x6b, 0xef, 0xb2, 0x05, 0xed, 0x5c, 0x63,
+	/* (2^276)P */ 0xbc, 0x0b, 0x27, 0x3a, 0x3a, 0xf8, 0xe1, 0x48, 0x02, 0x7e, 0x27, 0xe6, 0x81, 0x62, 0x07, 0x73, 0x74, 0xe5, 0x52, 0xd7, 0xf8, 0x26, 0xca, 0x93, 0x4d, 0x3e, 0x9b, 0x55, 0x09, 0x8e, 0xe3, 0xd7, 0xa6, 0xe3, 0xb6, 0x2a, 0xa9, 0xb3, 0xb0, 0xa0, 0x8c, 0x01, 0xbb, 0x07, 0x90, 0x78, 0x6d, 0x6d, 0xe9, 0xf0, 0x7a, 0x90, 0xbd, 0xdc, 0x0c, 0x36,
+	/* (2^277)P */ 0x7f, 0x20, 0x12, 0x0f, 0x40, 0x00, 0x53, 0xd8, 0x0c, 0x27, 0x47, 0x47, 0x22, 0x80, 0xfb, 0x62, 0xe4, 0xa7, 0xf7, 0xbd, 0x42, 0xa5, 0xc3, 0x2b, 0xb2, 0x7f, 0x50, 0xcc, 0xe2, 0xfb, 0xd5, 0xc0, 0x63, 0xdd, 0x24, 0x5f, 0x7c, 0x08, 0x91, 0xbf, 0x6e, 0x47, 0x44, 0xd4, 0x6a, 0xc0, 0xc3, 0x09, 0x39, 0x27, 0xdd, 0xc7, 0xca, 0x06, 0x29, 0x55,
+	/* (2^278)P */ 0x76, 0x28, 0x58, 0xb0, 0xd2, 0xf3, 0x0f, 0x04, 0xe9, 0xc9, 0xab, 0x66, 0x5b, 0x75, 0x51, 0xdc, 0xe5, 0x8f, 0xe8, 0x1f, 0xdb, 0x03, 0x0f, 0xb0, 0x7d, 0xf9, 0x20, 0x64, 0x89, 0xe9, 0xdc, 0xe6, 0x24, 0xc3, 0xd5, 0xd2, 0x41, 0xa6, 0xe4, 0xe3, 0xc4, 0x79, 0x7c, 0x0f, 0xa1, 0x61, 0x2f, 0xda, 0xa4, 0xc9, 0xfd, 0xad, 0x5c, 0x65, 0x6a, 0xf3,
+	/* (2^279)P */ 0xd5, 0xab, 0x72, 0x7a, 0x3b, 0x59, 0xea, 0xcf, 0xd5, 0x17, 0xd2, 0xb2, 0x5f, 0x2d, 0xab, 0xad, 0x9e, 0x88, 0x64, 0x55, 0x96, 0x6e, 0xf3, 0x44, 0xa9, 0x11, 0xf5, 0xf8, 0x3a, 0xf1, 0xcd, 0x79, 0x4c, 0x99, 0x6d, 0x23, 0x6a, 0xa0, 0xc2, 0x1a, 0x19, 0x45, 0xb5, 0xd8, 0x95, 0x2f, 0x49, 0xe9, 0x46, 0x39, 0x26, 0x60, 0x04, 0x15, 0x8b, 0xcc,
+	/* (2^280)P */ 0x66, 0x0c, 0xf0, 0x54, 0x41, 0x02, 0x91, 0xab, 0xe5, 0x85, 0x8a, 0x44, 0xa6, 0x34, 0x96, 0x32, 0xc0, 0xdf, 0x6c, 0x41, 0x39, 0xd4, 0xc6, 0xe1, 0xe3, 0x81, 0xb0, 0x4c, 0x34, 0x4f, 0xe5, 0xf4, 0x35, 0x46, 0x1f, 0xeb, 0x75, 0xfd, 0x43, 0x37, 0x50, 0x99, 0xab, 0xad, 0xb7, 0x8c, 0xa1, 0x57, 0xcb, 0xe6, 0xce, 0x16, 0x2e, 0x85, 0xcc, 0xf9,
+	/* (2^281)P */ 0x63, 0xd1, 0x3f, 0x9e, 0xa2, 0x17, 0x2e, 0x1d, 0x3e, 0xce, 0x48, 0x2d, 0xbb, 0x8f, 0x69, 0xc9, 0xa6, 0x3d, 0x4e, 0xfe, 0x09, 0x56, 0xb3, 0x02, 0x5f, 0x99, 0x97, 0x0c, 0x54, 0xda, 0x32, 0x97, 0x9b, 0xf4, 0x95, 0xf1, 0xad, 0xe3, 0x2b, 0x04, 0xa7, 0x9b, 0x3f, 0xbb, 0xe7, 0x87, 0x2e, 0x1f, 0x8b, 0x4b, 0x7a, 0xa4, 0x43, 0x0c, 0x0f, 0x35,
+	/* (2^282)P */ 0x05, 0xdc, 0xe0, 0x2c, 0xa1, 0xc1, 0xd0, 0xf1, 0x1f, 0x4e, 0xc0, 0x6c, 0x35, 0x7b, 0xca, 0x8f, 0x8b, 0x02, 0xb1, 0xf7, 0xd6, 0x2e, 0xe7, 0x93, 0x80, 0x85, 0x18, 0x88, 0x19, 0xb9, 0xb4, 0x4a, 0xbc, 0xeb, 0x5a, 0x78, 0x38, 0xed, 0xc6, 0x27, 0x2a, 0x74, 0x76, 0xf0, 0x1b, 0x79, 0x92, 0x2f, 0xd2, 0x81, 0x98, 0xdf, 0xa9, 0x50, 0x19, 0xeb,
+	/* (2^283)P */ 0xb5, 0xe7, 0xb4, 0x11, 0x3a, 0x81, 0xb6, 0xb4, 0xf8, 0xa2, 0xb3, 0x6c, 0xfc, 0x9d, 0xe0, 0xc0, 0xe0, 0x59, 0x7f, 0x05, 0x37, 0xef, 0x2c, 0xa9, 0x3a, 0x24, 0xac, 0x7b, 0x25, 0xa0, 0x55, 0xd2, 0x44, 0x82, 0x82, 0x6e, 0x64, 0xa3, 0x58, 0xc8, 0x67, 0xae, 0x26, 0xa7, 0x0f, 0x42, 0x63, 0xe1, 0x93, 0x01, 0x52, 0x19, 0xaf, 0x49, 0x3e, 0x33,
+	/* (2^284)P */ 0x05, 0x85, 0xe6, 0x66, 0xaf, 0x5f, 0xdf, 0xbf, 0x9d, 0x24, 0x62, 0x60, 0x90, 0xe2, 0x4c, 0x7d, 0x4e, 0xc3, 0x74, 0x5d, 0x4f, 0x53, 0xf3, 0x63, 0x13, 0xf4, 0x74, 0x28, 0x6b, 0x7d, 0x57, 0x0c, 0x9d, 0x84, 0xa7, 0x1a, 0xff, 0xa0, 0x79, 0xdf, 0xfc, 0x65, 0x98, 0x8e, 0x22, 0x0d, 0x62, 0x7e, 0xf2, 0x34, 0x60, 0x83, 0x05, 0x14, 0xb1, 0xc1,
+	/* (2^285)P */ 0x64, 0x22, 0xcc, 0xdf, 0x5c, 0xbc, 0x88, 0x68, 0x4c, 0xd9, 0xbc, 0x0e, 0xc9, 0x8b, 0xb4, 0x23, 0x52, 0xad, 0xb0, 0xb3, 0xf1, 0x17, 0xd8, 0x15, 0x04, 0x6b, 0x99, 0xf0, 0xc4, 0x7d, 0x48, 0x22, 0x4a, 0xf8, 0x6f, 0xaa, 0x88, 0x0d, 0xc5, 0x5e, 0xa9, 0x1c, 0x61, 0x3d, 0x95, 0xa9, 0x7b, 0x6a, 0x79, 0x33, 0x0a, 0x2b, 0x99, 0xe3, 0x4e, 0x48,
+	/* (2^286)P */ 0x6b, 0x9b, 0x6a, 0x2a, 0xf1, 0x60, 0x31, 0xb4, 0x73, 0xd1, 0x87, 0x45, 0x9c, 0x15, 0x58, 0x4b, 0x91, 0x6d, 0x94, 0x1c, 0x41, 0x11, 0x4a, 0x83, 0xec, 0xaf, 0x65, 0xbc, 0x34, 0xaa, 0x26, 0xe2, 0xaf, 0xed, 0x46, 0x05, 0x4e, 0xdb, 0xc6, 0x4e, 0x10, 0x28, 0x4e, 0x72, 0xe5, 0x31, 0xa3, 0x20, 0xd7, 0xb1, 0x96, 0x64, 0xf6, 0xce, 0x08, 0x08,
+	/* (2^287)P */ 0x16, 0xa9, 0x5c, 0x9f, 0x9a, 0xb4, 0xb8, 0xc8, 0x32, 0x78, 0xc0, 0x3a, 0xd9, 0x5f, 0x94, 0xac, 0x3a, 0x42, 0x1f, 0x43, 0xd6, 0x80, 0x47, 0x2c, 0xdc, 0x76, 0x27, 0xfa, 0x50, 0xe5, 0xa1, 0xe4, 0xc3, 0xcb, 0x61, 0x31, 0xe1, 0x2e, 0xde, 0x81, 0x3b, 0x77, 0x1c, 0x39, 0x3c, 0xdb, 0xda, 0x87, 0x4b, 0x84, 0x12, 0xeb, 0xdd, 0x54, 0xbf, 0xe7,
+	/* (2^288)P */ 0xbf, 0xcb, 0x73, 0x21, 0x3d, 0x7e, 0x13, 0x8c, 0xa6, 0x34, 0x21, 0x2b, 0xa5, 0xe4, 0x9f, 0x8e, 0x9c, 0x01, 0x9c, 0x43, 0xd9, 0xc7, 0xb9, 0xf1, 0xbe, 0x7f, 0x45, 0x51, 0x97, 0xa1, 0x8e, 0x01, 0xf8, 0xbd, 0xd2, 0xbf, 0x81, 0x3a, 0x8b, 0xab, 0xe4, 0x89, 0xb7, 0xbd, 0xf2, 0xcd, 0xa9, 0x8a, 0x8a, 0xde, 0xfb, 0x8a, 0x55, 0x12, 0x7b, 0x17,
+	/* (2^289)P */ 0x1b, 0x95, 0x58, 0x4d, 0xe6, 0x51, 0x31, 0x52, 0x1c, 0xd8, 0x15, 0x84, 0xb1, 0x0d, 0x36, 0x25, 0x88, 0x91, 0x46, 0x71, 0x42, 0x56, 0xe2, 0x90, 0x08, 0x9e, 0x77, 0x1b, 0xee, 0x22, 0x3f, 0xec, 0xee, 0x8c, 0x7b, 0x2e, 0x79, 0xc4, 0x6c, 0x07, 0xa1, 0x7e, 0x52, 0xf5, 0x26, 0x5c, 0x84, 0x2a, 0x50, 0x6e, 0x82, 0xb3, 0x76, 0xda, 0x35, 0x16,
+	/* (2^290)P */ 0x0a, 0x6f, 0x99, 0x87, 0xc0, 0x7d, 0x8a, 0xb2, 0xca, 0xae, 0xe8, 0x65, 0x98, 0x0f, 0xb3, 0x44, 0xe1, 0xdc, 0x52, 0x79, 0x75, 0xec, 0x8f, 0x95, 0x87, 0x45, 0xd1, 0x32, 0x18, 0x55, 0x15, 0xce, 0x64, 0x9b, 0x08, 0x4f, 0x2c, 0xea, 0xba, 0x1c, 0x57, 0x06, 0x63, 0xc8, 0xb1, 0xfd, 0xc5, 0x67, 0xe7, 0x1f, 0x87, 0x9e, 0xde, 0x72, 0x7d, 0xec,
+	/* (2^291)P */ 0x36, 0x8b, 0x4d, 0x2c, 0xc2, 0x46, 0xe8, 0x96, 0xac, 0x0b, 0x8c, 0xc5, 0x09, 0x10, 0xfc, 0xf2, 0xda, 0xea, 0x22, 0xb2, 0xd3, 0x89, 0xeb, 0xb2, 0x85, 0x0f, 0xff, 0x59, 0x50, 0x2c, 0x99, 0x5a, 0x1f, 0xec, 0x2a, 0x6f, 0xec, 0xcf, 0xe9, 0xce, 0x12, 0x6b, 0x19, 0xd8, 0xde, 0x9b, 0xce, 0x0e, 0x6a, 0xaa, 0xe1, 0x32, 0xea, 0x4c, 0xfe, 0x92,
+	/* (2^292)P */ 0x5f, 0x17, 0x70, 0x53, 0x26, 0x03, 0x0b, 0xab, 0xd1, 0xc1, 0x42, 0x0b, 0xab, 0x2b, 0x3d, 0x31, 0xa4, 0xd5, 0x2b, 0x5e, 0x00, 0xd5, 0x9a, 0x22, 0x34, 0xe0, 0x53, 0x3f, 0x59, 0x7f, 0x2c, 0x6d, 0x72, 0x9a, 0xa4, 0xbe, 0x3d, 0x42, 0x05, 0x1b, 0xf2, 0x7f, 0x88, 0x56, 0xd1, 0x7c, 0x7d, 0x6b, 0x9f, 0x43, 0xfe, 0x65, 0x19, 0xae, 0x9c, 0x4c,
+	/* (2^293)P */ 0xf3, 0x7c, 0x20, 0xa9, 0xfc, 0xf2, 0xf2, 0x3b, 0x3c, 0x57, 0x41, 0x94, 0xe5, 0xcc, 0x6a, 0x37, 0x5d, 0x09, 0xf2, 0xab, 0xc2, 0xca, 0x60, 0x38, 0x6b, 0x7a, 0xe1, 0x78, 0x2b, 0xc1, 0x1d, 0xe8, 0xfd, 0xbc, 0x3d, 0x5c, 0xa2, 0xdb, 0x49, 0x20, 0x79, 0xe6, 0x1b, 0x9b, 0x65, 0xd9, 0x6d, 0xec, 0x57, 0x1d, 0xd2, 0xe9, 0x90, 0xeb, 0x43, 0x7b,
+	/* (2^294)P */ 0x2a, 0x8b, 0x2e, 0x19, 0x18, 0x10, 0xb8, 0x83, 0xe7, 0x7d, 0x2d, 0x9a, 0x3a, 0xe5, 0xd1, 0xe4, 0x7c, 0x38, 0xe5, 0x59, 0x2a, 0x6e, 0xd9, 0x01, 0x29, 0x3d, 0x23, 0xf7, 0x52, 0xba, 0x61, 0x04, 0x9a, 0xde, 0xc4, 0x31, 0x50, 0xeb, 0x1b, 0xaa, 0xde, 0x39, 0x58, 0xd8, 0x1b, 0x1e, 0xfc, 0x57, 0x9a, 0x28, 0x43, 0x9e, 0x97, 0x5e, 0xaa, 0xa3,
+	/* (2^295)P */ 0x97, 0x0a, 0x74, 0xc4, 0x39, 0x99, 0x6b, 0x40, 0xc7, 0x3e, 0x8c, 0xa7, 0xb1, 0x4e, 0x9a, 0x59, 0x6e, 0x1c, 0xfe, 0xfc, 0x2a, 0x5e, 0x73, 0x2b, 0x8c, 0xa9, 0x71, 0xf5, 0xda, 0x6b, 0x15, 0xab, 0xf7, 0xbe, 0x2a, 0x44, 0x5f, 0xba, 0xae, 0x67, 0x93, 0xc5, 0x86, 0xc1, 0xb8, 0xdf, 0xdc, 0xcb, 0xd7, 0xff, 0xb1, 0x71, 0x7c, 0x6f, 0x88, 0xf8,
+	/* (2^296)P */ 0x3f, 0x89, 0xb1, 0xbf, 0x24, 0x16, 0xac, 0x56, 0xfe, 0xdf, 0x94, 0x71, 0xbf, 0xd6, 0x57, 0x0c, 0xb4, 0x77, 0x37, 0xaa, 0x2a, 0x70, 0x76, 0x49, 0xaf, 0x0c, 0x97, 0x8e, 0x78, 0x2a, 0x67, 0xc9, 0x3b, 0x3d, 0x5b, 0x01, 0x2f, 0xda, 0xd5, 0xa8, 0xde, 0x02, 0xa9, 0xac, 0x76, 0x00, 0x0b, 0x46, 0xc6, 0x2d, 0xdc, 0x08, 0xf4, 0x10, 0x2c, 0xbe,
+	/* (2^297)P */ 0xcb, 0x07, 0xf9, 0x91, 0xc6, 0xd5, 0x3e, 0x54, 0x63, 0xae, 0xfc, 0x10, 0xbe, 0x3a, 0x20, 0x73, 0x4e, 0x65, 0x0e, 0x2d, 0x86, 0x77, 0x83, 0x9d, 0xe2, 0x0a, 0xe9, 0xac, 0x22, 0x52, 0x76, 0xd4, 0x6e, 0xfa, 0xe0, 0x09, 0xef, 0x78, 0x82, 0x9f, 0x26, 0xf9, 0x06, 0xb5, 0xe7, 0x05, 0x0e, 0xf2, 0x46, 0x72, 0x93, 0xd3, 0x24, 0xbd, 0x87, 0x60,
+	/* (2^298)P */ 0x14, 0x55, 0x84, 0x7b, 0x6c, 0x60, 0x80, 0x73, 0x8c, 0xbe, 0x2d, 0xd6, 0x69, 0xd6, 0x17, 0x26, 0x44, 0x9f, 0x88, 0xa2, 0x39, 0x7c, 0x89, 0xbc, 0x6d, 0x9e, 0x46, 0xb6, 0x68, 0x66, 0xea, 0xdc, 0x31, 0xd6, 0x21, 0x51, 0x9f, 0x28, 0x28, 0xaf, 0x9e, 0x47, 0x2c, 0x4c, 0x8f, 0xf3, 0xaf, 0x1f, 0xe4, 0xab, 0xac, 0xe9, 0x0c, 0x91, 0x3a, 0x61,
+	/* (2^299)P */ 0xb0, 0x37, 0x55, 0x4b, 0xe9, 0xc3, 0xb1, 0xce, 0x42, 0xe6, 0xc5, 0x11, 0x7f, 0x2c, 0x11, 0xfc, 0x4e, 0x71, 0x17, 0x00, 0x74, 0x7f, 0xbf, 0x07, 0x4d, 0xfd, 0x40, 0xb2, 0x87, 0xb0, 0xef, 0x1f, 0x35, 0x2c, 0x2d, 0xd7, 0xe1, 0xe4, 0xad, 0x0e, 0x7f, 0x63, 0x66, 0x62, 0x23, 0x41, 0xf6, 0xc1, 0x14, 0xa6, 0xd7, 0xa9, 0x11, 0x56, 0x9d, 0x1b,
+	/* (2^300)P */ 0x02, 0x82, 0x42, 0x18, 0x4f, 0x1b, 0xc9, 0x5d, 0x78, 0x5f, 0xee, 0xed, 0x01, 0x49, 0x8f, 0xf2, 0xa0, 0xe2, 0x6e, 0xbb, 0x6b, 0x04, 0x8d, 0xb2, 0x41, 0xae, 0xc8, 0x1b, 0x59, 0x34, 0xb8, 0x2a, 0xdb, 0x1f, 0xd2, 0x52, 0xdf, 0x3f, 0x35, 0x00, 0x8b, 0x61, 0xbc, 0x97, 0xa0, 0xc4, 0x77, 0xd1, 0xe4, 0x2c, 0x59, 0x68, 0xff, 0x30, 0xf2, 0xe2,
+	/* (2^301)P */ 0x79, 0x08, 0xb1, 0xdb, 0x55, 0xae, 0xd0, 0xed, 0xda, 0xa0, 0xec, 0x6c, 0xae, 0x68, 0xf2, 0x0b, 0x61, 0xb3, 0xf5, 0x21, 0x69, 0x87, 0x0b, 0x03, 0xea, 0x8a, 0x15, 0xd9, 0x7e, 0xca, 0xf7, 0xcd, 0xf3, 0x33, 0xb3, 0x4c, 0x5b, 0x23, 0x4e, 0x6f, 0x90, 0xad, 0x91, 0x4b, 0x4f, 0x46, 0x37, 0xe5, 0xe8, 0xb7, 0xeb, 0xd5, 0xca, 0x34, 0x4e, 0x23,
+	/* (2^302)P */ 0x09, 0x02, 0xdd, 0xfd, 0x70, 0xac, 0x56, 0x80, 0x36, 0x5e, 0x49, 0xd0, 0x3f, 0xc2, 0xe0, 0xba, 0x46, 0x7f, 0x5c, 0xf7, 0xc5, 0xbd, 0xd5, 0x55, 0x7d, 0x3f, 0xd5, 0x7d, 0x06, 0xdf, 0x27, 0x20, 0x4f, 0xe9, 0x30, 0xec, 0x1b, 0xa0, 0x0c, 0xd4, 0x2c, 0xe1, 0x2b, 0x65, 0x73, 0xea, 0x75, 0x35, 0xe8, 0xe6, 0x56, 0xd6, 0x07, 0x15, 0x99, 0xdf,
+	/* (2^303)P */ 0x4e, 0x10, 0xb7, 0xd0, 0x63, 0x8c, 0xcf, 0x16, 0x00, 0x7c, 0x58, 0xdf, 0x86, 0xdc, 0x4e, 0xca, 0x9c, 0x40, 0x5a, 0x42, 0xfd, 0xec, 0x98, 0xa4, 0x42, 0x53, 0xae, 0x16, 0x9d, 0xfd, 0x75, 0x5a, 0x12, 0x56, 0x1e, 0xc6, 0x57, 0xcc, 0x79, 0x27, 0x96, 0x00, 0xcf, 0x80, 0x4f, 0x8a, 0x36, 0x5c, 0xbb, 0xe9, 0x12, 0xdb, 0xb6, 0x2b, 0xad, 0x96,
+	/* (2^304)P */ 0x92, 0x32, 0x1f, 0xfd, 0xc6, 0x02, 0x94, 0x08, 0x1b, 0x60, 0x6a, 0x9f, 0x8b, 0xd6, 0xc8, 0xad, 0xd5, 0x1b, 0x27, 0x4e, 0xa4, 0x4d, 0x4a, 0x00, 0x10, 0x5f, 0x86, 0x11, 0xf5, 0xe3, 0x14, 0x32, 0x43, 0xee, 0xb9, 0xc7, 0xab, 0xf4, 0x6f, 0xe5, 0x66, 0x0c, 0x06, 0x0d, 0x96, 0x79, 0x28, 0xaf, 0x45, 0x2b, 0x56, 0xbe, 0xe4, 0x4a, 0x52, 0xd6,
+	/* (2^305)P */ 0x15, 0x16, 0x69, 0xef, 0x60, 0xca, 0x82, 0x25, 0x0f, 0xc6, 0x30, 0xa0, 0x0a, 0xd1, 0x83, 0x29, 0xcd, 0xb6, 0x89, 0x6c, 0xf5, 0xb2, 0x08, 0x38, 0xe6, 0xca, 0x6b, 0x19, 0x93, 0xc6, 0x5f, 0x75, 0x8e, 0x60, 0x34, 0x23, 0xc4, 0x13, 0x17, 0x69, 0x55, 0xcc, 0x72, 0x9c, 0x2b, 0x6c, 0x80, 0xf4, 0x4b, 0x8b, 0xb6, 0x97, 0x65, 0x07, 0xb6, 0xfb,
+	/* (2^306)P */ 0x01, 0x99, 0x74, 0x28, 0xa6, 0x67, 0xa3, 0xe5, 0x25, 0xfb, 0xdf, 0x82, 0x93, 0xe7, 0x35, 0x74, 0xce, 0xe3, 0x15, 0x1c, 0x1d, 0x79, 0x52, 0x84, 0x08, 0x04, 0x2f, 0x5c, 0xb8, 0xcd, 0x7f, 0x89, 0xb0, 0x39, 0x93, 0x63, 0xc9, 0x5d, 0x06, 0x01, 0x59, 0xf7, 0x7e, 0xf1, 0x4c, 0x3d, 0x12, 0x8d, 0x69, 0x1d, 0xb7, 0x21, 0x5e, 0x88, 0x82, 0xa2,
+	/* (2^307)P */ 0x8e, 0x69, 0xaf, 0x9a, 0x41, 0x0d, 0x9d, 0xcf, 0x8e, 0x8d, 0x5c, 0x51, 0x6e, 0xde, 0x0e, 0x48, 0x23, 0x89, 0xe5, 0x37, 0x80, 0xd6, 0x9d, 0x72, 0x32, 0x26, 0x38, 0x2d, 0x63, 0xa0, 0xfa, 0xd3, 0x40, 0xc0, 0x8c, 0x68, 0x6f, 0x2b, 0x1e, 0x9a, 0x39, 0x51, 0x78, 0x74, 0x9a, 0x7b, 0x4a, 0x8f, 0x0c, 0xa0, 0x88, 0x60, 0xa5, 0x21, 0xcd, 0xc7,
+	/* (2^308)P */ 0x3a, 0x7f, 0x73, 0x14, 0xbf, 0x89, 0x6a, 0x4c, 0x09, 0x5d, 0xf2, 0x93, 0x20, 0x2d, 0xc4, 0x29, 0x86, 0x06, 0x95, 0xab, 0x22, 0x76, 0x4c, 0x54, 0xe1, 0x7e, 0x80, 0x6d, 0xab, 0x29, 0x61, 0x87, 0x77, 0xf6, 0xc0, 0x3e, 0xda, 0xab, 0x65, 0x7e, 0x39, 0x12, 0xa1, 0x6b, 0x42, 0xf7, 0xc5, 0x97, 0x77, 0xec, 0x6f, 0x22, 0xbe, 0x44, 0xc7, 0x03,
+	/* (2^309)P */ 0xa5, 0x23, 0x90, 0x41, 0xa3, 0xc5, 0x3e, 0xe0, 0xa5, 0x32, 0x49, 0x1f, 0x39, 0x78, 0xb1, 0xd8, 0x24, 0xea, 0xd4, 0x87, 0x53, 0x42, 0x51, 0xf4, 0xd9, 0x46, 0x25, 0x2f, 0x62, 0xa9, 0x90, 0x9a, 0x4a, 0x25, 0x8a, 0xd2, 0x10, 0xe7, 0x3c, 0xbc, 0x58, 0x8d, 0x16, 0x14, 0x96, 0xa4, 0x6f, 0xf8, 0x12, 0x69, 0x91, 0x73, 0xe2, 0xfa, 0xf4, 0x57,
+	/* (2^310)P */ 0x51, 0x45, 0x3f, 0x96, 0xdc, 0x97, 0x38, 0xa6, 0x01, 0x63, 0x09, 0xea, 0xc2, 0x13, 0x30, 0xb0, 0x00, 0xb8, 0x0a, 0xce, 0xd1, 0x8f, 0x3e, 0x69, 0x62, 0x46, 0x33, 0x9c, 0xbf, 0x4b, 0xcb, 0x0c, 0x90, 0x1c, 0x45, 0xcf, 0x37, 0x5b, 0xf7, 0x4b, 0x5e, 0x95, 0xc3, 0x28, 0x9f, 0x08, 0x83, 0x53, 0x74, 0xab, 0x0c, 0xb4, 0xc0, 0xa1, 0xbc, 0x89,
+	/* (2^311)P */ 0x06, 0xb1, 0x51, 0x15, 0x65, 0x60, 0x21, 0x17, 0x7a, 0x20, 0x65, 0xee, 0x12, 0x35, 0x4d, 0x46, 0xf4, 0xf8, 0xd0, 0xb1, 0xca, 0x09, 0x30, 0x08, 0x89, 0x23, 0x3b, 0xe7, 0xab, 0x8b, 0x77, 0xa6, 0xad, 0x25, 0xdd, 0xea, 0x3c, 0x7d, 0xa5, 0x24, 0xb3, 0xe8, 0xfa, 0xfb, 0xc9, 0xf2, 0x71, 0xe9, 0xfa, 0xf2, 0xdc, 0x54, 0xdd, 0x55, 0x2e, 0x2f,
+	/* (2^312)P */ 0x7f, 0x96, 0x96, 0xfb, 0x52, 0x86, 0xcf, 0xea, 0x62, 0x18, 0xf1, 0x53, 0x1f, 0x61, 0x2a, 0x9f, 0x8c, 0x51, 0xca, 0x2c, 0xde, 0x6d, 0xce, 0xab, 0x58, 0x32, 0x0b, 0x33, 0x9b, 0x99, 0xb4, 0x5c, 0x88, 0x2a, 0x76, 0xcc, 0x3e, 0x54, 0x1e, 0x9d, 0xa2, 0x89, 0xe4, 0x19, 0xba, 0x80, 0xc8, 0x39, 0x32, 0x7f, 0x0f, 0xc7, 0x84, 0xbb, 0x43, 0x56,
+	/* (2^313)P */ 0x9b, 0x07, 0xb4, 0x42, 0xa9, 0xa0, 0x78, 0x4f, 0x28, 0x70, 0x2b, 0x7e, 0x61, 0xe0, 0xdd, 0x02, 0x98, 0xfc, 0xed, 0x31, 0x80, 0xf1, 0x15, 0x52, 0x89, 0x23, 0xcd, 0x5d, 0x2b, 0xc5, 0x19, 0x32, 0xfb, 0x70, 0x50, 0x7a, 0x97, 0x6b, 0x42, 0xdb, 0xca, 0xdb, 0xc4, 0x59, 0x99, 0xe0, 0x12, 0x1f, 0x17, 0xba, 0x8b, 0xf0, 0xc4, 0x38, 0x5d, 0x27,
+	/* (2^314)P */ 0x29, 0x1d, 0xdc, 0x2b, 0xf6, 0x5b, 0x04, 0x61, 0x36, 0x76, 0xa0, 0x56, 0x36, 0x6e, 0xd7, 0x24, 0x4d, 0xe7, 0xef, 0x44, 0xd2, 0xd5, 0x07, 0xcd, 0xc4, 0x9d, 0x80, 0x48, 0xc3, 0x38, 0xcf, 0xd8, 0xa3, 0xdd, 0xb2, 0x5e, 0xb5, 0x70, 0x15, 0xbb, 0x36, 0x85, 0x8a, 0xd7, 0xfb, 0x56, 0x94, 0x73, 0x9c, 0x81, 0xbe, 0xb1, 0x44, 0x28, 0xf1, 0x37,
+	/* (2^315)P */ 0xbf, 0xcf, 0x5c, 0xd2, 0xe2, 0xea, 0xc2, 0xcd, 0x70, 0x7a, 0x9d, 0xcb, 0x81, 0xc1, 0xe9, 0xf1, 0x56, 0x71, 0x52, 0xf7, 0x1b, 0x87, 0xc6, 0xd8, 0xcc, 0xb2, 0x69, 0xf3, 0xb0, 0xbd, 0xba, 0x83, 0x12, 0x26, 0xc4, 0xce, 0x72, 0xde, 0x3b, 0x21, 0x28, 0x9e, 0x5a, 0x94, 0xf5, 0x04, 0xa3, 0xc8, 0x0f, 0x5e, 0xbc, 0x71, 0xf9, 0x0d, 0xce, 0xf5,
+	/* (2^316)P */ 0x93, 0x97, 0x00, 0x85, 0xf4, 0xb4, 0x40, 0xec, 0xd9, 0x2b, 0x6c, 0xd6, 0x63, 0x9e, 0x93, 0x0a, 0x5a, 0xf4, 0xa7, 0x9a, 0xe3, 0x3c, 0xf0, 0x55, 0xd1, 0x96, 0x6c, 0xf5, 0x2a, 0xce, 0xd7, 0x95, 0x72, 0xbf, 0xc5, 0x0c, 0xce, 0x79, 0xa2, 0x0a, 0x78, 0xe0, 0x72, 0xd0, 0x66, 0x28, 0x05, 0x75, 0xd3, 0x23, 0x09, 0x91, 0xed, 0x7e, 0xc4, 0xbc,
+	/* (2^317)P */ 0x77, 0xc2, 0x9a, 0xf7, 0xa6, 0xe6, 0x18, 0xb4, 0xe7, 0xf6, 0xda, 0xec, 0x44, 0x6d, 0xfb, 0x08, 0xee, 0x65, 0xa8, 0x92, 0x85, 0x1f, 0xba, 0x38, 0x93, 0x20, 0x5c, 0x4d, 0xd2, 0x18, 0x0f, 0x24, 0xbe, 0x1a, 0x96, 0x44, 0x7d, 0xeb, 0xb3, 0xda, 0x95, 0xf4, 0xaf, 0x6c, 0x06, 0x0f, 0x47, 0x37, 0xc8, 0x77, 0x63, 0xe1, 0x29, 0xef, 0xff, 0xa5,
+	/* (2^318)P */ 0x16, 0x12, 0xd9, 0x47, 0x90, 0x22, 0x9b, 0x05, 0xf2, 0xa5, 0x9a, 0xae, 0x83, 0x98, 0xb5, 0xac, 0xab, 0x29, 0xaa, 0xdc, 0x5f, 0xde, 0xcd, 0xf7, 0x42, 0xad, 0x3b, 0x96, 0xd6, 0x3e, 0x6e, 0x52, 0x47, 0xb1, 0xab, 0x51, 0xde, 0x49, 0x7c, 0x87, 0x8d, 0x86, 0xe2, 0x70, 0x13, 0x21, 0x51, 0x1c, 0x0c, 0x25, 0xc1, 0xb0, 0xe6, 0x19, 0xcf, 0x12,
+	/* (2^319)P */ 0xf0, 0xbc, 0x97, 0x8f, 0x4b, 0x2f, 0xd1, 0x1f, 0x8c, 0x57, 0xed, 0x3c, 0xf4, 0x26, 0x19, 0xbb, 0x60, 0xca, 0x24, 0xc5, 0xd9, 0x97, 0xe2, 0x5f, 0x76, 0x49, 0x39, 0x7e, 0x2d, 0x12, 0x21, 0x98, 0xda, 0xe6, 0xdb, 0xd2, 0xd8, 0x9f, 0x18, 0xd8, 0x83, 0x6c, 0xba, 0x89, 0x8d, 0x29, 0xfa, 0x46, 0x33, 0x8c, 0x28, 0xdf, 0x6a, 0xb3, 0x69, 0x28,
+	/* (2^320)P */ 0x86, 0x17, 0xbc, 0xd6, 0x7c, 0xba, 0x1e, 0x83, 0xbb, 0x84, 0xb5, 0x8c, 0xad, 0xdf, 0xa1, 0x24, 0x81, 0x70, 0x40, 0x0f, 0xad, 0xad, 0x3b, 0x23, 0xd0, 0x93, 0xa0, 0x49, 0x5c, 0x4b, 0x51, 0xbe, 0x20, 0x49, 0x4e, 0xda, 0x2d, 0xd3, 0xad, 0x1b, 0x74, 0x08, 0x41, 0xf0, 0xef, 0x19, 0xe9, 0x45, 0x5d, 0x02, 0xae, 0x26, 0x25, 0xd9, 0xd1, 0xc2,
+	/* (2^321)P */ 0x48, 0x81, 0x3e, 0xb2, 0x83, 0xf8, 0x4d, 0xb3, 0xd0, 0x4c, 0x75, 0xb3, 0xa0, 0x52, 0x26, 0xf2, 0xaf, 0x5d, 0x36, 0x70, 0x72, 0xd6, 0xb7, 0x88, 0x08, 0x69, 0xbd, 0x15, 0x25, 0xb1, 0x45, 0x1b, 0xb7, 0x0b, 0x5f, 0x71, 0x5d, 0x83, 0x49, 0xb9, 0x84, 0x3b, 0x7c, 0xc1, 0x50, 0x93, 0x05, 0x53, 0xe0, 0x61, 0xea, 0xc1, 0xef, 0xdb, 0x82, 0x97,
+	/* (2^322)P */ 0x00, 0xd5, 0xc3, 0x3a, 0x4d, 0x8a, 0x23, 0x7a, 0xef, 0xff, 0x37, 0xef, 0xf3, 0xbc, 0xa9, 0xb6, 0xae, 0xd7, 0x3a, 0x7b, 0xfd, 0x3e, 0x8e, 0x9b, 0xab, 0x44, 0x54, 0x60, 0x28, 0x6c, 0xbf, 0x15, 0x24, 0x4a, 0x56, 0x60, 0x7f, 0xa9, 0x7a, 0x28, 0x59, 0x2c, 0x8a, 0xd1, 0x7d, 0x6b, 0x00, 0xfd, 0xa5, 0xad, 0xbc, 0x19, 0x3f, 0xcb, 0x73, 0xe0,
+	/* (2^323)P */ 0xcf, 0x9e, 0x66, 0x06, 0x4d, 0x2b, 0xf5, 0x9c, 0xc2, 0x9d, 0x9e, 0xed, 0x5a, 0x5c, 0x2d, 0x00, 0xbf, 0x29, 0x90, 0x88, 0xe4, 0x5d, 0xfd, 0xe2, 0xf0, 0x38, 0xec, 0x4d, 0x26, 0xea, 0x54, 0xf0, 0x3c, 0x84, 0x10, 0x6a, 0xf9, 0x66, 0x9c, 0xe7, 0x21, 0xfd, 0x0f, 0xc7, 0x13, 0x50, 0x81, 0xb6, 0x50, 0xf9, 0x04, 0x7f, 0xa4, 0x37, 0x85, 0x14,
+	/* (2^324)P */ 0xdb, 0x87, 0x49, 0xc7, 0xa8, 0x39, 0x0c, 0x32, 0x98, 0x0c, 0xb9, 0x1a, 0x1b, 0x4d, 0xe0, 0x8a, 0x9a, 0x8e, 0x8f, 0xab, 0x5a, 0x17, 0x3d, 0x04, 0x21, 0xce, 0x3e, 0x2c, 0xf9, 0xa3, 0x97, 0xe4, 0x77, 0x95, 0x0e, 0xb6, 0xa5, 0x15, 0xad, 0x3a, 0x1e, 0x46, 0x53, 0x17, 0x09, 0x83, 0x71, 0x4e, 0x86, 0x38, 0xd5, 0x23, 0x44, 0x16, 0x8d, 0xc8,
+	/* (2^325)P */ 0x05, 0x5e, 0x99, 0x08, 0xbb, 0xc3, 0xc0, 0xb7, 0x6c, 0x12, 0xf2, 0xf3, 0xf4, 0x7c, 0x6a, 0x4d, 0x9e, 0xeb, 0x3d, 0xb9, 0x63, 0x94, 0xce, 0x81, 0xd8, 0x11, 0xcb, 0x55, 0x69, 0x4a, 0x20, 0x0b, 0x4c, 0x2e, 0x14, 0xb8, 0xd4, 0x6a, 0x7c, 0xf0, 0xed, 0xfc, 0x8f, 0xef, 0xa0, 0xeb, 0x6c, 0x01, 0xe2, 0xdc, 0x10, 0x22, 0xa2, 0x01, 0x85, 0x64,
+	/* (2^326)P */ 0x58, 0xe1, 0x9c, 0x27, 0x55, 0xc6, 0x25, 0xa6, 0x7d, 0x67, 0x88, 0x65, 0x99, 0x6c, 0xcb, 0xdb, 0x27, 0x4f, 0x44, 0x29, 0xf5, 0x4a, 0x23, 0x10, 0xbc, 0x03, 0x3f, 0x36, 0x1e, 0xef, 0xb0, 0xba, 0x75, 0xe8, 0x74, 0x5f, 0x69, 0x3e, 0x26, 0x40, 0xb4, 0x2f, 0xdc, 0x43, 0xbf, 0xa1, 0x8b, 0xbd, 0xca, 0x6e, 0xc1, 0x6e, 0x21, 0x79, 0xa0, 0xd0,
+	/* (2^327)P */ 0x78, 0x93, 0x4a, 0x2d, 0x22, 0x6e, 0x6e, 0x7d, 0x74, 0xd2, 0x66, 0x58, 0xce, 0x7b, 0x1d, 0x97, 0xb1, 0xf2, 0xda, 0x1c, 0x79, 0xfb, 0xba, 0xd1, 0xc0, 0xc5, 0x6e, 0xc9, 0x11, 0x89, 0xd2, 0x41, 0x8d, 0x70, 0xb9, 0xcc, 0xea, 0x6a, 0xb3, 0x45, 0xb6, 0x05, 0x2e, 0xf2, 0x17, 0xf1, 0x27, 0xb8, 0xed, 0x06, 0x1f, 0xdb, 0x9d, 0x1f, 0x69, 0x28,
+	/* (2^328)P */ 0x93, 0x12, 0xa8, 0x11, 0xe1, 0x92, 0x30, 0x8d, 0xac, 0xe1, 0x1c, 0x60, 0x7c, 0xed, 0x2d, 0x2e, 0xd3, 0x03, 0x5c, 0x9c, 0xc5, 0xbd, 0x64, 0x4a, 0x8c, 0xba, 0x76, 0xfe, 0xc6, 0xc1, 0xea, 0xc2, 0x4f, 0xbe, 0x70, 0x3d, 0x64, 0xcf, 0x8e, 0x18, 0xcb, 0xcd, 0x57, 0xa7, 0xf7, 0x36, 0xa9, 0x6b, 0x3e, 0xb8, 0x69, 0xee, 0x47, 0xa2, 0x7e, 0xb2,
+	/* (2^329)P */ 0x96, 0xaf, 0x3a, 0xf5, 0xed, 0xcd, 0xaf, 0xf7, 0x82, 0xaf, 0x59, 0x62, 0x0b, 0x36, 0x85, 0xf9, 0xaf, 0xd6, 0x38, 0xff, 0x87, 0x2e, 0x1d, 0x6c, 0x8b, 0xaf, 0x3b, 0xdf, 0x28, 0xa2, 0xd6, 0x4d, 0x80, 0x92, 0xc3, 0x0f, 0x34, 0xa8, 0xae, 0x69, 0x5d, 0x7b, 0x9d, 0xbc, 0xf5, 0xfd, 0x1d, 0xb1, 0x96, 0x55, 0x86, 0xe1, 0x5c, 0xb6, 0xac, 0xb9,
+	/* (2^330)P */ 0x50, 0x9e, 0x37, 0x28, 0x7d, 0xa8, 0x33, 0x63, 0xda, 0x3f, 0x20, 0x98, 0x0e, 0x09, 0xa8, 0x77, 0x3b, 0x7a, 0xfc, 0x16, 0x85, 0x44, 0x64, 0x77, 0x65, 0x68, 0x92, 0x41, 0xc6, 0x1f, 0xdf, 0x27, 0xf9, 0xec, 0xa0, 0x61, 0x22, 0xea, 0x19, 0xe7, 0x75, 0x8b, 0x4e, 0xe5, 0x0f, 0xb7, 0xf7, 0xd2, 0x53, 0xf4, 0xdd, 0x4a, 0xaa, 0x78, 0x40, 0xb7,
+	/* (2^331)P */ 0xd4, 0x89, 0xe3, 0x79, 0xba, 0xb6, 0xc3, 0xda, 0xe6, 0x78, 0x65, 0x7d, 0x6e, 0x22, 0x62, 0xb1, 0x3d, 0xea, 0x90, 0x84, 0x30, 0x5e, 0xd4, 0x39, 0x84, 0x78, 0xd9, 0x75, 0xd6, 0xce, 0x2a, 0x11, 0x29, 0x69, 0xa4, 0x5e, 0xaa, 0x2a, 0x98, 0x5a, 0xe5, 0x91, 0x8f, 0xb2, 0xfb, 0xda, 0x97, 0xe8, 0x83, 0x6f, 0x04, 0xb9, 0x5d, 0xaf, 0xe1, 0x9b,
+	/* (2^332)P */ 0x8b, 0xe4, 0xe1, 0x48, 0x9c, 0xc4, 0x83, 0x89, 0xdf, 0x65, 0xd3, 0x35, 0x55, 0x13, 0xf4, 0x1f, 0x36, 0x92, 0x33, 0x38, 0xcb, 0xed, 0x15, 0xe6, 0x60, 0x2d, 0x25, 0xf5, 0x36, 0x60, 0x3a, 0x37, 0x9b, 0x71, 0x9d, 0x42, 0xb0, 0x14, 0xc8, 0xba, 0x62, 0xa3, 0x49, 0xb0, 0x88, 0xc1, 0x72, 0x73, 0xdd, 0x62, 0x40, 0xa9, 0x62, 0x88, 0x99, 0xca,
+	/* (2^333)P */ 0x47, 0x7b, 0xea, 0xda, 0x46, 0x2f, 0x45, 0xc6, 0xe3, 0xb4, 0x4d, 0x8d, 0xac, 0x0b, 0x54, 0x22, 0x06, 0x31, 0x16, 0x66, 0x3e, 0xe4, 0x38, 0x12, 0xcd, 0xf3, 0xe7, 0x99, 0x37, 0xd9, 0x62, 0x24, 0x4b, 0x05, 0xf2, 0x58, 0xe6, 0x29, 0x4b, 0x0d, 0xf6, 0xc1, 0xba, 0xa0, 0x1e, 0x0f, 0xcb, 0x1f, 0xc6, 0x2b, 0x19, 0xfc, 0x82, 0x01, 0xd0, 0x86,
+	/* (2^334)P */ 0xa2, 0xae, 0x77, 0x20, 0xfb, 0xa8, 0x18, 0xb4, 0x61, 0xef, 0xe8, 0x52, 0x79, 0xbb, 0x86, 0x90, 0x5d, 0x2e, 0x76, 0xed, 0x66, 0x60, 0x5d, 0x00, 0xb5, 0xa4, 0x00, 0x40, 0x89, 0xec, 0xd1, 0xd2, 0x0d, 0x26, 0xb9, 0x30, 0xb2, 0xd2, 0xb8, 0xe8, 0x0e, 0x56, 0xf9, 0x67, 0x94, 0x2e, 0x62, 0xe1, 0x79, 0x48, 0x2b, 0xa9, 0xfa, 0xea, 0xdb, 0x28,
+	/* (2^335)P */ 0x35, 0xf1, 0xb0, 0x43, 0xbd, 0x27, 0xef, 0x18, 0x44, 0xa2, 0x04, 0xb4, 0x69, 0xa1, 0x97, 0x1f, 0x8c, 0x04, 0x82, 0x9b, 0x00, 0x6d, 0xf8, 0xbf, 0x7d, 0xc1, 0x5b, 0xab, 0xe8, 0xb2, 0x34, 0xbd, 0xaf, 0x7f, 0xb2, 0x0d, 0xf3, 0xed, 0xfc, 0x5b, 0x50, 0xee, 0xe7, 0x4a, 0x20, 0xd9, 0xf5, 0xc6, 0x9a, 0x97, 0x6d, 0x07, 0x2f, 0xb9, 0x31, 0x02,
+	/* (2^336)P */ 0xf9, 0x54, 0x4a, 0xc5, 0x61, 0x7e, 0x1d, 0xa6, 0x0e, 0x1a, 0xa8, 0xd3, 0x8c, 0x36, 0x7d, 0xf1, 0x06, 0xb1, 0xac, 0x93, 0xcd, 0xe9, 0x8f, 0x61, 0x6c, 0x5d, 0x03, 0x23, 0xdf, 0x85, 0x53, 0x39, 0x63, 0x5e, 0xeb, 0xf3, 0xd3, 0xd3, 0x75, 0x97, 0x9b, 0x62, 0x9b, 0x01, 0xb3, 0x19, 0xd8, 0x2b, 0x36, 0xf2, 0x2c, 0x2c, 0x6f, 0x36, 0xc6, 0x3c,
+	/* (2^337)P */ 0x05, 0x74, 0x43, 0x10, 0xb6, 0xb0, 0xf8, 0xbf, 0x02, 0x46, 0x9a, 0xee, 0xc1, 0xaf, 0xc1, 0xe5, 0x5a, 0x2e, 0xbb, 0xe1, 0xdc, 0xc6, 0xce, 0x51, 0x29, 0x50, 0xbf, 0x1b, 0xde, 0xff, 0xba, 0x4d, 0x8d, 0x8b, 0x7e, 0xe7, 0xbd, 0x5b, 0x8f, 0xbe, 0xe3, 0x75, 0x71, 0xff, 0x37, 0x05, 0x5a, 0x10, 0xeb, 0x54, 0x7e, 0x44, 0x72, 0x2c, 0xd4, 0xfc,
+	/* (2^338)P */ 0x03, 0x12, 0x1c, 0xb2, 0x08, 0x90, 0xa1, 0x2d, 0x50, 0xa0, 0xad, 0x7f, 0x8d, 0xa6, 0x97, 0xc1, 0xbd, 0xdc, 0xc3, 0xa7, 0xad, 0x31, 0xdf, 0xb8, 0x03, 0x84, 0xc3, 0xb9, 0x29, 0x3d, 0x92, 0x2e, 0xc3, 0x90, 0x07, 0xe8, 0xa7, 0xc7, 0xbc, 0x61, 0xe9, 0x3e, 0xa0, 0x35, 0xda, 0x1d, 0xab, 0x48, 0xfe, 0x50, 0xc9, 0x25, 0x59, 0x23, 0x69, 0x3f,
+	/* (2^339)P */ 0x8e, 0x91, 0xab, 0x6b, 0x91, 0x4f, 0x89, 0x76, 0x67, 0xad, 0xb2, 0x65, 0x9d, 0xad, 0x02, 0x36, 0xdc, 0xac, 0x96, 0x93, 0x97, 0x21, 0x14, 0xd0, 0xe8, 0x11, 0x60, 0x1e, 0xeb, 0x96, 0x06, 0xf2, 0x53, 0xf2, 0x6d, 0xb7, 0x93, 0x6f, 0x26, 0x91, 0x23, 0xe3, 0x34, 0x04, 0x92, 0x91, 0x37, 0x08, 0x50, 0xd6, 0x28, 0x09, 0x27, 0xa1, 0x0c, 0x00,
+	/* (2^340)P */ 0x1f, 0xbb, 0x21, 0x26, 0x33, 0xcb, 0xa4, 0xd1, 0xee, 0x85, 0xf9, 0xd9, 0x3c, 0x90, 0xc3, 0xd1, 0x26, 0xa2, 0x25, 0x93, 0x43, 0x61, 0xed, 0x91, 0x6e, 0x54, 0x03, 0x2e, 0x42, 0x9d, 0xf7, 0xa6, 0x02, 0x0f, 0x2f, 0x9c, 0x7a, 0x8d, 0x12, 0xc2, 0x18, 0xfc, 0x41, 0xff, 0x85, 0x26, 0x1a, 0x44, 0x55, 0x0b, 0x89, 0xab, 0x6f, 0x62, 0x33, 0x8c,
+	/* (2^341)P */ 0xe0, 0x3c, 0x5d, 0x70, 0x64, 0x87, 0x81, 0x35, 0xf2, 0x37, 0xa6, 0x24, 0x3e, 0xe0, 0x62, 0xd5, 0x71, 0xe7, 0x93, 0xfb, 0xac, 0xc3, 0xe7, 0xc7, 0x04, 0xe2, 0x70, 0xd3, 0x29, 0x5b, 0x21, 0xbf, 0xf4, 0x26, 0x5d, 0xf3, 0x95, 0xb4, 0x2a, 0x6a, 0x07, 0x55, 0xa6, 0x4b, 0x3b, 0x15, 0xf2, 0x25, 0x8a, 0x95, 0x3f, 0x63, 0x2f, 0x7a, 0x23, 0x96,
+	/* (2^342)P */ 0x0d, 0x3d, 0xd9, 0x13, 0xa7, 0xb3, 0x5e, 0x67, 0xf7, 0x02, 0x23, 0xee, 0x84, 0xff, 0x99, 0xda, 0xb9, 0x53, 0xf8, 0xf0, 0x0e, 0x39, 0x2f, 0x3c, 0x64, 0x34, 0xe3, 0x09, 0xfd, 0x2b, 0x33, 0xc7, 0xfe, 0x62, 0x2b, 0x84, 0xdf, 0x2b, 0xd2, 0x7c, 0x26, 0x01, 0x70, 0x66, 0x5b, 0x85, 0xc2, 0xbe, 0x88, 0x37, 0xf1, 0x30, 0xac, 0xb8, 0x76, 0xa3,
+	/* (2^343)P */ 0x6e, 0x01, 0xf0, 0x55, 0x35, 0xe4, 0xbd, 0x43, 0x62, 0x9d, 0xd6, 0x11, 0xef, 0x6f, 0xb8, 0x8c, 0xaa, 0x98, 0x87, 0xc6, 0x6d, 0xc4, 0xcc, 0x74, 0x92, 0x53, 0x4a, 0xdf, 0xe4, 0x08, 0x89, 0x17, 0xd0, 0x0f, 0xf4, 0x00, 0x60, 0x78, 0x08, 0x44, 0xb5, 0xda, 0x18, 0xed, 0x98, 0xc8, 0x61, 0x3d, 0x39, 0xdb, 0xcf, 0x1d, 0x49, 0x40, 0x65, 0x75,
+	/* (2^344)P */ 0x8e, 0x10, 0xae, 0x5f, 0x06, 0xd2, 0x95, 0xfd, 0x20, 0x16, 0x49, 0x5b, 0x57, 0xbe, 0x22, 0x8b, 0x43, 0xfb, 0xe6, 0xcc, 0x26, 0xa5, 0x5d, 0xd3, 0x68, 0xc5, 0xf9, 0x5a, 0x86, 0x24, 0x87, 0x27, 0x05, 0xfd, 0xe2, 0xff, 0xb3, 0xa3, 0x7b, 0x37, 0x59, 0xc5, 0x4e, 0x14, 0x94, 0xf9, 0x3b, 0xcb, 0x7c, 0xed, 0xca, 0x1d, 0xb2, 0xac, 0x05, 0x4a,
+	/* (2^345)P */ 0xf4, 0xd1, 0x81, 0xeb, 0x89, 0xbf, 0xfe, 0x1e, 0x41, 0x92, 0x29, 0xee, 0xe1, 0x43, 0xf5, 0x86, 0x1d, 0x2f, 0xbb, 0x1e, 0x84, 0x5d, 0x7b, 0x8d, 0xd5, 0xda, 0xee, 0x1e, 0x8a, 0xd0, 0x27, 0xf2, 0x60, 0x51, 0x59, 0x82, 0xf4, 0x84, 0x2b, 0x5b, 0x14, 0x2d, 0x81, 0x82, 0x3e, 0x2b, 0xb4, 0x6d, 0x51, 0x4f, 0xc5, 0xcb, 0xbf, 0x74, 0xe3, 0xb4,
+	/* (2^346)P */ 0x19, 0x2f, 0x22, 0xb3, 0x04, 0x5f, 0x81, 0xca, 0x05, 0x60, 0xb9, 0xaa, 0xee, 0x0e, 0x2f, 0x48, 0x38, 0xf9, 0x91, 0xb4, 0x66, 0xe4, 0x57, 0x28, 0x54, 0x10, 0xe9, 0x61, 0x9d, 0xd4, 0x90, 0x75, 0xb1, 0x39, 0x23, 0xb6, 0xfc, 0x82, 0xe0, 0xfa, 0xbb, 0x5c, 0x6e, 0xc3, 0x44, 0x13, 0x00, 0x83, 0x55, 0x9e, 0x8e, 0x10, 0x61, 0x81, 0x91, 0x04,
+	/* (2^347)P */ 0x5f, 0x2a, 0xd7, 0x81, 0xd9, 0x9c, 0xbb, 0x79, 0xbc, 0x62, 0x56, 0x98, 0x03, 0x5a, 0x18, 0x85, 0x2a, 0x9c, 0xd0, 0xfb, 0xd2, 0xb1, 0xaf, 0xef, 0x0d, 0x24, 0xc5, 0xfa, 0x39, 0xbb, 0x6b, 0xed, 0xa4, 0xdf, 0xe4, 0x87, 0xcd, 0x41, 0xd3, 0x72, 0x32, 0xc6, 0x28, 0x21, 0xb1, 0xba, 0x8b, 0xa3, 0x91, 0x79, 0x76, 0x22, 0x25, 0x10, 0x61, 0xd1,
+	/* (2^348)P */ 0x73, 0xb5, 0x32, 0x97, 0xdd, 0xeb, 0xdd, 0x22, 0x22, 0xf1, 0x33, 0x3c, 0x77, 0x56, 0x7d, 0x6b, 0x48, 0x2b, 0x05, 0x81, 0x03, 0x03, 0x91, 0x9a, 0xe3, 0x5e, 0xd4, 0xee, 0x3f, 0xf8, 0xbb, 0x50, 0x21, 0x32, 0x4c, 0x4a, 0x58, 0x49, 0xde, 0x0c, 0xde, 0x30, 0x82, 0x3d, 0x92, 0xf0, 0x6c, 0xcc, 0x32, 0x3e, 0xd2, 0x78, 0x8a, 0x6e, 0x2c, 0xd0,
+	/* (2^349)P */ 0xf0, 0xf7, 0xa1, 0x0b, 0xc1, 0x74, 0x85, 0xa8, 0xe9, 0xdd, 0x48, 0xa1, 0xc0, 0x16, 0xd8, 0x2b, 0x61, 0x08, 0xc2, 0x2b, 0x30, 0x26, 0x79, 0xce, 0x9e, 0xfd, 0x39, 0xd7, 0x81, 0xa4, 0x63, 0x8c, 0xd5, 0x74, 0xa0, 0x88, 0xfa, 0x03, 0x30, 0xe9, 0x7f, 0x2b, 0xc6, 0x02, 0xc9, 0x5e, 0xe4, 0xd5, 0x4d, 0x92, 0xd0, 0xf6, 0xf2, 0x5b, 0x79, 0x08,
+	/* (2^350)P */ 0x34, 0x89, 0x81, 0x43, 0xd1, 0x94, 0x2c, 0x10, 0x54, 0x9b, 0xa0, 0xe5, 0x44, 0xe8, 0xc2, 0x2f, 0x3e, 0x0e, 0x74, 0xae, 0xba, 0xe2, 0xac, 0x85, 0x6b, 0xd3, 0x5c, 0x97, 0xf7, 0x90, 0xf1, 0x12, 0xc0, 0x03, 0xc8, 0x1f, 0x37, 0x72, 0x8c, 0x9b, 0x9c, 0x17, 0x96, 0x9d, 0xc7, 0xbf, 0xa3, 0x3f, 0x44, 0x3d, 0x87, 0x81, 0xbd, 0x81, 0xa6, 0x5f,
+	/* (2^351)P */ 0xe4, 0xff, 0x78, 0x62, 0x82, 0x5b, 0x76, 0x58, 0xf5, 0x5b, 0xa6, 0xc4, 0x53, 0x11, 0x3b, 0x7b, 0xaa, 0x67, 0xf8, 0xea, 0x3b, 0x5d, 0x9a, 0x2e, 0x04, 0xeb, 0x4a, 0x24, 0xfb, 0x56, 0xf0, 0xa8, 0xd4, 0x14, 0xed, 0x0f, 0xfd, 0xc5, 0x26, 0x17, 0x2a, 0xf0, 0xb9, 0x13, 0x8c, 0xbd, 0x65, 0x14, 0x24, 0x95, 0x27, 0x12, 0x63, 0x2a, 0x09, 0x18,
+	/* (2^352)P */ 0xe1, 0x5c, 0xe7, 0xe0, 0x00, 0x6a, 0x96, 0xf2, 0x49, 0x6a, 0x39, 0xa5, 0xe0, 0x17, 0x79, 0x4a, 0x63, 0x07, 0x62, 0x09, 0x61, 0x1b, 0x6e, 0xa9, 0xb5, 0x62, 0xb7, 0xde, 0xdf, 0x80, 0x4c, 0x5a, 0x99, 0x73, 0x59, 0x9d, 0xfb, 0xb1, 0x5e, 0xbe, 0xb8, 0xb7, 0x63, 0x93, 0xe8, 0xad, 0x5e, 0x1f, 0xae, 0x59, 0x1c, 0xcd, 0xb4, 0xc2, 0xb3, 0x8a,
+	/* (2^353)P */ 0x78, 0x53, 0xa1, 0x4c, 0x70, 0x9c, 0x63, 0x7e, 0xb3, 0x12, 0x40, 0x5f, 0xbb, 0x23, 0xa7, 0xf7, 0x77, 0x96, 0x5b, 0x4d, 0x91, 0x10, 0x52, 0x85, 0x9e, 0xa5, 0x38, 0x0b, 0xfd, 0x25, 0x01, 0x4b, 0xfa, 0x4d, 0xd3, 0x3f, 0x78, 0x74, 0x42, 0xff, 0x62, 0x2d, 0x27, 0xdc, 0x9d, 0xd1, 0x29, 0x76, 0x2e, 0x78, 0xb3, 0x35, 0xfa, 0x15, 0xd5, 0x38,
+	/* (2^354)P */ 0x8b, 0xc7, 0x43, 0xce, 0xf0, 0x5e, 0xf1, 0x0d, 0x02, 0x38, 0xe8, 0x82, 0xc9, 0x25, 0xad, 0x2d, 0x27, 0xa4, 0x54, 0x18, 0xb2, 0x30, 0x73, 0xa4, 0x41, 0x08, 0xe4, 0x86, 0xe6, 0x8c, 0xe9, 0x2a, 0x34, 0xb3, 0xd6, 0x61, 0x8f, 0x66, 0x26, 0x08, 0xb6, 0x06, 0x33, 0xaa, 0x12, 0xac, 0x72, 0xec, 0x2e, 0x52, 0xa3, 0x25, 0x3e, 0xd7, 0x62, 0xe8,
+	/* (2^355)P */ 0xc4, 0xbb, 0x89, 0xc8, 0x40, 0xcc, 0x84, 0xec, 0x4a, 0xd9, 0xc4, 0x55, 0x78, 0x00, 0xcf, 0xd8, 0xe9, 0x24, 0x59, 0xdc, 0x5e, 0xf0, 0x66, 0xa1, 0x83, 0xae, 0x97, 0x18, 0xc5, 0x54, 0x27, 0xa2, 0x21, 0x52, 0x03, 0x31, 0x5b, 0x11, 0x67, 0xf6, 0x12, 0x00, 0x87, 0x2f, 0xff, 0x59, 0x70, 0x8f, 0x6d, 0x71, 0xab, 0xab, 0x24, 0xb8, 0xba, 0x35,
+	/* (2^356)P */ 0x69, 0x43, 0xa7, 0x14, 0x06, 0x96, 0xe9, 0xc2, 0xe3, 0x2b, 0x45, 0x22, 0xc0, 0xd0, 0x2f, 0x34, 0xd1, 0x01, 0x99, 0xfc, 0x99, 0x38, 0xa1, 0x25, 0x2e, 0x59, 0x6c, 0x27, 0xc9, 0xeb, 0x7b, 0xdc, 0x4e, 0x26, 0x68, 0xba, 0xfa, 0xec, 0x02, 0x05, 0x64, 0x80, 0x30, 0x20, 0x5c, 0x26, 0x7f, 0xaf, 0x95, 0x17, 0x3d, 0x5c, 0x9e, 0x96, 0x96, 0xaf,
+	/* (2^357)P */ 0xa6, 0xba, 0x21, 0x29, 0x32, 0xe2, 0x98, 0xde, 0x9b, 0x6d, 0x0b, 0x44, 0x91, 0xa8, 0x3e, 0xd4, 0xb8, 0x04, 0x6c, 0xf6, 0x04, 0x39, 0xbd, 0x52, 0x05, 0x15, 0x27, 0x78, 0x8e, 0x55, 0xac, 0x79, 0xc5, 0xe6, 0x00, 0x7f, 0x90, 0xa2, 0xdd, 0x07, 0x13, 0xe0, 0x24, 0x70, 0x5c, 0x0f, 0x4d, 0xa9, 0xf9, 0xae, 0xcb, 0x34, 0x10, 0x9d, 0x89, 0x9d,
+	/* (2^358)P */ 0x12, 0xe0, 0xb3, 0x9f, 0xc4, 0x96, 0x1d, 0xcf, 0xed, 0x99, 0x64, 0x28, 0x8d, 0xc7, 0x31, 0x82, 0xee, 0x5e, 0x75, 0x48, 0xff, 0x3a, 0xf2, 0x09, 0x34, 0x03, 0x93, 0x52, 0x19, 0xb2, 0xc5, 0x81, 0x93, 0x45, 0x5e, 0x59, 0x21, 0x2b, 0xec, 0x89, 0xba, 0x36, 0x6e, 0xf9, 0x82, 0x75, 0x7e, 0x82, 0x3f, 0xaa, 0xe2, 0xe3, 0x3b, 0x94, 0xfd, 0x98,
+	/* (2^359)P */ 0x7c, 0xdb, 0x75, 0x31, 0x61, 0xfb, 0x15, 0x28, 0x94, 0xd7, 0xc3, 0x5a, 0xa9, 0xa1, 0x0a, 0x66, 0x0f, 0x2b, 0x13, 0x3e, 0x42, 0xb5, 0x28, 0x3a, 0xca, 0x83, 0xf3, 0x61, 0x22, 0xf4, 0x40, 0xc5, 0xdf, 0xe7, 0x31, 0x9f, 0x7e, 0x51, 0x75, 0x06, 0x9d, 0x51, 0xc8, 0xe7, 0x9f, 0xc3, 0x71, 0x4f, 0x3d, 0x5b, 0xfb, 0xe9, 0x8e, 0x08, 0x40, 0x8e,
+	/* (2^360)P */ 0xf7, 0x31, 0xad, 0x50, 0x5d, 0x25, 0x93, 0x73, 0x68, 0xf6, 0x7c, 0x89, 0x5a, 0x3d, 0x9f, 0x9b, 0x05, 0x82, 0xe7, 0x70, 0x4b, 0x19, 0xaa, 0xcf, 0xff, 0xde, 0x50, 0x8f, 0x2f, 0x69, 0xd3, 0xf0, 0x99, 0x51, 0x6b, 0x9d, 0xb6, 0x56, 0x6f, 0xf8, 0x4c, 0x74, 0x8b, 0x4c, 0x91, 0xf9, 0xa9, 0xb1, 0x3e, 0x07, 0xdf, 0x0b, 0x27, 0x8a, 0xb1, 0xed,
+	/* (2^361)P */ 0xfb, 0x67, 0xd9, 0x48, 0xd2, 0xe4, 0x44, 0x9b, 0x43, 0x15, 0x8a, 0xeb, 0x00, 0x53, 0xad, 0x25, 0xc7, 0x7e, 0x19, 0x30, 0x87, 0xb7, 0xd5, 0x5f, 0x04, 0xf8, 0xaa, 0xdd, 0x57, 0xae, 0x34, 0x75, 0xe2, 0x84, 0x4b, 0x54, 0x60, 0x37, 0x95, 0xe4, 0xd3, 0xec, 0xac, 0xef, 0x47, 0x31, 0xa3, 0xc8, 0x31, 0x22, 0xdb, 0x26, 0xe7, 0x6a, 0xb5, 0xad,
+	/* (2^362)P */ 0x44, 0x09, 0x5c, 0x95, 0xe4, 0x72, 0x3c, 0x1a, 0xd1, 0xac, 0x42, 0x51, 0x99, 0x6f, 0xfa, 0x1f, 0xf2, 0x22, 0xbe, 0xff, 0x7b, 0x66, 0xf5, 0x6c, 0xb3, 0x66, 0xc7, 0x4d, 0x78, 0x31, 0x83, 0x80, 0xf5, 0x41, 0xe9, 0x7f, 0xbe, 0xf7, 0x23, 0x49, 0x6b, 0x84, 0x4e, 0x7e, 0x47, 0x07, 0x6e, 0x74, 0xdf, 0xe5, 0x9d, 0x9e, 0x56, 0x2a, 0xc0, 0xbc,
+	/* (2^363)P */ 0xac, 0x10, 0x80, 0x8c, 0x7c, 0xfa, 0x83, 0xdf, 0xb3, 0xd0, 0xc4, 0xbe, 0xfb, 0x9f, 0xac, 0xc9, 0xc3, 0x40, 0x95, 0x0b, 0x09, 0x23, 0xda, 0x63, 0x67, 0xcf, 0xe7, 0x9f, 0x7d, 0x7b, 0x6b, 0xe2, 0xe6, 0x6d, 0xdb, 0x87, 0x9e, 0xa6, 0xff, 0x6d, 0xab, 0xbd, 0xfb, 0x54, 0x84, 0x68, 0xcf, 0x89, 0xf1, 0xd0, 0xe2, 0x85, 0x61, 0xdc, 0x22, 0xd1,
+	/* (2^364)P */ 0xa8, 0x48, 0xfb, 0x8c, 0x6a, 0x63, 0x01, 0x72, 0x43, 0x43, 0xeb, 0x21, 0xa3, 0x00, 0x8a, 0xc0, 0x87, 0x51, 0x9e, 0x86, 0x75, 0x16, 0x79, 0xf9, 0x6b, 0x11, 0x80, 0x62, 0xc2, 0x9d, 0xb8, 0x8c, 0x30, 0x8e, 0x8d, 0x03, 0x52, 0x7e, 0x31, 0x59, 0x38, 0xf9, 0x25, 0xc7, 0x0f, 0xc7, 0xa8, 0x2b, 0x5c, 0x80, 0xfa, 0x90, 0xa2, 0x63, 0xca, 0xe7,
+	/* (2^365)P */ 0xf1, 0x5d, 0xb5, 0xd9, 0x20, 0x10, 0x7d, 0x0f, 0xc5, 0x50, 0x46, 0x07, 0xff, 0x02, 0x75, 0x2b, 0x4a, 0xf3, 0x39, 0x91, 0x72, 0xb7, 0xd5, 0xcc, 0x38, 0xb8, 0xe7, 0x36, 0x26, 0x5e, 0x11, 0x97, 0x25, 0xfb, 0x49, 0x68, 0xdc, 0xb4, 0x46, 0x87, 0x5c, 0xc2, 0x7f, 0xaa, 0x7d, 0x36, 0x23, 0xa6, 0xc6, 0x53, 0xec, 0xbc, 0x57, 0x47, 0xc1, 0x2b,
+	/* (2^366)P */ 0x25, 0x5d, 0x7d, 0x95, 0xda, 0x0b, 0x8f, 0x78, 0x1e, 0x19, 0x09, 0xfa, 0x67, 0xe0, 0xa0, 0x17, 0x24, 0x76, 0x6c, 0x30, 0x1f, 0x62, 0x3d, 0xbe, 0x45, 0x70, 0xcc, 0xb6, 0x1e, 0x68, 0x06, 0x25, 0x68, 0x16, 0x1a, 0x33, 0x3f, 0x90, 0xc7, 0x78, 0x2d, 0x98, 0x3c, 0x2f, 0xb9, 0x2d, 0x94, 0x0b, 0xfb, 0x49, 0x56, 0x30, 0xd7, 0xc1, 0xe6, 0x48,
+	/* (2^367)P */ 0x7a, 0xd1, 0xe0, 0x8e, 0x67, 0xfc, 0x0b, 0x50, 0x1f, 0x84, 0x98, 0xfa, 0xaf, 0xae, 0x2e, 0x31, 0x27, 0xcf, 0x3f, 0xf2, 0x6e, 0x8d, 0x81, 0x8f, 0xd2, 0x5f, 0xde, 0xd3, 0x5e, 0xe9, 0xe7, 0x13, 0x48, 0x83, 0x5a, 0x4e, 0x84, 0xd1, 0x58, 0xcf, 0x6b, 0x84, 0xdf, 0x13, 0x1d, 0x91, 0x85, 0xe8, 0xcb, 0x29, 0x79, 0xd2, 0xca, 0xac, 0x6a, 0x93,
+	/* (2^368)P */ 0x53, 0x82, 0xce, 0x61, 0x96, 0x88, 0x6f, 0xe1, 0x4a, 0x4c, 0x1e, 0x30, 0x73, 0xe8, 0x74, 0xde, 0x40, 0x2b, 0xe0, 0xc4, 0xb5, 0xd8, 0x7c, 0x15, 0xe7, 0xe1, 0xb1, 0xe0, 0xd6, 0x88, 0xb1, 0x6a, 0x57, 0x19, 0x6a, 0x22, 0x66, 0x57, 0xf6, 0x8d, 0xfd, 0xc0, 0xf2, 0xa3, 0x03, 0x56, 0xfb, 0x2e, 0x75, 0x5e, 0xc7, 0x8e, 0x22, 0x96, 0x5c, 0x06,
+	/* (2^369)P */ 0x98, 0x7e, 0xbf, 0x3e, 0xbf, 0x24, 0x9d, 0x15, 0xd3, 0xf6, 0xd3, 0xd2, 0xf0, 0x11, 0xf2, 0xdb, 0x36, 0x23, 0x38, 0xf7, 0x1d, 0x71, 0x20, 0xd2, 0x54, 0x7f, 0x1e, 0x24, 0x8f, 0xe2, 0xaa, 0xf7, 0x3f, 0x6b, 0x41, 0x4e, 0xdc, 0x0e, 0xec, 0xe8, 0x35, 0x0a, 0x08, 0x6d, 0x89, 0x5b, 0x32, 0x91, 0x01, 0xb6, 0xe0, 0x2c, 0xc6, 0xa1, 0xbe, 0xb4,
+	/* (2^370)P */ 0x29, 0xf2, 0x1e, 0x1c, 0xdc, 0x68, 0x8a, 0x43, 0x87, 0x2c, 0x48, 0xb3, 0x9e, 0xed, 0xd2, 0x82, 0x46, 0xac, 0x2f, 0xef, 0x93, 0x34, 0x37, 0xca, 0x64, 0x8d, 0xc9, 0x06, 0x90, 0xbb, 0x78, 0x0a, 0x3c, 0x4c, 0xcf, 0x35, 0x7a, 0x0f, 0xf7, 0xa7, 0xf4, 0x2f, 0x45, 0x69, 0x3f, 0xa9, 0x5d, 0xce, 0x7b, 0x8a, 0x84, 0xc3, 0xae, 0xf4, 0xda, 0xd5,
+	/* (2^371)P */ 0xca, 0xba, 0x95, 0x43, 0x05, 0x7b, 0x06, 0xd9, 0x5c, 0x0a, 0x18, 0x5f, 0x6a, 0x6a, 0xce, 0xc0, 0x3d, 0x95, 0x51, 0x0e, 0x1a, 0xbe, 0x85, 0x7a, 0xf2, 0x69, 0xec, 0xc0, 0x8c, 0xca, 0xa3, 0x32, 0x0a, 0x76, 0x50, 0xc6, 0x76, 0x61, 0x00, 0x89, 0xbf, 0x6e, 0x0f, 0x48, 0x90, 0x31, 0x93, 0xec, 0x34, 0x70, 0xf0, 0xc3, 0x8d, 0xf0, 0x0f, 0xb5,
+	/* (2^372)P */ 0xbe, 0x23, 0xe2, 0x18, 0x99, 0xf1, 0xed, 0x8a, 0xf6, 0xc9, 0xac, 0xb8, 0x1e, 0x9a, 0x3c, 0x15, 0xae, 0xd7, 0x6d, 0xb3, 0x04, 0xee, 0x5b, 0x0d, 0x1e, 0x79, 0xb7, 0xf9, 0xf9, 0x8d, 0xad, 0xf9, 0x8f, 0x5a, 0x6a, 0x7b, 0xd7, 0x9b, 0xca, 0x62, 0xfe, 0x9c, 0xc0, 0x6f, 0x6d, 0x9d, 0x76, 0xa3, 0x69, 0xb9, 0x4c, 0xa1, 0xc4, 0x0c, 0x76, 0xaa,
+	/* (2^373)P */ 0x1c, 0x06, 0xfe, 0x3f, 0x45, 0x70, 0xcd, 0x97, 0xa9, 0xa2, 0xb1, 0xd3, 0xf2, 0xa5, 0x0c, 0x49, 0x2c, 0x75, 0x73, 0x1f, 0xcf, 0x00, 0xaf, 0xd5, 0x2e, 0xde, 0x0d, 0x8f, 0x8f, 0x7c, 0xc4, 0x58, 0xce, 0xd4, 0xf6, 0x24, 0x19, 0x2e, 0xd8, 0xc5, 0x1d, 0x1a, 0x3f, 0xb8, 0x4f, 0xbc, 0x7d, 0xbd, 0x68, 0xe3, 0x81, 0x98, 0x1b, 0xa8, 0xc9, 0xd9,
+	/* (2^374)P */ 0x39, 0x95, 0x78, 0x24, 0x6c, 0x38, 0xe4, 0xe7, 0xd0, 0x8d, 0xb9, 0x38, 0x71, 0x5e, 0xc1, 0x62, 0x80, 0xcc, 0xcb, 0x8c, 0x97, 0xca, 0xf8, 0xb9, 0xd9, 0x9c, 0xce, 0x72, 0x7b, 0x70, 0xee, 0x5f, 0xea, 0xa2, 0xdf, 0xa9, 0x14, 0x10, 0xf9, 0x6e, 0x59, 0x9f, 0x9c, 0xe0, 0x0c, 0xb2, 0x07, 0x97, 0xcd, 0xd2, 0x89, 0x16, 0xfd, 0x9c, 0xa8, 0xa5,
+	/* (2^375)P */ 0x5a, 0x61, 0xf1, 0x59, 0x7c, 0x38, 0xda, 0xe2, 0x85, 0x99, 0x68, 0xe9, 0xc9, 0xf7, 0x32, 0x7e, 0xc4, 0xca, 0xb7, 0x11, 0x08, 0x69, 0x2b, 0x66, 0x02, 0xf7, 0x2e, 0x18, 0xc3, 0x8e, 0xe1, 0xf9, 0xc5, 0x19, 0x9a, 0x0a, 0x9c, 0x07, 0xba, 0xc7, 0x9c, 0x03, 0x34, 0x89, 0x99, 0x67, 0x0b, 0x16, 0x4b, 0x07, 0x36, 0x16, 0x36, 0x2c, 0xe2, 0xa1,
+	/* (2^376)P */ 0x70, 0x10, 0x91, 0x27, 0xa8, 0x24, 0x8e, 0x29, 0x04, 0x6f, 0x79, 0x1f, 0xd3, 0xa5, 0x68, 0xd3, 0x0b, 0x7d, 0x56, 0x4d, 0x14, 0x57, 0x7b, 0x2e, 0x00, 0x9f, 0x9a, 0xfd, 0x6c, 0x63, 0x18, 0x81, 0xdb, 0x9d, 0xb7, 0xd7, 0xa4, 0x1e, 0xe8, 0x40, 0xf1, 0x4c, 0xa3, 0x01, 0xd5, 0x4b, 0x75, 0xea, 0xdd, 0x97, 0xfd, 0x5b, 0xb2, 0x66, 0x6a, 0x24,
+	/* (2^377)P */ 0x72, 0x11, 0xfe, 0x73, 0x1b, 0xd3, 0xea, 0x7f, 0x93, 0x15, 0x15, 0x05, 0xfe, 0x40, 0xe8, 0x28, 0xd8, 0x50, 0x47, 0x66, 0xfa, 0xb7, 0xb5, 0x04, 0xba, 0x35, 0x1e, 0x32, 0x9f, 0x5f, 0x32, 0xba, 0x3d, 0xd1, 0xed, 0x9a, 0x76, 0xca, 0xa3, 0x3e, 0x77, 0xd8, 0xd8, 0x7c, 0x5f, 0x68, 0x42, 0xb5, 0x86, 0x7f, 0x3b, 0xc9, 0xc1, 0x89, 0x64, 0xda,
+	/* (2^378)P */ 0xd5, 0xd4, 0x17, 0x31, 0xfc, 0x6a, 0xfd, 0xb8, 0xe8, 0xe5, 0x3e, 0x39, 0x06, 0xe4, 0xd1, 0x90, 0x2a, 0xca, 0xf6, 0x54, 0x6c, 0x1b, 0x2f, 0x49, 0x97, 0xb1, 0x2a, 0x82, 0x43, 0x3d, 0x1f, 0x8b, 0xe2, 0x47, 0xc5, 0x24, 0xa8, 0xd5, 0x53, 0x29, 0x7d, 0xc6, 0x87, 0xa6, 0x25, 0x3a, 0x64, 0xdd, 0x71, 0x08, 0x9e, 0xcd, 0xe9, 0x45, 0xc7, 0xba,
+	/* (2^379)P */ 0x37, 0x72, 0x6d, 0x13, 0x7a, 0x8d, 0x04, 0x31, 0xe6, 0xe3, 0x9e, 0x36, 0x71, 0x3e, 0xc0, 0x1e, 0xe3, 0x71, 0xd3, 0x49, 0x4e, 0x4a, 0x36, 0x42, 0x68, 0x68, 0x61, 0xc7, 0x3c, 0xdb, 0x81, 0x49, 0xf7, 0x91, 0x4d, 0xea, 0x4c, 0x4f, 0x98, 0xc6, 0x7e, 0x60, 0x84, 0x4b, 0x6a, 0x37, 0xbb, 0x52, 0xf7, 0xce, 0x02, 0xe4, 0xad, 0xd1, 0x3c, 0xa7,
+	/* (2^380)P */ 0x51, 0x06, 0x2d, 0xf8, 0x08, 0xe8, 0xf1, 0x0c, 0xe5, 0xa9, 0xac, 0x29, 0x73, 0x3b, 0xed, 0x98, 0x5f, 0x55, 0x08, 0x38, 0x51, 0x44, 0x36, 0x5d, 0xea, 0xc3, 0xb8, 0x0e, 0xa0, 0x4f, 0xd2, 0x79, 0xe9, 0x98, 0xc3, 0xf5, 0x00, 0xb9, 0x26, 0x27, 0x42, 0xa8, 0x07, 0xc1, 0x12, 0x31, 0xc1, 0xc3, 0x3c, 0x3b, 0x7a, 0x72, 0x97, 0xc2, 0x70, 0x3a,
+	/* (2^381)P */ 0xf4, 0xb2, 0xba, 0x32, 0xbc, 0xa9, 0x2f, 0x87, 0xc7, 0x3c, 0x45, 0xcd, 0xae, 0xe2, 0x13, 0x6d, 0x3a, 0xf2, 0xf5, 0x66, 0x97, 0x29, 0xaf, 0x53, 0x9f, 0xda, 0xea, 0x14, 0xdf, 0x04, 0x98, 0x19, 0x95, 0x9e, 0x2a, 0x00, 0x5c, 0x9d, 0x1d, 0xf0, 0x39, 0x23, 0xff, 0xfc, 0xca, 0x36, 0xb7, 0xde, 0xdf, 0x37, 0x78, 0x52, 0x21, 0xfa, 0x19, 0x10,
+	/* (2^382)P */ 0x50, 0x20, 0x73, 0x74, 0x62, 0x21, 0xf2, 0xf7, 0x9b, 0x66, 0x85, 0x34, 0x74, 0xd4, 0x9d, 0x60, 0xd7, 0xbc, 0xc8, 0x46, 0x3b, 0xb8, 0x80, 0x42, 0x15, 0x0a, 0x6c, 0x35, 0x1a, 0x69, 0xf0, 0x1d, 0x4b, 0x29, 0x54, 0x5a, 0x9a, 0x48, 0xec, 0x9f, 0x37, 0x74, 0x91, 0xd0, 0xd1, 0x9e, 0x00, 0xc2, 0x76, 0x56, 0xd6, 0xa0, 0x15, 0x14, 0x83, 0x59,
+	/* (2^383)P */ 0xc2, 0xf8, 0x22, 0x20, 0x23, 0x07, 0xbd, 0x1d, 0x6f, 0x1e, 0x8c, 0x56, 0x06, 0x6a, 0x4b, 0x9f, 0xe2, 0xa9, 0x92, 0x46, 0x4b, 0x46, 0x59, 0xd7, 0xe1, 0xda, 0x14, 0x98, 0x07, 0x65, 0x7e, 0x28, 0x20, 0xf2, 0x9d, 0x4f, 0x36, 0x5c, 0x92, 0xe0, 0x9d, 0xfe, 0x3e, 0xda, 0xe4, 0x47, 0x19, 0x3c, 0x00, 0x7f, 0x22, 0xf2, 0x9e, 0x51, 0xae, 0x4d,
+	/* (2^384)P */ 0xbe, 0x8c, 0x1b, 0x10, 0xb6, 0xad, 0xcc, 0xcc, 0xd8, 0x5e, 0x21, 0xa6, 0xfb, 0xf1, 0xf6, 0xbd, 0x0a, 0x24, 0x67, 0xb4, 0x57, 0x7a, 0xbc, 0xe8, 0xe9, 0xff, 0xee, 0x0a, 0x1f, 0xee, 0xbd, 0xc8, 0x44, 0xed, 0x2b, 0xbb, 0x55, 0x1f, 0xdd, 0x7c, 0xb3, 0xeb, 0x3f, 0x63, 0xa1, 0x28, 0x91, 0x21, 0xab, 0x71, 0xc6, 0x4c, 0xd0, 0xe9, 0xb0, 0x21,
+	/* (2^385)P */ 0xad, 0xc9, 0x77, 0x2b, 0xee, 0x89, 0xa4, 0x7b, 0xfd, 0xf9, 0xf6, 0x14, 0xe4, 0xed, 0x1a, 0x16, 0x9b, 0x78, 0x41, 0x43, 0xa8, 0x83, 0x72, 0x06, 0x2e, 0x7c, 0xdf, 0xeb, 0x7e, 0xdd, 0xd7, 0x8b, 0xea, 0x9a, 0x2b, 0x03, 0xba, 0x57, 0xf3, 0xf1, 0xd9, 0xe5, 0x09, 0xc5, 0x98, 0x61, 0x1c, 0x51, 0x6d, 0x5d, 0x6e, 0xfb, 0x5e, 0x95, 0x9f, 0xb5,
+	/* (2^386)P */ 0x23, 0xe2, 0x1e, 0x95, 0xa3, 0x5e, 0x42, 0x10, 0xc7, 0xc3, 0x70, 0xbf, 0x4b, 0x6b, 0x83, 0x36, 0x93, 0xb7, 0x68, 0x47, 0x88, 0x3a, 0x10, 0x88, 0x48, 0x7f, 0x8c, 0xae, 0x54, 0x10, 0x02, 0xa4, 0x52, 0x8f, 0x8d, 0xf7, 0x26, 0x4f, 0x50, 0xc3, 0x6a, 0xe2, 0x4e, 0x3b, 0x4c, 0xb9, 0x8a, 0x14, 0x15, 0x6d, 0x21, 0x29, 0xb3, 0x6e, 0x4e, 0xd0,
+	/* (2^387)P */ 0x4c, 0x8a, 0x18, 0x3f, 0xb7, 0x20, 0xfd, 0x3e, 0x54, 0xca, 0x68, 0x3c, 0xea, 0x6f, 0xf4, 0x6b, 0xa2, 0xbd, 0x01, 0xbd, 0xfe, 0x08, 0xa8, 0xd8, 0xc2, 0x20, 0x36, 0x05, 0xcd, 0xe9, 0xf3, 0x9e, 0xfa, 0x85, 0x66, 0x8f, 0x4b, 0x1d, 0x8c, 0x64, 0x4f, 0xb8, 0xc6, 0x0f, 0x5b, 0x57, 0xd8, 0x24, 0x19, 0x5a, 0x14, 0x4b, 0x92, 0xd3, 0x96, 0xbc,
+	/* (2^388)P */ 0xa9, 0x3f, 0xc9, 0x6c, 0xca, 0x64, 0x1e, 0x6f, 0xdf, 0x65, 0x7f, 0x9a, 0x47, 0x6b, 0x8a, 0x60, 0x31, 0xa6, 0x06, 0xac, 0x69, 0x30, 0xe6, 0xea, 0x63, 0x42, 0x26, 0x5f, 0xdb, 0xd0, 0xf2, 0x8e, 0x34, 0x0a, 0x3a, 0xeb, 0xf3, 0x79, 0xc8, 0xb7, 0x60, 0x56, 0x5c, 0x37, 0x95, 0x71, 0xf8, 0x7f, 0x49, 0x3e, 0x9e, 0x01, 0x26, 0x1e, 0x80, 0x9f,
+	/* (2^389)P */ 0xf8, 0x16, 0x9a, 0xaa, 0xb0, 0x28, 0xb5, 0x8e, 0xd0, 0x60, 0xe5, 0x26, 0xa9, 0x47, 0xc4, 0x5c, 0xa9, 0x39, 0xfe, 0x0a, 0xd8, 0x07, 0x2b, 0xb3, 0xce, 0xf1, 0xea, 0x1a, 0xf4, 0x7b, 0x98, 0x31, 0x3d, 0x13, 0x29, 0x80, 0xe8, 0x0d, 0xcf, 0x56, 0x39, 0x86, 0x50, 0x0c, 0xb3, 0x18, 0xf4, 0xc5, 0xca, 0xf2, 0x6f, 0xcd, 0x8d, 0xd5, 0x02, 0xb0,
+	/* (2^390)P */ 0xbf, 0x39, 0x3f, 0xac, 0x6d, 0x1a, 0x6a, 0xe4, 0x42, 0x24, 0xd6, 0x41, 0x9d, 0xb9, 0x5b, 0x46, 0x73, 0x93, 0x76, 0xaa, 0xb7, 0x37, 0x36, 0xa6, 0x09, 0xe5, 0x04, 0x3b, 0x66, 0xc4, 0x29, 0x3e, 0x41, 0xc2, 0xcb, 0xe5, 0x17, 0xd7, 0x34, 0x67, 0x1d, 0x2c, 0x12, 0xec, 0x24, 0x7a, 0x40, 0xa2, 0x45, 0x41, 0xf0, 0x75, 0xed, 0x43, 0x30, 0xc9,
+	/* (2^391)P */ 0x80, 0xf6, 0x47, 0x5b, 0xad, 0x54, 0x02, 0xbc, 0xdd, 0xa4, 0xb2, 0xd7, 0x42, 0x95, 0xf2, 0x0d, 0x1b, 0xef, 0x37, 0xa7, 0xb4, 0x34, 0x04, 0x08, 0x71, 0x1b, 0xd3, 0xdf, 0xa1, 0xf0, 0x2b, 0xfa, 0xc0, 0x1f, 0xf3, 0x44, 0xb5, 0xc6, 0x47, 0x3d, 0x65, 0x67, 0x45, 0x4d, 0x2f, 0xde, 0x52, 0x73, 0xfc, 0x30, 0x01, 0x6b, 0xc1, 0x03, 0xd8, 0xd7,
+	/* (2^392)P */ 0x1c, 0x67, 0x55, 0x3e, 0x01, 0x17, 0x0f, 0x3e, 0xe5, 0x34, 0x58, 0xfc, 0xcb, 0x71, 0x24, 0x74, 0x5d, 0x36, 0x1e, 0x89, 0x2a, 0x63, 0xf8, 0xf8, 0x9f, 0x50, 0x9f, 0x32, 0x92, 0x29, 0xd8, 0x1a, 0xec, 0x76, 0x57, 0x6c, 0x67, 0x12, 0x6a, 0x6e, 0xef, 0x97, 0x1f, 0xc3, 0x77, 0x60, 0x3c, 0x22, 0xcb, 0xc7, 0x04, 0x1a, 0x89, 0x2d, 0x10, 0xa6,
+	/* (2^393)P */ 0x12, 0xf5, 0xa9, 0x26, 0x16, 0xd9, 0x3c, 0x65, 0x5d, 0x83, 0xab, 0xd1, 0x70, 0x6b, 0x1c, 0xdb, 0xe7, 0x86, 0x0d, 0xfb, 0xe7, 0xf8, 0x2a, 0x58, 0x6e, 0x7a, 0x66, 0x13, 0x53, 0x3a, 0x6f, 0x8d, 0x43, 0x5f, 0x14, 0x23, 0x14, 0xff, 0x3d, 0x52, 0x7f, 0xee, 0xbd, 0x7a, 0x34, 0x8b, 0x35, 0x24, 0xc3, 0x7a, 0xdb, 0xcf, 0x22, 0x74, 0x9a, 0x8f,
+	/* (2^394)P */ 0xdb, 0x20, 0xfc, 0xe5, 0x39, 0x4e, 0x7d, 0x78, 0xee, 0x0b, 0xbf, 0x1d, 0x80, 0xd4, 0x05, 0x4f, 0xb9, 0xd7, 0x4e, 0x94, 0x88, 0x9a, 0x50, 0x78, 0x1a, 0x70, 0x8c, 0xcc, 0x25, 0xb6, 0x61, 0x09, 0xdc, 0x7b, 0xea, 0x3f, 0x7f, 0xea, 0x2a, 0x0d, 0x47, 0x1c, 0x8e, 0xa6, 0x5b, 0xd2, 0xa3, 0x61, 0x93, 0x3c, 0x68, 0x9f, 0x8b, 0xea, 0xb0, 0xcb,
+	/* (2^395)P */ 0xff, 0x54, 0x02, 0x19, 0xae, 0x8b, 0x4c, 0x2c, 0x3a, 0xe0, 0xe4, 0xac, 0x87, 0xf7, 0x51, 0x45, 0x41, 0x43, 0xdc, 0xaa, 0xcd, 0xcb, 0xdc, 0x40, 0xe3, 0x44, 0x3b, 0x1d, 0x9e, 0x3d, 0xb9, 0x82, 0xcc, 0x7a, 0xc5, 0x12, 0xf8, 0x1e, 0xdd, 0xdb, 0x8d, 0xb0, 0x2a, 0xe8, 0xe6, 0x6c, 0x94, 0x3b, 0xb7, 0x2d, 0xba, 0x79, 0x3b, 0xb5, 0x86, 0xfb,
+	/* (2^396)P */ 0x82, 0x88, 0x13, 0xdd, 0x6c, 0xcd, 0x85, 0x2b, 0x90, 0x86, 0xb7, 0xac, 0x16, 0xa6, 0x6e, 0x6a, 0x94, 0xd8, 0x1e, 0x4e, 0x41, 0x0f, 0xce, 0x81, 0x6a, 0xa8, 0x26, 0x56, 0x43, 0x52, 0x52, 0xe6, 0xff, 0x88, 0xcf, 0x47, 0x05, 0x1d, 0xff, 0xf3, 0xa0, 0x10, 0xb2, 0x97, 0x87, 0xeb, 0x47, 0xbb, 0xfa, 0x1f, 0xe8, 0x4c, 0xce, 0xc4, 0xcd, 0x93,
+	/* (2^397)P */ 0xf4, 0x11, 0xf5, 0x8d, 0x89, 0x29, 0x79, 0xb3, 0x59, 0x0b, 0x29, 0x7d, 0x9c, 0x12, 0x4a, 0x65, 0x72, 0x3a, 0xf9, 0xec, 0x37, 0x18, 0x86, 0xef, 0x44, 0x07, 0x25, 0x74, 0x76, 0x53, 0xed, 0x51, 0x01, 0xc6, 0x28, 0xc5, 0xc3, 0x4a, 0x0f, 0x99, 0xec, 0xc8, 0x40, 0x5a, 0x83, 0x30, 0x79, 0xa2, 0x3e, 0x63, 0x09, 0x2d, 0x6f, 0x23, 0x54, 0x1c,
+	/* (2^398)P */ 0x5c, 0x6f, 0x3b, 0x1c, 0x30, 0x77, 0x7e, 0x87, 0x66, 0x83, 0x2e, 0x7e, 0x85, 0x50, 0xfd, 0xa0, 0x7a, 0xc2, 0xf5, 0x0f, 0xc1, 0x64, 0xe7, 0x0b, 0xbd, 0x59, 0xa7, 0xe7, 0x65, 0x53, 0xc3, 0xf5, 0x55, 0x5b, 0xe1, 0x82, 0x30, 0x5a, 0x61, 0xcd, 0xa0, 0x89, 0x32, 0xdb, 0x87, 0xfc, 0x21, 0x8a, 0xab, 0x6d, 0x82, 0xa8, 0x42, 0x81, 0x4f, 0xf2,
+	/* (2^399)P */ 0xb3, 0xeb, 0x88, 0x18, 0xf6, 0x56, 0x96, 0xbf, 0xba, 0x5d, 0x71, 0xa1, 0x5a, 0xd1, 0x04, 0x7b, 0xd5, 0x46, 0x01, 0x74, 0xfe, 0x15, 0x25, 0xb7, 0xff, 0x0c, 0x24, 0x47, 0xac, 0xfd, 0xab, 0x47, 0x32, 0xe1, 0x6a, 0x4e, 0xca, 0xcf, 0x7f, 0xdd, 0xf8, 0xd2, 0x4b, 0x3b, 0xf5, 0x17, 0xba, 0xba, 0x8b, 0xa1, 0xec, 0x28, 0x3f, 0x97, 0xab, 0x2a,
+	/* (2^400)P */ 0x51, 0x38, 0xc9, 0x5e, 0xc6, 0xb3, 0x64, 0xf2, 0x24, 0x4d, 0x04, 0x7d, 0xc8, 0x39, 0x0c, 0x4a, 0xc9, 0x73, 0x74, 0x1b, 0x5c, 0xb2, 0xc5, 0x41, 0x62, 0xa0, 0x4c, 0x6d, 0x8d, 0x91, 0x9a, 0x7b, 0x88, 0xab, 0x9c, 0x7e, 0x23, 0xdb, 0x6f, 0xb5, 0x72, 0xd6, 0x47, 0x40, 0xef, 0x22, 0x58, 0x62, 0x19, 0x6c, 0x38, 0xba, 0x5b, 0x00, 0x30, 0x9f,
+	/* (2^401)P */ 0x65, 0xbb, 0x3b, 0x9b, 0xe9, 0xae, 0xbf, 0xbe, 0xe4, 0x13, 0x95, 0xf3, 0xe3, 0x77, 0xcb, 0xe4, 0x9a, 0x22, 0xb5, 0x4a, 0x08, 0x9d, 0xb3, 0x9e, 0x27, 0xe0, 0x15, 0x6c, 0x9f, 0x7e, 0x9a, 0x5e, 0x15, 0x45, 0x25, 0x8d, 0x01, 0x0a, 0xd2, 0x2b, 0xbd, 0x48, 0x06, 0x0d, 0x18, 0x97, 0x4b, 0xdc, 0xbc, 0xf0, 0xcd, 0xb2, 0x52, 0x3c, 0xac, 0xf5,
+	/* (2^402)P */ 0x3e, 0xed, 0x47, 0x6b, 0x5c, 0xf6, 0x76, 0xd0, 0xe9, 0x15, 0xa3, 0xcb, 0x36, 0x00, 0x21, 0xa3, 0x79, 0x20, 0xa5, 0x3e, 0x88, 0x03, 0xcb, 0x7e, 0x63, 0xbb, 0xed, 0xa9, 0x13, 0x35, 0x16, 0xaf, 0x2e, 0xb4, 0x70, 0x14, 0x93, 0xfb, 0xc4, 0x9b, 0xd8, 0xb1, 0xbe, 0x43, 0xd1, 0x85, 0xb8, 0x97, 0xef, 0xea, 0x88, 0xa1, 0x25, 0x52, 0x62, 0x75,
+	/* (2^403)P */ 0x8e, 0x4f, 0xaa, 0x23, 0x62, 0x7e, 0x2b, 0x37, 0x89, 0x00, 0x11, 0x30, 0xc5, 0x33, 0x4a, 0x89, 0x8a, 0xe2, 0xfc, 0x5c, 0x6a, 0x75, 0xe5, 0xf7, 0x02, 0x4a, 0x9b, 0xf7, 0xb5, 0x6a, 0x85, 0x31, 0xd3, 0x5a, 0xcf, 0xc3, 0xf8, 0xde, 0x2f, 0xcf, 0xb5, 0x24, 0xf4, 0xe3, 0xa1, 0xad, 0x42, 0xae, 0x09, 0xb9, 0x2e, 0x04, 0x2d, 0x01, 0x22, 0x3f,
+	/* (2^404)P */ 0x41, 0x16, 0xfb, 0x7d, 0x50, 0xfd, 0xb5, 0xba, 0x88, 0x24, 0xba, 0xfd, 0x3d, 0xb2, 0x90, 0x15, 0xb7, 0xfa, 0xa2, 0xe1, 0x4c, 0x7d, 0xb9, 0xc6, 0xff, 0x81, 0x57, 0xb6, 0xc2, 0x9e, 0xcb, 0xc4, 0x35, 0xbd, 0x01, 0xb7, 0xaa, 0xce, 0xd0, 0xe9, 0xb5, 0xd6, 0x72, 0xbf, 0xd2, 0xee, 0xc7, 0xac, 0x94, 0xff, 0x29, 0x57, 0x02, 0x49, 0x09, 0xad,
+	/* (2^405)P */ 0x27, 0xa5, 0x78, 0x1b, 0xbf, 0x6b, 0xaf, 0x0b, 0x8c, 0xd9, 0xa8, 0x37, 0xb0, 0x67, 0x18, 0xb6, 0xc7, 0x05, 0x8a, 0x67, 0x03, 0x30, 0x62, 0x6e, 0x56, 0x82, 0xa9, 0x54, 0x3e, 0x0c, 0x4e, 0x07, 0xe1, 0x5a, 0x38, 0xed, 0xfa, 0xc8, 0x55, 0x6b, 0x08, 0xa3, 0x6b, 0x64, 0x2a, 0x15, 0xd6, 0x39, 0x6f, 0x47, 0x99, 0x42, 0x3f, 0x33, 0x84, 0x8f,
+	/* (2^406)P */ 0xbc, 0x45, 0x29, 0x81, 0x0e, 0xa4, 0xc5, 0x72, 0x3a, 0x10, 0xe1, 0xc4, 0x1e, 0xda, 0xc3, 0xfe, 0xb0, 0xce, 0xd2, 0x13, 0x34, 0x67, 0x21, 0xc6, 0x7e, 0xf9, 0x8c, 0xff, 0x39, 0x50, 0xae, 0x92, 0x60, 0x35, 0x2f, 0x8b, 0x6e, 0xc9, 0xc1, 0x27, 0x3a, 0x94, 0x66, 0x3e, 0x26, 0x84, 0x93, 0xc8, 0x6c, 0xcf, 0xd2, 0x03, 0xa1, 0x10, 0xcf, 0xb7,
+	/* (2^407)P */ 0x64, 0xda, 0x19, 0xf6, 0xc5, 0x73, 0x17, 0x44, 0x88, 0x81, 0x07, 0x0d, 0x34, 0xb2, 0x75, 0xf9, 0xd9, 0xe2, 0xe0, 0x8b, 0x71, 0xcf, 0x72, 0x34, 0x83, 0xb4, 0xce, 0xfc, 0xd7, 0x29, 0x09, 0x5a, 0x98, 0xbf, 0x14, 0xac, 0x77, 0x55, 0x38, 0x47, 0x5b, 0x0f, 0x40, 0x24, 0xe5, 0xa5, 0xa6, 0xac, 0x2d, 0xa6, 0xff, 0x9c, 0x73, 0xfe, 0x5c, 0x7e,
+	/* (2^408)P */ 0x1e, 0x33, 0xcc, 0x68, 0xb2, 0xbc, 0x8c, 0x93, 0xaf, 0xcc, 0x38, 0xf8, 0xd9, 0x16, 0x72, 0x50, 0xac, 0xd9, 0xb5, 0x0b, 0x9a, 0xbe, 0x46, 0x7a, 0xf1, 0xee, 0xf1, 0xad, 0xec, 0x5b, 0x59, 0x27, 0x9c, 0x05, 0xa3, 0x87, 0xe0, 0x37, 0x2c, 0x83, 0xce, 0xb3, 0x65, 0x09, 0x8e, 0xc3, 0x9c, 0xbf, 0x6a, 0xa2, 0x00, 0xcc, 0x12, 0x36, 0xc5, 0x95,
+	/* (2^409)P */ 0x36, 0x11, 0x02, 0x14, 0x9c, 0x3c, 0xeb, 0x2f, 0x23, 0x5b, 0x6b, 0x2b, 0x08, 0x54, 0x53, 0xac, 0xb2, 0xa3, 0xe0, 0x26, 0x62, 0x3c, 0xe4, 0xe1, 0x81, 0xee, 0x13, 0x3e, 0xa4, 0x97, 0xef, 0xf9, 0x92, 0x27, 0x01, 0xce, 0x54, 0x8b, 0x3e, 0x31, 0xbe, 0xa7, 0x88, 0xcf, 0x47, 0x99, 0x3c, 0x10, 0x6f, 0x60, 0xb3, 0x06, 0x4e, 0xee, 0x1b, 0xf0,
+	/* (2^410)P */ 0x59, 0x49, 0x66, 0xcf, 0x22, 0xe6, 0xf6, 0x73, 0xfe, 0xa3, 0x1c, 0x09, 0xfa, 0x5f, 0x65, 0xa8, 0xf0, 0x82, 0xc2, 0xef, 0x16, 0x63, 0x6e, 0x79, 0x69, 0x51, 0x39, 0x07, 0x65, 0xc4, 0x81, 0xec, 0x73, 0x0f, 0x15, 0x93, 0xe1, 0x30, 0x33, 0xe9, 0x37, 0x86, 0x42, 0x4c, 0x1f, 0x9b, 0xad, 0xee, 0x3f, 0xf1, 0x2a, 0x8e, 0x6a, 0xa3, 0xc8, 0x35,
+	/* (2^411)P */ 0x1e, 0x49, 0xf1, 0xdd, 0xd2, 0x9c, 0x8e, 0x78, 0xb2, 0x06, 0xe4, 0x6a, 0xab, 0x3a, 0xdc, 0xcd, 0xf4, 0xeb, 0xe1, 0xe7, 0x2f, 0xaa, 0xeb, 0x40, 0x31, 0x9f, 0xb9, 0xab, 0x13, 0xa9, 0x78, 0xbf, 0x38, 0x89, 0x0e, 0x85, 0x14, 0x8b, 0x46, 0x76, 0x14, 0xda, 0xcf, 0x33, 0xc8, 0x79, 0xd3, 0xd5, 0xa3, 0x6a, 0x69, 0x45, 0x70, 0x34, 0xc3, 0xe9,
+	/* (2^412)P */ 0x5e, 0xe7, 0x78, 0xe9, 0x24, 0xcc, 0xe9, 0xf4, 0xc8, 0x6b, 0xe0, 0xfb, 0x3a, 0xbe, 0xcc, 0x42, 0x4a, 0x00, 0x22, 0xf8, 0xe6, 0x32, 0xbe, 0x6d, 0x18, 0x55, 0x60, 0xe9, 0x72, 0x69, 0x50, 0x56, 0xca, 0x04, 0x18, 0x38, 0xa1, 0xee, 0xd8, 0x38, 0x3c, 0xa7, 0x70, 0xe2, 0xb9, 0x4c, 0xa0, 0xc8, 0x89, 0x72, 0xcf, 0x49, 0x7f, 0xdf, 0xbc, 0x67,
+	/* (2^413)P */ 0x1d, 0x17, 0xcb, 0x0b, 0xbd, 0xb2, 0x36, 0xe3, 0xa8, 0x99, 0x31, 0xb6, 0x26, 0x9c, 0x0c, 0x74, 0xaf, 0x4d, 0x24, 0x61, 0xcf, 0x31, 0x7b, 0xed, 0xdd, 0xc3, 0xf6, 0x32, 0x70, 0xfe, 0x17, 0xf6, 0x51, 0x37, 0x65, 0xce, 0x5d, 0xaf, 0xa5, 0x2f, 0x2a, 0xfe, 0x00, 0x71, 0x7c, 0x50, 0xbe, 0x21, 0xc7, 0xed, 0xc6, 0xfc, 0x67, 0xcf, 0x9c, 0xdd,
+	/* (2^414)P */ 0x26, 0x3e, 0xf8, 0xbb, 0xd0, 0xb1, 0x01, 0xd8, 0xeb, 0x0b, 0x62, 0x87, 0x35, 0x4c, 0xde, 0xca, 0x99, 0x9c, 0x6d, 0xf7, 0xb6, 0xf0, 0x57, 0x0a, 0x52, 0x29, 0x6a, 0x3f, 0x26, 0x31, 0x04, 0x07, 0x2a, 0xc9, 0xfa, 0x9b, 0x0e, 0x62, 0x8e, 0x72, 0xf2, 0xad, 0xce, 0xb6, 0x35, 0x7a, 0xc1, 0xae, 0x35, 0xc7, 0xa3, 0x14, 0xcf, 0x0c, 0x28, 0xb7,
+	/* (2^415)P */ 0xa6, 0xf1, 0x32, 0x3a, 0x20, 0xd2, 0x24, 0x97, 0xcf, 0x5d, 0x37, 0x99, 0xaf, 0x33, 0x7a, 0x5b, 0x7a, 0xcc, 0x4e, 0x41, 0x38, 0xb1, 0x4e, 0xad, 0xc9, 0xd9, 0x71, 0x7e, 0xb2, 0xf5, 0xd5, 0x01, 0x6c, 0x4d, 0xfd, 0xa1, 0xda, 0x03, 0x38, 0x9b, 0x3d, 0x92, 0x92, 0xf2, 0xca, 0xbf, 0x1f, 0x24, 0xa4, 0xbb, 0x30, 0x6a, 0x74, 0x56, 0xc8, 0xce,
+	/* (2^416)P */ 0x27, 0xf4, 0xed, 0xc9, 0xc3, 0xb1, 0x79, 0x85, 0xbe, 0xf6, 0xeb, 0xf3, 0x55, 0xc7, 0xaa, 0xa6, 0xe9, 0x07, 0x5d, 0xf4, 0xeb, 0xa6, 0x81, 0xe3, 0x0e, 0xcf, 0xa3, 0xc1, 0xef, 0xe7, 0x34, 0xb2, 0x03, 0x73, 0x8a, 0x91, 0xf1, 0xad, 0x05, 0xc7, 0x0b, 0x43, 0x99, 0x12, 0x31, 0xc8, 0xc7, 0xc5, 0xa4, 0x3d, 0xcd, 0xe5, 0x4e, 0x6d, 0x24, 0xdd,
+	/* (2^417)P */ 0x61, 0x54, 0xd0, 0x95, 0x2c, 0x45, 0x75, 0xac, 0xb5, 0x1a, 0x9d, 0x11, 0xeb, 0xed, 0x6b, 0x57, 0xa3, 0xe6, 0xcd, 0x77, 0xd4, 0x83, 0x8e, 0x39, 0xf1, 0x0f, 0x98, 0xcb, 0x40, 0x02, 0x6e, 0x10, 0x82, 0x9e, 0xb4, 0x93, 0x76, 0xd7, 0x97, 0xa3, 0x53, 0x12, 0x86, 0xc6, 0x15, 0x78, 0x73, 0x93, 0xe7, 0x7f, 0xcf, 0x1f, 0xbf, 0xcd, 0xd2, 0x7a,
+	/* (2^418)P */ 0xc2, 0x21, 0xdc, 0xd5, 0x69, 0xff, 0xca, 0x49, 0x3a, 0xe1, 0xc3, 0x69, 0x41, 0x56, 0xc1, 0x76, 0x63, 0x24, 0xbd, 0x64, 0x1b, 0x3d, 0x92, 0xf9, 0x13, 0x04, 0x25, 0xeb, 0x27, 0xa6, 0xef, 0x39, 0x3a, 0x80, 0xe0, 0xf8, 0x27, 0xee, 0xc9, 0x49, 0x77, 0xef, 0x3f, 0x29, 0x3d, 0x5e, 0xe6, 0x66, 0x83, 0xd1, 0xf6, 0xfe, 0x9d, 0xbc, 0xf1, 0x96,
+	/* (2^419)P */ 0x6b, 0xc6, 0x99, 0x26, 0x3c, 0xf3, 0x63, 0xf9, 0xc7, 0x29, 0x8c, 0x52, 0x62, 0x2d, 0xdc, 0x8a, 0x66, 0xce, 0x2c, 0xa7, 0xe4, 0xf0, 0xd7, 0x37, 0x17, 0x1e, 0xe4, 0xa3, 0x53, 0x7b, 0x29, 0x8e, 0x60, 0x99, 0xf9, 0x0c, 0x7c, 0x6f, 0xa2, 0xcc, 0x9f, 0x80, 0xdd, 0x5e, 0x46, 0xaa, 0x0d, 0x6c, 0xc9, 0x6c, 0xf7, 0x78, 0x5b, 0x38, 0xe3, 0x24,
+	/* (2^420)P */ 0x4b, 0x75, 0x6a, 0x2f, 0x08, 0xe1, 0x72, 0x76, 0xab, 0x82, 0x96, 0xdf, 0x3b, 0x1f, 0x9b, 0xd8, 0xed, 0xdb, 0xcd, 0x15, 0x09, 0x5a, 0x1e, 0xb7, 0xc5, 0x26, 0x72, 0x07, 0x0c, 0x50, 0xcd, 0x3b, 0x4d, 0x3f, 0xa2, 0x67, 0xc2, 0x02, 0x61, 0x2e, 0x68, 0xe9, 0x6f, 0xf0, 0x21, 0x2a, 0xa7, 0x3b, 0x88, 0x04, 0x11, 0x64, 0x49, 0x0d, 0xb4, 0x46,
+	/* (2^421)P */ 0x63, 0x85, 0xf3, 0xc5, 0x2b, 0x5a, 0x9f, 0xf0, 0x17, 0xcb, 0x45, 0x0a, 0xf3, 0x6e, 0x7e, 0xb0, 0x7c, 0xbc, 0xf0, 0x4f, 0x3a, 0xb0, 0xbc, 0x36, 0x36, 0x52, 0x51, 0xcb, 0xfe, 0x9a, 0xcb, 0xe8, 0x7e, 0x4b, 0x06, 0x7f, 0xaa, 0x35, 0xc8, 0x0e, 0x7a, 0x30, 0xa3, 0xb1, 0x09, 0xbb, 0x86, 0x4c, 0xbe, 0xb8, 0xbd, 0xe0, 0x32, 0xa5, 0xd4, 0xf7,
+	/* (2^422)P */ 0x7d, 0x50, 0x37, 0x68, 0x4e, 0x22, 0xb2, 0x2c, 0xd5, 0x0f, 0x2b, 0x6d, 0xb1, 0x51, 0xf2, 0x82, 0xe9, 0x98, 0x7c, 0x50, 0xc7, 0x96, 0x7e, 0x0e, 0xdc, 0xb1, 0x0e, 0xb2, 0x63, 0x8c, 0x30, 0x37, 0x72, 0x21, 0x9c, 0x61, 0xc2, 0xa7, 0x33, 0xd9, 0xb2, 0x63, 0x93, 0xd1, 0x6b, 0x6a, 0x73, 0xa5, 0x58, 0x80, 0xff, 0x04, 0xc7, 0x83, 0x21, 0x29,
+	/* (2^423)P */ 0x29, 0x04, 0xbc, 0x99, 0x39, 0xc9, 0x58, 0xc9, 0x6b, 0x17, 0xe8, 0x90, 0xb3, 0xe6, 0xa9, 0xb6, 0x28, 0x9b, 0xcb, 0x3b, 0x28, 0x90, 0x68, 0x71, 0xff, 0xcf, 0x08, 0x78, 0xc9, 0x8d, 0xa8, 0x4e, 0x43, 0xd1, 0x1c, 0x9e, 0xa4, 0xe3, 0xdf, 0xbf, 0x92, 0xf4, 0xf9, 0x41, 0xba, 0x4d, 0x1c, 0xf9, 0xdd, 0x74, 0x76, 0x1c, 0x6e, 0x3e, 0x94, 0x87,
+	/* (2^424)P */ 0xe4, 0xda, 0xc5, 0xd7, 0xfb, 0x87, 0xc5, 0x4d, 0x6b, 0x19, 0xaa, 0xb9, 0xbc, 0x8c, 0xf2, 0x8a, 0xd8, 0x5d, 0xdb, 0x4d, 0xef, 0xa6, 0xf2, 0x65, 0xf1, 0x22, 0x9c, 0xf1, 0x46, 0x30, 0x71, 0x7c, 0xe4, 0x53, 0x8e, 0x55, 0x2e, 0x9c, 0x9a, 0x31, 0x2a, 0xc3, 0xab, 0x0f, 0xde, 0xe4, 0xbe, 0xd8, 0x96, 0x50, 0x6e, 0x0c, 0x54, 0x49, 0xe6, 0xec,
+	/* (2^425)P */ 0x3c, 0x1d, 0x5a, 0xa5, 0xda, 0xad, 0xdd, 0xc2, 0xae, 0xac, 0x6f, 0x86, 0x75, 0x31, 0x91, 0x64, 0x45, 0x9d, 0xa4, 0xf0, 0x81, 0xf1, 0x0e, 0xba, 0x74, 0xaf, 0x7b, 0xcd, 0x6f, 0xfe, 0xac, 0x4e, 0xdb, 0x4e, 0x45, 0x35, 0x36, 0xc5, 0xc0, 0x6c, 0x3d, 0x64, 0xf4, 0xd8, 0x07, 0x62, 0xd1, 0xec, 0xf3, 0xfc, 0x93, 0xc9, 0x28, 0x0c, 0x2c, 0xf3,
+	/* (2^426)P */ 0x0c, 0x69, 0x2b, 0x5c, 0xb6, 0x41, 0x69, 0xf1, 0xa4, 0xf1, 0x5b, 0x75, 0x4c, 0x42, 0x8b, 0x47, 0xeb, 0x69, 0xfb, 0xa8, 0xe6, 0xf9, 0x7b, 0x48, 0x50, 0xaf, 0xd3, 0xda, 0xb2, 0x35, 0x10, 0xb5, 0x5b, 0x40, 0x90, 0x39, 0xc9, 0x07, 0x06, 0x73, 0x26, 0x20, 0x95, 0x01, 0xa4, 0x2d, 0xf0, 0xe7, 0x2e, 0x00, 0x7d, 0x41, 0x09, 0x68, 0x13, 0xc4,
+	/* (2^427)P */ 0xbe, 0x38, 0x78, 0xcf, 0xc9, 0x4f, 0x36, 0xca, 0x09, 0x61, 0x31, 0x3c, 0x57, 0x2e, 0xec, 0x17, 0xa4, 0x7d, 0x19, 0x2b, 0x9b, 0x5b, 0xbe, 0x8f, 0xd6, 0xc5, 0x2f, 0x86, 0xf2, 0x64, 0x76, 0x17, 0x00, 0x6e, 0x1a, 0x8c, 0x67, 0x1b, 0x68, 0xeb, 0x15, 0xa2, 0xd6, 0x09, 0x91, 0xdd, 0x23, 0x0d, 0x98, 0xb2, 0x10, 0x19, 0x55, 0x9b, 0x63, 0xf2,
+	/* (2^428)P */ 0x51, 0x1f, 0x93, 0xea, 0x2a, 0x3a, 0xfa, 0x41, 0xc0, 0x57, 0xfb, 0x74, 0xa6, 0x65, 0x09, 0x56, 0x14, 0xb6, 0x12, 0xaa, 0xb3, 0x1a, 0x8d, 0x3b, 0x76, 0x91, 0x7a, 0x23, 0x56, 0x9c, 0x6a, 0xc0, 0xe0, 0x3c, 0x3f, 0xb5, 0x1a, 0xf4, 0x57, 0x71, 0x93, 0x2b, 0xb1, 0xa7, 0x70, 0x57, 0x22, 0x80, 0xf5, 0xb8, 0x07, 0x77, 0x87, 0x0c, 0xbe, 0x83,
+	/* (2^429)P */ 0x07, 0x9b, 0x0e, 0x52, 0x38, 0x63, 0x13, 0x86, 0x6a, 0xa6, 0xb4, 0xd2, 0x60, 0x68, 0x9a, 0x99, 0x82, 0x0a, 0x04, 0x5f, 0x89, 0x7a, 0x1a, 0x2a, 0xae, 0x2d, 0x35, 0x0c, 0x1e, 0xad, 0xef, 0x4f, 0x9a, 0xfc, 0xc8, 0xd9, 0xcf, 0x9d, 0x48, 0x71, 0xa5, 0x55, 0x79, 0x73, 0x39, 0x1b, 0xd8, 0x73, 0xec, 0x9b, 0x03, 0x16, 0xd8, 0x82, 0xf7, 0x67,
+	/* (2^430)P */ 0x52, 0x67, 0x42, 0x21, 0xc9, 0x40, 0x78, 0x82, 0x2b, 0x95, 0x2d, 0x20, 0x92, 0xd1, 0xe2, 0x61, 0x25, 0xb0, 0xc6, 0x9c, 0x20, 0x59, 0x8e, 0x28, 0x6f, 0xf3, 0xfd, 0xd3, 0xc1, 0x32, 0x43, 0xc9, 0xa6, 0x08, 0x7a, 0x77, 0x9c, 0x4c, 0x8c, 0x33, 0x71, 0x13, 0x69, 0xe3, 0x52, 0x30, 0xa7, 0xf5, 0x07, 0x67, 0xac, 0xad, 0x46, 0x8a, 0x26, 0x25,
+	/* (2^431)P */ 0xda, 0x86, 0xc4, 0xa2, 0x71, 0x56, 0xdd, 0xd2, 0x48, 0xd3, 0xde, 0x42, 0x63, 0x01, 0xa7, 0x2c, 0x92, 0x83, 0x6f, 0x2e, 0xd8, 0x1e, 0x3f, 0xc1, 0xc5, 0x42, 0x4e, 0x34, 0x19, 0x54, 0x6e, 0x35, 0x2c, 0x51, 0x2e, 0xfd, 0x0f, 0x9a, 0x45, 0x66, 0x5e, 0x4a, 0x83, 0xda, 0x0a, 0x53, 0x68, 0x63, 0xfa, 0xce, 0x47, 0x20, 0xd3, 0x34, 0xba, 0x0d,
+	/* (2^432)P */ 0xd0, 0xe9, 0x64, 0xa4, 0x61, 0x4b, 0x86, 0xe5, 0x93, 0x6f, 0xda, 0x0e, 0x31, 0x7e, 0x6e, 0xe3, 0xc6, 0x73, 0xd8, 0xa3, 0x08, 0x57, 0x52, 0xcd, 0x51, 0x63, 0x1d, 0x9f, 0x93, 0x00, 0x62, 0x91, 0x26, 0x21, 0xa7, 0xdd, 0x25, 0x0f, 0x09, 0x0d, 0x35, 0xad, 0xcf, 0x11, 0x8e, 0x6e, 0xe8, 0xae, 0x1d, 0x95, 0xcb, 0x88, 0xf8, 0x70, 0x7b, 0x91,
+	/* (2^433)P */ 0x0c, 0x19, 0x5c, 0xd9, 0x8d, 0xda, 0x9d, 0x2c, 0x90, 0x54, 0x65, 0xe8, 0xb6, 0x35, 0x50, 0xae, 0xea, 0xae, 0x43, 0xb7, 0x1e, 0x99, 0x8b, 0x4c, 0x36, 0x4e, 0xe4, 0x1e, 0xc4, 0x64, 0x43, 0xb6, 0xeb, 0xd4, 0xe9, 0x60, 0x22, 0xee, 0xcf, 0xb8, 0x52, 0x1b, 0xf0, 0x04, 0xce, 0xbc, 0x2b, 0xf0, 0xbe, 0xcd, 0x44, 0x74, 0x1e, 0x1f, 0x63, 0xf9,
+	/* (2^434)P */ 0xe1, 0x3f, 0x95, 0x94, 0xb2, 0xb6, 0x31, 0xa9, 0x1b, 0xdb, 0xfd, 0x0e, 0xdb, 0xdd, 0x1a, 0x22, 0x78, 0x60, 0x9f, 0x75, 0x5f, 0x93, 0x06, 0x0c, 0xd8, 0xbb, 0xa2, 0x85, 0x2b, 0x5e, 0xc0, 0x9b, 0xa8, 0x5d, 0xaf, 0x93, 0x91, 0x91, 0x47, 0x41, 0x1a, 0xfc, 0xb4, 0x51, 0x85, 0xad, 0x69, 0x4d, 0x73, 0x69, 0xd5, 0x4e, 0x82, 0xfb, 0x66, 0xcb,
+	/* (2^435)P */ 0x7c, 0xbe, 0xc7, 0x51, 0xc4, 0x74, 0x6e, 0xab, 0xfd, 0x41, 0x4f, 0x76, 0x4f, 0x24, 0x03, 0xd6, 0x2a, 0xb7, 0x42, 0xb4, 0xda, 0x41, 0x2c, 0x82, 0x48, 0x4c, 0x7f, 0x6f, 0x25, 0x5d, 0x36, 0xd4, 0x69, 0xf5, 0xef, 0x02, 0x81, 0xea, 0x6f, 0x19, 0x69, 0xe8, 0x6f, 0x5b, 0x2f, 0x14, 0x0e, 0x6f, 0x89, 0xb4, 0xb5, 0xd8, 0xae, 0xef, 0x7b, 0x87,
+	/* (2^436)P */ 0xe9, 0x91, 0xa0, 0x8b, 0xc9, 0xe0, 0x01, 0x90, 0x37, 0xc1, 0x6f, 0xdc, 0x5e, 0xf7, 0xbf, 0x43, 0x00, 0xaa, 0x10, 0x76, 0x76, 0x18, 0x6e, 0x19, 0x1e, 0x94, 0x50, 0x11, 0x0a, 0xd1, 0xe2, 0xdb, 0x08, 0x21, 0xa0, 0x1f, 0xdb, 0x54, 0xfe, 0xea, 0x6e, 0xa3, 0x68, 0x56, 0x87, 0x0b, 0x22, 0x4e, 0x66, 0xf3, 0x82, 0x82, 0x00, 0xcd, 0xd4, 0x12,
+	/* (2^437)P */ 0x25, 0x8e, 0x24, 0x77, 0x64, 0x4c, 0xe0, 0xf8, 0x18, 0xc0, 0xdc, 0xc7, 0x1b, 0x35, 0x65, 0xde, 0x67, 0x41, 0x5e, 0x6f, 0x90, 0x82, 0xa7, 0x2e, 0x6d, 0xf1, 0x47, 0xb4, 0x92, 0x9c, 0xfd, 0x6a, 0x9a, 0x41, 0x36, 0x20, 0x24, 0x58, 0xc3, 0x59, 0x07, 0x9a, 0xfa, 0x9f, 0x03, 0xcb, 0xc7, 0x69, 0x37, 0x60, 0xe1, 0xab, 0x13, 0x72, 0xee, 0xa2,
+	/* (2^438)P */ 0x74, 0x78, 0xfb, 0x13, 0xcb, 0x8e, 0x37, 0x1a, 0xf6, 0x1d, 0x17, 0x83, 0x06, 0xd4, 0x27, 0x06, 0x21, 0xe8, 0xda, 0xdf, 0x6b, 0xf3, 0x83, 0x6b, 0x34, 0x8a, 0x8c, 0xee, 0x01, 0x05, 0x5b, 0xed, 0xd3, 0x1b, 0xc9, 0x64, 0x83, 0xc9, 0x49, 0xc2, 0x57, 0x1b, 0xdd, 0xcf, 0xf1, 0x9d, 0x63, 0xee, 0x1c, 0x0d, 0xa0, 0x0a, 0x73, 0x1f, 0x5b, 0x32,
+	/* (2^439)P */ 0x29, 0xce, 0x1e, 0xc0, 0x6a, 0xf5, 0xeb, 0x99, 0x5a, 0x39, 0x23, 0xe9, 0xdd, 0xac, 0x44, 0x88, 0xbc, 0x80, 0x22, 0xde, 0x2c, 0xcb, 0xa8, 0x3b, 0xff, 0xf7, 0x6f, 0xc7, 0x71, 0x72, 0xa8, 0xa3, 0xf6, 0x4d, 0xc6, 0x75, 0xda, 0x80, 0xdc, 0xd9, 0x30, 0xd9, 0x07, 0x50, 0x5a, 0x54, 0x7d, 0xda, 0x39, 0x6f, 0x78, 0x94, 0xbf, 0x25, 0x98, 0xdc,
+	/* (2^440)P */ 0x01, 0x26, 0x62, 0x44, 0xfb, 0x0f, 0x11, 0x72, 0x73, 0x0a, 0x16, 0xc7, 0x16, 0x9c, 0x9b, 0x37, 0xd8, 0xff, 0x4f, 0xfe, 0x57, 0xdb, 0xae, 0xef, 0x7d, 0x94, 0x30, 0x04, 0x70, 0x83, 0xde, 0x3c, 0xd4, 0xb5, 0x70, 0xda, 0xa7, 0x55, 0xc8, 0x19, 0xe1, 0x36, 0x15, 0x61, 0xe7, 0x3b, 0x7d, 0x85, 0xbb, 0xf3, 0x42, 0x5a, 0x94, 0xf4, 0x53, 0x2a,
+	/* (2^441)P */ 0x14, 0x60, 0xa6, 0x0b, 0x83, 0xe1, 0x23, 0x77, 0xc0, 0xce, 0x50, 0xed, 0x35, 0x8d, 0x98, 0x99, 0x7d, 0xf5, 0x8d, 0xce, 0x94, 0x25, 0xc8, 0x0f, 0x6d, 0xfa, 0x4a, 0xa4, 0x3a, 0x1f, 0x66, 0xfb, 0x5a, 0x64, 0xaf, 0x8b, 0x54, 0x54, 0x44, 0x3f, 0x5b, 0x88, 0x61, 0xe4, 0x48, 0x45, 0x26, 0x20, 0xbe, 0x0d, 0x06, 0xbb, 0x65, 0x59, 0xe1, 0x36,
+	/* (2^442)P */ 0xb7, 0x98, 0xce, 0xa3, 0xe3, 0xee, 0x11, 0x1b, 0x9e, 0x24, 0x59, 0x75, 0x31, 0x37, 0x44, 0x6f, 0x6b, 0x9e, 0xec, 0xb7, 0x44, 0x01, 0x7e, 0xab, 0xbb, 0x69, 0x5d, 0x11, 0xb0, 0x30, 0x64, 0xea, 0x91, 0xb4, 0x7a, 0x8c, 0x02, 0x4c, 0xb9, 0x10, 0xa7, 0xc7, 0x79, 0xe6, 0xdc, 0x77, 0xe3, 0xc8, 0xef, 0x3e, 0xf9, 0x38, 0x81, 0xce, 0x9a, 0xb2,
+	/* (2^443)P */ 0x91, 0x12, 0x76, 0xd0, 0x10, 0xb4, 0xaf, 0xe1, 0x89, 0x3a, 0x93, 0x6b, 0x5c, 0x19, 0x5f, 0x24, 0xed, 0x04, 0x92, 0xc7, 0xf0, 0x00, 0x08, 0xc1, 0x92, 0xff, 0x90, 0xdb, 0xb2, 0xbf, 0xdf, 0x49, 0xcd, 0xbd, 0x5c, 0x6e, 0xbf, 0x16, 0xbb, 0x61, 0xf9, 0x20, 0x33, 0x35, 0x93, 0x11, 0xbc, 0x59, 0x69, 0xce, 0x18, 0x9f, 0xf8, 0x7b, 0xa1, 0x6e,
+	/* (2^444)P */ 0xa1, 0xf4, 0xaf, 0xad, 0xf8, 0xe6, 0x99, 0xd2, 0xa1, 0x4d, 0xde, 0x56, 0xc9, 0x7b, 0x0b, 0x11, 0x3e, 0xbf, 0x89, 0x1a, 0x9a, 0x90, 0xe5, 0xe2, 0xa6, 0x37, 0x88, 0xa1, 0x68, 0x59, 0xae, 0x8c, 0xec, 0x02, 0x14, 0x8d, 0xb7, 0x2e, 0x25, 0x75, 0x7f, 0x76, 0x1a, 0xd3, 0x4d, 0xad, 0x8a, 0x00, 0x6c, 0x96, 0x49, 0xa4, 0xc3, 0x2e, 0x5c, 0x7b,
+	/* (2^445)P */ 0x26, 0x53, 0xf7, 0xda, 0xa8, 0x01, 0x14, 0xb1, 0x63, 0xe3, 0xc3, 0x89, 0x88, 0xb0, 0x85, 0x40, 0x2b, 0x26, 0x9a, 0x10, 0x1a, 0x70, 0x33, 0xf4, 0x50, 0x9d, 0x4d, 0xd8, 0x64, 0xc6, 0x0f, 0xe1, 0x17, 0xc8, 0x10, 0x4b, 0xfc, 0xa0, 0xc9, 0xba, 0x2c, 0x98, 0x09, 0xf5, 0x84, 0xb6, 0x7c, 0x4e, 0xa3, 0xe3, 0x81, 0x1b, 0x32, 0x60, 0x02, 0xdd,
+	/* (2^446)P */ 0xa3, 0xe5, 0x86, 0xd4, 0x43, 0xa8, 0xd1, 0x98, 0x9d, 0x9d, 0xdb, 0x04, 0xcf, 0x6e, 0x35, 0x05, 0x30, 0x53, 0x3b, 0xbc, 0x90, 0x00, 0x4a, 0xc5, 0x40, 0x2a, 0x0f, 0xde, 0x1a, 0xd7, 0x36, 0x27, 0x44, 0x62, 0xa6, 0xac, 0x9d, 0xd2, 0x70, 0x69, 0x14, 0x39, 0x9b, 0xd1, 0xc3, 0x0a, 0x3a, 0x82, 0x0e, 0xf1, 0x94, 0xd7, 0x42, 0x94, 0xd5, 0x7d,
+	/* (2^447)P */ 0x04, 0xc0, 0x6e, 0x12, 0x90, 0x70, 0xf9, 0xdf, 0xf7, 0xc9, 0x86, 0xc0, 0xe6, 0x92, 0x8b, 0x0a, 0xa1, 0xc1, 0x3b, 0xcc, 0x33, 0xb7, 0xf0, 0xeb, 0x51, 0x50, 0x80, 0x20, 0x69, 0x1c, 0x4f, 0x89, 0x05, 0x1e, 0xe4, 0x7a, 0x0a, 0xc2, 0xf0, 0xf5, 0x78, 0x91, 0x76, 0x34, 0x45, 0xdc, 0x24, 0x53, 0x24, 0x98, 0xe2, 0x73, 0x6f, 0xe6, 0x46, 0x67,
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/constants.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/constants.go
new file mode 100644
index 00000000..b6b236e5
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/constants.go
@@ -0,0 +1,71 @@
+package goldilocks
+
+import fp "github.com/cloudflare/circl/math/fp448"
+
+var (
+	// genX is the x-coordinate of the generator of Goldilocks curve.
+	genX = fp.Elt{
+		0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26,
+		0x8e, 0x93, 0x00, 0x8b, 0xe1, 0x80, 0x3b, 0x43,
+		0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
+		0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea,
+		0x67, 0x17, 0x0f, 0x47, 0x70, 0x65, 0x14, 0x9e,
+		0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
+		0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f,
+	}
+	// genY is the y-coordinate of the generator of Goldilocks curve.
+	genY = fp.Elt{
+		0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98,
+		0xad, 0xc8, 0xd7, 0x4e, 0x2c, 0x13, 0xbd, 0xfd,
+		0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
+		0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87,
+		0x40, 0x98, 0xa3, 0x6c, 0x73, 0x73, 0xea, 0x4b,
+		0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
+		0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69,
+	}
+	// paramD is -39081 in Fp.
+	paramD = fp.Elt{
+		0x56, 0x67, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	}
+	// order is 2^446-0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d,
+	// which is the number of points in the prime subgroup.
+	order = Scalar{
+		0xf3, 0x44, 0x58, 0xab, 0x92, 0xc2, 0x78, 0x23,
+		0x55, 0x8f, 0xc5, 0x8d, 0x72, 0xc2, 0x6c, 0x21,
+		0x90, 0x36, 0xd6, 0xae, 0x49, 0xdb, 0x4e, 0xc4,
+		0xe9, 0x23, 0xca, 0x7c, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f,
+	}
+	// residue448 is 2^448 mod order.
+	residue448 = [4]uint64{
+		0x721cf5b5529eec34, 0x7a4cf635c8e9c2ab, 0xeec492d944a725bf, 0x20cd77058,
+	}
+	// invFour is 1/4 mod order.
+	invFour = Scalar{
+		0x3d, 0x11, 0xd6, 0xaa, 0xa4, 0x30, 0xde, 0x48,
+		0xd5, 0x63, 0x71, 0xa3, 0x9c, 0x30, 0x5b, 0x08,
+		0xa4, 0x8d, 0xb5, 0x6b, 0xd2, 0xb6, 0x13, 0x71,
+		0xfa, 0x88, 0x32, 0xdf, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+	}
+	// paramDTwist is -39082 in Fp. The D parameter of the twist curve.
+	paramDTwist = fp.Elt{
+		0x55, 0x67, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	}
+)
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go
new file mode 100644
index 00000000..5a939100
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/curve.go
@@ -0,0 +1,80 @@
+// Package goldilocks provides elliptic curve operations over the goldilocks curve.
+package goldilocks
+
+import fp "github.com/cloudflare/circl/math/fp448"
+
+// Curve is the Goldilocks curve x^2+y^2=z^2-39081x^2y^2.
+type Curve struct{}
+
+// Identity returns the identity point.
+func (Curve) Identity() *Point {
+	return &Point{
+		y: fp.One(),
+		z: fp.One(),
+	}
+}
+
+// IsOnCurve returns true if the point lies on the curve.
+func (Curve) IsOnCurve(P *Point) bool {
+	x2, y2, t, t2, z2 := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{}
+	rhs, lhs := &fp.Elt{}, &fp.Elt{}
+	fp.Mul(t, &P.ta, &P.tb)  // t = ta*tb
+	fp.Sqr(x2, &P.x)         // x^2
+	fp.Sqr(y2, &P.y)         // y^2
+	fp.Sqr(z2, &P.z)         // z^2
+	fp.Sqr(t2, t)            // t^2
+	fp.Add(lhs, x2, y2)      // x^2 + y^2
+	fp.Mul(rhs, t2, &paramD) // dt^2
+	fp.Add(rhs, rhs, z2)     // z^2 + dt^2
+	fp.Sub(lhs, lhs, rhs)    // x^2 + y^2 - (z^2 + dt^2)
+	eq0 := fp.IsZero(lhs)
+
+	fp.Mul(lhs, &P.x, &P.y) // xy
+	fp.Mul(rhs, t, &P.z)    // tz
+	fp.Sub(lhs, lhs, rhs)   // xy - tz
+	eq1 := fp.IsZero(lhs)
+	return eq0 && eq1
+}
+
+// Generator returns the generator point.
+func (Curve) Generator() *Point {
+	return &Point{
+		x:  genX,
+		y:  genY,
+		z:  fp.One(),
+		ta: genX,
+		tb: genY,
+	}
+}
+
+// Order returns the number of points in the prime subgroup.
+func (Curve) Order() Scalar { return order }
+
+// Double returns 2P.
+func (Curve) Double(P *Point) *Point { R := *P; R.Double(); return &R }
+
+// Add returns P+Q.
+func (Curve) Add(P, Q *Point) *Point { R := *P; R.Add(Q); return &R }
+
+// ScalarMult returns kP. This function runs in constant time.
+func (e Curve) ScalarMult(k *Scalar, P *Point) *Point {
+	k4 := &Scalar{}
+	k4.divBy4(k)
+	return e.pull(twistCurve{}.ScalarMult(k4, e.push(P)))
+}
+
+// ScalarBaseMult returns kG where G is the generator point. This function runs in constant time.
+func (e Curve) ScalarBaseMult(k *Scalar) *Point {
+	k4 := &Scalar{}
+	k4.divBy4(k)
+	return e.pull(twistCurve{}.ScalarBaseMult(k4))
+}
+
+// CombinedMult returns mG+nP, where G is the generator point. This function is non-constant time.
+func (e Curve) CombinedMult(m, n *Scalar, P *Point) *Point {
+	m4 := &Scalar{}
+	n4 := &Scalar{}
+	m4.divBy4(m)
+	n4.divBy4(n)
+	return e.pull(twistCurve{}.CombinedMult(m4, n4, twistCurve{}.pull(P)))
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/isogeny.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/isogeny.go
new file mode 100644
index 00000000..b1daab85
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/isogeny.go
@@ -0,0 +1,52 @@
+package goldilocks
+
+import fp "github.com/cloudflare/circl/math/fp448"
+
+func (Curve) pull(P *twistPoint) *Point      { return twistCurve{}.push(P) }
+func (twistCurve) pull(P *Point) *twistPoint { return Curve{}.push(P) }
+
+// push sends a point on the Goldilocks curve to a point on the twist curve.
+func (Curve) push(P *Point) *twistPoint {
+	Q := &twistPoint{}
+	Px, Py, Pz := &P.x, &P.y, &P.z
+	a, b, c, d, e, f, g, h := &Q.x, &Q.y, &Q.z, &fp.Elt{}, &Q.ta, &Q.x, &Q.y, &Q.tb
+	fp.Add(e, Px, Py)  // x+y
+	fp.Sqr(a, Px)      // A = x^2
+	fp.Sqr(b, Py)      // B = y^2
+	fp.Sqr(c, Pz)      // z^2
+	fp.Add(c, c, c)    // C = 2*z^2
+	*d = *a            // D = A
+	fp.Sqr(e, e)       // (x+y)^2
+	fp.Sub(e, e, a)    // (x+y)^2-A
+	fp.Sub(e, e, b)    // E = (x+y)^2-A-B
+	fp.Add(h, b, d)    // H = B+D
+	fp.Sub(g, b, d)    // G = B-D
+	fp.Sub(f, c, h)    // F = C-H
+	fp.Mul(&Q.z, f, g) // Z = F * G
+	fp.Mul(&Q.x, e, f) // X = E * F
+	fp.Mul(&Q.y, g, h) // Y = G * H, // T = E * H
+	return Q
+}
+
+// push sends a point on the twist curve to a point on the Goldilocks curve.
+func (twistCurve) push(P *twistPoint) *Point {
+	Q := &Point{}
+	Px, Py, Pz := &P.x, &P.y, &P.z
+	a, b, c, d, e, f, g, h := &Q.x, &Q.y, &Q.z, &fp.Elt{}, &Q.ta, &Q.x, &Q.y, &Q.tb
+	fp.Add(e, Px, Py)  // x+y
+	fp.Sqr(a, Px)      // A = x^2
+	fp.Sqr(b, Py)      // B = y^2
+	fp.Sqr(c, Pz)      // z^2
+	fp.Add(c, c, c)    // C = 2*z^2
+	fp.Neg(d, a)       // D = -A
+	fp.Sqr(e, e)       // (x+y)^2
+	fp.Sub(e, e, a)    // (x+y)^2-A
+	fp.Sub(e, e, b)    // E = (x+y)^2-A-B
+	fp.Add(h, b, d)    // H = B+D
+	fp.Sub(g, b, d)    // G = B-D
+	fp.Sub(f, c, h)    // F = C-H
+	fp.Mul(&Q.z, f, g) // Z = F * G
+	fp.Mul(&Q.x, e, f) // X = E * F
+	fp.Mul(&Q.y, g, h) // Y = G * H, // T = E * H
+	return Q
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/point.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/point.go
new file mode 100644
index 00000000..11f73de0
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/point.go
@@ -0,0 +1,171 @@
+package goldilocks
+
+import (
+	"errors"
+	"fmt"
+
+	fp "github.com/cloudflare/circl/math/fp448"
+)
+
+// Point is a point on the Goldilocks Curve.
+type Point struct{ x, y, z, ta, tb fp.Elt }
+
+func (P Point) String() string {
+	return fmt.Sprintf("x: %v\ny: %v\nz: %v\nta: %v\ntb: %v", P.x, P.y, P.z, P.ta, P.tb)
+}
+
+// FromAffine creates a point from affine coordinates.
+func FromAffine(x, y *fp.Elt) (*Point, error) {
+	P := &Point{
+		x:  *x,
+		y:  *y,
+		z:  fp.One(),
+		ta: *x,
+		tb: *y,
+	}
+	if !(Curve{}).IsOnCurve(P) {
+		return P, errors.New("point not on curve")
+	}
+	return P, nil
+}
+
+// isLessThan returns true if 0 <= x < y, and assumes that slices are of the
+// same length and are interpreted in little-endian order.
+func isLessThan(x, y []byte) bool {
+	i := len(x) - 1
+	for i > 0 && x[i] == y[i] {
+		i--
+	}
+	return x[i] < y[i]
+}
+
+// FromBytes returns a point from the input buffer.
+func FromBytes(in []byte) (*Point, error) {
+	if len(in) < fp.Size+1 {
+		return nil, errors.New("wrong input length")
+	}
+	err := errors.New("invalid decoding")
+	P := &Point{}
+	signX := in[fp.Size] >> 7
+	copy(P.y[:], in[:fp.Size])
+	p := fp.P()
+	if !isLessThan(P.y[:], p[:]) {
+		return nil, err
+	}
+
+	u, v := &fp.Elt{}, &fp.Elt{}
+	one := fp.One()
+	fp.Sqr(u, &P.y)                // u = y^2
+	fp.Mul(v, u, &paramD)          // v = dy^2
+	fp.Sub(u, u, &one)             // u = y^2-1
+	fp.Sub(v, v, &one)             // v = dy^2-1
+	isQR := fp.InvSqrt(&P.x, u, v) // x = sqrt(u/v)
+	if !isQR {
+		return nil, err
+	}
+	fp.Modp(&P.x) // x = x mod p
+	if fp.IsZero(&P.x) && signX == 1 {
+		return nil, err
+	}
+	if signX != (P.x[0] & 1) {
+		fp.Neg(&P.x, &P.x)
+	}
+	P.ta = P.x
+	P.tb = P.y
+	P.z = fp.One()
+	return P, nil
+}
+
+// IsIdentity returns true is P is the identity Point.
+func (P *Point) IsIdentity() bool {
+	return fp.IsZero(&P.x) && !fp.IsZero(&P.y) && !fp.IsZero(&P.z) && P.y == P.z
+}
+
+// IsEqual returns true if P is equivalent to Q.
+func (P *Point) IsEqual(Q *Point) bool {
+	l, r := &fp.Elt{}, &fp.Elt{}
+	fp.Mul(l, &P.x, &Q.z)
+	fp.Mul(r, &Q.x, &P.z)
+	fp.Sub(l, l, r)
+	b := fp.IsZero(l)
+	fp.Mul(l, &P.y, &Q.z)
+	fp.Mul(r, &Q.y, &P.z)
+	fp.Sub(l, l, r)
+	b = b && fp.IsZero(l)
+	fp.Mul(l, &P.ta, &P.tb)
+	fp.Mul(l, l, &Q.z)
+	fp.Mul(r, &Q.ta, &Q.tb)
+	fp.Mul(r, r, &P.z)
+	fp.Sub(l, l, r)
+	b = b && fp.IsZero(l)
+	return b
+}
+
+// Neg obtains the inverse of the Point.
+func (P *Point) Neg() { fp.Neg(&P.x, &P.x); fp.Neg(&P.ta, &P.ta) }
+
+// ToAffine returns the x,y affine coordinates of P.
+func (P *Point) ToAffine() (x, y fp.Elt) {
+	fp.Inv(&P.z, &P.z)       // 1/z
+	fp.Mul(&P.x, &P.x, &P.z) // x/z
+	fp.Mul(&P.y, &P.y, &P.z) // y/z
+	fp.Modp(&P.x)
+	fp.Modp(&P.y)
+	fp.SetOne(&P.z)
+	P.ta = P.x
+	P.tb = P.y
+	return P.x, P.y
+}
+
+// ToBytes stores P into a slice of bytes.
+func (P *Point) ToBytes(out []byte) error {
+	if len(out) < fp.Size+1 {
+		return errors.New("invalid decoding")
+	}
+	x, y := P.ToAffine()
+	out[fp.Size] = (x[0] & 1) << 7
+	return fp.ToBytes(out[:fp.Size], &y)
+}
+
+// MarshalBinary encodes the receiver into a binary form and returns the result.
+func (P *Point) MarshalBinary() (data []byte, err error) {
+	data = make([]byte, fp.Size+1)
+	err = P.ToBytes(data[:fp.Size+1])
+	return data, err
+}
+
+// UnmarshalBinary must be able to decode the form generated by MarshalBinary.
+func (P *Point) UnmarshalBinary(data []byte) error { Q, err := FromBytes(data); *P = *Q; return err }
+
+// Double sets P = 2Q.
+func (P *Point) Double() { P.Add(P) }
+
+// Add sets P =P+Q..
+func (P *Point) Add(Q *Point) {
+	// This is formula (5) from "Twisted Edwards Curves Revisited" by
+	// Hisil H., Wong K.KH., Carter G., Dawson E. (2008)
+	// https://doi.org/10.1007/978-3-540-89255-7_20
+	x1, y1, z1, ta1, tb1 := &P.x, &P.y, &P.z, &P.ta, &P.tb
+	x2, y2, z2, ta2, tb2 := &Q.x, &Q.y, &Q.z, &Q.ta, &Q.tb
+	x3, y3, z3, E, H := &P.x, &P.y, &P.z, &P.ta, &P.tb
+	A, B, C, D := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}, &fp.Elt{}
+	t1, t2, F, G := C, D, &fp.Elt{}, &fp.Elt{}
+	fp.Mul(t1, ta1, tb1)  // t1 = ta1*tb1
+	fp.Mul(t2, ta2, tb2)  // t2 = ta2*tb2
+	fp.Mul(A, x1, x2)     // A = x1*x2
+	fp.Mul(B, y1, y2)     // B = y1*y2
+	fp.Mul(C, t1, t2)     // t1*t2
+	fp.Mul(C, C, &paramD) // C = d*t1*t2
+	fp.Mul(D, z1, z2)     // D = z1*z2
+	fp.Add(F, x1, y1)     // x1+y1
+	fp.Add(E, x2, y2)     // x2+y2
+	fp.Mul(E, E, F)       // (x1+y1)*(x2+y2)
+	fp.Sub(E, E, A)       // (x1+y1)*(x2+y2)-A
+	fp.Sub(E, E, B)       // E = (x1+y1)*(x2+y2)-A-B
+	fp.Sub(F, D, C)       // F = D-C
+	fp.Add(G, D, C)       // G = D+C
+	fp.Sub(H, B, A)       // H = B-A
+	fp.Mul(z3, F, G)      // Z = F * G
+	fp.Mul(x3, E, F)      // X = E * F
+	fp.Mul(y3, G, H)      // Y = G * H, T = E * H
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/scalar.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/scalar.go
new file mode 100644
index 00000000..f98117b2
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/scalar.go
@@ -0,0 +1,203 @@
+package goldilocks
+
+import (
+	"encoding/binary"
+	"math/bits"
+)
+
+// ScalarSize is the size (in bytes) of scalars.
+const ScalarSize = 56 // 448 / 8
+
+// _N is the number of 64-bit words to store scalars.
+const _N = 7 // 448 / 64
+
+// Scalar represents a positive integer stored in little-endian order.
+type Scalar [ScalarSize]byte
+
+type scalar64 [_N]uint64
+
+func (z *scalar64) fromScalar(x *Scalar) {
+	z[0] = binary.LittleEndian.Uint64(x[0*8 : 1*8])
+	z[1] = binary.LittleEndian.Uint64(x[1*8 : 2*8])
+	z[2] = binary.LittleEndian.Uint64(x[2*8 : 3*8])
+	z[3] = binary.LittleEndian.Uint64(x[3*8 : 4*8])
+	z[4] = binary.LittleEndian.Uint64(x[4*8 : 5*8])
+	z[5] = binary.LittleEndian.Uint64(x[5*8 : 6*8])
+	z[6] = binary.LittleEndian.Uint64(x[6*8 : 7*8])
+}
+
+func (z *scalar64) toScalar(x *Scalar) {
+	binary.LittleEndian.PutUint64(x[0*8:1*8], z[0])
+	binary.LittleEndian.PutUint64(x[1*8:2*8], z[1])
+	binary.LittleEndian.PutUint64(x[2*8:3*8], z[2])
+	binary.LittleEndian.PutUint64(x[3*8:4*8], z[3])
+	binary.LittleEndian.PutUint64(x[4*8:5*8], z[4])
+	binary.LittleEndian.PutUint64(x[5*8:6*8], z[5])
+	binary.LittleEndian.PutUint64(x[6*8:7*8], z[6])
+}
+
+// add calculates z = x + y. Assumes len(z) > max(len(x),len(y)).
+func add(z, x, y []uint64) uint64 {
+	l, L, zz := len(x), len(y), y
+	if l > L {
+		l, L, zz = L, l, x
+	}
+	c := uint64(0)
+	for i := 0; i < l; i++ {
+		z[i], c = bits.Add64(x[i], y[i], c)
+	}
+	for i := l; i < L; i++ {
+		z[i], c = bits.Add64(zz[i], 0, c)
+	}
+	return c
+}
+
+// sub calculates z = x - y. Assumes len(z) > max(len(x),len(y)).
+func sub(z, x, y []uint64) uint64 {
+	l, L, zz := len(x), len(y), y
+	if l > L {
+		l, L, zz = L, l, x
+	}
+	c := uint64(0)
+	for i := 0; i < l; i++ {
+		z[i], c = bits.Sub64(x[i], y[i], c)
+	}
+	for i := l; i < L; i++ {
+		z[i], c = bits.Sub64(zz[i], 0, c)
+	}
+	return c
+}
+
+// mulWord calculates z = x * y. Assumes len(z) >= len(x)+1.
+func mulWord(z, x []uint64, y uint64) {
+	for i := range z {
+		z[i] = 0
+	}
+	carry := uint64(0)
+	for i := range x {
+		hi, lo := bits.Mul64(x[i], y)
+		lo, cc := bits.Add64(lo, z[i], 0)
+		hi, _ = bits.Add64(hi, 0, cc)
+		z[i], cc = bits.Add64(lo, carry, 0)
+		carry, _ = bits.Add64(hi, 0, cc)
+	}
+	z[len(x)] = carry
+}
+
+// Cmov moves x into z if b=1.
+func (z *scalar64) Cmov(b uint64, x *scalar64) {
+	m := uint64(0) - b
+	for i := range z {
+		z[i] = (z[i] &^ m) | (x[i] & m)
+	}
+}
+
+// leftShift shifts to the left the words of z returning the more significant word.
+func (z *scalar64) leftShift(low uint64) uint64 {
+	high := z[_N-1]
+	for i := _N - 1; i > 0; i-- {
+		z[i] = z[i-1]
+	}
+	z[0] = low
+	return high
+}
+
+// reduceOneWord calculates z = z + 2^448*x such that the result fits in a Scalar.
+func (z *scalar64) reduceOneWord(x uint64) {
+	prod := (&scalar64{})[:]
+	mulWord(prod, residue448[:], x)
+	cc := add(z[:], z[:], prod)
+	mulWord(prod, residue448[:], cc)
+	add(z[:], z[:], prod)
+}
+
+// modOrder reduces z mod order.
+func (z *scalar64) modOrder() {
+	var o64, x scalar64
+	o64.fromScalar(&order)
+	// Performs: while (z >= order) { z = z-order }
+	// At most 8 (eight) iterations reduce 3 bits by subtracting.
+	for i := 0; i < 8; i++ {
+		c := sub(x[:], z[:], o64[:]) // (c || x) = z-order
+		z.Cmov(1-c, &x)              // if c != 0 { z = x }
+	}
+}
+
+// FromBytes stores z = x mod order, where x is a number stored in little-endian order.
+func (z *Scalar) FromBytes(x []byte) {
+	n := len(x)
+	nCeil := (n + 7) >> 3
+	for i := range z {
+		z[i] = 0
+	}
+	if nCeil < _N {
+		copy(z[:], x)
+		return
+	}
+	copy(z[:], x[8*(nCeil-_N):])
+	var z64 scalar64
+	z64.fromScalar(z)
+	for i := nCeil - _N - 1; i >= 0; i-- {
+		low := binary.LittleEndian.Uint64(x[8*i:])
+		high := z64.leftShift(low)
+		z64.reduceOneWord(high)
+	}
+	z64.modOrder()
+	z64.toScalar(z)
+}
+
+// divBy4 calculates z = x/4 mod order.
+func (z *Scalar) divBy4(x *Scalar) { z.Mul(x, &invFour) }
+
+// Red reduces z mod order.
+func (z *Scalar) Red() { var t scalar64; t.fromScalar(z); t.modOrder(); t.toScalar(z) }
+
+// Neg calculates z = -z mod order.
+func (z *Scalar) Neg() { z.Sub(&order, z) }
+
+// Add calculates z = x+y mod order.
+func (z *Scalar) Add(x, y *Scalar) {
+	var z64, x64, y64, t scalar64
+	x64.fromScalar(x)
+	y64.fromScalar(y)
+	c := add(z64[:], x64[:], y64[:])
+	add(t[:], z64[:], residue448[:])
+	z64.Cmov(c, &t)
+	z64.modOrder()
+	z64.toScalar(z)
+}
+
+// Sub calculates z = x-y mod order.
+func (z *Scalar) Sub(x, y *Scalar) {
+	var z64, x64, y64, t scalar64
+	x64.fromScalar(x)
+	y64.fromScalar(y)
+	c := sub(z64[:], x64[:], y64[:])
+	sub(t[:], z64[:], residue448[:])
+	z64.Cmov(c, &t)
+	z64.modOrder()
+	z64.toScalar(z)
+}
+
+// Mul calculates z = x*y mod order.
+func (z *Scalar) Mul(x, y *Scalar) {
+	var z64, x64, y64 scalar64
+	prod := (&[_N + 1]uint64{})[:]
+	x64.fromScalar(x)
+	y64.fromScalar(y)
+	mulWord(prod, x64[:], y64[_N-1])
+	copy(z64[:], prod[:_N])
+	z64.reduceOneWord(prod[_N])
+	for i := _N - 2; i >= 0; i-- {
+		h := z64.leftShift(0)
+		z64.reduceOneWord(h)
+		mulWord(prod, x64[:], y64[i])
+		c := add(z64[:], z64[:], prod[:_N])
+		z64.reduceOneWord(prod[_N] + c)
+	}
+	z64.modOrder()
+	z64.toScalar(z)
+}
+
+// IsZero returns true if z=0.
+func (z *Scalar) IsZero() bool { z.Red(); return *z == Scalar{} }
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist.go
new file mode 100644
index 00000000..83d7cdad
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist.go
@@ -0,0 +1,138 @@
+package goldilocks
+
+import (
+	"crypto/subtle"
+	"math/bits"
+
+	"github.com/cloudflare/circl/internal/conv"
+	"github.com/cloudflare/circl/math"
+	fp "github.com/cloudflare/circl/math/fp448"
+)
+
+// twistCurve is -x^2+y^2=1-39082x^2y^2 and is 4-isogenous to Goldilocks.
+type twistCurve struct{}
+
+// Identity returns the identity point.
+func (twistCurve) Identity() *twistPoint {
+	return &twistPoint{
+		y: fp.One(),
+		z: fp.One(),
+	}
+}
+
+// subYDiv16 update x = (x - y) / 16.
+func subYDiv16(x *scalar64, y int64) {
+	s := uint64(y >> 63)
+	x0, b0 := bits.Sub64((*x)[0], uint64(y), 0)
+	x1, b1 := bits.Sub64((*x)[1], s, b0)
+	x2, b2 := bits.Sub64((*x)[2], s, b1)
+	x3, b3 := bits.Sub64((*x)[3], s, b2)
+	x4, b4 := bits.Sub64((*x)[4], s, b3)
+	x5, b5 := bits.Sub64((*x)[5], s, b4)
+	x6, _ := bits.Sub64((*x)[6], s, b5)
+	x[0] = (x0 >> 4) | (x1 << 60)
+	x[1] = (x1 >> 4) | (x2 << 60)
+	x[2] = (x2 >> 4) | (x3 << 60)
+	x[3] = (x3 >> 4) | (x4 << 60)
+	x[4] = (x4 >> 4) | (x5 << 60)
+	x[5] = (x5 >> 4) | (x6 << 60)
+	x[6] = (x6 >> 4)
+}
+
+func recodeScalar(d *[113]int8, k *Scalar) {
+	var k64 scalar64
+	k64.fromScalar(k)
+	for i := 0; i < 112; i++ {
+		d[i] = int8((k64[0] & 0x1f) - 16)
+		subYDiv16(&k64, int64(d[i]))
+	}
+	d[112] = int8(k64[0])
+}
+
+// ScalarMult returns kP.
+func (e twistCurve) ScalarMult(k *Scalar, P *twistPoint) *twistPoint {
+	var TabP [8]preTwistPointProy
+	var S preTwistPointProy
+	var d [113]int8
+
+	var isZero int
+	if k.IsZero() {
+		isZero = 1
+	}
+	subtle.ConstantTimeCopy(isZero, k[:], order[:])
+
+	minusK := *k
+	isEven := 1 - int(k[0]&0x1)
+	minusK.Neg()
+	subtle.ConstantTimeCopy(isEven, k[:], minusK[:])
+	recodeScalar(&d, k)
+
+	P.oddMultiples(TabP[:])
+	Q := e.Identity()
+	for i := 112; i >= 0; i-- {
+		Q.Double()
+		Q.Double()
+		Q.Double()
+		Q.Double()
+		mask := d[i] >> 7
+		absDi := (d[i] + mask) ^ mask
+		inx := int32((absDi - 1) >> 1)
+		sig := int((d[i] >> 7) & 0x1)
+		for j := range TabP {
+			S.cmov(&TabP[j], uint(subtle.ConstantTimeEq(inx, int32(j))))
+		}
+		S.cneg(sig)
+		Q.mixAdd(&S)
+	}
+	Q.cneg(uint(isEven))
+	return Q
+}
+
+const (
+	omegaFix = 7
+	omegaVar = 5
+)
+
+// CombinedMult returns mG+nP.
+func (e twistCurve) CombinedMult(m, n *Scalar, P *twistPoint) *twistPoint {
+	nafFix := math.OmegaNAF(conv.BytesLe2BigInt(m[:]), omegaFix)
+	nafVar := math.OmegaNAF(conv.BytesLe2BigInt(n[:]), omegaVar)
+
+	if len(nafFix) > len(nafVar) {
+		nafVar = append(nafVar, make([]int32, len(nafFix)-len(nafVar))...)
+	} else if len(nafFix) < len(nafVar) {
+		nafFix = append(nafFix, make([]int32, len(nafVar)-len(nafFix))...)
+	}
+
+	var TabQ [1 << (omegaVar - 2)]preTwistPointProy
+	P.oddMultiples(TabQ[:])
+	Q := e.Identity()
+	for i := len(nafFix) - 1; i >= 0; i-- {
+		Q.Double()
+		// Generator point
+		if nafFix[i] != 0 {
+			idxM := absolute(nafFix[i]) >> 1
+			R := tabVerif[idxM]
+			if nafFix[i] < 0 {
+				R.neg()
+			}
+			Q.mixAddZ1(&R)
+		}
+		// Variable input point
+		if nafVar[i] != 0 {
+			idxN := absolute(nafVar[i]) >> 1
+			S := TabQ[idxN]
+			if nafVar[i] < 0 {
+				S.neg()
+			}
+			Q.mixAdd(&S)
+		}
+	}
+	return Q
+}
+
+// absolute returns always a positive value.
+func absolute(x int32) int32 {
+	mask := x >> 31
+	return (x + mask) ^ mask
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/twistPoint.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twistPoint.go
new file mode 100644
index 00000000..c55db77b
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twistPoint.go
@@ -0,0 +1,135 @@
+package goldilocks
+
+import (
+	"fmt"
+
+	fp "github.com/cloudflare/circl/math/fp448"
+)
+
+type twistPoint struct{ x, y, z, ta, tb fp.Elt }
+
+type preTwistPointAffine struct{ addYX, subYX, dt2 fp.Elt }
+
+type preTwistPointProy struct {
+	preTwistPointAffine
+	z2 fp.Elt
+}
+
+func (P *twistPoint) String() string {
+	return fmt.Sprintf("x: %v\ny: %v\nz: %v\nta: %v\ntb: %v", P.x, P.y, P.z, P.ta, P.tb)
+}
+
+// cneg conditionally negates the point if b=1.
+func (P *twistPoint) cneg(b uint) {
+	t := &fp.Elt{}
+	fp.Neg(t, &P.x)
+	fp.Cmov(&P.x, t, b)
+	fp.Neg(t, &P.ta)
+	fp.Cmov(&P.ta, t, b)
+}
+
+// Double updates P with 2P.
+func (P *twistPoint) Double() {
+	// This is formula (7) from "Twisted Edwards Curves Revisited" by
+	// Hisil H., Wong K.KH., Carter G., Dawson E. (2008)
+	// https://doi.org/10.1007/978-3-540-89255-7_20
+	Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb
+	a, b, c, e, f, g, h := Px, Py, Pz, Pta, Px, Py, Ptb
+	fp.Add(e, Px, Py) // x+y
+	fp.Sqr(a, Px)     // A = x^2
+	fp.Sqr(b, Py)     // B = y^2
+	fp.Sqr(c, Pz)     // z^2
+	fp.Add(c, c, c)   // C = 2*z^2
+	fp.Add(h, a, b)   // H = A+B
+	fp.Sqr(e, e)      // (x+y)^2
+	fp.Sub(e, e, h)   // E = (x+y)^2-A-B
+	fp.Sub(g, b, a)   // G = B-A
+	fp.Sub(f, c, g)   // F = C-G
+	fp.Mul(Pz, f, g)  // Z = F * G
+	fp.Mul(Px, e, f)  // X = E * F
+	fp.Mul(Py, g, h)  // Y = G * H, T = E * H
+}
+
+// mixAdd calculates P= P+Q, where Q is a precomputed point with Z_Q = 1.
+func (P *twistPoint) mixAddZ1(Q *preTwistPointAffine) {
+	fp.Add(&P.z, &P.z, &P.z) // D = 2*z1 (z2=1)
+	P.coreAddition(Q)
+}
+
+// coreAddition calculates P=P+Q for curves with A=-1.
+func (P *twistPoint) coreAddition(Q *preTwistPointAffine) {
+	// This is the formula following (5) from "Twisted Edwards Curves Revisited" by
+	// Hisil H., Wong K.KH., Carter G., Dawson E. (2008)
+	// https://doi.org/10.1007/978-3-540-89255-7_20
+	Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb
+	addYX2, subYX2, dt2 := &Q.addYX, &Q.subYX, &Q.dt2
+	a, b, c, d, e, f, g, h := Px, Py, &fp.Elt{}, Pz, Pta, Px, Py, Ptb
+	fp.Mul(c, Pta, Ptb)  // t1 = ta*tb
+	fp.Sub(h, Py, Px)    // y1-x1
+	fp.Add(b, Py, Px)    // y1+x1
+	fp.Mul(a, h, subYX2) // A = (y1-x1)*(y2-x2)
+	fp.Mul(b, b, addYX2) // B = (y1+x1)*(y2+x2)
+	fp.Mul(c, c, dt2)    // C = 2*D*t1*t2
+	fp.Sub(e, b, a)      // E = B-A
+	fp.Add(h, b, a)      // H = B+A
+	fp.Sub(f, d, c)      // F = D-C
+	fp.Add(g, d, c)      // G = D+C
+	fp.Mul(Pz, f, g)     // Z = F * G
+	fp.Mul(Px, e, f)     // X = E * F
+	fp.Mul(Py, g, h)     // Y = G * H, T = E * H
+}
+
+func (P *preTwistPointAffine) neg() {
+	P.addYX, P.subYX = P.subYX, P.addYX
+	fp.Neg(&P.dt2, &P.dt2)
+}
+
+func (P *preTwistPointAffine) cneg(b int) {
+	t := &fp.Elt{}
+	fp.Cswap(&P.addYX, &P.subYX, uint(b))
+	fp.Neg(t, &P.dt2)
+	fp.Cmov(&P.dt2, t, uint(b))
+}
+
+func (P *preTwistPointAffine) cmov(Q *preTwistPointAffine, b uint) {
+	fp.Cmov(&P.addYX, &Q.addYX, b)
+	fp.Cmov(&P.subYX, &Q.subYX, b)
+	fp.Cmov(&P.dt2, &Q.dt2, b)
+}
+
+// mixAdd calculates P= P+Q, where Q is a precomputed point with Z_Q != 1.
+func (P *twistPoint) mixAdd(Q *preTwistPointProy) {
+	fp.Mul(&P.z, &P.z, &Q.z2) // D = 2*z1*z2
+	P.coreAddition(&Q.preTwistPointAffine)
+}
+
+// oddMultiples calculates T[i] = (2*i-1)P for 0 < i < len(T).
+func (P *twistPoint) oddMultiples(T []preTwistPointProy) {
+	if n := len(T); n > 0 {
+		T[0].FromTwistPoint(P)
+		_2P := *P
+		_2P.Double()
+		R := &preTwistPointProy{}
+		R.FromTwistPoint(&_2P)
+		for i := 1; i < n; i++ {
+			P.mixAdd(R)
+			T[i].FromTwistPoint(P)
+		}
+	}
+}
+
+// cmov conditionally moves Q into P if b=1.
+func (P *preTwistPointProy) cmov(Q *preTwistPointProy, b uint) {
+	P.preTwistPointAffine.cmov(&Q.preTwistPointAffine, b)
+	fp.Cmov(&P.z2, &Q.z2, b)
+}
+
+// FromTwistPoint precomputes some coordinates of Q for missed addition.
+func (P *preTwistPointProy) FromTwistPoint(Q *twistPoint) {
+	fp.Add(&P.addYX, &Q.y, &Q.x)         // addYX = X + Y
+	fp.Sub(&P.subYX, &Q.y, &Q.x)         // subYX = Y - X
+	fp.Mul(&P.dt2, &Q.ta, &Q.tb)         // T = ta*tb
+	fp.Mul(&P.dt2, &P.dt2, &paramDTwist) // D*T
+	fp.Add(&P.dt2, &P.dt2, &P.dt2)       // dt2 = 2*D*T
+	fp.Add(&P.z2, &Q.z, &Q.z)            // z2 = 2*Z
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/twistTables.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twistTables.go
new file mode 100644
index 00000000..ed432e02
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twistTables.go
@@ -0,0 +1,216 @@
+package goldilocks
+
+import fp "github.com/cloudflare/circl/math/fp448"
+
+var tabFixMult = [fxV][fx2w1]preTwistPointAffine{
+	{
+		{
+			addYX: fp.Elt{0x65, 0x4a, 0xdd, 0xdf, 0xb4, 0x79, 0x60, 0xc8, 0xa1, 0x70, 0xb4, 0x3a, 0x1e, 0x0c, 0x9b, 0x19, 0xe5, 0x48, 0x3f, 0xd7, 0x44, 0x18, 0x18, 0x14, 0x14, 0x27, 0x45, 0xd0, 0x2b, 0x24, 0xd5, 0x93, 0xc3, 0x74, 0x4c, 0x50, 0x70, 0x43, 0x26, 0x05, 0x08, 0x24, 0xca, 0x78, 0x30, 0xc1, 0x06, 0x8d, 0xd4, 0x86, 0x42, 0xf0, 0x14, 0xde, 0x08, 0x05},
+			subYX: fp.Elt{0x64, 0x4a, 0xdd, 0xdf, 0xb4, 0x79, 0x60, 0xc8, 0xa1, 0x70, 0xb4, 0x3a, 0x1e, 0x0c, 0x9b, 0x19, 0xe5, 0x48, 0x3f, 0xd7, 0x44, 0x18, 0x18, 0x14, 0x14, 0x27, 0x45, 0xd0, 0x2d, 0x24, 0xd5, 0x93, 0xc3, 0x74, 0x4c, 0x50, 0x70, 0x43, 0x26, 0x05, 0x08, 0x24, 0xca, 0x78, 0x30, 0xc1, 0x06, 0x8d, 0xd4, 0x86, 0x42, 0xf0, 0x14, 0xde, 0x08, 0x05},
+			dt2:   fp.Elt{0x1a, 0x33, 0xea, 0x64, 0x45, 0x1c, 0xdf, 0x17, 0x1d, 0x16, 0x34, 0x28, 0xd6, 0x61, 0x19, 0x67, 0x79, 0xb4, 0x13, 0xcf, 0x3e, 0x7c, 0x0e, 0x72, 0xda, 0xf1, 0x5f, 0xda, 0xe6, 0xcf, 0x42, 0xd3, 0xb6, 0x17, 0xc2, 0x68, 0x13, 0x2d, 0xd9, 0x60, 0x3e, 0xae, 0xf0, 0x5b, 0x96, 0xf0, 0xcd, 0xaf, 0xea, 0xb7, 0x0d, 0x59, 0x16, 0xa7, 0xff, 0x55},
+		},
+		{
+			addYX: fp.Elt{0xca, 0xd8, 0x7d, 0x86, 0x1a, 0xef, 0xad, 0x11, 0xe3, 0x27, 0x41, 0x7e, 0x7f, 0x3e, 0xa9, 0xd2, 0xb5, 0x4e, 0x50, 0xe0, 0x77, 0x91, 0xc2, 0x13, 0x52, 0x73, 0x41, 0x09, 0xa6, 0x57, 0x9a, 0xc8, 0xa8, 0x90, 0x9d, 0x26, 0x14, 0xbb, 0xa1, 0x2a, 0xf7, 0x45, 0x43, 0x4e, 0xea, 0x35, 0x62, 0xe1, 0x08, 0x85, 0x46, 0xb8, 0x24, 0x05, 0x2d, 0xab},
+			subYX: fp.Elt{0x9b, 0xe6, 0xd3, 0xe5, 0xfe, 0x50, 0x36, 0x3c, 0x3c, 0x6d, 0x74, 0x1d, 0x74, 0xc0, 0xde, 0x5b, 0x45, 0x27, 0xe5, 0x12, 0xee, 0x63, 0x35, 0x6b, 0x13, 0xe2, 0x41, 0x6b, 0x3a, 0x05, 0x2b, 0xb1, 0x89, 0x26, 0xb6, 0xc6, 0xd1, 0x84, 0xff, 0x0e, 0x9b, 0xa3, 0xfb, 0x21, 0x36, 0x6b, 0x01, 0xf7, 0x9f, 0x7c, 0xeb, 0xf5, 0x18, 0x7a, 0x2a, 0x70},
+			dt2:   fp.Elt{0x09, 0xad, 0x99, 0x1a, 0x38, 0xd3, 0xdf, 0x22, 0x37, 0x32, 0x61, 0x8b, 0xf3, 0x19, 0x48, 0x08, 0xe8, 0x49, 0xb6, 0x4a, 0xa7, 0xed, 0xa4, 0xa2, 0xee, 0x86, 0xd7, 0x31, 0x5e, 0xce, 0x95, 0x76, 0x86, 0x42, 0x1c, 0x9d, 0x07, 0x14, 0x8c, 0x34, 0x18, 0x9c, 0x6d, 0x3a, 0xdf, 0xa9, 0xe8, 0x36, 0x7e, 0xe4, 0x95, 0xbe, 0xb5, 0x09, 0xf8, 0x9c},
+		},
+		{
+			addYX: fp.Elt{0x51, 0xdb, 0x49, 0xa8, 0x9f, 0xe3, 0xd7, 0xec, 0x0d, 0x0f, 0x49, 0xe8, 0xb6, 0xc5, 0x0f, 0x5a, 0x1c, 0xce, 0x54, 0x0d, 0xb1, 0x8d, 0x5b, 0xbf, 0xf4, 0xaa, 0x34, 0x77, 0xc4, 0x5d, 0x59, 0xb6, 0xc5, 0x0e, 0x5a, 0xd8, 0x5b, 0x30, 0xc2, 0x1d, 0xec, 0x85, 0x1c, 0x42, 0xbe, 0x24, 0x2e, 0x50, 0x55, 0x44, 0xb2, 0x3a, 0x01, 0xaa, 0x98, 0xfb},
+			subYX: fp.Elt{0xe7, 0x29, 0xb7, 0xd0, 0xaa, 0x4f, 0x32, 0x53, 0x56, 0xde, 0xbc, 0xd1, 0x92, 0x5d, 0x19, 0xbe, 0xa3, 0xe3, 0x75, 0x48, 0xe0, 0x7a, 0x1b, 0x54, 0x7a, 0xb7, 0x41, 0x77, 0x84, 0x38, 0xdd, 0x14, 0x9f, 0xca, 0x3f, 0xa3, 0xc8, 0xa7, 0x04, 0x70, 0xf1, 0x4d, 0x3d, 0xb3, 0x84, 0x79, 0xcb, 0xdb, 0xe4, 0xc5, 0x42, 0x9b, 0x57, 0x19, 0xf1, 0x2d},
+			dt2:   fp.Elt{0x20, 0xb4, 0x94, 0x9e, 0xdf, 0x31, 0x44, 0x0b, 0xc9, 0x7b, 0x75, 0x40, 0x9d, 0xd1, 0x96, 0x39, 0x70, 0x71, 0x15, 0xc8, 0x93, 0xd5, 0xc5, 0xe5, 0xba, 0xfe, 0xee, 0x08, 0x6a, 0x98, 0x0a, 0x1b, 0xb2, 0xaa, 0x3a, 0xf4, 0xa4, 0x79, 0xf9, 0x8e, 0x4d, 0x65, 0x10, 0x9b, 0x3a, 0x6e, 0x7c, 0x87, 0x94, 0x92, 0x11, 0x65, 0xbf, 0x1a, 0x09, 0xde},
+		},
+		{
+			addYX: fp.Elt{0xf3, 0x84, 0x76, 0x77, 0xa5, 0x6b, 0x27, 0x3b, 0x83, 0x3d, 0xdf, 0xa0, 0xeb, 0x32, 0x6d, 0x58, 0x81, 0x57, 0x64, 0xc2, 0x21, 0x7c, 0x9b, 0xea, 0xe6, 0xb0, 0x93, 0xf9, 0xe7, 0xc3, 0xed, 0x5a, 0x8e, 0xe2, 0xb4, 0x72, 0x76, 0x66, 0x0f, 0x22, 0x29, 0x94, 0x3e, 0x63, 0x48, 0x5e, 0x80, 0xcb, 0xac, 0xfa, 0x95, 0xb6, 0x4b, 0xc4, 0x95, 0x33},
+			subYX: fp.Elt{0x0c, 0x55, 0xd1, 0x5e, 0x5f, 0xbf, 0xbf, 0xe2, 0x4c, 0xfc, 0x37, 0x4a, 0xc4, 0xb1, 0xf4, 0x83, 0x61, 0x93, 0x60, 0x8e, 0x9f, 0x31, 0xf0, 0xa0, 0x41, 0xff, 0x1d, 0xe2, 0x7f, 0xca, 0x40, 0xd6, 0x88, 0xe8, 0x91, 0x61, 0xe2, 0x11, 0x18, 0x83, 0xf3, 0x25, 0x2f, 0x3f, 0x49, 0x40, 0xd4, 0x83, 0xe2, 0xd7, 0x74, 0x6a, 0x16, 0x86, 0x4e, 0xab},
+			dt2:   fp.Elt{0xdd, 0x58, 0x65, 0xd8, 0x9f, 0xdd, 0x70, 0x7f, 0x0f, 0xec, 0xbd, 0x5c, 0x5c, 0x9b, 0x7e, 0x1b, 0x9f, 0x79, 0x36, 0x1f, 0xfd, 0x79, 0x10, 0x1c, 0x52, 0xf3, 0x22, 0xa4, 0x1f, 0x71, 0x6e, 0x63, 0x14, 0xf4, 0xa7, 0x3e, 0xbe, 0xad, 0x43, 0x30, 0x38, 0x8c, 0x29, 0xc6, 0xcf, 0x50, 0x75, 0x21, 0xe5, 0x78, 0xfd, 0xb0, 0x9a, 0xc4, 0x6d, 0xd4},
+		},
+	},
+	{
+		{
+			addYX: fp.Elt{0x7a, 0xa1, 0x38, 0xa6, 0xfd, 0x0e, 0x96, 0xd5, 0x26, 0x76, 0x86, 0x70, 0x80, 0x30, 0xa6, 0x67, 0xeb, 0xf4, 0x39, 0xdb, 0x22, 0xf5, 0x9f, 0x98, 0xe4, 0xb5, 0x3a, 0x0c, 0x59, 0xbf, 0x85, 0xc6, 0xf0, 0x0b, 0x1c, 0x41, 0x38, 0x09, 0x01, 0xdb, 0xd6, 0x3c, 0xb7, 0xf1, 0x08, 0x6b, 0x4b, 0x9e, 0x63, 0x53, 0x83, 0xd3, 0xab, 0xa3, 0x72, 0x0d},
+			subYX: fp.Elt{0x84, 0x68, 0x25, 0xe8, 0xe9, 0x8f, 0x91, 0xbf, 0xf7, 0xa4, 0x30, 0xae, 0xea, 0x9f, 0xdd, 0x56, 0x64, 0x09, 0xc9, 0x54, 0x68, 0x4e, 0x33, 0xc5, 0x6f, 0x7b, 0x2d, 0x52, 0x2e, 0x42, 0xbe, 0xbe, 0xf5, 0x64, 0xbf, 0x77, 0x54, 0xdf, 0xb0, 0x10, 0xd2, 0x16, 0x5d, 0xce, 0xaf, 0x9f, 0xfb, 0xa3, 0x63, 0x50, 0xcb, 0xc0, 0xd0, 0x88, 0x44, 0xa3},
+			dt2:   fp.Elt{0xc3, 0x8b, 0xa5, 0xf1, 0x44, 0xe4, 0x41, 0xcd, 0x75, 0xe3, 0x17, 0x69, 0x5b, 0xb9, 0xbb, 0xee, 0x82, 0xbb, 0xce, 0x57, 0xdf, 0x2a, 0x9c, 0x12, 0xab, 0x66, 0x08, 0x68, 0x05, 0x1b, 0x87, 0xee, 0x5d, 0x1e, 0x18, 0x14, 0x22, 0x4b, 0x99, 0x61, 0x75, 0x28, 0xe7, 0x65, 0x1c, 0x36, 0xb6, 0x18, 0x09, 0xa8, 0xdf, 0xef, 0x30, 0x35, 0xbc, 0x58},
+		},
+		{
+			addYX: fp.Elt{0xc5, 0xd3, 0x0e, 0x6f, 0xaf, 0x06, 0x69, 0xc4, 0x07, 0x9e, 0x58, 0x6e, 0x3f, 0x49, 0xd9, 0x0a, 0x3c, 0x2c, 0x37, 0xcd, 0x27, 0x4d, 0x87, 0x91, 0x7a, 0xb0, 0x28, 0xad, 0x2f, 0x68, 0x92, 0x05, 0x97, 0xf1, 0x30, 0x5f, 0x4c, 0x10, 0x20, 0x30, 0xd3, 0x08, 0x3f, 0xc1, 0xc6, 0xb7, 0xb5, 0xd1, 0x71, 0x7b, 0xa8, 0x0a, 0xd8, 0xf5, 0x17, 0xcf},
+			subYX: fp.Elt{0x64, 0xd4, 0x8f, 0x91, 0x40, 0xab, 0x6e, 0x1a, 0x62, 0x83, 0xdc, 0xd7, 0x30, 0x1a, 0x4a, 0x2a, 0x4c, 0x54, 0x86, 0x19, 0x81, 0x5d, 0x04, 0x52, 0xa3, 0xca, 0x82, 0x38, 0xdc, 0x1e, 0xf0, 0x7a, 0x78, 0x76, 0x49, 0x4f, 0x71, 0xc4, 0x74, 0x2f, 0xf0, 0x5b, 0x2e, 0x5e, 0xac, 0xef, 0x17, 0xe4, 0x8e, 0x6e, 0xed, 0x43, 0x23, 0x61, 0x99, 0x49},
+			dt2:   fp.Elt{0x64, 0x90, 0x72, 0x76, 0xf8, 0x2c, 0x7d, 0x57, 0xf9, 0x30, 0x5e, 0x7a, 0x10, 0x74, 0x19, 0x39, 0xd9, 0xaf, 0x0a, 0xf1, 0x43, 0xed, 0x88, 0x9c, 0x8b, 0xdc, 0x9b, 0x1c, 0x90, 0xe7, 0xf7, 0xa3, 0xa5, 0x0d, 0xc6, 0xbc, 0x30, 0xfb, 0x91, 0x1a, 0x51, 0xba, 0x2d, 0xbe, 0x89, 0xdf, 0x1d, 0xdc, 0x53, 0xa8, 0x82, 0x8a, 0xd3, 0x8d, 0x16, 0x68},
+		},
+		{
+			addYX: fp.Elt{0xef, 0x5c, 0xe3, 0x74, 0xbf, 0x13, 0x4a, 0xbf, 0x66, 0x73, 0x64, 0xb7, 0xd4, 0xce, 0x98, 0x82, 0x05, 0xfa, 0x98, 0x0c, 0x0a, 0xae, 0xe5, 0x6b, 0x9f, 0xac, 0xbb, 0x6e, 0x1f, 0xcf, 0xff, 0xa6, 0x71, 0x9a, 0xa8, 0x7a, 0x9e, 0x64, 0x1f, 0x20, 0x4a, 0x61, 0xa2, 0xd6, 0x50, 0xe3, 0xba, 0x81, 0x0c, 0x50, 0x59, 0x69, 0x59, 0x15, 0x55, 0xdb},
+			subYX: fp.Elt{0xe8, 0x77, 0x4d, 0xe8, 0x66, 0x3d, 0xc1, 0x00, 0x3c, 0xf2, 0x25, 0x00, 0xdc, 0xb2, 0xe5, 0x9b, 0x12, 0x89, 0xf3, 0xd6, 0xea, 0x85, 0x60, 0xfe, 0x67, 0x91, 0xfd, 0x04, 0x7c, 0xe0, 0xf1, 0x86, 0x06, 0x11, 0x66, 0xee, 0xd4, 0xd5, 0xbe, 0x3b, 0x0f, 0xe3, 0x59, 0xb3, 0x4f, 0x00, 0xb6, 0xce, 0x80, 0xc1, 0x61, 0xf7, 0xaf, 0x04, 0x6a, 0x3c},
+			dt2:   fp.Elt{0x00, 0xd7, 0x32, 0x93, 0x67, 0x70, 0x6f, 0xd7, 0x69, 0xab, 0xb1, 0xd3, 0xdc, 0xd6, 0xa8, 0xdd, 0x35, 0x25, 0xca, 0xd3, 0x8a, 0x6d, 0xce, 0xfb, 0xfd, 0x2b, 0x83, 0xf0, 0xd4, 0xac, 0x66, 0xfb, 0x72, 0x87, 0x7e, 0x55, 0xb7, 0x91, 0x58, 0x10, 0xc3, 0x11, 0x7e, 0x15, 0xfe, 0x7c, 0x55, 0x90, 0xa3, 0x9e, 0xed, 0x9a, 0x7f, 0xa7, 0xb7, 0xeb},
+		},
+		{
+			addYX: fp.Elt{0x25, 0x0f, 0xc2, 0x09, 0x9c, 0x10, 0xc8, 0x7c, 0x93, 0xa7, 0xbe, 0xe9, 0x26, 0x25, 0x7c, 0x21, 0xfe, 0xe7, 0x5f, 0x3c, 0x02, 0x83, 0xa7, 0x9e, 0xdf, 0xc0, 0x94, 0x2b, 0x7d, 0x1a, 0xd0, 0x1d, 0xcc, 0x2e, 0x7d, 0xd4, 0x85, 0xe7, 0xc1, 0x15, 0x66, 0xd6, 0xd6, 0x32, 0xb8, 0xf7, 0x63, 0xaa, 0x3b, 0xa5, 0xea, 0x49, 0xad, 0x88, 0x9b, 0x66},
+			subYX: fp.Elt{0x09, 0x97, 0x79, 0x36, 0x41, 0x56, 0x9b, 0xdf, 0x15, 0xd8, 0x43, 0x28, 0x17, 0x5b, 0x96, 0xc9, 0xcf, 0x39, 0x1f, 0x13, 0xf7, 0x4d, 0x1d, 0x1f, 0xda, 0x51, 0x56, 0xe7, 0x0a, 0x5a, 0x65, 0xb6, 0x2a, 0x87, 0x49, 0x86, 0xc2, 0x2b, 0xcd, 0xfe, 0x07, 0xf6, 0x4c, 0xe2, 0x1d, 0x9b, 0xd8, 0x82, 0x09, 0x5b, 0x11, 0x10, 0x62, 0x56, 0x89, 0xbd},
+			dt2:   fp.Elt{0xd9, 0x15, 0x73, 0xf2, 0x96, 0x35, 0x53, 0xb0, 0xe7, 0xa8, 0x0b, 0x93, 0x35, 0x0b, 0x3a, 0x00, 0xf5, 0x18, 0xb1, 0xc3, 0x12, 0x3f, 0x91, 0x17, 0xc1, 0x4c, 0x15, 0x5a, 0x86, 0x92, 0x11, 0xbd, 0x44, 0x40, 0x5a, 0x7b, 0x15, 0x89, 0xba, 0xc1, 0xc1, 0xbc, 0x43, 0x45, 0xe6, 0x52, 0x02, 0x73, 0x0a, 0xd0, 0x2a, 0x19, 0xda, 0x47, 0xa8, 0xff},
+		},
+	},
+}
+
+// tabVerif contains the odd multiples of P. The entry T[i] = (2i+1)P, where
+// P = phi(G) and G is the generator of the Goldilocks curve, and phi is a
+// 4-degree isogeny.
+var tabVerif = [1 << (omegaFix - 2)]preTwistPointAffine{
+	{ /* 1P*/
+		addYX: fp.Elt{0x65, 0x4a, 0xdd, 0xdf, 0xb4, 0x79, 0x60, 0xc8, 0xa1, 0x70, 0xb4, 0x3a, 0x1e, 0x0c, 0x9b, 0x19, 0xe5, 0x48, 0x3f, 0xd7, 0x44, 0x18, 0x18, 0x14, 0x14, 0x27, 0x45, 0xd0, 0x2b, 0x24, 0xd5, 0x93, 0xc3, 0x74, 0x4c, 0x50, 0x70, 0x43, 0x26, 0x05, 0x08, 0x24, 0xca, 0x78, 0x30, 0xc1, 0x06, 0x8d, 0xd4, 0x86, 0x42, 0xf0, 0x14, 0xde, 0x08, 0x05},
+		subYX: fp.Elt{0x64, 0x4a, 0xdd, 0xdf, 0xb4, 0x79, 0x60, 0xc8, 0xa1, 0x70, 0xb4, 0x3a, 0x1e, 0x0c, 0x9b, 0x19, 0xe5, 0x48, 0x3f, 0xd7, 0x44, 0x18, 0x18, 0x14, 0x14, 0x27, 0x45, 0xd0, 0x2d, 0x24, 0xd5, 0x93, 0xc3, 0x74, 0x4c, 0x50, 0x70, 0x43, 0x26, 0x05, 0x08, 0x24, 0xca, 0x78, 0x30, 0xc1, 0x06, 0x8d, 0xd4, 0x86, 0x42, 0xf0, 0x14, 0xde, 0x08, 0x05},
+		dt2:   fp.Elt{0x1a, 0x33, 0xea, 0x64, 0x45, 0x1c, 0xdf, 0x17, 0x1d, 0x16, 0x34, 0x28, 0xd6, 0x61, 0x19, 0x67, 0x79, 0xb4, 0x13, 0xcf, 0x3e, 0x7c, 0x0e, 0x72, 0xda, 0xf1, 0x5f, 0xda, 0xe6, 0xcf, 0x42, 0xd3, 0xb6, 0x17, 0xc2, 0x68, 0x13, 0x2d, 0xd9, 0x60, 0x3e, 0xae, 0xf0, 0x5b, 0x96, 0xf0, 0xcd, 0xaf, 0xea, 0xb7, 0x0d, 0x59, 0x16, 0xa7, 0xff, 0x55},
+	},
+	{ /* 3P*/
+		addYX: fp.Elt{0xd1, 0xe9, 0xa8, 0x33, 0x20, 0x76, 0x18, 0x08, 0x45, 0x2a, 0xc9, 0x67, 0x2a, 0xc3, 0x15, 0x24, 0xf9, 0x74, 0x21, 0x30, 0x99, 0x59, 0x8b, 0xb2, 0xf0, 0xa4, 0x07, 0xe2, 0x6a, 0x36, 0x8d, 0xd9, 0xd2, 0x4a, 0x7f, 0x73, 0x50, 0x39, 0x3d, 0xaa, 0xa7, 0x51, 0x73, 0x0d, 0x2b, 0x8b, 0x96, 0x47, 0xac, 0x3c, 0x5d, 0xaa, 0x39, 0x9c, 0xcf, 0xd5},
+		subYX: fp.Elt{0x6b, 0x11, 0x5d, 0x1a, 0xf9, 0x41, 0x9d, 0xc5, 0x30, 0x3e, 0xad, 0x25, 0x2c, 0x04, 0x45, 0xea, 0xcc, 0x67, 0x07, 0x85, 0xe9, 0xda, 0x0e, 0xb5, 0x40, 0xb7, 0x32, 0xb4, 0x49, 0xdd, 0xff, 0xaa, 0xfc, 0xbb, 0x19, 0xca, 0x8b, 0x79, 0x2b, 0x8f, 0x8d, 0x00, 0x33, 0xc2, 0xad, 0xe9, 0xd3, 0x12, 0xa8, 0xaa, 0x87, 0x62, 0xad, 0x2d, 0xff, 0xa4},
+		dt2:   fp.Elt{0xb0, 0xaf, 0x3b, 0xea, 0xf0, 0x42, 0x0b, 0x5e, 0x88, 0xd3, 0x98, 0x08, 0x87, 0x59, 0x72, 0x0a, 0xc2, 0xdf, 0xcb, 0x7f, 0x59, 0xb5, 0x4c, 0x63, 0x68, 0xe8, 0x41, 0x38, 0x67, 0x4f, 0xe9, 0xc6, 0xb2, 0x6b, 0x08, 0xa7, 0xf7, 0x0e, 0xcd, 0xea, 0xca, 0x3d, 0xaf, 0x8e, 0xda, 0x4b, 0x2e, 0xd2, 0x88, 0x64, 0x8d, 0xc5, 0x5f, 0x76, 0x0f, 0x3d},
+	},
+	{ /* 5P*/
+		addYX: fp.Elt{0xe5, 0x65, 0xc9, 0xe2, 0x75, 0xf0, 0x7d, 0x1a, 0xba, 0xa4, 0x40, 0x4b, 0x93, 0x12, 0xa2, 0x80, 0x95, 0x0d, 0x03, 0x93, 0xe8, 0xa5, 0x4d, 0xe2, 0x3d, 0x81, 0xf5, 0xce, 0xd4, 0x2d, 0x25, 0x59, 0x16, 0x5c, 0xe7, 0xda, 0xc7, 0x45, 0xd2, 0x7e, 0x2c, 0x38, 0xd4, 0x37, 0x64, 0xb2, 0xc2, 0x28, 0xc5, 0x72, 0x16, 0x32, 0x45, 0x36, 0x6f, 0x9f},
+		subYX: fp.Elt{0x09, 0xf4, 0x7e, 0xbd, 0x89, 0xdb, 0x19, 0x58, 0xe1, 0x08, 0x00, 0x8a, 0xf4, 0x5f, 0x2a, 0x32, 0x40, 0xf0, 0x2c, 0x3f, 0x5d, 0xe4, 0xfc, 0x89, 0x11, 0x24, 0xb4, 0x2f, 0x97, 0xad, 0xac, 0x8f, 0x19, 0xab, 0xfa, 0x12, 0xe5, 0xf9, 0x50, 0x4e, 0x50, 0x6f, 0x32, 0x30, 0x88, 0xa6, 0xe5, 0x48, 0x28, 0xa2, 0x1b, 0x9f, 0xcd, 0xe2, 0x43, 0x38},
+		dt2:   fp.Elt{0xa9, 0xcc, 0x53, 0x39, 0x86, 0x02, 0x60, 0x75, 0x34, 0x99, 0x57, 0xbd, 0xfc, 0x5a, 0x8e, 0xce, 0x5e, 0x98, 0x22, 0xd0, 0xa5, 0x24, 0xff, 0x90, 0x28, 0x9f, 0x58, 0xf3, 0x39, 0xe9, 0xba, 0x36, 0x23, 0xfb, 0x7f, 0x41, 0xcc, 0x2b, 0x5a, 0x25, 0x3f, 0x4c, 0x2a, 0xf1, 0x52, 0x6f, 0x2f, 0x07, 0xe3, 0x88, 0x81, 0x77, 0xdd, 0x7c, 0x88, 0x82},
+	},
+	{ /* 7P*/
+		addYX: fp.Elt{0xf7, 0xee, 0x88, 0xfd, 0x3a, 0xbf, 0x7e, 0x28, 0x39, 0x23, 0x79, 0xe6, 0x5c, 0x56, 0xcb, 0xb5, 0x48, 0x6a, 0x80, 0x6d, 0x37, 0x60, 0x6c, 0x10, 0x35, 0x49, 0x4b, 0x46, 0x60, 0xd4, 0x79, 0xd4, 0x53, 0xd3, 0x67, 0x88, 0xd0, 0x41, 0xd5, 0x43, 0x85, 0xc8, 0x71, 0xe3, 0x1c, 0xb6, 0xda, 0x22, 0x64, 0x8f, 0x80, 0xac, 0xad, 0x7d, 0xd5, 0x82},
+		subYX: fp.Elt{0x92, 0x40, 0xc1, 0x83, 0x21, 0x9b, 0xd5, 0x7d, 0x3f, 0x29, 0xb6, 0x26, 0xef, 0x12, 0xb9, 0x27, 0x39, 0x42, 0x37, 0x97, 0x09, 0x9a, 0x08, 0xe1, 0x68, 0xb6, 0x7a, 0x3f, 0x9f, 0x45, 0xf8, 0x37, 0x19, 0x83, 0x97, 0xe6, 0x73, 0x30, 0x32, 0x35, 0xcf, 0xae, 0x5c, 0x12, 0x68, 0xdf, 0x6e, 0x2b, 0xde, 0x83, 0xa0, 0x44, 0x74, 0x2e, 0x4a, 0xe9},
+		dt2:   fp.Elt{0xcb, 0x22, 0x0a, 0xda, 0x6b, 0xc1, 0x8a, 0x29, 0xa1, 0xac, 0x8b, 0x5b, 0x8b, 0x32, 0x20, 0xf2, 0x21, 0xae, 0x0c, 0x43, 0xc4, 0xd7, 0x19, 0x37, 0x3d, 0x79, 0x25, 0x98, 0x6c, 0x9c, 0x22, 0x31, 0x2a, 0x55, 0x9f, 0xda, 0x5e, 0xa8, 0x13, 0xdb, 0x8e, 0x2e, 0x16, 0x39, 0xf4, 0x91, 0x6f, 0xec, 0x71, 0x71, 0xc9, 0x10, 0xf2, 0xa4, 0x8f, 0x11},
+	},
+	{ /* 9P*/
+		addYX: fp.Elt{0x85, 0xdd, 0x37, 0x62, 0x74, 0x8e, 0x33, 0x5b, 0x25, 0x12, 0x1b, 0xe7, 0xdf, 0x47, 0xe5, 0x12, 0xfd, 0x3a, 0x3a, 0xf5, 0x5d, 0x4c, 0xa2, 0x29, 0x3c, 0x5c, 0x2f, 0xee, 0x18, 0x19, 0x0a, 0x2b, 0xef, 0x67, 0x50, 0x7a, 0x0d, 0x29, 0xae, 0x55, 0x82, 0xcd, 0xd6, 0x41, 0x90, 0xb4, 0x13, 0x31, 0x5d, 0x11, 0xb8, 0xaa, 0x12, 0x86, 0x08, 0xac},
+		subYX: fp.Elt{0xcc, 0x37, 0x8d, 0x83, 0x5f, 0xfd, 0xde, 0xd5, 0xf7, 0xf1, 0xae, 0x0a, 0xa7, 0x0b, 0xeb, 0x6d, 0x19, 0x8a, 0xb6, 0x1a, 0x59, 0xd8, 0xff, 0x3c, 0xbc, 0xbc, 0xef, 0x9c, 0xda, 0x7b, 0x75, 0x12, 0xaf, 0x80, 0x8f, 0x2c, 0x3c, 0xaa, 0x0b, 0x17, 0x86, 0x36, 0x78, 0x18, 0xc8, 0x8a, 0xf6, 0xb8, 0x2c, 0x2f, 0x57, 0x2c, 0x62, 0x57, 0xf6, 0x90},
+		dt2:   fp.Elt{0x83, 0xbc, 0xa2, 0x07, 0xa5, 0x38, 0x96, 0xea, 0xfe, 0x11, 0x46, 0x1d, 0x3b, 0xcd, 0x42, 0xc5, 0xee, 0x67, 0x04, 0x72, 0x08, 0xd8, 0xd9, 0x96, 0x07, 0xf7, 0xac, 0xc3, 0x64, 0xf1, 0x98, 0x2c, 0x55, 0xd7, 0x7d, 0xc8, 0x6c, 0xbd, 0x2c, 0xff, 0x15, 0xd6, 0x6e, 0xb8, 0x17, 0x8e, 0xa8, 0x27, 0x66, 0xb1, 0x73, 0x79, 0x96, 0xff, 0x29, 0x10},
+	},
+	{ /* 11P*/
+		addYX: fp.Elt{0x76, 0xcb, 0x9b, 0x0c, 0x5b, 0xfe, 0xe1, 0x2a, 0xdd, 0x6f, 0x6c, 0xdd, 0x6f, 0xb4, 0xc0, 0xc2, 0x1b, 0x4b, 0x38, 0xe8, 0x66, 0x8c, 0x1e, 0x31, 0x63, 0xb9, 0x94, 0xcd, 0xc3, 0x8c, 0x44, 0x25, 0x7b, 0xd5, 0x39, 0x80, 0xfc, 0x01, 0xaa, 0xf7, 0x2a, 0x61, 0x8a, 0x25, 0xd2, 0x5f, 0xc5, 0x66, 0x38, 0xa4, 0x17, 0xcf, 0x3e, 0x11, 0x0f, 0xa3},
+		subYX: fp.Elt{0xe0, 0xb6, 0xd1, 0x9c, 0x71, 0x49, 0x2e, 0x7b, 0xde, 0x00, 0xda, 0x6b, 0xf1, 0xec, 0xe6, 0x7a, 0x15, 0x38, 0x71, 0xe9, 0x7b, 0xdb, 0xf8, 0x98, 0xc0, 0x91, 0x2e, 0x53, 0xee, 0x92, 0x87, 0x25, 0xc9, 0xb0, 0xbb, 0x33, 0x15, 0x46, 0x7f, 0xfd, 0x4f, 0x8b, 0x77, 0x05, 0x96, 0xb6, 0xe2, 0x08, 0xdb, 0x0d, 0x09, 0xee, 0x5b, 0xd1, 0x2a, 0x63},
+		dt2:   fp.Elt{0x8f, 0x7b, 0x57, 0x8c, 0xbf, 0x06, 0x0d, 0x43, 0x21, 0x92, 0x94, 0x2d, 0x6a, 0x38, 0x07, 0x0f, 0xa0, 0xf1, 0xe3, 0xd8, 0x2a, 0xbf, 0x46, 0xc6, 0x9e, 0x1f, 0x8f, 0x2b, 0x46, 0x84, 0x0b, 0x74, 0xed, 0xff, 0xf8, 0xa5, 0x94, 0xae, 0xf1, 0x67, 0xb1, 0x9b, 0xdd, 0x4a, 0xd0, 0xdb, 0xc2, 0xb5, 0x58, 0x49, 0x0c, 0xa9, 0x1d, 0x7d, 0xa9, 0xd3},
+	},
+	{ /* 13P*/
+		addYX: fp.Elt{0x73, 0x84, 0x2e, 0x31, 0x1f, 0xdc, 0xed, 0x9f, 0x74, 0xfa, 0xe0, 0x35, 0xb1, 0x85, 0x6a, 0x8d, 0x86, 0xd0, 0xff, 0xd6, 0x08, 0x43, 0x73, 0x1a, 0xd5, 0xf8, 0x43, 0xd4, 0xb3, 0xe5, 0x3f, 0xa8, 0x84, 0x17, 0x59, 0x65, 0x4e, 0xe6, 0xee, 0x54, 0x9c, 0xda, 0x5e, 0x7e, 0x98, 0x29, 0x6d, 0x73, 0x34, 0x1f, 0x99, 0x80, 0x54, 0x54, 0x81, 0x0b},
+		subYX: fp.Elt{0xb1, 0xe5, 0xbb, 0x80, 0x22, 0x9c, 0x81, 0x6d, 0xaf, 0x27, 0x65, 0x6f, 0x7e, 0x9c, 0xb6, 0x8d, 0x35, 0x5c, 0x2e, 0x20, 0x48, 0x7a, 0x28, 0xf0, 0x97, 0xfe, 0xb7, 0x71, 0xce, 0xd6, 0xad, 0x3a, 0x81, 0xf6, 0x74, 0x5e, 0xf3, 0xfd, 0x1b, 0xd4, 0x1e, 0x7c, 0xc2, 0xb7, 0xc8, 0xa6, 0xc9, 0x89, 0x03, 0x47, 0xec, 0x24, 0xd6, 0x0e, 0xec, 0x9c},
+		dt2:   fp.Elt{0x91, 0x0a, 0x43, 0x34, 0x20, 0xc2, 0x64, 0xf7, 0x4e, 0x48, 0xc8, 0xd2, 0x95, 0x83, 0xd1, 0xa4, 0xfb, 0x4e, 0x41, 0x3b, 0x0d, 0xd5, 0x07, 0xd9, 0xf1, 0x13, 0x16, 0x78, 0x54, 0x57, 0xd0, 0xf1, 0x4f, 0x20, 0xac, 0xcf, 0x9c, 0x3b, 0x33, 0x0b, 0x99, 0x54, 0xc3, 0x7f, 0x3e, 0x57, 0x26, 0x86, 0xd5, 0xa5, 0x2b, 0x8d, 0xe3, 0x19, 0x36, 0xf7},
+	},
+	{ /* 15P*/
+		addYX: fp.Elt{0x23, 0x69, 0x47, 0x14, 0xf9, 0x9a, 0x50, 0xff, 0x64, 0xd1, 0x50, 0x35, 0xc3, 0x11, 0xd3, 0x19, 0xcf, 0x87, 0xda, 0x30, 0x0b, 0x50, 0xda, 0xc0, 0xe0, 0x25, 0x00, 0xe5, 0x68, 0x93, 0x04, 0xc2, 0xaf, 0xbd, 0x2f, 0x36, 0x5f, 0x47, 0x96, 0x10, 0xa8, 0xbd, 0xe4, 0x88, 0xac, 0x80, 0x52, 0x61, 0x73, 0xe9, 0x63, 0xdd, 0x99, 0xad, 0x20, 0x5b},
+		subYX: fp.Elt{0x1b, 0x5e, 0xa2, 0x2a, 0x25, 0x0f, 0x86, 0xc0, 0xb1, 0x2e, 0x0c, 0x13, 0x40, 0x8d, 0xf0, 0xe6, 0x00, 0x55, 0x08, 0xc5, 0x7d, 0xf4, 0xc9, 0x31, 0x25, 0x3a, 0x99, 0x69, 0xdd, 0x67, 0x63, 0x9a, 0xd6, 0x89, 0x2e, 0xa1, 0x19, 0xca, 0x2c, 0xd9, 0x59, 0x5f, 0x5d, 0xc3, 0x6e, 0x62, 0x36, 0x12, 0x59, 0x15, 0xe1, 0xdc, 0xa4, 0xad, 0xc9, 0xd0},
+		dt2:   fp.Elt{0xbc, 0xea, 0xfc, 0xaf, 0x66, 0x23, 0xb7, 0x39, 0x6b, 0x2a, 0x96, 0xa8, 0x54, 0x43, 0xe9, 0xaa, 0x32, 0x40, 0x63, 0x92, 0x5e, 0xdf, 0x35, 0xc2, 0x9f, 0x24, 0x0c, 0xed, 0xfc, 0xde, 0x73, 0x8f, 0xa7, 0xd5, 0xa3, 0x2b, 0x18, 0x1f, 0xb0, 0xf8, 0xeb, 0x55, 0xd9, 0xc3, 0xfd, 0x28, 0x7c, 0x4f, 0xce, 0x0d, 0xf7, 0xae, 0xc2, 0x83, 0xc3, 0x78},
+	},
+	{ /* 17P*/
+		addYX: fp.Elt{0x71, 0xe6, 0x60, 0x93, 0x37, 0xdb, 0x01, 0xa5, 0x4c, 0xba, 0xe8, 0x8e, 0xd5, 0xf9, 0xd3, 0x98, 0xe5, 0xeb, 0xab, 0x3a, 0x15, 0x8b, 0x35, 0x60, 0xbe, 0xe5, 0x9c, 0x2d, 0x10, 0x9b, 0x2e, 0xcf, 0x65, 0x64, 0xea, 0x8f, 0x72, 0xce, 0xf5, 0x18, 0xe5, 0xe2, 0xf0, 0x0e, 0xae, 0x04, 0xec, 0xa0, 0x20, 0x65, 0x63, 0x07, 0xb1, 0x9f, 0x03, 0x97},
+		subYX: fp.Elt{0x9e, 0x41, 0x64, 0x30, 0x95, 0x7f, 0x3a, 0x89, 0x7b, 0x0a, 0x79, 0x59, 0x23, 0x9a, 0x3b, 0xfe, 0xa4, 0x13, 0x08, 0xb2, 0x2e, 0x04, 0x50, 0x10, 0x30, 0xcd, 0x2e, 0xa4, 0x91, 0x71, 0x50, 0x36, 0x4a, 0x02, 0xf4, 0x8d, 0xa3, 0x36, 0x1b, 0xf4, 0x52, 0xba, 0x15, 0x04, 0x8b, 0x80, 0x25, 0xd9, 0xae, 0x67, 0x20, 0xd9, 0x88, 0x8f, 0x97, 0xa6},
+		dt2:   fp.Elt{0xb5, 0xe7, 0x46, 0xbd, 0x55, 0x23, 0xa0, 0x68, 0xc0, 0x12, 0xd9, 0xf1, 0x0a, 0x75, 0xe2, 0xda, 0xf4, 0x6b, 0xca, 0x14, 0xe4, 0x9f, 0x0f, 0xb5, 0x3c, 0xa6, 0xa5, 0xa2, 0x63, 0x94, 0xd1, 0x1c, 0x39, 0x58, 0x57, 0x02, 0x27, 0x98, 0xb6, 0x47, 0xc6, 0x61, 0x4b, 0x5c, 0xab, 0x6f, 0x2d, 0xab, 0xe3, 0xc1, 0x69, 0xf9, 0x12, 0xb0, 0xc8, 0xd5},
+	},
+	{ /* 19P*/
+		addYX: fp.Elt{0x19, 0x7d, 0xd5, 0xac, 0x79, 0xa2, 0x82, 0x9b, 0x28, 0x31, 0x22, 0xc0, 0x73, 0x02, 0x76, 0x17, 0x10, 0x70, 0x79, 0x57, 0xc9, 0x84, 0x62, 0x8e, 0x04, 0x04, 0x61, 0x67, 0x08, 0x48, 0xb4, 0x4b, 0xde, 0x53, 0x8c, 0xff, 0x36, 0x1b, 0x62, 0x86, 0x5d, 0xe1, 0x9b, 0xb1, 0xe5, 0xe8, 0x44, 0x64, 0xa1, 0x68, 0x3f, 0xa8, 0x45, 0x52, 0x91, 0xed},
+		subYX: fp.Elt{0x42, 0x1a, 0x36, 0x1f, 0x90, 0x15, 0x24, 0x8d, 0x24, 0x80, 0xe6, 0xfe, 0x1e, 0xf0, 0xad, 0xaf, 0x6a, 0x93, 0xf0, 0xa6, 0x0d, 0x5d, 0xea, 0xf6, 0x62, 0x96, 0x7a, 0x05, 0x76, 0x85, 0x74, 0x32, 0xc7, 0xc8, 0x64, 0x53, 0x62, 0xe7, 0x54, 0x84, 0xe0, 0x40, 0x66, 0x19, 0x70, 0x40, 0x95, 0x35, 0x68, 0x64, 0x43, 0xcd, 0xba, 0x29, 0x32, 0xa8},
+		dt2:   fp.Elt{0x3e, 0xf6, 0xd6, 0xe4, 0x99, 0xeb, 0x20, 0x66, 0x08, 0x2e, 0x26, 0x64, 0xd7, 0x76, 0xf3, 0xb4, 0xc5, 0xa4, 0x35, 0x92, 0xd2, 0x99, 0x70, 0x5a, 0x1a, 0xe9, 0xe9, 0x3d, 0x3b, 0xe1, 0xcd, 0x0e, 0xee, 0x24, 0x13, 0x03, 0x22, 0xd6, 0xd6, 0x72, 0x08, 0x2b, 0xde, 0xfd, 0x93, 0xed, 0x0c, 0x7f, 0x5e, 0x31, 0x22, 0x4d, 0x80, 0x78, 0xc0, 0x48},
+	},
+	{ /* 21P*/
+		addYX: fp.Elt{0x8f, 0x72, 0xd2, 0x9e, 0xc4, 0xcd, 0x2c, 0xbf, 0xa8, 0xd3, 0x24, 0x62, 0x28, 0xee, 0x39, 0x0a, 0x19, 0x3a, 0x58, 0xff, 0x21, 0x2e, 0x69, 0x6c, 0x6e, 0x18, 0xd0, 0xcd, 0x61, 0xc1, 0x18, 0x02, 0x5a, 0xe9, 0xe3, 0xef, 0x1f, 0x8e, 0x10, 0xe8, 0x90, 0x2b, 0x48, 0xcd, 0xee, 0x38, 0xbd, 0x3a, 0xca, 0xbc, 0x2d, 0xe2, 0x3a, 0x03, 0x71, 0x02},
+		subYX: fp.Elt{0xf8, 0xa4, 0x32, 0x26, 0x66, 0xaf, 0x3b, 0x53, 0xe7, 0xb0, 0x91, 0x92, 0xf5, 0x3c, 0x74, 0xce, 0xf2, 0xdd, 0x68, 0xa9, 0xf4, 0xcd, 0x5f, 0x60, 0xab, 0x71, 0xdf, 0xcd, 0x5c, 0x5d, 0x51, 0x72, 0x3a, 0x96, 0xea, 0xd6, 0xde, 0x54, 0x8e, 0x55, 0x4c, 0x08, 0x4c, 0x60, 0xdd, 0x34, 0xa9, 0x6f, 0xf3, 0x04, 0x02, 0xa8, 0xa6, 0x4e, 0x4d, 0x62},
+		dt2:   fp.Elt{0x76, 0x4a, 0xae, 0x38, 0x62, 0x69, 0x72, 0xdc, 0xe8, 0x43, 0xbe, 0x1d, 0x61, 0xde, 0x31, 0xc3, 0x42, 0x8f, 0x33, 0x9d, 0xca, 0xc7, 0x9c, 0xec, 0x6a, 0xe2, 0xaa, 0x01, 0x49, 0x78, 0x8d, 0x72, 0x4f, 0x38, 0xea, 0x52, 0xc2, 0xd3, 0xc9, 0x39, 0x71, 0xba, 0xb9, 0x09, 0x9b, 0xa3, 0x7f, 0x45, 0x43, 0x65, 0x36, 0x29, 0xca, 0xe7, 0x5c, 0x5f},
+	},
+	{ /* 23P*/
+		addYX: fp.Elt{0x89, 0x42, 0x35, 0x48, 0x6d, 0x74, 0xe5, 0x1f, 0xc3, 0xdd, 0x28, 0x5b, 0x84, 0x41, 0x33, 0x9f, 0x42, 0xf3, 0x1d, 0x5d, 0x15, 0x6d, 0x76, 0x33, 0x36, 0xaf, 0xe9, 0xdd, 0xfa, 0x63, 0x4f, 0x7a, 0x9c, 0xeb, 0x1c, 0x4f, 0x34, 0x65, 0x07, 0x54, 0xbb, 0x4c, 0x8b, 0x62, 0x9d, 0xd0, 0x06, 0x99, 0xb3, 0xe9, 0xda, 0x85, 0x19, 0xb0, 0x3d, 0x3c},
+		subYX: fp.Elt{0xbb, 0x99, 0xf6, 0xbf, 0xaf, 0x2c, 0x22, 0x0d, 0x7a, 0xaa, 0x98, 0x6f, 0x01, 0x82, 0x99, 0xcf, 0x88, 0xbd, 0x0e, 0x3a, 0x89, 0xe0, 0x9c, 0x8c, 0x17, 0x20, 0xc4, 0xe0, 0xcf, 0x43, 0x7a, 0xef, 0x0d, 0x9f, 0x87, 0xd4, 0xfb, 0xf2, 0x96, 0xb8, 0x03, 0xe8, 0xcb, 0x5c, 0xec, 0x65, 0x5f, 0x49, 0xa4, 0x7c, 0x85, 0xb4, 0xf6, 0xc7, 0xdb, 0xa3},
+		dt2:   fp.Elt{0x11, 0xf3, 0x32, 0xa3, 0xa7, 0xb2, 0x7d, 0x51, 0x82, 0x44, 0xeb, 0xa2, 0x7d, 0x72, 0xcb, 0xc6, 0xf6, 0xc7, 0xb2, 0x38, 0x0e, 0x0f, 0x4f, 0x29, 0x00, 0xe4, 0x5b, 0x94, 0x46, 0x86, 0x66, 0xa1, 0x83, 0xb3, 0xeb, 0x15, 0xb6, 0x31, 0x50, 0x28, 0xeb, 0xed, 0x0d, 0x32, 0x39, 0xe9, 0x23, 0x81, 0x99, 0x3e, 0xff, 0x17, 0x4c, 0x11, 0x43, 0xd1},
+	},
+	{ /* 25P*/
+		addYX: fp.Elt{0xce, 0xe7, 0xf8, 0x94, 0x8f, 0x96, 0xf8, 0x96, 0xe6, 0x72, 0x20, 0x44, 0x2c, 0xa7, 0xfc, 0xba, 0xc8, 0xe1, 0xbb, 0xc9, 0x16, 0x85, 0xcd, 0x0b, 0xe5, 0xb5, 0x5a, 0x7f, 0x51, 0x43, 0x63, 0x8b, 0x23, 0x8e, 0x1d, 0x31, 0xff, 0x46, 0x02, 0x66, 0xcc, 0x9e, 0x4d, 0xa2, 0xca, 0xe2, 0xc7, 0xfd, 0x22, 0xb1, 0xdb, 0xdf, 0x6f, 0xe6, 0xa5, 0x82},
+		subYX: fp.Elt{0xd0, 0xf5, 0x65, 0x40, 0xec, 0x8e, 0x65, 0x42, 0x78, 0xc1, 0x65, 0xe4, 0x10, 0xc8, 0x0b, 0x1b, 0xdd, 0x96, 0x68, 0xce, 0xee, 0x45, 0x55, 0xd8, 0x6e, 0xd3, 0xe6, 0x77, 0x19, 0xae, 0xc2, 0x8d, 0x8d, 0x3e, 0x14, 0x3f, 0x6d, 0x00, 0x2f, 0x9b, 0xd1, 0x26, 0x60, 0x28, 0x0f, 0x3a, 0x47, 0xb3, 0xe6, 0x68, 0x28, 0x24, 0x25, 0xca, 0xc8, 0x06},
+		dt2:   fp.Elt{0x54, 0xbb, 0x60, 0x92, 0xdb, 0x8f, 0x0f, 0x38, 0xe0, 0xe6, 0xe4, 0xc9, 0xcc, 0x14, 0x62, 0x01, 0xc4, 0x2b, 0x0f, 0xcf, 0xed, 0x7d, 0x8e, 0xa4, 0xd9, 0x73, 0x0b, 0xba, 0x0c, 0xaf, 0x0c, 0xf9, 0xe2, 0xeb, 0x29, 0x2a, 0x53, 0xdf, 0x2c, 0x5a, 0xfa, 0x8f, 0xc1, 0x01, 0xd7, 0xb1, 0x45, 0x73, 0x92, 0x32, 0x83, 0x85, 0x12, 0x74, 0x89, 0x44},
+	},
+	{ /* 27P*/
+		addYX: fp.Elt{0x0b, 0x73, 0x3c, 0xc2, 0xb1, 0x2e, 0xe1, 0xa7, 0xf5, 0xc9, 0x7a, 0xfb, 0x3d, 0x2d, 0xac, 0x59, 0xdb, 0xfa, 0x36, 0x11, 0xd1, 0x13, 0x04, 0x51, 0x1d, 0xab, 0x9b, 0x6b, 0x93, 0xfe, 0xda, 0xb0, 0x8e, 0xb4, 0x79, 0x11, 0x21, 0x0f, 0x65, 0xb9, 0xbb, 0x79, 0x96, 0x2a, 0xfd, 0x30, 0xe0, 0xb4, 0x2d, 0x9a, 0x55, 0x25, 0x5d, 0xd4, 0xad, 0x2a},
+		subYX: fp.Elt{0x9e, 0xc5, 0x04, 0xfe, 0xec, 0x3c, 0x64, 0x1c, 0xed, 0x95, 0xed, 0xae, 0xaf, 0x5c, 0x6e, 0x08, 0x9e, 0x02, 0x29, 0x59, 0x7e, 0x5f, 0xc4, 0x9a, 0xd5, 0x32, 0x72, 0x86, 0xe1, 0x4e, 0x3c, 0xce, 0x99, 0x69, 0x3b, 0xc4, 0xdd, 0x4d, 0xb7, 0xbb, 0xda, 0x3b, 0x1a, 0x99, 0xaa, 0x62, 0x15, 0xc1, 0xf0, 0xb6, 0x6c, 0xec, 0x56, 0xc1, 0xff, 0x0c},
+		dt2:   fp.Elt{0x2f, 0xf1, 0x3f, 0x7a, 0x2d, 0x56, 0x19, 0x7f, 0xea, 0xbe, 0x59, 0x2e, 0x13, 0x67, 0x81, 0xfb, 0xdb, 0xc8, 0xa3, 0x1d, 0xd5, 0xe9, 0x13, 0x8b, 0x29, 0xdf, 0xcf, 0x9f, 0xe7, 0xd9, 0x0b, 0x70, 0xd3, 0x15, 0x57, 0x4a, 0xe9, 0x50, 0x12, 0x1b, 0x81, 0x4b, 0x98, 0x98, 0xa8, 0x31, 0x1d, 0x27, 0x47, 0x38, 0xed, 0x57, 0x99, 0x26, 0xb2, 0xee},
+	},
+	{ /* 29P*/
+		addYX: fp.Elt{0x1c, 0xb2, 0xb2, 0x67, 0x3b, 0x8b, 0x3d, 0x5a, 0x30, 0x7e, 0x38, 0x7e, 0x3c, 0x3d, 0x28, 0x56, 0x59, 0xd8, 0x87, 0x53, 0x8b, 0xe6, 0x6c, 0x5d, 0xe5, 0x0a, 0x33, 0x10, 0xce, 0xa2, 0x17, 0x0d, 0xe8, 0x76, 0xee, 0x68, 0xa8, 0x72, 0x54, 0xbd, 0xa6, 0x24, 0x94, 0x6e, 0x77, 0xc7, 0x53, 0xb7, 0x89, 0x1c, 0x7a, 0xe9, 0x78, 0x9a, 0x74, 0x5f},
+		subYX: fp.Elt{0x76, 0x96, 0x1c, 0xcf, 0x08, 0x55, 0xd8, 0x1e, 0x0d, 0xa3, 0x59, 0x95, 0x32, 0xf4, 0xc2, 0x8e, 0x84, 0x5e, 0x4b, 0x04, 0xda, 0x71, 0xc9, 0x78, 0x52, 0xde, 0x14, 0xb4, 0x31, 0xf4, 0xd4, 0xb8, 0x58, 0xc5, 0x20, 0xe8, 0xdd, 0x15, 0xb5, 0xee, 0xea, 0x61, 0xe0, 0xf5, 0xd6, 0xae, 0x55, 0x59, 0x05, 0x3e, 0xaf, 0x74, 0xac, 0x1f, 0x17, 0x82},
+		dt2:   fp.Elt{0x59, 0x24, 0xcd, 0xfc, 0x11, 0x7e, 0x85, 0x18, 0x3d, 0x69, 0xf7, 0x71, 0x31, 0x66, 0x98, 0x42, 0x95, 0x00, 0x8c, 0xb2, 0xae, 0x39, 0x7e, 0x85, 0xd6, 0xb0, 0x02, 0xec, 0xce, 0xfc, 0x25, 0xb2, 0xe3, 0x99, 0x8e, 0x5b, 0x61, 0x96, 0x2e, 0x6d, 0x96, 0x57, 0x71, 0xa5, 0x93, 0x41, 0x0e, 0x6f, 0xfd, 0x0a, 0xbf, 0xa9, 0xf7, 0x56, 0xa9, 0x3e},
+	},
+	{ /* 31P*/
+		addYX: fp.Elt{0xa2, 0x2e, 0x0c, 0x17, 0x4d, 0xcc, 0x85, 0x2c, 0x18, 0xa0, 0xd2, 0x08, 0xba, 0x11, 0xfa, 0x47, 0x71, 0x86, 0xaf, 0x36, 0x6a, 0xd7, 0xfe, 0xb9, 0xb0, 0x2f, 0x89, 0x98, 0x49, 0x69, 0xf8, 0x6a, 0xad, 0x27, 0x5e, 0x0a, 0x22, 0x60, 0x5e, 0x5d, 0xca, 0x06, 0x51, 0x27, 0x99, 0x29, 0x85, 0x68, 0x98, 0xe1, 0xc4, 0x21, 0x50, 0xa0, 0xe9, 0xc1},
+		subYX: fp.Elt{0x4d, 0x70, 0xee, 0x91, 0x92, 0x3f, 0xb7, 0xd3, 0x1d, 0xdb, 0x8d, 0x6e, 0x16, 0xf5, 0x65, 0x7d, 0x5f, 0xb5, 0x6c, 0x59, 0x26, 0x70, 0x4b, 0xf2, 0xfc, 0xe7, 0xdf, 0x86, 0xfe, 0xa5, 0xa7, 0xa6, 0x5d, 0xfb, 0x06, 0xe9, 0xf9, 0xcc, 0xc0, 0x37, 0xcc, 0xd8, 0x09, 0x04, 0xd2, 0xa5, 0x1d, 0xd7, 0xb7, 0xce, 0x92, 0xac, 0x3c, 0xad, 0xfb, 0xae},
+		dt2:   fp.Elt{0x17, 0xa3, 0x9a, 0xc7, 0x86, 0x2a, 0x51, 0xf7, 0x96, 0x79, 0x49, 0x22, 0x2e, 0x5a, 0x01, 0x5c, 0xb5, 0x95, 0xd4, 0xe8, 0xcb, 0x00, 0xca, 0x2d, 0x55, 0xb6, 0x34, 0x36, 0x0b, 0x65, 0x46, 0xf0, 0x49, 0xfc, 0x87, 0x86, 0xe5, 0xc3, 0x15, 0xdb, 0x32, 0xcd, 0xf2, 0xd3, 0x82, 0x4c, 0xe6, 0x61, 0x8a, 0xaf, 0xd4, 0x9e, 0x0f, 0x5a, 0xf2, 0x81},
+	},
+	{ /* 33P*/
+		addYX: fp.Elt{0x88, 0x10, 0xc0, 0xcb, 0xf5, 0x77, 0xae, 0xa5, 0xbe, 0xf6, 0xcd, 0x2e, 0x8b, 0x7e, 0xbd, 0x79, 0x62, 0x4a, 0xeb, 0x69, 0xc3, 0x28, 0xaa, 0x72, 0x87, 0xa9, 0x25, 0x87, 0x46, 0xea, 0x0e, 0x62, 0xa3, 0x6a, 0x1a, 0xe2, 0xba, 0xdc, 0x81, 0x10, 0x33, 0x01, 0xf6, 0x16, 0x89, 0x80, 0xc6, 0xcd, 0xdb, 0xdc, 0xba, 0x0e, 0x09, 0x4a, 0x35, 0x4a},
+		subYX: fp.Elt{0x86, 0xb2, 0x2b, 0xd0, 0xb8, 0x4a, 0x6d, 0x66, 0x7b, 0x32, 0xdf, 0x3b, 0x1a, 0x19, 0x1f, 0x63, 0xee, 0x1f, 0x3d, 0x1c, 0x5c, 0x14, 0x60, 0x5b, 0x72, 0x49, 0x07, 0xb1, 0x0d, 0x72, 0xc6, 0x35, 0xf0, 0xbc, 0x5e, 0xda, 0x80, 0x6b, 0x64, 0x5b, 0xe5, 0x34, 0x54, 0x39, 0xdd, 0xe6, 0x3c, 0xcb, 0xe5, 0x29, 0x32, 0x06, 0xc6, 0xb1, 0x96, 0x34},
+		dt2:   fp.Elt{0x85, 0x86, 0xf5, 0x84, 0x86, 0xe6, 0x77, 0x8a, 0x71, 0x85, 0x0c, 0x4f, 0x81, 0x5b, 0x29, 0x06, 0xb5, 0x2e, 0x26, 0x71, 0x07, 0x78, 0x07, 0xae, 0xbc, 0x95, 0x46, 0xc3, 0x65, 0xac, 0xe3, 0x76, 0x51, 0x7d, 0xd4, 0x85, 0x31, 0xe3, 0x43, 0xf3, 0x1b, 0x7c, 0xf7, 0x6b, 0x2c, 0xf8, 0x1c, 0xbb, 0x8d, 0xca, 0xab, 0x4b, 0xba, 0x7f, 0xa4, 0xe2},
+	},
+	{ /* 35P*/
+		addYX: fp.Elt{0x1a, 0xee, 0xe7, 0xa4, 0x8a, 0x9d, 0x53, 0x80, 0xc6, 0xb8, 0x4e, 0xdc, 0x89, 0xe0, 0xc4, 0x2b, 0x60, 0x52, 0x6f, 0xec, 0x81, 0xd2, 0x55, 0x6b, 0x1b, 0x6f, 0x17, 0x67, 0x8e, 0x42, 0x26, 0x4c, 0x65, 0x23, 0x29, 0xc6, 0x7b, 0xcd, 0x9f, 0xad, 0x4b, 0x42, 0xd3, 0x0c, 0x75, 0xc3, 0x8a, 0xf5, 0xbe, 0x9e, 0x55, 0xf7, 0x47, 0x5d, 0xbd, 0x3a},
+		subYX: fp.Elt{0x0d, 0xa8, 0x3b, 0xf9, 0xc7, 0x7e, 0xc6, 0x86, 0x94, 0xc0, 0x01, 0xff, 0x27, 0xce, 0x43, 0xac, 0xe5, 0xe1, 0xd2, 0x8d, 0xc1, 0x22, 0x31, 0xbe, 0xe1, 0xaf, 0xf9, 0x4a, 0x78, 0xa1, 0x0c, 0xaa, 0xd4, 0x80, 0xe4, 0x09, 0x8d, 0xfb, 0x1d, 0x52, 0xc8, 0x60, 0x2d, 0xf2, 0xa2, 0x89, 0x02, 0x56, 0x3d, 0x56, 0x27, 0x85, 0xc7, 0xf0, 0x2b, 0x9a},
+		dt2:   fp.Elt{0x62, 0x7c, 0xc7, 0x6b, 0x2c, 0x9d, 0x0a, 0x7c, 0xe5, 0x50, 0x3c, 0xe6, 0x87, 0x1c, 0x82, 0x30, 0x67, 0x3c, 0x39, 0xb6, 0xa0, 0x31, 0xfb, 0x03, 0x7b, 0xa1, 0x58, 0xdf, 0x12, 0x76, 0x5d, 0x5d, 0x0a, 0x8f, 0x9b, 0x37, 0x32, 0xc3, 0x60, 0x33, 0xea, 0x9f, 0x0a, 0x99, 0xfa, 0x20, 0xd0, 0x33, 0x21, 0xc3, 0x94, 0xd4, 0x86, 0x49, 0x7c, 0x4e},
+	},
+	{ /* 37P*/
+		addYX: fp.Elt{0xc7, 0x0c, 0x71, 0xfe, 0x55, 0xd1, 0x95, 0x8f, 0x43, 0xbb, 0x6b, 0x74, 0x30, 0xbd, 0xe8, 0x6f, 0x1c, 0x1b, 0x06, 0x62, 0xf5, 0xfc, 0x65, 0xa0, 0xeb, 0x81, 0x12, 0xc9, 0x64, 0x66, 0x61, 0xde, 0xf3, 0x6d, 0xd4, 0xae, 0x8e, 0xb1, 0x72, 0xe0, 0xcd, 0x37, 0x01, 0x28, 0x52, 0xd7, 0x39, 0x46, 0x0c, 0x55, 0xcf, 0x47, 0x70, 0xef, 0xa1, 0x17},
+		subYX: fp.Elt{0x8d, 0x58, 0xde, 0x83, 0x88, 0x16, 0x0e, 0x12, 0x42, 0x03, 0x50, 0x60, 0x4b, 0xdf, 0xbf, 0x95, 0xcc, 0x7d, 0x18, 0x17, 0x7e, 0x31, 0x5d, 0x8a, 0x66, 0xc1, 0xcf, 0x14, 0xea, 0xf4, 0xf4, 0xe5, 0x63, 0x2d, 0x32, 0x86, 0x9b, 0xed, 0x1f, 0x4f, 0x03, 0xaf, 0x33, 0x92, 0xcb, 0xaf, 0x9c, 0x05, 0x0d, 0x47, 0x1b, 0x42, 0xba, 0x13, 0x22, 0x98},
+		dt2:   fp.Elt{0xb5, 0x48, 0xeb, 0x7d, 0x3d, 0x10, 0x9f, 0x59, 0xde, 0xf8, 0x1c, 0x4f, 0x7d, 0x9d, 0x40, 0x4d, 0x9e, 0x13, 0x24, 0xb5, 0x21, 0x09, 0xb7, 0xee, 0x98, 0x5c, 0x56, 0xbc, 0x5e, 0x2b, 0x78, 0x38, 0x06, 0xac, 0xe3, 0xe0, 0xfa, 0x2e, 0xde, 0x4f, 0xd2, 0xb3, 0xfb, 0x2d, 0x71, 0x84, 0xd1, 0x9d, 0x12, 0x5b, 0x35, 0xc8, 0x03, 0x68, 0x67, 0xc7},
+	},
+	{ /* 39P*/
+		addYX: fp.Elt{0xb6, 0x65, 0xfb, 0xa7, 0x06, 0x35, 0xbb, 0xe0, 0x31, 0x8d, 0x91, 0x40, 0x98, 0xab, 0x30, 0xe4, 0xca, 0x12, 0x59, 0x89, 0xed, 0x65, 0x5d, 0x7f, 0xae, 0x69, 0xa0, 0xa4, 0xfa, 0x78, 0xb4, 0xf7, 0xed, 0xae, 0x86, 0x78, 0x79, 0x64, 0x24, 0xa6, 0xd4, 0xe1, 0xf6, 0xd3, 0xa0, 0x89, 0xba, 0x20, 0xf4, 0x54, 0x0d, 0x8f, 0xdb, 0x1a, 0x79, 0xdb},
+		subYX: fp.Elt{0xe1, 0x82, 0x0c, 0x4d, 0xde, 0x9f, 0x40, 0xf0, 0xc1, 0xbd, 0x8b, 0xd3, 0x24, 0x03, 0xcd, 0xf2, 0x92, 0x7d, 0xe2, 0x68, 0x7f, 0xf1, 0xbe, 0x69, 0xde, 0x34, 0x67, 0x4c, 0x85, 0x3b, 0xec, 0x98, 0xcc, 0x4d, 0x3e, 0xc0, 0x96, 0x27, 0xe6, 0x75, 0xfc, 0xdf, 0x37, 0xc0, 0x1e, 0x27, 0xe0, 0xf6, 0xc2, 0xbd, 0xbc, 0x3d, 0x9b, 0x39, 0xdc, 0xe2},
+		dt2:   fp.Elt{0xd8, 0x29, 0xa7, 0x39, 0xe3, 0x9f, 0x2f, 0x0e, 0x4b, 0x24, 0x21, 0x70, 0xef, 0xfd, 0x91, 0xea, 0xbf, 0xe1, 0x72, 0x90, 0xcc, 0xc9, 0x84, 0x0e, 0xad, 0xd5, 0xe6, 0xbb, 0xc5, 0x99, 0x7f, 0xa4, 0xf0, 0x2e, 0xcc, 0x95, 0x64, 0x27, 0x19, 0xd8, 0x4c, 0x27, 0x0d, 0xff, 0xb6, 0x29, 0xe2, 0x6c, 0xfa, 0xbb, 0x4d, 0x9c, 0xbb, 0xaf, 0xa5, 0xec},
+	},
+	{ /* 41P*/
+		addYX: fp.Elt{0xd6, 0x33, 0x3f, 0x9f, 0xcf, 0xfd, 0x4c, 0xd1, 0xfe, 0xe5, 0xeb, 0x64, 0x27, 0xae, 0x7a, 0xa2, 0x82, 0x50, 0x6d, 0xaa, 0xe3, 0x5d, 0xe2, 0x48, 0x60, 0xb3, 0x76, 0x04, 0xd9, 0x19, 0xa7, 0xa1, 0x73, 0x8d, 0x38, 0xa9, 0xaf, 0x45, 0xb5, 0xb2, 0x62, 0x9b, 0xf1, 0x35, 0x7b, 0x84, 0x66, 0xeb, 0x06, 0xef, 0xf1, 0xb2, 0x2d, 0x6a, 0x61, 0x15},
+		subYX: fp.Elt{0x86, 0x50, 0x42, 0xf7, 0xda, 0x59, 0xb2, 0xcf, 0x0d, 0x3d, 0xee, 0x8e, 0x53, 0x5d, 0xf7, 0x9e, 0x6a, 0x26, 0x2d, 0xc7, 0x8c, 0x8e, 0x18, 0x50, 0x6d, 0xb7, 0x51, 0x4c, 0xa7, 0x52, 0x6e, 0x0e, 0x0a, 0x16, 0x74, 0xb2, 0x81, 0x8b, 0x56, 0x27, 0x22, 0x84, 0xf4, 0x56, 0xc5, 0x06, 0xe1, 0x8b, 0xca, 0x2d, 0xdb, 0x9a, 0xf6, 0x10, 0x9c, 0x51},
+		dt2:   fp.Elt{0x1f, 0x16, 0xa2, 0x78, 0x96, 0x1b, 0x85, 0x9c, 0x76, 0x49, 0xd4, 0x0f, 0xac, 0xb0, 0xf4, 0xd0, 0x06, 0x2c, 0x7e, 0x6d, 0x6e, 0x8e, 0xc7, 0x9f, 0x18, 0xad, 0xfc, 0x88, 0x0c, 0x0c, 0x09, 0x05, 0x05, 0xa0, 0x79, 0x72, 0x32, 0x72, 0x87, 0x0f, 0x49, 0x87, 0x0c, 0xb4, 0x12, 0xc2, 0x09, 0xf8, 0x9f, 0x30, 0x72, 0xa9, 0x47, 0x13, 0x93, 0x49},
+	},
+	{ /* 43P*/
+		addYX: fp.Elt{0xcc, 0xb1, 0x4c, 0xd3, 0xc0, 0x9e, 0x9e, 0x4d, 0x6d, 0x28, 0x0b, 0xa5, 0x94, 0xa7, 0x2e, 0xc2, 0xc7, 0xaf, 0x29, 0x73, 0xc9, 0x68, 0xea, 0x0f, 0x34, 0x37, 0x8d, 0x96, 0x8f, 0x3a, 0x3d, 0x73, 0x1e, 0x6d, 0x9f, 0xcf, 0x8d, 0x83, 0xb5, 0x71, 0xb9, 0xe1, 0x4b, 0x67, 0x71, 0xea, 0xcf, 0x56, 0xe5, 0xeb, 0x72, 0x15, 0x2f, 0x9e, 0xa8, 0xaa},
+		subYX: fp.Elt{0xf4, 0x3e, 0x85, 0x1c, 0x1a, 0xef, 0x50, 0xd1, 0xb4, 0x20, 0xb2, 0x60, 0x05, 0x98, 0xfe, 0x47, 0x3b, 0xc1, 0x76, 0xca, 0x2c, 0x4e, 0x5a, 0x42, 0xa3, 0xf7, 0x20, 0xaa, 0x57, 0x39, 0xee, 0x34, 0x1f, 0xe1, 0x68, 0xd3, 0x7e, 0x06, 0xc4, 0x6c, 0xc7, 0x76, 0x2b, 0xe4, 0x1c, 0x48, 0x44, 0xe6, 0xe5, 0x44, 0x24, 0x8d, 0xb3, 0xb6, 0x88, 0x32},
+		dt2:   fp.Elt{0x18, 0xa7, 0xba, 0xd0, 0x44, 0x6f, 0x33, 0x31, 0x00, 0xf8, 0xf6, 0x12, 0xe3, 0xc5, 0xc7, 0xb5, 0x91, 0x9c, 0x91, 0xb5, 0x75, 0x18, 0x18, 0x8a, 0xab, 0xed, 0x24, 0x11, 0x2e, 0xce, 0x5a, 0x0f, 0x94, 0x5f, 0x2e, 0xca, 0xd3, 0x80, 0xea, 0xe5, 0x34, 0x96, 0x67, 0x8b, 0x6a, 0x26, 0x5e, 0xc8, 0x9d, 0x2c, 0x5e, 0x6c, 0xa2, 0x0c, 0xbf, 0xf0},
+	},
+	{ /* 45P*/
+		addYX: fp.Elt{0xb3, 0xbf, 0xa3, 0x85, 0xee, 0xf6, 0x58, 0x02, 0x78, 0xc4, 0x30, 0xd6, 0x57, 0x59, 0x8c, 0x88, 0x08, 0x7c, 0xbc, 0xbe, 0x0a, 0x74, 0xa9, 0xde, 0x69, 0xe7, 0x41, 0xd8, 0xbf, 0x66, 0x8d, 0x3d, 0x28, 0x00, 0x8c, 0x47, 0x65, 0x34, 0xfe, 0x86, 0x9e, 0x6a, 0xf2, 0x41, 0x6a, 0x94, 0xc4, 0x88, 0x75, 0x23, 0x0d, 0x52, 0x69, 0xee, 0x07, 0x89},
+		subYX: fp.Elt{0x22, 0x3c, 0xa1, 0x70, 0x58, 0x97, 0x93, 0xbe, 0x59, 0xa8, 0x0b, 0x8a, 0x46, 0x2a, 0x38, 0x1e, 0x08, 0x6b, 0x61, 0x9f, 0xf2, 0x4a, 0x8b, 0x80, 0x68, 0x6e, 0xc8, 0x92, 0x60, 0xf3, 0xc9, 0x89, 0xb2, 0x6d, 0x63, 0xb0, 0xeb, 0x83, 0x15, 0x63, 0x0e, 0x64, 0xbb, 0xb8, 0xfe, 0xb4, 0x81, 0x90, 0x01, 0x28, 0x10, 0xb9, 0x74, 0x6e, 0xde, 0xa4},
+		dt2:   fp.Elt{0x1a, 0x23, 0x45, 0xa8, 0x6f, 0x4e, 0xa7, 0x4a, 0x0c, 0xeb, 0xb0, 0x43, 0xf9, 0xef, 0x99, 0x60, 0x5b, 0xdb, 0x66, 0xc0, 0x86, 0x71, 0x43, 0xb1, 0x22, 0x7b, 0x1c, 0xe7, 0x8d, 0x09, 0x1d, 0x83, 0x76, 0x9c, 0xd3, 0x5a, 0xdd, 0x42, 0xd9, 0x2f, 0x2d, 0xba, 0x7a, 0xc2, 0xd9, 0x6b, 0xd4, 0x7a, 0xf1, 0xd5, 0x5f, 0x6b, 0x85, 0xbf, 0x0b, 0xf1},
+	},
+	{ /* 47P*/
+		addYX: fp.Elt{0xb2, 0x83, 0xfa, 0x1f, 0xd2, 0xce, 0xb6, 0xf2, 0x2d, 0xea, 0x1b, 0xe5, 0x29, 0xa5, 0x72, 0xf9, 0x25, 0x48, 0x4e, 0xf2, 0x50, 0x1b, 0x39, 0xda, 0x34, 0xc5, 0x16, 0x13, 0xb4, 0x0c, 0xa1, 0x00, 0x79, 0x7a, 0xf5, 0x8b, 0xf3, 0x70, 0x14, 0xb6, 0xfc, 0x9a, 0x47, 0x68, 0x1e, 0x42, 0x70, 0x64, 0x2a, 0x84, 0x3e, 0x3d, 0x20, 0x58, 0xf9, 0x6a},
+		subYX: fp.Elt{0xd9, 0xee, 0xc0, 0xc4, 0xf5, 0xc2, 0x86, 0xaf, 0x45, 0xd2, 0xd2, 0x87, 0x1b, 0x64, 0xd5, 0xe0, 0x8c, 0x44, 0x00, 0x4f, 0x43, 0x89, 0x04, 0x48, 0x4a, 0x0b, 0xca, 0x94, 0x06, 0x2f, 0x23, 0x5b, 0x6c, 0x8d, 0x44, 0x66, 0x53, 0xf5, 0x5a, 0x20, 0x72, 0x28, 0x58, 0x84, 0xcc, 0x73, 0x22, 0x5e, 0xd1, 0x0b, 0x56, 0x5e, 0x6a, 0xa3, 0x11, 0x91},
+		dt2:   fp.Elt{0x6e, 0x9f, 0x88, 0xa8, 0x68, 0x2f, 0x12, 0x37, 0x88, 0xfc, 0x92, 0x8f, 0x24, 0xeb, 0x5b, 0x2a, 0x2a, 0xd0, 0x14, 0x40, 0x4c, 0xa9, 0xa4, 0x03, 0x0c, 0x45, 0x48, 0x13, 0xe8, 0xa6, 0x37, 0xab, 0xc0, 0x06, 0x38, 0x6c, 0x96, 0x73, 0x40, 0x6c, 0xc6, 0xea, 0x56, 0xc6, 0xe9, 0x1a, 0x69, 0xeb, 0x7a, 0xd1, 0x33, 0x69, 0x58, 0x2b, 0xea, 0x2f},
+	},
+	{ /* 49P*/
+		addYX: fp.Elt{0x58, 0xa8, 0x05, 0x41, 0x00, 0x9d, 0xaa, 0xd9, 0x98, 0xcf, 0xb9, 0x41, 0xb5, 0x4a, 0x8d, 0xe2, 0xe7, 0xc0, 0x72, 0xef, 0xc8, 0x28, 0x6b, 0x68, 0x9d, 0xc9, 0xdf, 0x05, 0x8b, 0xd0, 0x04, 0x74, 0x79, 0x45, 0x52, 0x05, 0xa3, 0x6e, 0x35, 0x3a, 0xe3, 0xef, 0xb2, 0xdc, 0x08, 0x6f, 0x4e, 0x76, 0x85, 0x67, 0xba, 0x23, 0x8f, 0xdd, 0xaf, 0x09},
+		subYX: fp.Elt{0xb4, 0x38, 0xc8, 0xff, 0x4f, 0x65, 0x2a, 0x7e, 0xad, 0xb1, 0xc6, 0xb9, 0x3d, 0xd6, 0xf7, 0x14, 0xcf, 0xf6, 0x98, 0x75, 0xbb, 0x47, 0x83, 0x90, 0xe7, 0xe1, 0xf6, 0x14, 0x99, 0x7e, 0xfa, 0xe4, 0x77, 0x24, 0xe3, 0xe7, 0xf0, 0x1e, 0xdb, 0x27, 0x4e, 0x16, 0x04, 0xf2, 0x08, 0x52, 0xfc, 0xec, 0x55, 0xdb, 0x2e, 0x67, 0xe1, 0x94, 0x32, 0x89},
+		dt2:   fp.Elt{0x00, 0xad, 0x03, 0x35, 0x1a, 0xb1, 0x88, 0xf0, 0xc9, 0x11, 0xe4, 0x12, 0x52, 0x61, 0xfd, 0x8a, 0x1b, 0x6a, 0x0a, 0x4c, 0x42, 0x46, 0x22, 0x0e, 0xa5, 0xf9, 0xe2, 0x50, 0xf2, 0xb2, 0x1f, 0x20, 0x78, 0x10, 0xf6, 0xbf, 0x7f, 0x0c, 0x9c, 0xad, 0x40, 0x8b, 0x82, 0xd4, 0xba, 0x69, 0x09, 0xac, 0x4b, 0x6d, 0xc4, 0x49, 0x17, 0x81, 0x57, 0x3b},
+	},
+	{ /* 51P*/
+		addYX: fp.Elt{0x0d, 0xfe, 0xb4, 0x35, 0x11, 0xbd, 0x1d, 0x6b, 0xc2, 0xc5, 0x3b, 0xd2, 0x23, 0x2c, 0x72, 0xe3, 0x48, 0xb1, 0x48, 0x73, 0xfb, 0xa3, 0x21, 0x6e, 0xc0, 0x09, 0x69, 0xac, 0xe1, 0x60, 0xbc, 0x24, 0x03, 0x99, 0x63, 0x0a, 0x00, 0xf0, 0x75, 0xf6, 0x92, 0xc5, 0xd6, 0xdb, 0x51, 0xd4, 0x7d, 0xe6, 0xf4, 0x11, 0x79, 0xd7, 0xc3, 0xaf, 0x48, 0xd0},
+		subYX: fp.Elt{0xf4, 0x4f, 0xaf, 0x31, 0xe3, 0x10, 0x89, 0x95, 0xf0, 0x8a, 0xf6, 0x31, 0x9f, 0x48, 0x02, 0xba, 0x42, 0x2b, 0x3c, 0x22, 0x8b, 0xcc, 0x12, 0x98, 0x6e, 0x7a, 0x64, 0x3a, 0xc4, 0xca, 0x32, 0x2a, 0x72, 0xf8, 0x2c, 0xcf, 0x78, 0x5e, 0x7a, 0x75, 0x6e, 0x72, 0x46, 0x48, 0x62, 0x28, 0xac, 0x58, 0x1a, 0xc6, 0x59, 0x88, 0x2a, 0x44, 0x9e, 0x83},
+		dt2:   fp.Elt{0xb3, 0xde, 0x36, 0xfd, 0xeb, 0x1b, 0xd4, 0x24, 0x1b, 0x08, 0x8c, 0xfe, 0xa9, 0x41, 0xa1, 0x64, 0xf2, 0x6d, 0xdb, 0xf9, 0x94, 0xae, 0x86, 0x71, 0xab, 0x10, 0xbf, 0xa3, 0xb2, 0xa0, 0xdf, 0x10, 0x8c, 0x74, 0xce, 0xb3, 0xfc, 0xdb, 0xba, 0x15, 0xf6, 0x91, 0x7a, 0x9c, 0x36, 0x1e, 0x45, 0x07, 0x3c, 0xec, 0x1a, 0x61, 0x26, 0x93, 0xe3, 0x50},
+	},
+	{ /* 53P*/
+		addYX: fp.Elt{0xc5, 0x50, 0xc5, 0x83, 0xb0, 0xbd, 0xd9, 0xf6, 0x6d, 0x15, 0x5e, 0xc1, 0x1a, 0x33, 0xa0, 0xce, 0x13, 0x70, 0x3b, 0xe1, 0x31, 0xc6, 0xc4, 0x02, 0xec, 0x8c, 0xd5, 0x9c, 0x97, 0xd3, 0x12, 0xc4, 0xa2, 0xf9, 0xd5, 0xfb, 0x22, 0x69, 0x94, 0x09, 0x2f, 0x59, 0xce, 0xdb, 0xf2, 0xf2, 0x00, 0xe0, 0xa9, 0x08, 0x44, 0x2e, 0x8b, 0x6b, 0xf5, 0xb3},
+		subYX: fp.Elt{0x90, 0xdd, 0xec, 0xa2, 0x65, 0xb7, 0x61, 0xbc, 0xaa, 0x70, 0xa2, 0x15, 0xd8, 0xb0, 0xf8, 0x8e, 0x23, 0x3d, 0x9f, 0x46, 0xa3, 0x29, 0x20, 0xd1, 0xa1, 0x15, 0x81, 0xc6, 0xb6, 0xde, 0xbe, 0x60, 0x63, 0x24, 0xac, 0x15, 0xfb, 0xeb, 0xd3, 0xea, 0x57, 0x13, 0x86, 0x38, 0x1e, 0x22, 0xf4, 0x8c, 0x5d, 0xaf, 0x1b, 0x27, 0x21, 0x4f, 0xa3, 0x63},
+		dt2:   fp.Elt{0x07, 0x15, 0x87, 0xc4, 0xfd, 0xa1, 0x97, 0x7a, 0x07, 0x1f, 0x56, 0xcc, 0xe3, 0x6a, 0x01, 0x90, 0xce, 0xf9, 0xfa, 0x50, 0xb2, 0xe0, 0x87, 0x8b, 0x6c, 0x63, 0x6c, 0xf6, 0x2a, 0x09, 0xef, 0xef, 0xd2, 0x31, 0x40, 0x25, 0xf6, 0x84, 0xcb, 0xe0, 0xc4, 0x23, 0xc1, 0xcb, 0xe2, 0x02, 0x83, 0x2d, 0xed, 0x74, 0x74, 0x8b, 0xf8, 0x7c, 0x81, 0x18},
+	},
+	{ /* 55P*/
+		addYX: fp.Elt{0x9e, 0xe5, 0x59, 0x95, 0x63, 0x2e, 0xac, 0x8b, 0x03, 0x3c, 0xc1, 0x8e, 0xe1, 0x5b, 0x56, 0x3c, 0x16, 0x41, 0xe4, 0xc2, 0x60, 0x0c, 0x6d, 0x65, 0x9f, 0xfc, 0x27, 0x68, 0x43, 0x44, 0x05, 0x12, 0x6c, 0xda, 0x04, 0xef, 0xcf, 0xcf, 0xdc, 0x0a, 0x1a, 0x7f, 0x12, 0xd3, 0xeb, 0x02, 0xb6, 0x04, 0xca, 0xd6, 0xcb, 0xf0, 0x22, 0xba, 0x35, 0x6d},
+		subYX: fp.Elt{0x09, 0x6d, 0xf9, 0x64, 0x4c, 0xe6, 0x41, 0xff, 0x01, 0x4d, 0xce, 0x1e, 0xfa, 0x38, 0xa2, 0x25, 0x62, 0xff, 0x03, 0x39, 0x18, 0x91, 0xbb, 0x9d, 0xce, 0x02, 0xf0, 0xf1, 0x3c, 0x55, 0x18, 0xa9, 0xab, 0x4d, 0xd2, 0x35, 0xfd, 0x8d, 0xa9, 0xb2, 0xad, 0xb7, 0x06, 0x6e, 0xc6, 0x69, 0x49, 0xd6, 0x98, 0x98, 0x0b, 0x22, 0x81, 0x6b, 0xbd, 0xa0},
+		dt2:   fp.Elt{0x22, 0xf4, 0x85, 0x5d, 0x2b, 0xf1, 0x55, 0xa5, 0xd6, 0x27, 0x86, 0x57, 0x12, 0x1f, 0x16, 0x0a, 0x5a, 0x9b, 0xf2, 0x38, 0xb6, 0x28, 0xd8, 0x99, 0x0c, 0x89, 0x1d, 0x7f, 0xca, 0x21, 0x17, 0x1a, 0x0b, 0x02, 0x5f, 0x77, 0x2f, 0x73, 0x30, 0x7c, 0xc8, 0xd7, 0x2b, 0xcc, 0xe7, 0xf3, 0x21, 0xac, 0x53, 0xa7, 0x11, 0x5d, 0xd8, 0x1d, 0x9b, 0xf5},
+	},
+	{ /* 57P*/
+		addYX: fp.Elt{0x94, 0x63, 0x5d, 0xef, 0xfd, 0x6d, 0x25, 0x4e, 0x6d, 0x29, 0x03, 0xed, 0x24, 0x28, 0x27, 0x57, 0x47, 0x3e, 0x6a, 0x1a, 0xfe, 0x37, 0xee, 0x5f, 0x83, 0x29, 0x14, 0xfd, 0x78, 0x25, 0x8a, 0xe1, 0x02, 0x38, 0xd8, 0xca, 0x65, 0x55, 0x40, 0x7d, 0x48, 0x2c, 0x7c, 0x7e, 0x60, 0xb6, 0x0c, 0x6d, 0xf7, 0xe8, 0xb3, 0x62, 0x53, 0xd6, 0x9c, 0x2b},
+		subYX: fp.Elt{0x47, 0x25, 0x70, 0x62, 0xf5, 0x65, 0x93, 0x62, 0x08, 0xac, 0x59, 0x66, 0xdb, 0x08, 0xd9, 0x1a, 0x19, 0xaf, 0xf4, 0xef, 0x02, 0xa2, 0x78, 0xa9, 0x55, 0x1c, 0xfa, 0x08, 0x11, 0xcb, 0xa3, 0x71, 0x74, 0xb1, 0x62, 0xe7, 0xc7, 0xf3, 0x5a, 0xb5, 0x8b, 0xd4, 0xf6, 0x10, 0x57, 0x79, 0x72, 0x2f, 0x13, 0x86, 0x7b, 0x44, 0x5f, 0x48, 0xfd, 0x88},
+		dt2:   fp.Elt{0x10, 0x02, 0xcd, 0x05, 0x9a, 0xc3, 0x32, 0x6d, 0x10, 0x3a, 0x74, 0xba, 0x06, 0xc4, 0x3b, 0x34, 0xbc, 0x36, 0xed, 0xa3, 0xba, 0x9a, 0xdb, 0x6d, 0xd4, 0x69, 0x99, 0x97, 0xd0, 0xe4, 0xdd, 0xf5, 0xd4, 0x7c, 0xd3, 0x4e, 0xab, 0xd1, 0x3b, 0xbb, 0xe9, 0xc7, 0x6a, 0x94, 0x25, 0x61, 0xf0, 0x06, 0xc5, 0x12, 0xa8, 0x86, 0xe5, 0x35, 0x46, 0xeb},
+	},
+	{ /* 59P*/
+		addYX: fp.Elt{0x9e, 0x95, 0x11, 0xc6, 0xc7, 0xe8, 0xee, 0x5a, 0x26, 0xa0, 0x72, 0x72, 0x59, 0x91, 0x59, 0x16, 0x49, 0x99, 0x7e, 0xbb, 0xd7, 0x15, 0xb4, 0xf2, 0x40, 0xf9, 0x5a, 0x4d, 0xc8, 0xa0, 0xe2, 0x34, 0x7b, 0x34, 0xf3, 0x99, 0xbf, 0xa9, 0xf3, 0x79, 0xc1, 0x1a, 0x0c, 0xf4, 0x86, 0x74, 0x4e, 0xcb, 0xbc, 0x90, 0xad, 0xb6, 0x51, 0x6d, 0xaa, 0x33},
+		subYX: fp.Elt{0x9f, 0xd1, 0xc5, 0xa2, 0x6c, 0x24, 0x88, 0x15, 0x71, 0x68, 0xf6, 0x07, 0x45, 0x02, 0xc4, 0x73, 0x7e, 0x75, 0x87, 0xca, 0x7c, 0xf0, 0x92, 0x00, 0x75, 0xd6, 0x5a, 0xdd, 0xe0, 0x64, 0x16, 0x9d, 0x62, 0x80, 0x33, 0x9f, 0xf4, 0x8e, 0x1a, 0x15, 0x1c, 0xd3, 0x0f, 0x4d, 0x4f, 0x62, 0x2d, 0xd7, 0xa5, 0x77, 0xe3, 0xea, 0xf0, 0xfb, 0x1a, 0xdb},
+		dt2:   fp.Elt{0x6a, 0xa2, 0xb1, 0xaa, 0xfb, 0x5a, 0x32, 0x4e, 0xff, 0x47, 0x06, 0xd5, 0x9a, 0x4f, 0xce, 0x83, 0x5b, 0x82, 0x34, 0x3e, 0x47, 0xb8, 0xf8, 0xe9, 0x7c, 0x67, 0x69, 0x8d, 0x9c, 0xb7, 0xde, 0x57, 0xf4, 0x88, 0x41, 0x56, 0x0c, 0x87, 0x1e, 0xc9, 0x2f, 0x54, 0xbf, 0x5c, 0x68, 0x2c, 0xd9, 0xc4, 0xef, 0x53, 0x73, 0x1e, 0xa6, 0x38, 0x02, 0x10},
+	},
+	{ /* 61P*/
+		addYX: fp.Elt{0x08, 0x80, 0x4a, 0xc9, 0xb7, 0xa8, 0x88, 0xd9, 0xfc, 0x6a, 0xc0, 0x3e, 0xc2, 0x33, 0x4d, 0x2b, 0x2a, 0xa3, 0x6d, 0x72, 0x3e, 0xdc, 0x34, 0x68, 0x08, 0xbf, 0x27, 0xef, 0xf4, 0xff, 0xe2, 0x0c, 0x31, 0x0c, 0xa2, 0x0a, 0x1f, 0x65, 0xc1, 0x4c, 0x61, 0xd3, 0x1b, 0xbc, 0x25, 0xb1, 0xd0, 0xd4, 0x89, 0xb2, 0x53, 0xfb, 0x43, 0xa5, 0xaf, 0x04},
+		subYX: fp.Elt{0xe3, 0xe1, 0x37, 0xad, 0x58, 0xa9, 0x55, 0x81, 0xee, 0x64, 0x21, 0xb9, 0xf5, 0x4c, 0x35, 0xea, 0x4a, 0xd3, 0x26, 0xaa, 0x90, 0xd4, 0x60, 0x46, 0x09, 0x4b, 0x4a, 0x62, 0xf9, 0xcd, 0xe1, 0xee, 0xbb, 0xc2, 0x09, 0x0b, 0xb0, 0x96, 0x8e, 0x43, 0x77, 0xaf, 0x25, 0x20, 0x5e, 0x47, 0xe4, 0x1d, 0x50, 0x69, 0x74, 0x08, 0xd7, 0xb9, 0x90, 0x13},
+		dt2:   fp.Elt{0x51, 0x91, 0x95, 0x64, 0x03, 0x16, 0xfd, 0x6e, 0x26, 0x94, 0x6b, 0x61, 0xe7, 0xd9, 0xe0, 0x4a, 0x6d, 0x7c, 0xfa, 0xc0, 0xe2, 0x43, 0x23, 0x53, 0x70, 0xf5, 0x6f, 0x73, 0x8b, 0x81, 0xb0, 0x0c, 0xee, 0x2e, 0x46, 0xf2, 0x8d, 0xa6, 0xfb, 0xb5, 0x1c, 0x33, 0xbf, 0x90, 0x59, 0xc9, 0x7c, 0xb8, 0x6f, 0xad, 0x75, 0x02, 0x90, 0x8e, 0x59, 0x75},
+	},
+	{ /* 63P*/
+		addYX: fp.Elt{0x36, 0x4d, 0x77, 0x04, 0xb8, 0x7d, 0x4a, 0xd1, 0xc5, 0xbb, 0x7b, 0x50, 0x5f, 0x8d, 0x9d, 0x62, 0x0f, 0x66, 0x71, 0xec, 0x87, 0xc5, 0x80, 0x82, 0xc8, 0xf4, 0x6a, 0x94, 0x92, 0x5b, 0xb0, 0x16, 0x9b, 0xb2, 0xc9, 0x6f, 0x2b, 0x2d, 0xee, 0x95, 0x73, 0x2e, 0xc2, 0x1b, 0xc5, 0x55, 0x36, 0x86, 0x24, 0xf8, 0x20, 0x05, 0x0d, 0x93, 0xd7, 0x76},
+		subYX: fp.Elt{0x7f, 0x01, 0xeb, 0x2e, 0x48, 0x4d, 0x1d, 0xf1, 0x06, 0x7e, 0x7c, 0x2a, 0x43, 0xbf, 0x28, 0xac, 0xe9, 0x58, 0x13, 0xc8, 0xbf, 0x8e, 0xc0, 0xef, 0xe8, 0x4f, 0x46, 0x8a, 0xe7, 0xc0, 0xf6, 0x0f, 0x0a, 0x03, 0x48, 0x91, 0x55, 0x39, 0x2a, 0xe3, 0xdc, 0xf6, 0x22, 0x9d, 0x4d, 0x71, 0x55, 0x68, 0x25, 0x6e, 0x95, 0x52, 0xee, 0x4c, 0xd9, 0x01},
+		dt2:   fp.Elt{0xac, 0x33, 0x3f, 0x7c, 0x27, 0x35, 0x15, 0x91, 0x33, 0x8d, 0xf9, 0xc4, 0xf4, 0xf3, 0x90, 0x09, 0x75, 0x69, 0x62, 0x9f, 0x61, 0x35, 0x83, 0x92, 0x04, 0xef, 0x96, 0x38, 0x80, 0x9e, 0x88, 0xb3, 0x67, 0x95, 0xbe, 0x79, 0x3c, 0x35, 0xd8, 0xdc, 0xb2, 0x3e, 0x2d, 0xe6, 0x46, 0xbe, 0x81, 0xf3, 0x32, 0x0e, 0x37, 0x23, 0x75, 0x2a, 0x3d, 0xa0},
+	},
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist_basemult.go b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist_basemult.go
new file mode 100644
index 00000000..f6ac5edb
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/goldilocks/twist_basemult.go
@@ -0,0 +1,62 @@
+package goldilocks
+
+import (
+	"crypto/subtle"
+
+	mlsb "github.com/cloudflare/circl/math/mlsbset"
+)
+
+const (
+	// MLSBRecoding parameters
+	fxT   = 448
+	fxV   = 2
+	fxW   = 3
+	fx2w1 = 1 << (uint(fxW) - 1)
+)
+
+// ScalarBaseMult returns kG where G is the generator point.
+func (e twistCurve) ScalarBaseMult(k *Scalar) *twistPoint {
+	m, err := mlsb.New(fxT, fxV, fxW)
+	if err != nil {
+		panic(err)
+	}
+	if m.IsExtended() {
+		panic("not extended")
+	}
+
+	var isZero int
+	if k.IsZero() {
+		isZero = 1
+	}
+	subtle.ConstantTimeCopy(isZero, k[:], order[:])
+
+	minusK := *k
+	isEven := 1 - int(k[0]&0x1)
+	minusK.Neg()
+	subtle.ConstantTimeCopy(isEven, k[:], minusK[:])
+	c, err := m.Encode(k[:])
+	if err != nil {
+		panic(err)
+	}
+
+	gP := c.Exp(groupMLSB{})
+	P := gP.(*twistPoint)
+	P.cneg(uint(isEven))
+	return P
+}
+
+type groupMLSB struct{}
+
+func (e groupMLSB) ExtendedEltP() mlsb.EltP      { return nil }
+func (e groupMLSB) Sqr(x mlsb.EltG)              { x.(*twistPoint).Double() }
+func (e groupMLSB) Mul(x mlsb.EltG, y mlsb.EltP) { x.(*twistPoint).mixAddZ1(y.(*preTwistPointAffine)) }
+func (e groupMLSB) Identity() mlsb.EltG          { return twistCurve{}.Identity() }
+func (e groupMLSB) NewEltP() mlsb.EltP           { return &preTwistPointAffine{} }
+func (e groupMLSB) Lookup(a mlsb.EltP, v uint, s, u int32) {
+	Tabj := &tabFixMult[v]
+	P := a.(*preTwistPointAffine)
+	for k := range Tabj {
+		P.cmov(&Tabj[k], uint(subtle.ConstantTimeEq(int32(k), u)))
+	}
+	P.cneg(int(s >> 31))
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/p384/LICENSE b/vendor/github.com/cloudflare/circl/ecc/p384/LICENSE
new file mode 100644
index 00000000..4e5596db
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/p384/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2018, Brendan McMillion. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+2. 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.
+
+3. Neither the name of the copyright holder nor the names of its contributors
+may be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/cloudflare/circl/ecc/p384/arith.go b/vendor/github.com/cloudflare/circl/ecc/p384/arith.go
new file mode 100644
index 00000000..889e7771
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/p384/arith.go
@@ -0,0 +1,149 @@
+//go:build (!purego && arm64) || (!purego && amd64)
+// +build !purego,arm64 !purego,amd64
+
+package p384
+
+import (
+	"math/big"
+
+	"github.com/cloudflare/circl/internal/conv"
+)
+
+const sizeFp = 48
+
+type fp384 [sizeFp]byte
+
+func (e fp384) BigInt() *big.Int { return conv.BytesLe2BigInt(e[:]) }
+func (e fp384) String() string   { return conv.BytesLe2Hex(e[:]) }
+
+func (e *fp384) SetBigInt(b *big.Int) {
+	if b.BitLen() > 384 || b.Sign() < 0 {
+		b = new(big.Int).Mod(b, p.BigInt())
+	}
+	conv.BigInt2BytesLe(e[:], b)
+}
+
+func montEncode(c, a *fp384) { fp384Mul(c, a, &r2) }
+func montDecode(c, a *fp384) { fp384Mul(c, a, &fp384{1}) }
+func fp384Sqr(c, a *fp384)   { fp384Mul(c, a, a) }
+
+func fp384Inv(z, x *fp384) {
+	t0, t1, t2, t3, t4 := &fp384{}, &fp384{}, &fp384{}, &fp384{}, &fp384{}
+	/* alpha_1 */
+	fp384Sqr(t4, x)
+	/* alpha_2 */
+	fp384Mul(t4, t4, x)
+	/* alpha_3 */
+	fp384Sqr(t0, t4)
+	fp384Mul(t0, t0, x)
+	/* alpha_6 */
+	fp384Sqr(t1, t0)
+	fp384Sqr(t1, t1)
+	fp384Sqr(t1, t1)
+	fp384Mul(t1, t1, t0)
+	/* alpha_12 */
+	fp384Sqr(t2, t1)
+	for i := 0; i < 5; i++ {
+		fp384Sqr(t2, t2)
+	}
+	fp384Mul(t2, t2, t1)
+	/* alpha_15 */
+	for i := 0; i < 3; i++ {
+		fp384Sqr(t2, t2)
+	}
+	fp384Mul(t2, t2, t0)
+	/* alpha_30 */
+	fp384Sqr(t1, t2)
+	for i := 0; i < 14; i++ {
+		fp384Sqr(t1, t1)
+	}
+	fp384Mul(t1, t1, t2)
+	/* alpha_60 */
+	fp384Sqr(t3, t1)
+	for i := 0; i < 29; i++ {
+		fp384Sqr(t3, t3)
+	}
+	fp384Mul(t3, t3, t1)
+	/* T_3 = alpha_30^(2^2) */
+	fp384Sqr(t1, t1)
+	fp384Sqr(t1, t1)
+	/* alpha_32 */
+	*t0 = *t1
+	fp384Mul(t0, t0, t4)
+	/* T_3 = a^(2^32-3) = (alpha_30)^(2^2)*alpha_1 */
+	fp384Mul(t1, t1, x)
+	/* alpha_120 */
+	fp384Sqr(t4, t3)
+	for i := 0; i < 59; i++ {
+		fp384Sqr(t4, t4)
+	}
+	fp384Mul(t4, t4, t3)
+	/* alpha_240 */
+	fp384Sqr(t3, t4)
+	for i := 0; i < 119; i++ {
+		fp384Sqr(t3, t3)
+	}
+	fp384Mul(t3, t3, t4)
+	/* alpha_255 */
+	for i := 0; i < 15; i++ {
+		fp384Sqr(t3, t3)
+	}
+	fp384Mul(t3, t3, t2)
+	/* T_5 = a^(2^288-2^32-1) = (alpha_255)^(2^33)*alpha_32 */
+	for i := 0; i < 33; i++ {
+		fp384Sqr(t3, t3)
+	}
+	fp384Mul(t3, t3, t0)
+	/* T_1 = a^(2^384-2^128-2^96+2^32-3) = (T_1)^(2^96)*T_3 */
+	fp384Sqr(t4, t3)
+	for i := 0; i < 95; i++ {
+		fp384Sqr(t4, t4)
+	}
+	fp384Mul(z, t4, t1)
+}
+
+//go:noescape
+func fp384Cmov(x, y *fp384, b int)
+
+//go:noescape
+func fp384Neg(c, a *fp384)
+
+//go:noescape
+func fp384Add(c, a, b *fp384)
+
+//go:noescape
+func fp384Sub(c, a, b *fp384)
+
+//go:noescape
+func fp384Mul(c, a, b *fp384)
+
+var (
+	// p is the order of the base field, represented as little-endian 64-bit words.
+	p = fp384{
+		0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	}
+	// pp satisfies r*rp - p*pp = 1 where rp and pp are both integers.
+	pp = fp384{ //nolint
+		0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff,
+		0xfa, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00,
+		0x0c, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+	}
+	// r2 is R^2 where R = 2^384 mod p.
+	r2 = fp384{
+		0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+		0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
+		0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	}
+	// bb is the Montgomery encoding of the curve parameter B.
+	bb = fp384{
+		0xcc, 0x2d, 0x41, 0x9d, 0x71, 0x88, 0x11, 0x08, 0xec, 0x32, 0x4c, 0x7a,
+		0xd8, 0xad, 0x29, 0xf7, 0x2e, 0x02, 0x20, 0x19, 0x9b, 0x20, 0xf2, 0x77,
+		0xe2, 0x8a, 0x93, 0x94, 0xee, 0x4b, 0x37, 0xe3, 0x94, 0x20, 0x02, 0x1f,
+		0xf4, 0x21, 0x2b, 0xb6, 0xf9, 0xbf, 0x4f, 0x60, 0x4b, 0x11, 0x08, 0xcd,
+	}
+)
diff --git a/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.go b/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.go
new file mode 100644
index 00000000..2e9d8fdd
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.go
@@ -0,0 +1,8 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+package p384
+
+import "golang.org/x/sys/cpu"
+
+var hasBMI2 = cpu.X86.HasBMI2 //nolint
diff --git a/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.s b/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.s
new file mode 100644
index 00000000..eaf6fb7a
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/p384/arith_amd64.s
@@ -0,0 +1,730 @@
+// +build amd64,!purego
+
+#include "textflag.h"
+
+#define storeBlock(a0,a1,a2,a3,a4,a5, r) \
+	MOVQ a0,  0+r \
+	MOVQ a1,  8+r \
+	MOVQ a2, 16+r \
+	MOVQ a3, 24+r \
+	MOVQ a4, 32+r \
+	MOVQ a5, 40+r
+
+#define loadBlock(r, a0,a1,a2,a3,a4,a5) \
+	MOVQ  0+r, a0 \
+	MOVQ  8+r, a1 \
+	MOVQ 16+r, a2 \
+	MOVQ 24+r, a3 \
+	MOVQ 32+r, a4 \
+	MOVQ 40+r, a5
+
+#define fp384Carry(a0,a1,a2,a3,a4,a5,a6, b0,b1,b2,b3,b4,b5,b6) \
+	\ // b = a-p
+	MOVQ a0, b0 \
+	MOVQ a1, b1 \
+	MOVQ a2, b2 \
+	MOVQ a3, b3 \
+	MOVQ a4, b4 \
+	MOVQ a5, b5 \
+	MOVQ a6, b6 \
+	\
+	SUBQ ·p+0(SB), b0 \
+	SBBQ ·p+8(SB), b1 \
+	SBBQ ·p+16(SB), b2 \
+	SBBQ ·p+24(SB), b3 \
+	SBBQ ·p+32(SB), b4 \
+	SBBQ ·p+40(SB), b5 \
+	SBBQ $0, b6 \
+	\
+	\ // if b is negative then return a
+	\ // else return b
+	CMOVQCC b0, a0 \
+	CMOVQCC b1, a1 \
+	CMOVQCC b2, a2 \
+	CMOVQCC b3, a3 \
+	CMOVQCC b4, a4 \
+	CMOVQCC b5, a5
+
+#define mul(a0,a1,a2,a3,a4,a5, rb, stack) \
+	\ // a0
+	MOVQ a0, AX \
+	MULQ 0+rb \
+	MOVQ AX, R8 \
+	MOVQ DX, R9 \
+	MOVQ a0, AX \
+	MULQ 8+rb \
+	ADDQ AX, R9 \
+	ADCQ $0, DX \
+	MOVQ DX, R10 \
+	MOVQ a0, AX \
+	MULQ 16+rb \
+	ADDQ AX, R10 \
+	ADCQ $0, DX \
+	MOVQ DX, R11 \
+	MOVQ a0, AX \
+	MULQ 24+rb \
+	ADDQ AX, R11 \
+	ADCQ $0, DX \
+	MOVQ DX, R12 \
+	MOVQ a0, AX \
+	MULQ 32+rb \
+	ADDQ AX, R12 \
+	ADCQ $0, DX \
+	MOVQ DX, R13 \
+	MOVQ a0, AX \
+	MULQ 40+rb \
+	ADDQ AX, R13 \
+	ADCQ $0, DX \
+	MOVQ DX, R14 \
+	\
+	storeBlock(R8,R9,R10,R11,R12,R13, 0+stack) \
+	MOVQ R14, 48+stack \
+	\
+	\ // a1
+	MOVQ a1, AX \
+	MULQ 0+rb \
+	MOVQ AX, R8 \
+	MOVQ DX, R9 \
+	MOVQ a1, AX \
+	MULQ 8+rb \
+	ADDQ AX, R9 \
+	ADCQ $0, DX \
+	MOVQ DX, R10 \
+	MOVQ a1, AX \
+	MULQ 16+rb \
+	ADDQ AX, R10 \
+	ADCQ $0, DX \
+	MOVQ DX, R11 \
+	MOVQ a1, AX \
+	MULQ 24+rb \
+	ADDQ AX, R11 \
+	ADCQ $0, DX \
+	MOVQ DX, R12 \
+	MOVQ a1, AX \
+	MULQ 32+rb \
+	ADDQ AX, R12 \
+	ADCQ $0, DX \
+	MOVQ DX, R13 \
+	MOVQ a1, AX \
+	MULQ 40+rb \
+	ADDQ AX, R13 \
+	ADCQ $0, DX \
+	MOVQ DX, R14 \
+	\
+	ADDQ 8+stack, R8 \
+	ADCQ 16+stack, R9 \
+	ADCQ 24+stack, R10 \
+	ADCQ 32+stack, R11 \
+	ADCQ 40+stack, R12 \
+	ADCQ 48+stack, R13 \
+	ADCQ $0, R14 \
+	storeBlock(R8,R9,R10,R11,R12,R13, 8+stack) \
+	MOVQ R14, 56+stack \
+	\
+	\ // a2
+	MOVQ a2, AX \
+	MULQ 0+rb \
+	MOVQ AX, R8 \
+	MOVQ DX, R9 \
+	MOVQ a2, AX \
+	MULQ 8+rb \
+	ADDQ AX, R9 \
+	ADCQ $0, DX \
+	MOVQ DX, R10 \
+	MOVQ a2, AX \
+	MULQ 16+rb \
+	ADDQ AX, R10 \
+	ADCQ $0, DX \
+	MOVQ DX, R11 \
+	MOVQ a2, AX \
+	MULQ 24+rb \
+	ADDQ AX, R11 \
+	ADCQ $0, DX \
+	MOVQ DX, R12 \
+	MOVQ a2, AX \
+	MULQ 32+rb \
+	ADDQ AX, R12 \
+	ADCQ $0, DX \
+	MOVQ DX, R13 \
+	MOVQ a2, AX \
+	MULQ 40+rb \
+	ADDQ AX, R13 \
+	ADCQ $0, DX \
+	MOVQ DX, R14 \
+	\
+	ADDQ 16+stack, R8 \
+	ADCQ 24+stack, R9 \
+	ADCQ 32+stack, R10 \
+	ADCQ 40+stack, R11 \
+	ADCQ 48+stack, R12 \
+	ADCQ 56+stack, R13 \
+	ADCQ $0, R14 \
+	storeBlock(R8,R9,R10,R11,R12,R13, 16+stack) \
+	MOVQ R14, 64+stack \
+	\
+	\ // a3
+	MOVQ a3, AX \
+	MULQ 0+rb \
+	MOVQ AX, R8 \
+	MOVQ DX, R9 \
+	MOVQ a3, AX \
+	MULQ 8+rb \
+	ADDQ AX, R9 \
+	ADCQ $0, DX \
+	MOVQ DX, R10 \
+	MOVQ a3, AX \
+	MULQ 16+rb \
+	ADDQ AX, R10 \
+	ADCQ $0, DX \
+	MOVQ DX, R11 \
+	MOVQ a3, AX \
+	MULQ 24+rb \
+	ADDQ AX, R11 \
+	ADCQ $0, DX \
+	MOVQ DX, R12 \
+	MOVQ a3, AX \
+	MULQ 32+rb \
+	ADDQ AX, R12 \
+	ADCQ $0, DX \
+	MOVQ DX, R13 \
+	MOVQ a3, AX \
+	MULQ 40+rb \
+	ADDQ AX, R13 \
+	ADCQ $0, DX \
+	MOVQ DX, R14 \
+	\
+	ADDQ 24+stack, R8 \
+	ADCQ 32+stack, R9 \
+	ADCQ 40+stack, R10 \
+	ADCQ 48+stack, R11 \
+	ADCQ 56+stack, R12 \
+	ADCQ 64+stack, R13 \
+	ADCQ $0, R14 \
+	storeBlock(R8,R9,R10,R11,R12,R13, 24+stack) \
+	MOVQ R14, 72+stack \
+	\
+	\ // a4
+	MOVQ a4, AX \
+	MULQ 0+rb \
+	MOVQ AX, R8 \
+	MOVQ DX, R9 \
+	MOVQ a4, AX \
+	MULQ 8+rb \
+	ADDQ AX, R9 \
+	ADCQ $0, DX \
+	MOVQ DX, R10 \
+	MOVQ a4, AX \
+	MULQ 16+rb \
+	ADDQ AX, R10 \
+	ADCQ $0, DX \
+	MOVQ DX, R11 \
+	MOVQ a4, AX \
+	MULQ 24+rb \
+	ADDQ AX, R11 \
+	ADCQ $0, DX \
+	MOVQ DX, R12 \
+	MOVQ a4, AX \
+	MULQ 32+rb \
+	ADDQ AX, R12 \
+	ADCQ $0, DX \
+	MOVQ DX, R13 \
+	MOVQ a4, AX \
+	MULQ 40+rb \
+	ADDQ AX, R13 \
+	ADCQ $0, DX \
+	MOVQ DX, R14 \
+	\
+	ADDQ 32+stack, R8 \
+	ADCQ 40+stack, R9 \
+	ADCQ 48+stack, R10 \
+	ADCQ 56+stack, R11 \
+	ADCQ 64+stack, R12 \
+	ADCQ 72+stack, R13 \
+	ADCQ $0, R14 \
+	storeBlock(R8,R9,R10,R11,R12,R13, 32+stack) \
+	MOVQ R14, 80+stack \
+	\
+	\ // a5
+	MOVQ a5, AX \
+	MULQ 0+rb \
+	MOVQ AX, R8 \
+	MOVQ DX, R9 \
+	MOVQ a5, AX \
+	MULQ 8+rb \
+	ADDQ AX, R9 \
+	ADCQ $0, DX \
+	MOVQ DX, R10 \
+	MOVQ a5, AX \
+	MULQ 16+rb \
+	ADDQ AX, R10 \
+	ADCQ $0, DX \
+	MOVQ DX, R11 \
+	MOVQ a5, AX \
+	MULQ 24+rb \
+	ADDQ AX, R11 \
+	ADCQ $0, DX \
+	MOVQ DX, R12 \
+	MOVQ a5, AX \
+	MULQ 32+rb \
+	ADDQ AX, R12 \
+	ADCQ $0, DX \
+	MOVQ DX, R13 \
+	MOVQ a5, AX \
+	MULQ 40+rb \
+	ADDQ AX, R13 \
+	ADCQ $0, DX \
+	MOVQ DX, R14 \
+	\
+	ADDQ 40+stack, R8 \
+	ADCQ 48+stack, R9 \
+	ADCQ 56+stack, R10 \
+	ADCQ 64+stack, R11 \
+	ADCQ 72+stack, R12 \
+	ADCQ 80+stack, R13 \
+	ADCQ $0, R14 \
+	storeBlock(R8,R9,R10,R11,R12,R13, 40+stack) \
+	MOVQ R14, 88+stack
+
+#define fp384Reduce(stack) \
+	\ // m = (T * P') mod R, store m in R8:R9:R10:R11:R12:R13
+	MOVQ ·pp+0(SB), AX \
+	MULQ 0+stack \
+	MOVQ AX, R8 ; MOVQ R8, 96+stack\
+	MOVQ DX, R9 \
+	MOVQ ·pp+0(SB), AX \
+	MULQ 8+stack \
+	ADDQ AX, R9 \
+	ADCQ $0, DX \
+	MOVQ DX, R10 \
+	MOVQ ·pp+0(SB), AX \
+	MULQ 16+stack \
+	ADDQ AX, R10 \
+	ADCQ $0, DX \
+	MOVQ DX, R11 \
+	MOVQ ·pp+0(SB), AX \
+	MULQ 24+stack \
+	ADDQ AX, R11 \
+	ADCQ $0, DX \
+	MOVQ DX, R12 \
+	MOVQ ·pp+0(SB), AX \
+	MULQ 32+stack \
+	ADDQ AX, R12 \
+	ADCQ $0, DX \
+	MOVQ DX, R13 \
+	MOVQ ·pp+0(SB), AX \
+	MULQ 40+stack \
+	ADDQ AX, R13 \
+	\
+	ADDQ 0+stack, R9 \
+	ADCQ 8+stack, R10 \
+	ADCQ 16+stack, R11 \
+	ADCQ 24+stack, R12 \
+	ADCQ 32+stack, R13 \
+	\
+	MOVQ ·pp+16(SB), AX \
+	MULQ 0+stack \
+	MOVQ AX, R14 \
+	MOVQ DX, R8 \
+	MOVQ ·pp+16(SB), AX \
+	MULQ 8+stack \
+	ADDQ AX, R8 \
+	ADCQ $0, DX \
+	MOVQ DX, BX \
+	MOVQ ·pp+16(SB), AX \
+	MULQ 16+stack \
+	ADDQ AX, BX \
+	ADCQ $0, DX \
+	MOVQ DX, CX \
+	MOVQ ·pp+16(SB), AX \
+	MULQ 24+stack \
+	ADDQ AX, CX \
+	\
+	ADDQ R14, R10 \
+	ADCQ R8, R11 \
+	ADCQ BX, R12 \
+	ADCQ CX, R13 \
+	\
+	MOVQ ·pp+24(SB), AX \
+	MULQ 0+stack \
+	MOVQ AX, R14 \
+	MOVQ DX, R8 \
+	MOVQ ·pp+24(SB), AX \
+	MULQ 8+stack \
+	ADDQ AX, R8 \
+	ADCQ $0, DX \
+	MOVQ DX, BX \
+	MOVQ ·pp+24(SB), AX \
+	MULQ 16+stack \
+	ADDQ AX, BX \
+	\
+	ADDQ R14, R11 \
+	ADCQ R8, R12 \
+	ADCQ BX, R13 \
+	\
+	MOVQ ·pp+32(SB), AX \
+	MULQ 0+stack \
+	MOVQ AX, R14 \
+	MOVQ DX, R8 \
+	MOVQ ·pp+32(SB), AX \
+	MULQ 8+stack \
+	ADDQ AX, R8 \
+	\
+	ADDQ R14, R12 \
+	ADCQ R8, R13 \
+	\
+	MOVQ ·pp+40(SB), AX \
+	MULQ 0+stack \
+	ADDQ AX, R13 \
+	\
+	MOVQ 96+stack, R8 \
+	\
+	storeBlock(R8,R9,R10,R11,R12,R13, 96+stack) \
+	\
+	\ // m * P
+	mul(·p+0(SB),·p+8(SB),·p+16(SB),·p+24(SB),·p+32(SB),·p+40(SB), 96+stack, 144+stack) \
+	\
+	\ // Add the 768-bit intermediate to m*N
+	MOVQ $0, R15 \
+	loadBlock(144+stack, R8,R9,R10,R11,R12,R13) \
+	loadBlock(192+stack, R14,SI,AX,BX,CX,DX) \
+	\
+	ADDQ 0+stack, R8 \
+	ADCQ 8+stack, R9 \
+	ADCQ 16+stack, R10 \
+	ADCQ 24+stack, R11 \
+	ADCQ 32+stack, R12 \
+	ADCQ 40+stack, R13 \
+	ADCQ 48+stack, R14 \
+	ADCQ 56+stack, SI \
+	ADCQ 64+stack, AX \
+	ADCQ 72+stack, BX \
+	ADCQ 80+stack, CX \
+	ADCQ 88+stack, DX \
+	ADCQ $0, R15 \
+	\
+	fp384Carry(R14,SI,AX,BX,CX,DX,R15, R8,R9,R10,R11,R12,R13,DI)
+
+#define mulBMI2(a0,a1,a2,a3,a4,a5, rb, stack) \
+	MOVQ a0, DX \
+	MULXQ 0+rb, R8, R9; MOVQ R8, 0+stack; MOVQ $0, R8 \
+	MULXQ 8+rb, AX, R10 \
+	ADDQ AX, R9 \
+	MULXQ 16+rb, AX, R11 \
+	ADCQ AX, R10 \
+	MULXQ 24+rb, AX, R12 \
+	ADCQ AX, R11 \
+	MULXQ 32+rb, AX, R13 \
+	ADCQ AX, R12 \
+	MULXQ 40+rb, AX, R14 \
+	ADCQ AX, R13 \
+	ADCQ $0, R14 \
+	\
+	MOVQ a1, DX \
+	MULXQ 0+rb, AX, BX \
+	ADDQ AX, R9; MOVQ R9, 8+stack; MOVL $0, R9 \
+	ADCQ BX, R10 \
+	MULXQ 16+rb, AX, BX \
+	ADCQ AX, R11 \
+	ADCQ BX, R12 \
+	MULXQ 32+rb, AX, BX \
+	ADCQ AX, R13 \
+	ADCQ BX, R14 \
+	ADCQ $0,  R8 \
+	MULXQ 8+rb, AX, BX \
+	ADDQ AX, R10 \
+	ADCQ BX, R11 \
+	MULXQ 24+rb, AX, BX \
+	ADCQ AX, R12 \
+	ADCQ BX, R13 \
+	MULXQ 40+rb, AX, BX \
+	ADCQ AX, R14 \
+	ADCQ BX, R8 \
+	ADCQ $0, R9 \
+	\
+	MOVQ a2, DX \
+	MULXQ 0+rb, AX, BX \
+	ADDQ AX, R10; MOVQ R10, 16+stack; MOVL $0, R10 \
+	ADCQ BX, R11 \
+	MULXQ 16+rb, AX, BX \
+	ADCQ AX, R12 \
+	ADCQ BX, R13 \
+	MULXQ 32+rb, AX, BX \
+	ADCQ AX, R14 \
+	ADCQ BX, R8 \
+	ADCQ $0, R9 \
+	MULXQ 8+rb, AX, BX \
+	ADDQ AX, R11 \
+	ADCQ BX, R12 \
+	MULXQ 24+rb, AX, BX \
+	ADCQ AX, R13 \
+	ADCQ BX, R14 \
+	MULXQ 40+rb, AX, BX \
+	ADCQ AX, R8 \
+	ADCQ BX, R9 \
+	ADCQ $0, R10 \
+	\
+	MOVQ a3, DX \
+	MULXQ 0+rb, AX, BX \
+	ADDQ AX, R11; MOVQ R11, 24+stack; MOVL $0, R11 \
+	ADCQ BX, R12 \
+	MULXQ 16+rb, AX, BX \
+	ADCQ AX, R13 \
+	ADCQ BX, R14 \
+	MULXQ 32+rb, AX, BX \
+	ADCQ AX, R8 \
+	ADCQ BX, R9 \
+	ADCQ $0, R10 \
+	MULXQ 8+rb, AX, BX \
+	ADDQ AX, R12 \
+	ADCQ BX, R13 \
+	MULXQ 24+rb, AX, BX \
+	ADCQ AX, R14 \
+	ADCQ BX, R8 \
+	MULXQ 40+rb, AX, BX \
+	ADCQ AX, R9 \
+	ADCQ BX, R10 \
+	ADCQ $0, R11 \
+	\
+	MOVQ a4, DX \
+	MULXQ 0+rb, AX, BX \
+	ADDQ AX, R12; MOVQ R12, 32+stack; MOVL $0, R12 \
+	ADCQ BX, R13 \
+	MULXQ 16+rb, AX, BX \
+	ADCQ AX, R14 \
+	ADCQ BX, R8 \
+	MULXQ 32+rb, AX, BX \
+	ADCQ AX, R9 \
+	ADCQ BX, R10 \
+	ADCQ $0, R11 \
+	MULXQ 8+rb, AX, BX \
+	ADDQ AX, R13 \
+	ADCQ BX, R14 \
+	MULXQ 24+rb, AX, BX \
+	ADCQ AX, R8 \
+	ADCQ BX, R9 \
+	MULXQ 40+rb, AX, BX \
+	ADCQ AX, R10 \
+	ADCQ BX, R11 \
+	ADCQ $0, R12 \
+	\
+	MOVQ a5, DX \
+	MULXQ 0+rb, AX, BX \
+	ADDQ AX, R13; MOVQ R13, 40+stack \
+	ADCQ BX, R14 \
+	MULXQ 16+rb, AX, BX \
+	ADCQ AX, R8 \
+	ADCQ BX, R9 \
+	MULXQ 32+rb, AX, BX \
+	ADCQ AX, R10 \
+	ADCQ BX, R11 \
+	ADCQ $0, R12 \
+	MULXQ 8+rb, AX, BX \
+	ADDQ AX, R14 \
+	ADCQ BX, R8 \
+	MULXQ 24+rb, AX, BX \
+	ADCQ AX, R9 \
+	ADCQ BX, R10 \
+	MULXQ 40+rb, AX, BX \
+	ADCQ AX, R11 \
+	ADCQ BX, R12
+
+#define fp384ReduceBMI2(stack) \
+	\ // m = (T * P') mod R, store m in R8:R9:R10:R11:R12:R13
+	MOVQ ·pp+0(SB), DX \
+	MULXQ 0+stack, R8, R9 \
+	MULXQ 8+stack, AX, R10 \
+	ADDQ AX, R9 \
+	MULXQ 16+stack, AX, R11 \
+	ADCQ AX, R10 \
+	MULXQ 24+stack, AX, R12 \
+	ADCQ AX, R11 \
+	MULXQ 32+stack, AX, R13 \
+	ADCQ AX, R12 \
+	MULXQ 40+stack, AX, BX \
+	ADCQ AX, R13 \
+	\
+	ADDQ 0+stack, R9 \
+	ADCQ 8+stack, R10 \
+	ADCQ 16+stack, R11 \
+	ADCQ 24+stack, R12 \
+	ADCQ 32+stack, R13 \
+	\
+	MOVQ ·pp+16(SB), DX \
+	MULXQ 0+stack, AX, BX \
+	ADDQ AX, R10 \
+	ADCQ BX, R11 \
+	MULXQ 16+stack, AX, BX \
+	ADCQ AX, R12 \
+	ADCQ BX, R13 \
+	MULXQ 8+stack, AX, BX \
+	ADDQ AX, R11 \
+	ADCQ BX, R12 \
+	MULXQ 24+stack, AX, BX \
+	ADCQ AX, R13 \
+	\
+	MOVQ ·pp+24(SB), DX \
+	MULXQ 0+stack, AX, BX \
+	ADDQ AX, R11 \
+	ADCQ BX, R12 \
+	MULXQ 16+stack, AX, BX \
+	ADCQ AX, R13 \
+	MULXQ 8+stack, AX, BX \
+	ADDQ AX, R12 \
+	ADCQ BX, R13 \
+	\
+	MOVQ ·pp+32(SB), DX \
+	MULXQ 0+stack, AX, BX \
+	ADDQ AX, R12 \
+	ADCQ BX, R13 \
+	MULXQ 8+stack, AX, BX \
+	ADDQ AX, R13 \
+	\
+	MOVQ ·pp+40(SB), DX \
+	MULXQ 0+stack, AX, BX \
+	ADDQ AX, R13 \
+	\
+	storeBlock(R8,R9,R10,R11,R12,R13, 96+stack) \
+	\
+	\ // m * P
+	mulBMI2(·p+0(SB),·p+8(SB),·p+16(SB),·p+24(SB),·p+32(SB),·p+40(SB), 96+stack, 144+stack) \
+	\
+	\ // Add the 768-bit intermediate to m*N
+	loadBlock(144+stack, AX,R13,BX,CX,DX,DI) \
+	\
+	ADDQ 0+stack,  AX \
+	ADCQ 8+stack, R13 \
+	ADCQ 16+stack, BX \
+	ADCQ 24+stack, CX \
+	ADCQ 32+stack, DX \
+	ADCQ 40+stack, DI \
+	ADCQ 48+stack, R14 \
+	ADCQ 56+stack, R8 \
+	ADCQ 64+stack, R9 \
+	ADCQ 72+stack, R10 \
+	ADCQ 80+stack, R11 \
+	ADCQ 88+stack, R12 \
+	MOVQ $0, 0+stack \
+	ADCQ $0, 0+stack \
+	\
+	fp384Carry(R14,R8,R9,R10,R11,R12, 0+stack, AX,R13,BX,CX,DX,DI,SI)
+
+TEXT ·fp384Neg(SB), NOSPLIT, $0-16
+	MOVQ ·p+0(SB), R8
+	MOVQ ·p+8(SB), R9
+	MOVQ ·p+16(SB), R10
+	MOVQ ·p+24(SB), R11
+	MOVQ ·p+32(SB), R12
+	MOVQ ·p+40(SB), R13
+
+	MOVQ a+8(FP), DI
+	SUBQ 0(DI), R8
+	SBBQ 8(DI), R9
+	SBBQ 16(DI), R10
+	SBBQ 24(DI), R11
+	SBBQ 32(DI), R12
+	SBBQ 40(DI), R13
+
+	MOVQ $0, R15
+	fp384Carry(R8,R9,R10,R11,R12,R13,R15, R14,AX,BX,CX,DX,DI,SI)
+
+	MOVQ c+0(FP), DI
+	storeBlock(R8,R9,R10,R11,R12,R13, 0(DI))
+	RET
+
+TEXT ·fp384Add(SB), NOSPLIT, $0-24
+	MOVQ a+8(FP), DI
+	MOVQ b+16(FP), SI
+
+	loadBlock(0(DI), R8,R9,R10,R11,R12,R13)
+	MOVQ $0, R15
+
+	ADDQ  0(SI), R8
+	ADCQ  8(SI), R9
+	ADCQ 16(SI), R10
+	ADCQ 24(SI), R11
+	ADCQ 32(SI), R12
+	ADCQ 40(SI), R13
+	ADCQ $0, R15
+
+	fp384Carry(R8,R9,R10,R11,R12,R13,R15, R14,AX,BX,CX,DX,DI,SI)
+
+	MOVQ c+0(FP), DI
+	storeBlock(R8,R9,R10,R11,R12,R13, 0(DI))
+	RET
+
+TEXT ·fp384Sub(SB), NOSPLIT, $0-24
+	MOVQ ·p+0(SB), R8
+	MOVQ ·p+8(SB), R9
+	MOVQ ·p+16(SB), R10
+	MOVQ ·p+24(SB), R11
+	MOVQ ·p+32(SB), R12
+	MOVQ ·p+40(SB), R13
+
+	MOVQ b+16(FP), DI
+	SUBQ 0(DI), R8
+	SBBQ 8(DI), R9
+	SBBQ 16(DI), R10
+	SBBQ 24(DI), R11
+	SBBQ 32(DI), R12
+	SBBQ 40(DI), R13
+
+	MOVQ $0, R15
+	MOVQ a+8(FP), DI
+	ADDQ 0(DI), R8
+	ADCQ 8(DI), R9
+	ADCQ 16(DI), R10
+	ADCQ 24(DI), R11
+	ADCQ 32(DI), R12
+	ADCQ 40(DI), R13
+	ADCQ $0, R15
+
+	fp384Carry(R8,R9,R10,R11,R12,R13,R15, R14,AX,BX,CX,DX,DI,SI)
+
+	MOVQ c+0(FP), DI
+	storeBlock(R8,R9,R10,R11,R12,R13, 0(DI))
+	RET
+
+TEXT ·fp384Mul(SB), NOSPLIT, $240-24
+	MOVQ a+8(FP), DI
+	MOVQ b+16(FP), SI
+
+	// Jump to a slightly different implementation if MULX isn't supported.
+	CMPB ·hasBMI2(SB), $0
+	JE   nobmi2Mul
+
+	// T = a * b
+	mulBMI2(0(DI),8(DI),16(DI),24(DI),32(DI),40(DI), 0(SI), 0(SP))
+	storeBlock(R14,R8,R9,R10,R11,R12, 48(SP))
+
+	// Reduce T.
+	fp384ReduceBMI2(0(SP))
+
+	MOVQ c+0(FP), DI
+	storeBlock(R14,R8,R9,R10,R11,R12, 0(DI))
+	JMP end
+
+nobmi2Mul:
+	// T = a * b
+	mul(0(DI),8(DI),16(DI),24(DI),32(DI),40(DI), 0(SI), 0(SP))
+
+	// Reduce T.
+	fp384Reduce(0(SP))
+
+	MOVQ c+0(FP), DI
+	storeBlock(R14,SI,AX,BX,CX,DX, 0(DI))
+
+end:
+	RET
+
+TEXT ·fp384Cmov(SB), NOSPLIT, $0
+    MOVQ x+0(FP), DI
+    MOVQ y+8(FP), SI
+    MOVQ b+16(FP), BX
+    TESTQ BX, BX
+    MOVQ  0(DI), AX; MOVQ  0(SI), DX; CMOVQNE DX, AX; MOVQ AX,  0(DI);
+    MOVQ  8(DI), AX; MOVQ  8(SI), DX; CMOVQNE DX, AX; MOVQ AX,  8(DI);
+    MOVQ 16(DI), AX; MOVQ 16(SI), DX; CMOVQNE DX, AX; MOVQ AX, 16(DI);
+    MOVQ 24(DI), AX; MOVQ 24(SI), DX; CMOVQNE DX, AX; MOVQ AX, 24(DI);
+    MOVQ 32(DI), AX; MOVQ 32(SI), DX; CMOVQNE DX, AX; MOVQ AX, 32(DI);
+    MOVQ 40(DI), AX; MOVQ 40(SI), DX; CMOVQNE DX, AX; MOVQ AX, 40(DI);
+    RET
diff --git a/vendor/github.com/cloudflare/circl/ecc/p384/arith_arm64.s b/vendor/github.com/cloudflare/circl/ecc/p384/arith_arm64.s
new file mode 100644
index 00000000..a02e76d5
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/p384/arith_arm64.s
@@ -0,0 +1,511 @@
+// +build arm64,!purego
+
+#include "textflag.h"
+
+TEXT ·fp384Cmov(SB), NOSPLIT, $0
+    MOVD x+0(FP), R0
+    MOVD y+8(FP), R1
+    MOVW b+16(FP), R2
+    CMP $0, R2
+    LDP   0(R0), (R3, R5)
+    LDP   0(R1), (R4, R6)
+    CSEL NE,R4,R3,R7
+    CSEL NE,R6,R5,R8
+    STP  (R7, R8),  0(R0)
+    LDP  16(R0), (R3, R5)
+    LDP  16(R1), (R4, R6)
+    CSEL NE,R4,R3,R7
+    CSEL NE,R6,R5,R8
+    STP  (R7, R8), 16(R0)
+    LDP  32(R0), (R3, R5)
+    LDP  32(R1), (R4, R6)
+    CSEL NE,R4,R3,R7
+    CSEL NE,R6,R5,R8
+    STP  (R7, R8), 32(R0)
+    RET
+
+// Compute c = -a mod p
+TEXT ·fp384Neg(SB), NOSPLIT, $0-16
+	MOVD	c+0(FP), R0
+	MOVD	a+8(FP), R1
+
+	// Load p in R2-R7, a in R8-R13
+	// Compute p-a in R8-R13
+	LDP	·p+0(SB), (R2, R3)
+	LDP	0(R1), (R8, R9)
+	SUBS	R8, R2, R8
+	SBCS	R9, R3, R9
+	LDP	·p+16(SB), (R4, R5)
+	LDP	16(R1), (R10, R11)
+	SBCS	R10, R4, R10
+	SBCS	R11, R5, R11
+	LDP	·p+32(SB), (R6, R7)
+	LDP	32(R1), (R12, R13)
+	SBCS	R12, R6, R12
+	SBC	R13, R7, R13
+
+	// Compute (p-a)-p in R2-R7
+	SUBS	R2,  R8, R2
+	SBCS	R3,  R9, R3
+	SBCS	R4, R10, R4
+	SBCS	R5, R11, R5
+	SBCS	R6, R12, R6
+	SBCS	R7, R13, R7
+
+	// If (p-a)-p < 0 (nearly always), return p-a
+	// Only return (p-a)-p for a = 0
+	// Store result in c
+	CSEL	CC, R8, R2, R2
+	CSEL	CC, R9, R3, R3
+	STP	(R2, R3), 0(R0)
+	CSEL	CC, R10, R4, R4
+	CSEL	CC, R11, R5, R5
+	STP	(R4, R5), 16(R0)
+	CSEL	CC, R12, R6, R6
+	CSEL	CC, R13, R7, R7
+	STP	(R6, R7), 32(R0)
+
+	RET
+
+// Compute c = a+b mod p
+TEXT ·fp384Add(SB), NOSPLIT, $0-24
+	MOVD	c+0(FP), R0
+	MOVD	a+8(FP), R1
+	MOVD	b+16(FP), R2
+
+	// Load a in R3-R8, b in R9-R14
+	// Compute a+b in R3-R9
+	LDP	0(R1), (R3, R4)
+	LDP	0(R2), (R9, R10)
+	ADDS	R9, R3
+	ADCS	R10, R4
+	LDP	16(R1), (R5, R6)
+	LDP	16(R2), (R11, R12)
+	ADCS	R11, R5
+	ADCS	R12, R6
+	LDP	32(R1), (R7, R8)
+	LDP	32(R2), (R13, R14)
+	ADCS	R13, R7
+	ADCS	R14, R8
+	ADC	ZR, ZR, R9
+
+	// Load p in R10-R15
+	LDP	·p+ 0(SB), (R10, R11)
+	LDP	·p+16(SB), (R12, R13)
+	LDP	·p+32(SB), (R14, R15)
+
+	// Compute a+b-p in R10-R16
+	SUBS	R10, R3, R10
+	SBCS	R11, R4, R11
+	SBCS	R12, R5, R12
+	SBCS	R13, R6, R13
+	SBCS	R14, R7, R14
+	SBCS	R15, R8, R15
+	SBCS	 ZR, R9, R16
+
+	// If a+b-p is negative, return a+b
+	// Store result in c
+	CSEL	CC, R3, R10, R3
+	CSEL	CC, R4, R11, R4
+	STP	(R3, R4), 0(R0)
+	CSEL	CC, R5, R12, R5
+	CSEL	CC, R6, R13, R6
+	STP	(R5, R6), 16(R0)
+	CSEL	CC, R7, R14, R7
+	CSEL	CC, R8, R15, R8
+	STP	(R7, R8), 32(R0)
+
+	RET
+
+// Compute c = a-b mod p
+TEXT ·fp384Sub(SB), NOSPLIT, $0-24
+	MOVD	c+0(FP), R0
+	MOVD	a+8(FP), R1
+	MOVD	b+16(FP), R2
+
+	// Load a in R3-R8, b in R9-R14
+	// Compute a-b in R3-R9
+	LDP	0(R1), (R3, R4)
+	LDP	0(R2), (R9, R10)
+	SUBS	R9, R3
+	SBCS	R10, R4
+	LDP	16(R1), (R5, R6)
+	LDP	16(R2), (R11, R12)
+	SBCS	R11, R5
+	SBCS	R12, R6
+	LDP	32(R1), (R7, R8)
+	LDP	32(R2), (R13, R14)
+	SBCS	R13, R7
+	SBCS	R14, R8
+	SBC	ZR, ZR, R9
+
+	// Load p in R10-R15
+	// If a-b < 0, (a-b)+p to R3-R8
+	// Store result in c
+	LDP	·p+ 0(SB), (R10, R11)
+	AND	R9, R10
+	LDP	·p+16(SB), (R12, R13)
+	AND	R9, R11
+	AND	R9, R12
+	LDP	·p+32(SB), (R14, R15)
+	AND	R9, R13
+	AND	R9, R14
+	AND	R9, R15
+
+	ADDS	R10, R3
+	ADCS	R11, R4
+	STP	(R3, R4), 0(R0)
+	ADCS	R12, R5
+	ADCS	R13, R6
+	STP	(R5, R6), 16(R0)
+	ADCS	R14, R7
+	ADC	R15, R8
+	STP	(R7, R8), 32(R0)
+
+	RET
+
+// Expects that A0*B0 is already in C0(low),C3(high) and A0*B1 in C1(low),C2(high)
+// C0 is not actually touched
+// Result of (A0-A2) * (B0-B2) will be in C0-C5
+// Inputs remain intact
+#define mul192x192comba(A0,A1,A2, B0,B1,B2, C0,C1,C2,C3,C4,C5, S0,S1,S2,S3) \
+	MUL	A1, B0, S2	\
+	UMULH	A1, B0, S3	\
+				\
+	ADDS	C3, C1		\
+	ADCS	ZR, C2		\
+	ADC	ZR, ZR, C3	\
+				\
+	MUL	A0, B2, S0	\
+	UMULH	A0, B2, S1	\
+				\
+	ADDS	S2, C1		\
+	ADCS	S3, C2		\
+	ADC	ZR, C3		\
+				\
+	MUL	A1, B1, S2	\
+	UMULH	A1, B1, S3	\
+				\
+	ADDS	S0, C2		\
+	ADCS	S1, C3		\
+	ADC	ZR, ZR, C4	\
+				\
+	MUL	A2, B0, S0	\
+	UMULH	A2, B0, S1	\
+				\
+	ADDS	S2, C2		\
+	ADCS	S3, C3		\
+	ADC	ZR, C4		\
+				\
+	MUL	A1, B2, S2	\
+	UMULH	A1, B2, S3	\
+				\
+	ADDS	S0, C2		\
+	ADCS	S1, C3		\
+	ADC	ZR, C4		\
+				\
+	MUL	A2, B1, S0	\
+	UMULH	A2, B1, S1	\
+				\
+	ADDS	S2, C3		\
+	ADCS	S3, C4		\
+	ADC	ZR, ZR, C5	\
+				\
+	MUL	A2, B2, S2	\
+	UMULH	A2, B2, S3	\
+				\
+	ADDS	S0, C3		\
+	ADCS	S1, C4		\
+	ADC	ZR, C5		\
+				\
+	ADDS	S2, C4		\
+	ADC	S3, C5
+
+
+// Assumes that there are at least 96 bytes left on the stack
+// Expects that X and Y point to input
+// X and Y get overwritten, Z0 will be in Y
+#define mul384x384karatsuba(X,Y, Z1,Z2,Z3,Z4,Z5,Z6,Z7,Z8,Z9,Z10,Z11, T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12) \
+	/* Load a in Z1-Z6, b in T12,Z7-Z11 */ \
+	LDP	 0(X), ( Z1,  Z2)	\
+	LDP	 0(Y), (T12,  Z7)	\
+	MUL	Z1,  Z7, T1		\
+	UMULH	Z1, T12, T3		\
+	LDP	16(X), ( Z3,  Z4)	\
+	LDP	16(Y), ( Z8,  Z9)	\
+	MUL	Z1, T12, T0		\
+	UMULH	Z1,  Z7, T2		\
+	LDP	32(X), ( Z5,  Z6)	\
+	LDP	32(Y), (Z10, Z11)	\
+					\
+	/* Compute aL*bL in T0-T5 */	\
+	mul192x192comba(Z1,Z2,Z3, T12,Z7,Z8, T0,T1,T2,T3,T4,T5, T6,T7,T8,T9) \
+					\
+	/* Compute aH*bH in T6-T11, destroys aL and bL */ \
+	MUL	Z4, Z10, T7		\
+	MUL	Z4,  Z9, T6		\
+	UMULH	Z4,  Z9, T9		\
+	UMULH	Z4, Z10, T8		\
+	mul192x192comba(Z4,Z5,Z6, Z9,Z10,Z11, T6,T7,T8,T9,T10,T11, Z1,Z2,T12,Z7) \
+					\
+	/* Compute aL*bL + aH*bH in Z1-Z6,T12, destroys aH */ \
+	ADDS	T0,  T6,  Z1		\
+	ADCS	T1,  T7,  Z2		\
+	ADCS	T2,  T8,  Z3		\
+	ADCS	T3,  T9,  Z4		\
+	ADCS	T4, T10,  Z5		\
+	ADCS	T5, T11,  Z6		\
+	ADC	ZR,  ZR, T12		\
+					\
+	/* Add to T0-T11 and store on stack */ \
+	STP	( T0,  T1), -16(RSP)	\
+	ADDS	Z1, T3			\
+	STP	( T2,  T3), -32(RSP)	\
+	ADCS	Z2, T4			\
+	ADCS	Z3, T5			\
+	STP	( T4,  T5), -48(RSP)	\
+	ADCS	Z4, T6			\
+	ADCS	Z5, T7			\
+	STP	( T6,  T7), -64(RSP)	\
+	ADCS	Z6, T8			\
+	ADC	ZR, T12			\
+	STP	( T8,  T9), -80(RSP)	\
+	STP	(T10, T11), -96(RSP)	\
+					\
+	/* Load a to Z1-Z6 */		\
+	LDP	 0(X), (Z1, Z2)		\
+	LDP	16(X), (Z3, Z4)		\
+	LDP	32(X), (Z5, Z6)		\
+					\
+	/* Compute |aL-aH| to Z1-Z3, keep borrow in X */ \
+	SUBS	Z4, Z1			\
+	SBCS	Z5, Z2			\
+	SBCS	Z6, Z3			\
+	SBC	ZR, ZR, X		\
+	NEGS	Z1, Z4			\
+	NGCS	Z2, Z5			\
+	NGC	Z3, Z6			\
+	ADDS	$1, X			\
+					\
+	/* Load b to Z7-Z11,T0 */	\
+	LDP	 0(Y), ( Z7,  Z8)	\
+	LDP	16(Y), ( Z9, Z10)	\
+	LDP	32(Y), (Z11,  T0)	\
+					\
+	CSEL	EQ, Z4, Z1, Z1		\
+	CSEL	EQ, Z5, Z2 ,Z2		\
+	CSEL	EQ, Z6, Z3, Z3		\
+					\
+	/* Compute |bH-bL| to Z7-Z9, keep borrow in Y */ \
+	SUBS	Z7, Z10			\
+	SBCS	Z8, Z11			\
+	SBCS	Z9, T0			\
+	SBC	ZR, ZR, Y		\
+	NEGS	Z10, Z7			\
+	NGCS	Z11, Z8			\
+	NGC	T0, Z9			\
+	ADDS	$1, Y			\
+	CSEL	EQ, Z7, Z10, Z7		\
+	CSEL	EQ, Z8, Z11, Z8		\
+	CSEL	EQ, Z9,  T0, Z9		\
+					\
+	/* Combine borrows */		\
+	EOR	Y, X			\
+					\
+	/* Compute |aL-aH|*|bH-bL| to Z10,Z11,T0-T3 */ \
+	MUL	Z1, Z8, Z11		\
+	MUL	Z1, Z7, Z10		\
+	UMULH	Z1, Z8,  T0		\
+	UMULH	Z1, Z7,  T1		\
+	mul192x192comba(Z1,Z2,Z3, Z7,Z8,Z9, Z10,Z11,T0,T1,T2,T3, T4,T5,T6,T7) \
+					\
+	/* The result has to be negated if exactly one of the operands was negative */ \
+	NEGS	Z10,  Y			\
+	NGCS	Z11, Z1			\
+	NGCS	 T0, Z2			\
+	NGCS	 T1, Z3			\
+	NGCS	 T2, Z4			\
+	NGCS	 T3, Z5			\
+	NGC	 ZR, T4			\
+					\
+	AND	T4, X			\
+	CMP	$1, X			\
+	CSEL	EQ,  Y, Z10, Z10	\
+	CSEL	EQ, Z1, Z11, Z11	\
+	CSEL	EQ, Z2,  T0,  T0	\
+	CSEL	EQ, Z3,  T1,  T1	\
+	CSEL	EQ, Z4,  T2,  T2	\
+	CSEL	EQ, Z5,  T3,  T3	\
+					\
+	/* Add that to the middle part */ \
+	LDP	-16(RSP), (  Y,  Z1)	\
+	LDP	-32(RSP), ( Z2,  Z3)	\
+	LDP	-48(RSP), ( Z4,  Z5)	\
+	ADDS	Z10, Z3			\
+	ADCS	Z11, Z4			\
+	LDP	-64(RSP), ( Z6,  Z7)	\
+	ADCS	T0, Z5			\
+	ADCS	T1, Z6			\
+	LDP	-80(RSP), ( Z8,  Z9)	\
+	ADCS	T2, Z7			\
+	ADCS	T3, Z8			\
+	LDP	-96(RSP), (Z10, Z11)	\
+	ADCS	T12, Z9			\
+	ADCS	ZR, Z10			\
+	ADC	ZR, Z11			\
+	SUBS	X, Z9			\
+	SBCS	ZR, Z10			\
+	SBC	ZR, Z11
+
+// Compute c = a*b*R^-1 mod p
+TEXT ·fp384Mul(SB), NOSPLIT, $200-24
+	MOVD	c+0(FP), R0
+	MOVD	a+8(FP), R1
+	MOVD	b+16(FP), R2
+
+	// Compute a*b in R2-R13
+	mul384x384karatsuba(R1, R2, R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,R13, R14,R15,R16,R17,R19,R20,R21,R22,R23,R24,R25,R26,R27)
+
+	// Store a*b on the stack
+	STP	( R2,  R3), -112(RSP)
+	STP	( R4,  R5), -128(RSP)
+	STP	( R6,  R7), -144(RSP)
+	STP	( R8,  R9), -160(RSP)
+	STP	(R10, R11), -176(RSP)
+	STP	(R12, R13), -192(RSP)
+
+	// Compute m = a*b*pp mod 2^384 in R19-R24
+	// Store it temporarily in c
+	MOVD	·pp+0(SB), R14
+	MUL	R14, R2, R19
+	UMULH	R14, R2, R20
+
+	MUL	R14, R3, R16
+	UMULH	R14, R3, R21
+	ADDS	R16, R20
+	ADC	 ZR, R21
+
+	MUL	R14, R4, R16
+	UMULH	R14, R4, R22
+	ADDS	R16, R21
+	ADC	 ZR, R22
+
+	MUL	R14, R5, R16
+	UMULH	R14, R5, R23
+	ADDS	R16, R22
+	ADC	 ZR, R23
+
+	MUL	R14, R6, R16
+	UMULH	R14, R6, R24
+	ADDS	R16, R23
+	ADC	 ZR, R24
+
+	MADD	R14, R24, R7, R24
+
+	// ·pp+8(SB) = 1, so we can just add
+	ADDS	R2, R20
+	STP	(R19, R20), 0(R0)
+	ADCS	R3, R21
+	ADCS	R4, R22
+	ADCS	R5, R23
+	ADC	R6, R24
+
+	LDP	·pp+16(SB), (R14, R15)
+	MUL	R14, R2, R8
+	UMULH	R14, R2, R9
+
+	MUL	R14, R3, R16
+	UMULH	R14, R3, R10
+	ADDS	R16, R9
+	ADC	 ZR, R10
+
+	MUL	R14, R4, R16
+	UMULH	R14, R4, R11
+	ADDS	R16, R10
+	ADC	 ZR, R11
+
+	MUL	R14, R5, R16
+	ADD	R16, R11
+
+	ADDS	 R8, R21
+	ADCS	 R9, R22
+	ADCS	R10, R23
+	ADC	R11, R24
+
+	MUL	R15, R2, R8
+	UMULH	R15, R2, R9
+
+	MUL	R15, R3, R16
+	UMULH	R15, R3, R10
+	ADDS	R16, R9
+	ADC	 ZR, R10
+
+	MADD	R15, R10, R4, R10
+
+	ADDS	R8, R22
+	STP	(R21, R22), 16(R0)
+	ADCS	R9, R23
+	ADC	R10, R24
+
+	LDP	·pp+32(SB), (R14, R15)
+	MUL	R14, R2, R8
+	UMULH	R14, R2, R9
+
+	MADD	R14, R9, R3, R9
+
+	ADDS	R8, R23
+	ADC	R9, R24
+
+	MADD	R15, R24, R2, R24
+	STP	(R23, R24), 32(R0)
+
+	// Compute m*p in R1-R12
+	MOVD	$·p(SB), R1
+	mul384x384karatsuba(R0, R1, R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12, R13,R14,R15,R16,R17,R19,R20,R21,R22,R23,R24,R25,R26)
+
+	// Add a*b to m*p in R1-R12,R26
+	LDP	-112(RSP), (R13, R14)
+	ADDS	R13, R1
+	LDP	-128(RSP), (R15, R16)
+	ADCS	R14, R2
+	ADCS	R15, R3
+	LDP	-144(RSP), (R17, R19)
+	ADCS	R16, R4
+	ADCS	R17, R5
+	LDP	-160(RSP), (R20, R21)
+	ADCS	R19, R6
+	ADCS	R20, R7
+	LDP	-176(RSP), (R22, R23)
+	ADCS	R21, R8
+	ADCS	R22, R9
+	LDP	-192(RSP), (R24, R25)
+	ADCS	R23, R10
+	ADCS	R24, R11
+	ADCS	R25, R12
+	ADC	ZR, ZR, R26
+
+	// Reduce the top half mod p
+	LDP	·p+ 0(SB), (R13, R14)
+	SUBS	R13, R7, R13
+	LDP	·p+16(SB), (R15, R16)
+	SBCS	R14, R8, R14
+	SBCS	R15, R9, R15
+	LDP	·p+32(SB), (R17, R19)
+	SBCS	R16, R10, R16
+	SBCS	R17, R11, R17
+	SBCS	R19, R12, R19
+	SBCS	ZR, R26
+
+	// Store result in c
+	MOVD	c+0(FP), R0
+	CSEL	CC, R7, R13, R7
+	CSEL	CC, R8, R14, R8
+	STP	( R7,  R8),  0(R0)
+	CSEL	CC, R9, R15, R9
+	CSEL	CC, R10, R16, R10
+	STP	( R9, R10), 16(R0)
+	CSEL	CC, R11, R17, R11
+	CSEL	CC, R12, R19, R12
+	STP	(R11, R12), 32(R0)
+
+	RET
diff --git a/vendor/github.com/cloudflare/circl/ecc/p384/doc.go b/vendor/github.com/cloudflare/circl/ecc/p384/doc.go
new file mode 100644
index 00000000..807676fb
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/p384/doc.go
@@ -0,0 +1,10 @@
+// Package p384 provides optimized elliptic curve operations on the P-384 curve.
+//
+// These are some improvements over crypto/elliptic package:
+//   - Around 10x faster in amd64 architecture.
+//   - Reduced number of memory allocations.
+//   - Native support for arm64 architecture.
+//   - ScalarMult is performed using a constant-time algorithm.
+//   - ScalarBaseMult fallbacks into ScalarMult.
+//   - A new method included for double-point multiplication.
+package p384
diff --git a/vendor/github.com/cloudflare/circl/ecc/p384/p384.go b/vendor/github.com/cloudflare/circl/ecc/p384/p384.go
new file mode 100644
index 00000000..75005d08
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/p384/p384.go
@@ -0,0 +1,28 @@
+package p384
+
+import (
+	"crypto/elliptic"
+	"math/big"
+)
+
+// Curve is used to provide the extended functionality and performance of
+// elliptic.Curve interface.
+type Curve interface {
+	elliptic.Curve
+	// IsAtInfinity returns True is the point is the identity point.
+	IsAtInfinity(X, Y *big.Int) bool
+	// CombinedMult calculates P=mG+nQ, where G is the generator and
+	// Q=(Qx,Qy). The scalars m and n are positive integers in big-endian form.
+	// Runs in non-constant time to be used in signature verification.
+	CombinedMult(Qx, Qy *big.Int, m, n []byte) (Px, Py *big.Int)
+}
+
+// Params returns the parameters for the curve. Note: The value returned by
+// this function fallbacks to the stdlib implementation of elliptic curve
+// operations. Use this method to only recover elliptic curve parameters.
+func (c curve) Params() *elliptic.CurveParams { return elliptic.P384().Params() }
+
+// IsAtInfinity returns True is the point is the identity point.
+func (c curve) IsAtInfinity(x, y *big.Int) bool {
+	return x.Sign() == 0 && y.Sign() == 0
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/p384/p384_generic.go b/vendor/github.com/cloudflare/circl/ecc/p384/p384_generic.go
new file mode 100644
index 00000000..9b14feae
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/p384/p384_generic.go
@@ -0,0 +1,21 @@
+//go:build purego || (!amd64 && !arm64)
+// +build purego !amd64,!arm64
+
+package p384
+
+import (
+	"crypto/elliptic"
+	"math/big"
+)
+
+type curve struct{ elliptic.Curve }
+
+func P384() Curve { return curve{elliptic.P384()} }
+
+// CombinedMult calculates P=mG+nQ, where G is the generator and Q=(x,y,z).
+// The scalars m and n are integers in big-endian form. Non-constant time.
+func (c curve) CombinedMult(xQ, yQ *big.Int, m, n []byte) (xP, yP *big.Int) {
+	x1, y1 := c.ScalarBaseMult(m)
+	x2, y2 := c.ScalarMult(xQ, yQ, n)
+	return c.Add(x1, y1, x2, y2)
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/p384/p384opt.go b/vendor/github.com/cloudflare/circl/ecc/p384/p384opt.go
new file mode 100644
index 00000000..5f744eac
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/p384/p384opt.go
@@ -0,0 +1,181 @@
+//go:build (!purego && arm64) || (!purego && amd64)
+// +build !purego,arm64 !purego,amd64
+
+package p384
+
+import (
+	"crypto/subtle"
+	"math/big"
+
+	"github.com/cloudflare/circl/math"
+)
+
+type curve struct{}
+
+// P384 returns a Curve which implements P-384 (see FIPS 186-3, section D.2.4).
+func P384() Curve { return curve{} }
+
+// IsOnCurve reports whether the given (x,y) lies on the curve.
+func (c curve) IsOnCurve(x, y *big.Int) bool {
+	x1, y1 := &fp384{}, &fp384{}
+	x1.SetBigInt(x)
+	y1.SetBigInt(y)
+	montEncode(x1, x1)
+	montEncode(y1, y1)
+
+	y2, x3 := &fp384{}, &fp384{}
+	fp384Sqr(y2, y1)
+	fp384Sqr(x3, x1)
+	fp384Mul(x3, x3, x1)
+
+	threeX := &fp384{}
+	fp384Add(threeX, x1, x1)
+	fp384Add(threeX, threeX, x1)
+
+	fp384Sub(x3, x3, threeX)
+	fp384Add(x3, x3, &bb)
+
+	return *y2 == *x3
+}
+
+// Add returns the sum of (x1,y1) and (x2,y2).
+func (c curve) Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int) {
+	P := newAffinePoint(x1, y1).toJacobian()
+	P.mixadd(P, newAffinePoint(x2, y2))
+	return P.toAffine().toInt()
+}
+
+// Double returns 2*(x,y).
+func (c curve) Double(x1, y1 *big.Int) (x, y *big.Int) {
+	P := newAffinePoint(x1, y1).toJacobian()
+	P.double()
+	return P.toAffine().toInt()
+}
+
+// reduceScalar shorten a scalar modulo the order of the curve.
+func (c curve) reduceScalar(k []byte) []byte {
+	bigK := new(big.Int).SetBytes(k)
+	bigK.Mod(bigK, c.Params().N)
+	return bigK.FillBytes(make([]byte, sizeFp))
+}
+
+// toOdd performs k = (-k mod N) if k is even.
+func (c curve) toOdd(k []byte) ([]byte, int) {
+	var X, Y big.Int
+	X.SetBytes(k)
+	Y.Neg(&X).Mod(&Y, c.Params().N)
+	isEven := 1 - int(X.Bit(0))
+	x := X.Bytes()
+	y := Y.Bytes()
+
+	if len(x) < len(y) {
+		x = append(make([]byte, len(y)-len(x)), x...)
+	} else if len(x) > len(y) {
+		y = append(make([]byte, len(x)-len(y)), y...)
+	}
+	subtle.ConstantTimeCopy(isEven, x, y)
+	return x, isEven
+}
+
+// ScalarMult returns (Qx,Qy)=k*(Px,Py) where k is a number in big-endian form.
+func (c curve) ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int) {
+	return c.scalarMultOmega(x1, y1, k, 5)
+}
+
+func (c curve) scalarMultOmega(x1, y1 *big.Int, k []byte, omega uint) (x, y *big.Int) {
+	k = c.reduceScalar(k)
+	oddK, isEvenK := c.toOdd(k)
+
+	var scalar big.Int
+	scalar.SetBytes(oddK)
+	if scalar.Sign() == 0 {
+		return new(big.Int), new(big.Int)
+	}
+	const bitsN = uint(384)
+	L := math.SignedDigit(&scalar, omega, bitsN)
+
+	var R jacobianPoint
+	Q := zeroPoint().toJacobian()
+	TabP := newAffinePoint(x1, y1).oddMultiples(omega)
+	for i := len(L) - 1; i > 0; i-- {
+		for j := uint(0); j < omega-1; j++ {
+			Q.double()
+		}
+		idx := absolute(L[i]) >> 1
+		for j := range TabP {
+			R.cmov(&TabP[j], subtle.ConstantTimeEq(int32(j), idx))
+		}
+		R.cneg(int(L[i]>>31) & 1)
+		Q.add(Q, &R)
+	}
+	// Calculate the last iteration using complete addition formula.
+	for j := uint(0); j < omega-1; j++ {
+		Q.double()
+	}
+	idx := absolute(L[0]) >> 1
+	for j := range TabP {
+		R.cmov(&TabP[j], subtle.ConstantTimeEq(int32(j), idx))
+	}
+	R.cneg(int(L[0]>>31) & 1)
+	QQ := Q.toProjective()
+	QQ.completeAdd(QQ, R.toProjective())
+	QQ.cneg(isEvenK)
+	return QQ.toAffine().toInt()
+}
+
+// ScalarBaseMult returns k*G, where G is the base point of the group
+// and k is an integer in big-endian form.
+func (c curve) ScalarBaseMult(k []byte) (x, y *big.Int) {
+	params := c.Params()
+	return c.ScalarMult(params.Gx, params.Gy, k)
+}
+
+// CombinedMult calculates P=mG+nQ, where G is the generator and Q=(x,y,z).
+// The scalars m and n are integers in big-endian form. Non-constant time.
+func (c curve) CombinedMult(xQ, yQ *big.Int, m, n []byte) (xP, yP *big.Int) {
+	const nOmega = uint(5)
+	var k big.Int
+	k.SetBytes(m)
+	nafM := math.OmegaNAF(&k, baseOmega)
+	k.SetBytes(n)
+	nafN := math.OmegaNAF(&k, nOmega)
+
+	if len(nafM) > len(nafN) {
+		nafN = append(nafN, make([]int32, len(nafM)-len(nafN))...)
+	} else if len(nafM) < len(nafN) {
+		nafM = append(nafM, make([]int32, len(nafN)-len(nafM))...)
+	}
+
+	TabQ := newAffinePoint(xQ, yQ).oddMultiples(nOmega)
+	var jR jacobianPoint
+	var aR affinePoint
+	P := zeroPoint().toJacobian()
+	for i := len(nafN) - 1; i >= 0; i-- {
+		P.double()
+		// Generator point
+		if nafM[i] != 0 {
+			idxM := absolute(nafM[i]) >> 1
+			aR = baseOddMultiples[idxM]
+			if nafM[i] < 0 {
+				aR.neg()
+			}
+			P.mixadd(P, &aR)
+		}
+		// Input point
+		if nafN[i] != 0 {
+			idxN := absolute(nafN[i]) >> 1
+			jR = TabQ[idxN]
+			if nafN[i] < 0 {
+				jR.neg()
+			}
+			P.add(P, &jR)
+		}
+	}
+	return P.toAffine().toInt()
+}
+
+// absolute returns always a positive value.
+func absolute(x int32) int32 {
+	mask := x >> 31
+	return (x + mask) ^ mask
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/p384/point.go b/vendor/github.com/cloudflare/circl/ecc/p384/point.go
new file mode 100644
index 00000000..e20b57b0
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/p384/point.go
@@ -0,0 +1,358 @@
+//go:build (!purego && arm64) || (!purego && amd64)
+// +build !purego,arm64 !purego,amd64
+
+package p384
+
+import (
+	"fmt"
+	"math/big"
+)
+
+// affinePoint represents an affine point of the curve. The point at
+// infinity is (0,0) leveraging that it is not an affine point.
+type affinePoint struct{ x, y fp384 }
+
+func newAffinePoint(x, y *big.Int) *affinePoint {
+	var P affinePoint
+	P.x.SetBigInt(x)
+	P.y.SetBigInt(y)
+	montEncode(&P.x, &P.x)
+	montEncode(&P.y, &P.y)
+	return &P
+}
+
+func zeroPoint() *affinePoint { return &affinePoint{} }
+
+func (ap affinePoint) String() string {
+	if ap.isZero() {
+		return "inf"
+	}
+	return fmt.Sprintf("x: %v\ny: %v", ap.x, ap.y)
+}
+
+func (ap *affinePoint) isZero() bool {
+	zero := fp384{}
+	return ap.x == zero && ap.y == zero
+}
+
+func (ap *affinePoint) neg() { fp384Neg(&ap.y, &ap.y) }
+
+func (ap *affinePoint) toInt() (x, y *big.Int) {
+	var x1, y1 fp384
+	montDecode(&x1, &ap.x)
+	montDecode(&y1, &ap.y)
+	return x1.BigInt(), y1.BigInt()
+}
+
+func (ap *affinePoint) toJacobian() *jacobianPoint {
+	var P jacobianPoint
+	if ap.isZero() {
+		montEncode(&P.x, &fp384{1})
+		montEncode(&P.y, &fp384{1})
+	} else {
+		P.x = ap.x
+		P.y = ap.y
+		montEncode(&P.z, &fp384{1})
+	}
+	return &P
+}
+
+func (ap *affinePoint) toProjective() *projectivePoint {
+	var P projectivePoint
+	if ap.isZero() {
+		montEncode(&P.y, &fp384{1})
+	} else {
+		P.x = ap.x
+		P.y = ap.y
+		montEncode(&P.z, &fp384{1})
+	}
+	return &P
+}
+
+// OddMultiples calculates the points iP for i={1,3,5,7,..., 2^(n-1)-1}
+// Ensure that 1 < n < 31, otherwise it returns an empty slice.
+func (ap affinePoint) oddMultiples(n uint) []jacobianPoint {
+	var t []jacobianPoint
+	if n > 1 && n < 31 {
+		P := ap.toJacobian()
+		s := int32(1) << (n - 1)
+		t = make([]jacobianPoint, s)
+		t[0] = *P
+		_2P := *P
+		_2P.double()
+		for i := int32(1); i < s; i++ {
+			t[i].add(&t[i-1], &_2P)
+		}
+	}
+	return t
+}
+
+// p2Point is a point in P^2
+type p2Point struct{ x, y, z fp384 }
+
+func (P *p2Point) String() string {
+	return fmt.Sprintf("x: %v\ny: %v\nz: %v", P.x, P.y, P.z)
+}
+
+func (P *p2Point) neg() { fp384Neg(&P.y, &P.y) }
+
+// condNeg if P is negated if b=1.
+func (P *p2Point) cneg(b int) {
+	var mY fp384
+	fp384Neg(&mY, &P.y)
+	fp384Cmov(&P.y, &mY, b)
+}
+
+// cmov sets P to Q if b=1.
+func (P *p2Point) cmov(Q *p2Point, b int) {
+	fp384Cmov(&P.x, &Q.x, b)
+	fp384Cmov(&P.y, &Q.y, b)
+	fp384Cmov(&P.z, &Q.z, b)
+}
+
+func (P *p2Point) toInt() (x, y, z *big.Int) {
+	var x1, y1, z1 fp384
+	montDecode(&x1, &P.x)
+	montDecode(&y1, &P.y)
+	montDecode(&z1, &P.z)
+	return x1.BigInt(), y1.BigInt(), z1.BigInt()
+}
+
+// jacobianPoint represents a point in Jacobian coordinates. The point at
+// infinity is any point (x,y,0) such that x and y are different from 0.
+type jacobianPoint struct{ p2Point }
+
+func (P *jacobianPoint) isZero() bool {
+	zero := fp384{}
+	return P.x != zero && P.y != zero && P.z == zero
+}
+
+func (P *jacobianPoint) toAffine() *affinePoint {
+	var aP affinePoint
+	z, z2 := &fp384{}, &fp384{}
+	fp384Inv(z, &P.z)
+	fp384Sqr(z2, z)
+	fp384Mul(&aP.x, &P.x, z2)
+	fp384Mul(&aP.y, &P.y, z)
+	fp384Mul(&aP.y, &aP.y, z2)
+	return &aP
+}
+
+func (P *jacobianPoint) cmov(Q *jacobianPoint, b int) { P.p2Point.cmov(&Q.p2Point, b) }
+
+// add calculates P=Q+R such that Q and R are different than the identity point,
+// and Q!==R. This function cannot be used for doublings.
+func (P *jacobianPoint) add(Q, R *jacobianPoint) {
+	if Q.isZero() {
+		*P = *R
+		return
+	} else if R.isZero() {
+		*P = *Q
+		return
+	}
+
+	// Cohen-Miyagi-Ono (1998)
+	// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-1998-cmo-2
+	X1, Y1, Z1 := &Q.x, &Q.y, &Q.z
+	X2, Y2, Z2 := &R.x, &R.y, &R.z
+	Z1Z1, Z2Z2, U1, U2 := &fp384{}, &fp384{}, &fp384{}, &fp384{}
+	H, HH, HHH, RR := &fp384{}, &fp384{}, &fp384{}, &fp384{}
+	V, t4, t5, t6, t7, t8 := &fp384{}, &fp384{}, &fp384{}, &fp384{}, &fp384{}, &fp384{}
+	t0, t1, t2, t3, S1, S2 := &fp384{}, &fp384{}, &fp384{}, &fp384{}, &fp384{}, &fp384{}
+	fp384Sqr(Z1Z1, Z1)     // Z1Z1 = Z1 ^ 2
+	fp384Sqr(Z2Z2, Z2)     // Z2Z2 = Z2 ^ 2
+	fp384Mul(U1, X1, Z2Z2) // U1 = X1 * Z2Z2
+	fp384Mul(U2, X2, Z1Z1) // U2 = X2 * Z1Z1
+	fp384Mul(t0, Z2, Z2Z2) // t0 = Z2 * Z2Z2
+	fp384Mul(S1, Y1, t0)   // S1 = Y1 * t0
+	fp384Mul(t1, Z1, Z1Z1) // t1 = Z1 * Z1Z1
+	fp384Mul(S2, Y2, t1)   // S2 = Y2 * t1
+	fp384Sub(H, U2, U1)    // H = U2 - U1
+	fp384Sqr(HH, H)        // HH = H ^ 2
+	fp384Mul(HHH, H, HH)   // HHH = H * HH
+	fp384Sub(RR, S2, S1)   // r = S2 - S1
+	fp384Mul(V, U1, HH)    // V = U1 * HH
+	fp384Sqr(t2, RR)       // t2 = r ^ 2
+	fp384Add(t3, V, V)     // t3 = V + V
+	fp384Sub(t4, t2, HHH)  // t4 = t2 - HHH
+	fp384Sub(&P.x, t4, t3) // X3 = t4 - t3
+	fp384Sub(t5, V, &P.x)  // t5 = V - X3
+	fp384Mul(t6, S1, HHH)  // t6 = S1 * HHH
+	fp384Mul(t7, RR, t5)   // t7 = r * t5
+	fp384Sub(&P.y, t7, t6) // Y3 = t7 - t6
+	fp384Mul(t8, Z2, H)    // t8 = Z2 * H
+	fp384Mul(&P.z, Z1, t8) // Z3 = Z1 * t8
+}
+
+// mixadd calculates P=Q+R such that P and Q different than the identity point,
+// and Q not in {P,-P, O}.
+func (P *jacobianPoint) mixadd(Q *jacobianPoint, R *affinePoint) {
+	if Q.isZero() {
+		*P = *R.toJacobian()
+		return
+	} else if R.isZero() {
+		*P = *Q
+		return
+	}
+
+	z1z1, u2 := &fp384{}, &fp384{}
+	fp384Sqr(z1z1, &Q.z)
+	fp384Mul(u2, &R.x, z1z1)
+
+	s2 := &fp384{}
+	fp384Mul(s2, &R.y, &Q.z)
+	fp384Mul(s2, s2, z1z1)
+	if Q.x == *u2 {
+		if Q.y != *s2 {
+			*P = *(zeroPoint().toJacobian())
+			return
+		}
+		*P = *Q
+		P.double()
+		return
+	}
+
+	h, r := &fp384{}, &fp384{}
+	fp384Sub(h, u2, &Q.x)
+	fp384Mul(&P.z, h, &Q.z)
+	fp384Sub(r, s2, &Q.y)
+
+	h2, h3 := &fp384{}, &fp384{}
+	fp384Sqr(h2, h)
+	fp384Mul(h3, h2, h)
+	h3y1 := &fp384{}
+	fp384Mul(h3y1, h3, &Q.y)
+
+	h2x1 := &fp384{}
+	fp384Mul(h2x1, h2, &Q.x)
+
+	fp384Sqr(&P.x, r)
+	fp384Sub(&P.x, &P.x, h3)
+	fp384Sub(&P.x, &P.x, h2x1)
+	fp384Sub(&P.x, &P.x, h2x1)
+
+	fp384Sub(&P.y, h2x1, &P.x)
+	fp384Mul(&P.y, &P.y, r)
+	fp384Sub(&P.y, &P.y, h3y1)
+}
+
+func (P *jacobianPoint) double() {
+	delta, gamma, alpha, alpha2 := &fp384{}, &fp384{}, &fp384{}, &fp384{}
+	fp384Sqr(delta, &P.z)
+	fp384Sqr(gamma, &P.y)
+	fp384Sub(alpha, &P.x, delta)
+	fp384Add(alpha2, &P.x, delta)
+	fp384Mul(alpha, alpha, alpha2)
+	*alpha2 = *alpha
+	fp384Add(alpha, alpha, alpha)
+	fp384Add(alpha, alpha, alpha2)
+
+	beta := &fp384{}
+	fp384Mul(beta, &P.x, gamma)
+
+	beta8 := &fp384{}
+	fp384Sqr(&P.x, alpha)
+	fp384Add(beta8, beta, beta)
+	fp384Add(beta8, beta8, beta8)
+	fp384Add(beta8, beta8, beta8)
+	fp384Sub(&P.x, &P.x, beta8)
+
+	fp384Add(&P.z, &P.y, &P.z)
+	fp384Sqr(&P.z, &P.z)
+	fp384Sub(&P.z, &P.z, gamma)
+	fp384Sub(&P.z, &P.z, delta)
+
+	fp384Add(beta, beta, beta)
+	fp384Add(beta, beta, beta)
+	fp384Sub(beta, beta, &P.x)
+
+	fp384Mul(&P.y, alpha, beta)
+
+	fp384Sqr(gamma, gamma)
+	fp384Add(gamma, gamma, gamma)
+	fp384Add(gamma, gamma, gamma)
+	fp384Add(gamma, gamma, gamma)
+	fp384Sub(&P.y, &P.y, gamma)
+}
+
+func (P *jacobianPoint) toProjective() *projectivePoint {
+	var hP projectivePoint
+	hP.y = P.y
+	fp384Mul(&hP.x, &P.x, &P.z)
+	fp384Sqr(&hP.z, &P.z)
+	fp384Mul(&hP.z, &hP.z, &P.z)
+	return &hP
+}
+
+// projectivePoint represents a point in projective homogeneous coordinates.
+// The point at infinity is (0,y,0) such that y is different from 0.
+type projectivePoint struct{ p2Point }
+
+func (P *projectivePoint) isZero() bool {
+	zero := fp384{}
+	return P.x == zero && P.y != zero && P.z == zero
+}
+
+func (P *projectivePoint) toAffine() *affinePoint {
+	var aP affinePoint
+	z := &fp384{}
+	fp384Inv(z, &P.z)
+	fp384Mul(&aP.x, &P.x, z)
+	fp384Mul(&aP.y, &P.y, z)
+	return &aP
+}
+
+// add calculates P=Q+R using complete addition formula for prime groups.
+func (P *projectivePoint) completeAdd(Q, R *projectivePoint) {
+	// Reference:
+	//   "Complete addition formulas for prime order elliptic curves" by
+	//   Costello-Renes-Batina. [Alg.4] (eprint.iacr.org/2015/1060).
+	X1, Y1, Z1 := &Q.x, &Q.y, &Q.z
+	X2, Y2, Z2 := &R.x, &R.y, &R.z
+	X3, Y3, Z3 := &fp384{}, &fp384{}, &fp384{}
+	t0, t1, t2, t3, t4 := &fp384{}, &fp384{}, &fp384{}, &fp384{}, &fp384{}
+	fp384Mul(t0, X1, X2)  // 1.  t0 ← X1 · X2
+	fp384Mul(t1, Y1, Y2)  // 2.  t1 ← Y1 · Y2
+	fp384Mul(t2, Z1, Z2)  // 3.  t2 ← Z1 · Z2
+	fp384Add(t3, X1, Y1)  // 4.  t3 ← X1 + Y1
+	fp384Add(t4, X2, Y2)  // 5.  t4 ← X2 + Y2
+	fp384Mul(t3, t3, t4)  // 6.  t3 ← t3 · t4
+	fp384Add(t4, t0, t1)  // 7.  t4 ← t0 + t1
+	fp384Sub(t3, t3, t4)  // 8.  t3 ← t3 − t4
+	fp384Add(t4, Y1, Z1)  // 9.  t4 ← Y1 + Z1
+	fp384Add(X3, Y2, Z2)  // 10. X3 ← Y2 + Z2
+	fp384Mul(t4, t4, X3)  // 11. t4 ← t4 · X3
+	fp384Add(X3, t1, t2)  // 12. X3 ← t1 + t2
+	fp384Sub(t4, t4, X3)  // 13. t4 ← t4 − X3
+	fp384Add(X3, X1, Z1)  // 14. X3 ← X1 + Z1
+	fp384Add(Y3, X2, Z2)  // 15. Y3 ← X2 + Z2
+	fp384Mul(X3, X3, Y3)  // 16. X3 ← X3 · Y3
+	fp384Add(Y3, t0, t2)  // 17. Y3 ← t0 + t2
+	fp384Sub(Y3, X3, Y3)  // 18. Y3 ← X3 − Y3
+	fp384Mul(Z3, &bb, t2) // 19. Z3 ←  b · t2
+	fp384Sub(X3, Y3, Z3)  // 20. X3 ← Y3 − Z3
+	fp384Add(Z3, X3, X3)  // 21. Z3 ← X3 + X3
+	fp384Add(X3, X3, Z3)  // 22. X3 ← X3 + Z3
+	fp384Sub(Z3, t1, X3)  // 23. Z3 ← t1 − X3
+	fp384Add(X3, t1, X3)  // 24. X3 ← t1 + X3
+	fp384Mul(Y3, &bb, Y3) // 25. Y3 ←  b · Y3
+	fp384Add(t1, t2, t2)  // 26. t1 ← t2 + t2
+	fp384Add(t2, t1, t2)  // 27. t2 ← t1 + t2
+	fp384Sub(Y3, Y3, t2)  // 28. Y3 ← Y3 − t2
+	fp384Sub(Y3, Y3, t0)  // 29. Y3 ← Y3 − t0
+	fp384Add(t1, Y3, Y3)  // 30. t1 ← Y3 + Y3
+	fp384Add(Y3, t1, Y3)  // 31. Y3 ← t1 + Y3
+	fp384Add(t1, t0, t0)  // 32. t1 ← t0 + t0
+	fp384Add(t0, t1, t0)  // 33. t0 ← t1 + t0
+	fp384Sub(t0, t0, t2)  // 34. t0 ← t0 − t2
+	fp384Mul(t1, t4, Y3)  // 35. t1 ← t4 · Y3
+	fp384Mul(t2, t0, Y3)  // 36. t2 ← t0 · Y3
+	fp384Mul(Y3, X3, Z3)  // 37. Y3 ← X3 · Z3
+	fp384Add(Y3, Y3, t2)  // 38. Y3 ← Y3 + t2
+	fp384Mul(X3, t3, X3)  // 39. X3 ← t3 · X3
+	fp384Sub(X3, X3, t1)  // 40. X3 ← X3 − t1
+	fp384Mul(Z3, t4, Z3)  // 41. Z3 ← t4 · Z3
+	fp384Mul(t1, t3, t0)  // 42. t1 ← t3 · t0
+	fp384Add(Z3, Z3, t1)  // 43. Z3 ← Z3 + t1
+	P.x, P.y, P.z = *X3, *Y3, *Z3
+}
diff --git a/vendor/github.com/cloudflare/circl/ecc/p384/tableBase.go b/vendor/github.com/cloudflare/circl/ecc/p384/tableBase.go
new file mode 100644
index 00000000..5132565e
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/ecc/p384/tableBase.go
@@ -0,0 +1,331 @@
+//go:build (!purego && arm64) || (!purego && amd64)
+// +build !purego,arm64 !purego,amd64
+
+package p384
+
+const baseOmega = uint(7)
+
+// baseOddMultiples has [2*i+1] * G at position i.
+// Each coordinate has been multiplied by R=2^384
+var baseOddMultiples = [1 << (baseOmega - 1)]affinePoint{
+	// 1P
+	{
+		x: fp384{0x28, 0xb5, 0xc0, 0x49, 0x66, 0x75, 0xd0, 0x3d, 0x38, 0xce, 0xd6, 0xa0, 0xe2, 0x78, 0xe3, 0x20, 0x6e, 0x4d, 0x1b, 0x54, 0xfc, 0x3a, 0x9c, 0x87, 0xff, 0xe, 0xa3, 0x59, 0x84, 0x86, 0x54, 0x64, 0x2b, 0xde, 0x4e, 0x61, 0x23, 0xf7, 0x2f, 0x81, 0x13, 0x15, 0x9e, 0x29, 0xc2, 0xad, 0x3a, 0x4d},
+		y: fp384{0xfe, 0xa4, 0x3, 0x4b, 0xad, 0x3d, 0x4, 0x23, 0xac, 0xa9, 0xb4, 0x7b, 0xbf, 0xa8, 0xbf, 0xa1, 0x50, 0xb0, 0x83, 0x2e, 0x56, 0xe7, 0xad, 0x8b, 0xd9, 0xff, 0xf4, 0x68, 0x19, 0x52, 0xc3, 0xc6, 0x40, 0xa8, 0x69, 0x39, 0x26, 0x2, 0x80, 0xdd, 0xe9, 0xc5, 0x15, 0x5a, 0xc2, 0xab, 0x78, 0x2b},
+	},
+	// 3P
+	{
+		x: fp384{0x73, 0x40, 0xdc, 0xc1, 0xe6, 0xdb, 0xe4, 0x5, 0x9c, 0x77, 0x4f, 0xf0, 0xff, 0xa9, 0x4e, 0xc5, 0xf0, 0xcc, 0x70, 0xa1, 0xe9, 0x34, 0x20, 0x6b, 0x3e, 0x6c, 0x1c, 0xd5, 0x32, 0xd7, 0x48, 0x3a, 0x70, 0xa4, 0x3a, 0x26, 0x2d, 0x7e, 0x6f, 0xe3, 0xac, 0xc3, 0xc1, 0xe7, 0x68, 0xfe, 0x83, 0xd2},
+		y: fp384{0x57, 0xe1, 0x4e, 0xc0, 0x21, 0x48, 0x28, 0x7e, 0x6d, 0xe3, 0xe0, 0x7a, 0xa7, 0x89, 0xd7, 0x92, 0x46, 0x74, 0xf6, 0x4e, 0xc0, 0x63, 0x26, 0x13, 0xb4, 0xd0, 0xe1, 0xd2, 0x5a, 0x2d, 0x1, 0x68, 0x39, 0xb3, 0x2, 0x51, 0xb1, 0x68, 0xdb, 0xf6, 0xaf, 0x92, 0x32, 0x98, 0xfc, 0x65, 0x54, 0x46},
+	},
+	// 5P
+	{
+		x: fp384{0xdf, 0xf0, 0xf1, 0x68, 0xba, 0x5e, 0x59, 0xbb, 0x66, 0x34, 0x87, 0xcc, 0xcb, 0xc0, 0x85, 0xc1, 0x3b, 0x70, 0x3c, 0x29, 0xb5, 0xb1, 0x1e, 0x7f, 0xe6, 0x5, 0xcc, 0xaa, 0xf5, 0x2c, 0xdb, 0x60, 0xc6, 0xe4, 0xe8, 0xe2, 0x87, 0xb9, 0x76, 0xc6, 0xfb, 0x8f, 0x17, 0x1d, 0xb1, 0x26, 0xbb, 0xe1},
+		y: fp384{0x21, 0xfa, 0x73, 0x70, 0xa0, 0x4b, 0x69, 0x2b, 0x66, 0x45, 0xf3, 0x72, 0x2e, 0x6e, 0xc1, 0x22, 0x99, 0x5b, 0xc3, 0x1, 0x31, 0x1b, 0xb6, 0x80, 0x11, 0x4, 0x2c, 0x98, 0xaf, 0x7f, 0x23, 0x4b, 0x6d, 0x23, 0xde, 0x24, 0x40, 0x94, 0xc5, 0xe6, 0xa3, 0xe4, 0x9, 0xe2, 0xd6, 0xc9, 0xb1, 0x4d},
+	},
+	// 7P
+	{
+		x: fp384{0x2b, 0x22, 0x69, 0x7d, 0xd1, 0xb9, 0x13, 0xdf, 0xb1, 0x74, 0x47, 0x87, 0x5f, 0x41, 0xe6, 0x4c, 0x95, 0xaa, 0x1f, 0x21, 0xf8, 0xdc, 0x1e, 0x73, 0xed, 0x53, 0x97, 0x65, 0xd1, 0x15, 0x42, 0x5f, 0x55, 0xdf, 0xb2, 0x9d, 0x58, 0xdb, 0x93, 0xf8, 0x5b, 0x2, 0x89, 0x1c, 0x81, 0x9f, 0x2c, 0x93},
+		y: fp384{0x1e, 0xa6, 0x6, 0x77, 0x20, 0xb2, 0x96, 0x9, 0x79, 0x1c, 0x64, 0xa8, 0xd5, 0x49, 0x53, 0x13, 0x44, 0x8, 0x13, 0x50, 0x6f, 0xd7, 0xaa, 0x65, 0x80, 0xf7, 0xff, 0x1, 0x4, 0x7c, 0xf3, 0xf, 0x6, 0x7, 0x3b, 0x69, 0x8e, 0x23, 0x7f, 0xf5, 0x3e, 0x9b, 0x6c, 0xaf, 0xb6, 0x16, 0xa, 0xd9},
+	},
+	// 9P
+	{
+		x: fp384{0x2f, 0xb9, 0x53, 0x23, 0xe, 0x20, 0x5d, 0x2f, 0xf9, 0xe4, 0xd7, 0x3f, 0x29, 0x87, 0x5d, 0xe3, 0x5d, 0x74, 0x6d, 0xa9, 0x33, 0x48, 0x9, 0x26, 0x3f, 0xff, 0xbf, 0x3c, 0xc1, 0x1d, 0x35, 0xdc, 0x6a, 0x4d, 0xd5, 0xda, 0xc6, 0x64, 0xd4, 0x26, 0x6a, 0x6c, 0x63, 0x53, 0x1d, 0x1d, 0xab, 0x5c},
+		y: fp384{0xb0, 0xc0, 0x8e, 0xb1, 0x72, 0x30, 0x81, 0xf2, 0x2f, 0xaa, 0x42, 0xd7, 0x70, 0xe2, 0x77, 0x37, 0xc2, 0xa7, 0x3c, 0x3, 0xc7, 0x61, 0xf0, 0x27, 0xd8, 0xd0, 0xea, 0x68, 0xcc, 0xac, 0xec, 0xa6, 0x54, 0xa7, 0x69, 0xee, 0xf4, 0x29, 0x94, 0x7d, 0xc6, 0xf5, 0xe8, 0x31, 0x34, 0x63, 0x70, 0xe7},
+	},
+	// 11P
+	{
+		x: fp384{0x7d, 0x8c, 0x8b, 0xb6, 0x19, 0x8b, 0x70, 0xc7, 0xba, 0x7a, 0x37, 0x44, 0x7c, 0x7, 0x32, 0x45, 0x4f, 0xd6, 0xda, 0x6c, 0x70, 0x67, 0xcc, 0xd, 0x2, 0x66, 0x7b, 0x14, 0x56, 0xbf, 0xb8, 0x1, 0x79, 0x1d, 0x56, 0xf0, 0x85, 0x98, 0xd8, 0xf8, 0x37, 0xc4, 0xa9, 0x7b, 0xfc, 0xe9, 0x19, 0x9c},
+		y: fp384{0x25, 0xba, 0xc4, 0xbd, 0x46, 0xb1, 0x4e, 0x76, 0x83, 0x4b, 0x14, 0xac, 0x6b, 0xe4, 0x4f, 0x60, 0x80, 0xe7, 0x77, 0x8a, 0x29, 0x13, 0xe8, 0x3c, 0x2e, 0x68, 0x9e, 0xfe, 0x36, 0xf, 0x7, 0x2e, 0x7a, 0x28, 0x53, 0x3a, 0xc, 0x1d, 0x82, 0x41, 0x18, 0xf9, 0x33, 0x35, 0x9f, 0x2f, 0xa6, 0x9a},
+	},
+	// 13P
+	{
+		x: fp384{0xfb, 0xbd, 0xcc, 0x75, 0x7e, 0xeb, 0x7a, 0x9b, 0x95, 0x9a, 0x74, 0xf6, 0xc5, 0x28, 0x5e, 0xb2, 0xae, 0xd4, 0xb7, 0x33, 0x46, 0x8e, 0x7a, 0x8a, 0x56, 0xbd, 0xc1, 0xd9, 0xa8, 0x3, 0x52, 0xdb, 0x97, 0xdf, 0x22, 0xed, 0x65, 0x72, 0x65, 0xd2, 0x94, 0x3c, 0xf2, 0x8c, 0xe1, 0x56, 0x1c, 0xb5},
+		y: fp384{0x2d, 0x81, 0x3d, 0x6c, 0x59, 0x94, 0xd3, 0xf4, 0xc2, 0xe0, 0xca, 0x87, 0x1a, 0x8f, 0xe8, 0xd8, 0xe3, 0xf, 0x4d, 0xcf, 0x48, 0x2a, 0x9a, 0x78, 0x60, 0x8d, 0xc3, 0xfe, 0x2d, 0xac, 0xfe, 0xb7, 0xc3, 0xe, 0x49, 0x3b, 0x1c, 0xbd, 0xfd, 0x81, 0xe1, 0x79, 0x69, 0xcc, 0xb7, 0xad, 0x17, 0x46},
+	},
+	// 15P
+	{
+		x: fp384{0xa9, 0xf4, 0x9, 0x47, 0x88, 0xd8, 0x6a, 0x44, 0xd8, 0xab, 0x3d, 0xec, 0xe2, 0x10, 0x72, 0x2b, 0x34, 0x7b, 0xe0, 0x50, 0x95, 0xf1, 0xcc, 0x83, 0x75, 0x30, 0x9b, 0x78, 0x17, 0x9, 0x50, 0x59, 0x93, 0x59, 0x8, 0xeb, 0xd4, 0x1f, 0xc0, 0xf, 0x6b, 0x2, 0x3, 0x49, 0x6f, 0xd2, 0x62, 0xfb},
+		y: fp384{0xbb, 0x89, 0xe9, 0x6f, 0x9d, 0xcc, 0x9, 0x23, 0x86, 0xd5, 0x4b, 0x14, 0xbd, 0x9c, 0x60, 0x61, 0xc, 0x61, 0x6, 0xde, 0xa0, 0xd3, 0x23, 0x4b, 0x70, 0xf4, 0x98, 0xd8, 0x66, 0x28, 0xdc, 0xdd, 0x97, 0x57, 0xc, 0x40, 0x41, 0xfc, 0x33, 0x87, 0x16, 0x27, 0xbc, 0xd0, 0xfe, 0xc6, 0x68, 0x5a},
+	},
+	// 17P
+	{
+		x: fp384{0xd0, 0x3c, 0x4a, 0x4b, 0x30, 0xe1, 0x3, 0x89, 0x3e, 0xf4, 0xf1, 0x8f, 0x4c, 0xea, 0xa4, 0x3e, 0xd, 0xa1, 0x55, 0xf6, 0x2a, 0x3f, 0xfc, 0xe6, 0xfc, 0xfe, 0x4f, 0x52, 0x7d, 0x73, 0xe3, 0x7b, 0x5e, 0x45, 0x30, 0x53, 0x55, 0x28, 0x69, 0x9f, 0x70, 0xce, 0x75, 0xe4, 0x6e, 0x16, 0x4f, 0x52},
+		y: fp384{0x55, 0xf0, 0x12, 0x6c, 0xcd, 0x69, 0xcc, 0x3f, 0xda, 0xc0, 0xb9, 0xd5, 0xff, 0xb6, 0x23, 0x4e, 0x83, 0xf1, 0x6b, 0x33, 0x93, 0x69, 0xce, 0x49, 0x4a, 0x50, 0x54, 0x4a, 0x85, 0x6d, 0x7d, 0xf8, 0x7a, 0x67, 0xc2, 0xb3, 0xf1, 0x5d, 0xeb, 0x25, 0xc9, 0x64, 0xb1, 0x55, 0x6f, 0x98, 0x37, 0xac},
+	},
+	// 19P
+	{
+		x: fp384{0x8, 0x4c, 0xa8, 0xba, 0x4a, 0xed, 0xa2, 0x82, 0x12, 0xc9, 0xa8, 0x41, 0x5f, 0xcc, 0xc4, 0x22, 0x5e, 0xad, 0x4a, 0x15, 0x3b, 0x9c, 0x10, 0xca, 0x8e, 0x53, 0x38, 0xfc, 0x98, 0x12, 0x89, 0x23, 0xae, 0x2, 0x98, 0x53, 0x9c, 0x63, 0xb6, 0xb3, 0x6, 0xd7, 0x90, 0x3, 0x45, 0x1f, 0xf, 0xfa},
+		y: fp384{0xd0, 0x21, 0xdc, 0xb0, 0x5d, 0x8e, 0xb7, 0x46, 0xac, 0x2e, 0xda, 0xc3, 0x3c, 0x2d, 0xc7, 0xa8, 0x43, 0xf6, 0xf2, 0x6f, 0x78, 0xb3, 0x70, 0x91, 0xc3, 0x30, 0x7f, 0xb6, 0x9b, 0x79, 0x5a, 0x3f, 0x72, 0xb6, 0x64, 0x82, 0x77, 0xdc, 0xd1, 0x15, 0x64, 0x77, 0x57, 0xe9, 0x23, 0x7b, 0xd4, 0xa1},
+	},
+	// 21P
+	{
+		x: fp384{0x2f, 0xce, 0x22, 0x4, 0x51, 0x5e, 0x26, 0x8, 0x21, 0x9e, 0x2f, 0xdd, 0x96, 0xd4, 0xe0, 0x88, 0x5d, 0xf7, 0x77, 0x61, 0xa0, 0x8a, 0x12, 0x30, 0x69, 0xbe, 0x9e, 0xbd, 0x62, 0xab, 0x59, 0x2e, 0x37, 0xe5, 0xf0, 0x5d, 0x6c, 0xf, 0x1a, 0x1b, 0xb5, 0x12, 0xc0, 0xda, 0x26, 0xc6, 0x16, 0xab},
+		y: fp384{0xe7, 0x5d, 0x8c, 0x0, 0x4b, 0x21, 0x14, 0x80, 0xea, 0x7b, 0xf1, 0x38, 0x9e, 0xa, 0x74, 0xaa, 0x98, 0x90, 0x14, 0x8a, 0x49, 0xbb, 0x2e, 0x26, 0x59, 0xcd, 0x27, 0x85, 0x1e, 0x11, 0x54, 0xb4, 0x17, 0x58, 0xea, 0xac, 0x5a, 0xd1, 0x6a, 0x26, 0xba, 0xcc, 0x53, 0x13, 0x41, 0x4f, 0x82, 0x21},
+	},
+	// 23P
+	{
+		x: fp384{0x3b, 0x68, 0xe3, 0x12, 0x4d, 0xe7, 0xb4, 0xd1, 0xf6, 0x8e, 0x9b, 0x56, 0xb, 0xd2, 0xe, 0x99, 0x18, 0xa, 0x9c, 0x42, 0x25, 0xdd, 0xd3, 0xb9, 0x83, 0x17, 0x35, 0x2a, 0xab, 0xb8, 0x75, 0x1c, 0xf0, 0x32, 0x54, 0x90, 0x2b, 0xca, 0xe4, 0x61, 0x24, 0xf2, 0xa8, 0xee, 0x69, 0x6a, 0x82, 0x80},
+		y: fp384{0xad, 0xab, 0x52, 0xec, 0x6b, 0x3a, 0xc3, 0x7f, 0x13, 0x48, 0x5e, 0xa6, 0xf0, 0xa3, 0xcc, 0xb, 0xbe, 0xce, 0x27, 0xa5, 0x32, 0xa1, 0xd8, 0x7a, 0x7e, 0x2c, 0xf2, 0xea, 0x50, 0x89, 0x13, 0xf0, 0xc1, 0x18, 0x67, 0x56, 0x37, 0x24, 0x2d, 0x28, 0x59, 0x25, 0x21, 0xe2, 0xd, 0xcb, 0xfc, 0x9d},
+	},
+	// 25P
+	{
+		x: fp384{0x83, 0x3b, 0xce, 0x58, 0x27, 0x72, 0x93, 0x1e, 0x36, 0xfb, 0xb3, 0x3c, 0xfa, 0xd, 0x28, 0xbb, 0x4a, 0x17, 0xbe, 0xe2, 0xd2, 0xf3, 0xd0, 0x57, 0x1e, 0xbe, 0x8a, 0x20, 0x99, 0x1b, 0xd5, 0x9b, 0x24, 0x80, 0x24, 0xde, 0x50, 0xab, 0x9, 0x38, 0x31, 0x73, 0xbb, 0xa5, 0x2c, 0x6e, 0x9c, 0xc2},
+		y: fp384{0x5, 0x4f, 0x12, 0x61, 0x2e, 0xfd, 0x44, 0x99, 0x91, 0xe3, 0x9, 0x90, 0x4e, 0xbc, 0xcc, 0x83, 0xcc, 0xa3, 0x24, 0x94, 0x5, 0x8f, 0x62, 0x1, 0x44, 0x43, 0x8e, 0xea, 0x1d, 0xf5, 0xa2, 0xd6, 0x6e, 0xc9, 0xeb, 0x4c, 0x3d, 0x1a, 0x3e, 0xda, 0xdc, 0x9, 0x78, 0xe9, 0x42, 0xfb, 0xe6, 0x1f},
+	},
+	// 27P
+	{
+		x: fp384{0xe4, 0x66, 0x7d, 0x46, 0xd2, 0x82, 0x44, 0xa0, 0x1d, 0x29, 0x78, 0x4d, 0x93, 0x12, 0x19, 0xcf, 0xf9, 0x96, 0x23, 0x48, 0x68, 0x41, 0xd, 0x8e, 0xd0, 0x14, 0x8f, 0xd1, 0xd5, 0xe2, 0x28, 0x72, 0xfe, 0x58, 0x6a, 0x9c, 0x50, 0x8d, 0x7e, 0x2f, 0xec, 0x5a, 0x3e, 0x37, 0xe, 0x78, 0xca, 0xe8},
+		y: fp384{0xf8, 0xe9, 0x68, 0x1b, 0xd6, 0xd1, 0xaa, 0x42, 0xf4, 0xf8, 0xe2, 0x69, 0xf5, 0xd7, 0xa6, 0x58, 0xea, 0x1b, 0xda, 0x31, 0xfe, 0xad, 0x79, 0xd7, 0x85, 0x5a, 0xc8, 0x38, 0x6, 0x54, 0x26, 0x7d, 0xdf, 0x3c, 0x4d, 0xd4, 0x95, 0x71, 0xe6, 0x67, 0xd7, 0x4e, 0x13, 0xc5, 0xb, 0xa, 0x82, 0x17},
+	},
+	// 29P
+	{
+		x: fp384{0x70, 0x14, 0x2, 0xd3, 0xc5, 0x6a, 0x9d, 0x1, 0xd6, 0x43, 0x4, 0x78, 0x66, 0x6b, 0x84, 0x25, 0x47, 0x76, 0xc9, 0x55, 0xed, 0x15, 0x3c, 0xce, 0xf, 0xeb, 0x3f, 0xe, 0x49, 0x2d, 0xc2, 0x3d, 0xe4, 0x26, 0xdf, 0xa7, 0xcb, 0xb7, 0x65, 0x20, 0x1f, 0xea, 0x7c, 0x18, 0xe8, 0xa, 0xb0, 0xc8},
+		y: fp384{0xd3, 0xde, 0x5d, 0x86, 0xa0, 0x84, 0x52, 0x1a, 0xe2, 0x3d, 0xc8, 0x20, 0x49, 0x16, 0x3c, 0x29, 0xb3, 0x51, 0xe8, 0xcc, 0x26, 0x8d, 0x17, 0xab, 0xfb, 0x5, 0x45, 0x40, 0xb, 0xb1, 0x6d, 0x8e, 0x33, 0x20, 0xc8, 0x90, 0x71, 0x7e, 0xf5, 0xf6, 0x6c, 0xf1, 0x77, 0x59, 0x1, 0x1c, 0x2a, 0x1d},
+	},
+	// 31P
+	{
+		x: fp384{0xa4, 0x6, 0x89, 0x7c, 0x31, 0x89, 0x9c, 0xa3, 0xe6, 0x1e, 0x82, 0x9e, 0xdd, 0xec, 0xe7, 0xb6, 0xe6, 0x4f, 0xdf, 0xf0, 0x40, 0x83, 0xcf, 0x2e, 0x65, 0x49, 0xc1, 0x53, 0xc9, 0x7d, 0x2f, 0xd4, 0x85, 0x82, 0xba, 0xe3, 0xa3, 0x51, 0xfb, 0x1a, 0xd1, 0x5, 0x33, 0xa, 0x4, 0xc4, 0x7, 0x6c},
+		y: fp384{0xda, 0xc1, 0x7f, 0x12, 0x88, 0x32, 0xb8, 0xda, 0x8, 0x4b, 0x4c, 0x37, 0x9b, 0x69, 0xa, 0xbc, 0xdd, 0x20, 0xeb, 0x42, 0xab, 0x9b, 0x2a, 0x40, 0x1c, 0x7a, 0x5a, 0x4, 0x4f, 0x46, 0xdd, 0xd7, 0xc4, 0xec, 0xbe, 0x36, 0x6d, 0xd, 0x3d, 0x5b, 0x9d, 0xa1, 0x98, 0x63, 0x75, 0x3e, 0x5a, 0x47},
+	},
+	// 33P
+	{
+		x: fp384{0x63, 0xba, 0xb3, 0x2f, 0x38, 0x3a, 0x33, 0x61, 0x86, 0x3c, 0x94, 0x5b, 0x9d, 0xd, 0x33, 0xdf, 0xaf, 0xf3, 0x5e, 0x95, 0xee, 0xc7, 0xc7, 0xbb, 0xfb, 0x9e, 0xf0, 0x60, 0xc1, 0x1f, 0x63, 0xda, 0x0, 0xc4, 0xd5, 0x41, 0x26, 0x62, 0xaf, 0x68, 0x9d, 0x3e, 0x83, 0x6c, 0xa4, 0x97, 0x9e, 0xcc},
+		y: fp384{0x76, 0x5e, 0x62, 0x3a, 0x8e, 0x3e, 0xd7, 0x7f, 0x5e, 0xe5, 0x9, 0xc2, 0x24, 0x61, 0xbf, 0x13, 0x91, 0xb, 0xb9, 0x48, 0xea, 0x7c, 0x46, 0x8, 0xba, 0xa, 0x6f, 0xbb, 0xb9, 0x6e, 0x41, 0x8a, 0x72, 0x10, 0xc3, 0xb8, 0xa1, 0x93, 0xcc, 0x6f, 0xd7, 0xda, 0x57, 0x90, 0x61, 0x2b, 0xfd, 0xa7},
+	},
+	// 35P
+	{
+		x: fp384{0x9b, 0xec, 0x20, 0x37, 0x43, 0xb5, 0xa5, 0x58, 0xb4, 0x2f, 0x7c, 0x2d, 0xd5, 0x0, 0x38, 0xbb, 0xa, 0xbd, 0xe6, 0xdd, 0x20, 0x86, 0x50, 0x4a, 0xfd, 0x83, 0x25, 0xa0, 0x73, 0x62, 0xf1, 0x65, 0x23, 0x85, 0xc7, 0x4f, 0xe3, 0xd8, 0x2b, 0x83, 0xc6, 0x7b, 0x41, 0xe9, 0x75, 0x9f, 0x14, 0xd6},
+		y: fp384{0x2a, 0xb5, 0xee, 0x3d, 0xe9, 0x26, 0xb0, 0xfe, 0x56, 0x9, 0x5e, 0xa5, 0x88, 0x80, 0xe1, 0xc, 0xa2, 0x92, 0x80, 0x98, 0x98, 0x89, 0x1, 0x50, 0xee, 0x5e, 0xf3, 0x28, 0xab, 0x9f, 0xf1, 0x22, 0x5c, 0xd3, 0xcc, 0x52, 0x7f, 0x87, 0x8a, 0xac, 0x26, 0x3f, 0xe2, 0x30, 0xd8, 0x8a, 0x3a, 0xb1},
+	},
+	// 37P
+	{
+		x: fp384{0xa3, 0x61, 0x4f, 0xe4, 0x7d, 0xd5, 0x2, 0x2, 0xf2, 0xe, 0x63, 0xb5, 0x4b, 0x70, 0x27, 0x40, 0x5d, 0x4a, 0xb5, 0xf5, 0xdf, 0xe2, 0x29, 0xa1, 0x86, 0x2b, 0x48, 0x97, 0x75, 0xa, 0xb6, 0xac, 0x14, 0x71, 0xf2, 0x7e, 0xe8, 0xed, 0x61, 0x92, 0xb5, 0x58, 0xfc, 0xde, 0xf3, 0x28, 0xba, 0x1e},
+		y: fp384{0x9e, 0x58, 0xe5, 0x8b, 0xc9, 0xc0, 0x91, 0x6c, 0xee, 0x4b, 0x59, 0x14, 0xd5, 0x43, 0x16, 0x2f, 0x34, 0xa0, 0x2c, 0x5d, 0x43, 0x12, 0xa9, 0x2e, 0x1f, 0x7d, 0x4, 0x94, 0xa8, 0x49, 0x6, 0xb5, 0x37, 0xa3, 0x8c, 0x63, 0xb5, 0xcb, 0x4f, 0x28, 0x85, 0xbf, 0x85, 0xfe, 0xb7, 0x7, 0xe, 0xfa},
+	},
+	// 39P
+	{
+		x: fp384{0x42, 0xe, 0x6e, 0x50, 0x80, 0x4f, 0x89, 0x7d, 0x46, 0x2c, 0x3d, 0x8e, 0x4a, 0x24, 0x84, 0xd9, 0x6f, 0x0, 0x7f, 0x2b, 0x64, 0xdf, 0x7e, 0x6d, 0x30, 0x62, 0x9b, 0xde, 0x6d, 0xcd, 0xa1, 0x36, 0x65, 0x6, 0x6c, 0xb7, 0x40, 0x50, 0x98, 0xc9, 0xc2, 0x1f, 0x9b, 0xb8, 0xd6, 0xf4, 0x7d, 0x58},
+		y: fp384{0x7a, 0xae, 0x71, 0x6a, 0x47, 0x38, 0x6, 0x4c, 0x47, 0x47, 0x29, 0xe8, 0xb3, 0xa, 0x2b, 0x7b, 0xb8, 0x53, 0x31, 0xb5, 0x3a, 0x55, 0x5c, 0x34, 0xe2, 0x9f, 0x6d, 0x43, 0x53, 0xe4, 0x46, 0xb6, 0x40, 0x3, 0xd6, 0x1c, 0x5f, 0x35, 0x95, 0x1a, 0xfb, 0x68, 0x49, 0x7, 0x28, 0xc1, 0x7b, 0x2d},
+	},
+	// 41P
+	{
+		x: fp384{0x4c, 0xd1, 0xa6, 0xbc, 0x87, 0x8e, 0x14, 0xad, 0x1e, 0x20, 0x6a, 0x45, 0x4d, 0xd2, 0xdf, 0x41, 0xf3, 0x68, 0xd, 0xa8, 0x33, 0x29, 0xa8, 0x73, 0x35, 0xa0, 0x2c, 0x85, 0x8d, 0x6c, 0x74, 0x89, 0xae, 0x71, 0xfd, 0x95, 0x88, 0x77, 0xbc, 0xe3, 0x5d, 0x24, 0x92, 0xda, 0x2c, 0xcd, 0x64, 0x87},
+		y: fp384{0xe2, 0x23, 0xeb, 0x82, 0x47, 0x2c, 0xfe, 0xa2, 0x6e, 0x9d, 0x3c, 0xf, 0xe0, 0x62, 0xc7, 0x5a, 0x31, 0x6f, 0x64, 0x21, 0xe1, 0xc, 0x86, 0x57, 0x9a, 0x58, 0x9f, 0x4f, 0xc3, 0xd6, 0xc9, 0xbd, 0x2e, 0x27, 0x93, 0xd1, 0xc7, 0x52, 0x99, 0x67, 0xc5, 0xf1, 0x18, 0xeb, 0x2e, 0x70, 0xea, 0x82},
+	},
+	// 43P
+	{
+		x: fp384{0x44, 0x6d, 0x84, 0x0, 0x55, 0x93, 0xfa, 0x37, 0x8c, 0xbc, 0x78, 0x5, 0xc5, 0x2f, 0x11, 0x9, 0x3d, 0x94, 0xc4, 0x39, 0xb2, 0xf5, 0xd9, 0xda, 0x86, 0xbd, 0x6d, 0x41, 0xf0, 0xf5, 0x14, 0x73, 0x56, 0xfb, 0xfe, 0x1, 0xa9, 0x95, 0xf0, 0x5c, 0x93, 0xb3, 0xda, 0x22, 0xad, 0x8b, 0x17, 0x35},
+		y: fp384{0xa7, 0xf1, 0xba, 0x36, 0x1b, 0xfc, 0x79, 0xcf, 0x98, 0x54, 0x9e, 0x74, 0x2d, 0xe4, 0x7e, 0x1b, 0xbb, 0x14, 0xe3, 0xed, 0xa9, 0x8a, 0xe7, 0xbc, 0xdf, 0x28, 0x6, 0xbd, 0xf6, 0xe0, 0xf8, 0xaa, 0x48, 0xf9, 0xcb, 0x15, 0x94, 0xb0, 0x74, 0xa9, 0x78, 0x2b, 0x63, 0xc9, 0x63, 0x1f, 0x3f, 0x8f},
+	},
+	// 45P
+	{
+		x: fp384{0x5b, 0xda, 0xdd, 0x4f, 0x56, 0x11, 0xc4, 0xd4, 0x12, 0x91, 0xad, 0x73, 0xc6, 0x65, 0xaf, 0xd4, 0x59, 0x8f, 0xeb, 0x39, 0xbb, 0xe0, 0xe8, 0xff, 0x13, 0xcf, 0x6f, 0x8d, 0xe, 0xc, 0x4, 0xb0, 0x99, 0xb5, 0x2b, 0x1f, 0xc6, 0xc0, 0xe1, 0x99, 0x5, 0x34, 0xac, 0xb2, 0x58, 0xc8, 0x94, 0x9c},
+		y: fp384{0x5d, 0xd8, 0xee, 0x6e, 0xd7, 0x78, 0x88, 0x8f, 0x3f, 0xca, 0xfc, 0x51, 0x43, 0xf5, 0xb2, 0x62, 0x18, 0x69, 0xb5, 0xe5, 0xa9, 0x44, 0x3b, 0xeb, 0x93, 0x4e, 0x23, 0xb7, 0x76, 0x66, 0xf9, 0x16, 0x9e, 0xf1, 0x2a, 0xbd, 0x22, 0x77, 0x47, 0x17, 0x85, 0xa4, 0x83, 0xdb, 0x79, 0x29, 0xeb, 0x42},
+	},
+	// 47P
+	{
+		x: fp384{0xca, 0x68, 0xc6, 0xf0, 0x7d, 0x8f, 0x88, 0x6f, 0x6c, 0xc6, 0xd, 0x5f, 0x78, 0x88, 0xc7, 0x65, 0xa0, 0x7, 0x5b, 0x5f, 0x12, 0x85, 0xb1, 0xbf, 0xd0, 0xac, 0x78, 0xd8, 0xf7, 0xbf, 0xa, 0x78, 0x50, 0xf9, 0xc, 0x57, 0xb1, 0x21, 0x4f, 0x50, 0x71, 0x33, 0x23, 0xda, 0xc5, 0x37, 0x5b, 0xea},
+		y: fp384{0xd1, 0x7e, 0x43, 0x22, 0xbd, 0xe8, 0x7a, 0x48, 0xb7, 0xf9, 0x9c, 0x24, 0x58, 0x17, 0x70, 0x9c, 0xff, 0x34, 0xfb, 0x98, 0xa8, 0x62, 0x65, 0xf8, 0x91, 0xfc, 0xe0, 0x65, 0xa2, 0xa1, 0xee, 0xdf, 0x23, 0xfc, 0x20, 0x2e, 0x91, 0x6, 0xf0, 0xee, 0x8b, 0x2a, 0xa7, 0xdf, 0xc7, 0xfe, 0x9d, 0xac},
+	},
+	// 49P
+	{
+		x: fp384{0xc6, 0x36, 0x71, 0x69, 0xef, 0x3a, 0x5c, 0xfa, 0xb8, 0x6f, 0xea, 0xa5, 0x63, 0xaf, 0xa5, 0x8e, 0xa4, 0x65, 0xe3, 0x42, 0x65, 0x15, 0x69, 0xa6, 0x86, 0x33, 0x6e, 0x5b, 0x11, 0x6c, 0xc5, 0x47, 0x56, 0x3f, 0xa0, 0xce, 0x2b, 0x83, 0x97, 0x11, 0x9e, 0xea, 0xe4, 0x50, 0xb2, 0xb, 0x47, 0xb},
+		y: fp384{0x12, 0x57, 0xb2, 0x13, 0x43, 0xc7, 0x13, 0x31, 0x48, 0x7d, 0x49, 0xd2, 0x4e, 0x17, 0x6c, 0x8d, 0xe8, 0xeb, 0xc9, 0x49, 0xee, 0x86, 0x44, 0xfc, 0xd3, 0xbd, 0x82, 0x7f, 0xd5, 0xed, 0x87, 0x24, 0x2f, 0xbe, 0x57, 0x5b, 0x41, 0x64, 0x1e, 0x77, 0xdb, 0x2b, 0x8b, 0xe2, 0x18, 0xc5, 0x1c, 0x2d},
+	},
+	// 51P
+	{
+		x: fp384{0x8d, 0xac, 0x70, 0x20, 0xc7, 0xca, 0x4c, 0x2c, 0xb8, 0x22, 0x4a, 0xec, 0xca, 0xc0, 0x47, 0x19, 0xd9, 0x78, 0x5a, 0x8c, 0x59, 0xfb, 0xe0, 0xa5, 0xe7, 0x4d, 0xa8, 0x41, 0xd2, 0xe8, 0x4a, 0x46, 0x27, 0xbc, 0xaa, 0xda, 0xe9, 0x16, 0xba, 0x3d, 0x3c, 0xcb, 0x35, 0x4f, 0x50, 0x4a, 0x63, 0x16},
+		y: fp384{0x4f, 0xc8, 0x6e, 0xb1, 0xf9, 0x8b, 0xc1, 0xad, 0x35, 0xdd, 0x59, 0x73, 0x7e, 0x6, 0x4d, 0x32, 0xf0, 0x43, 0x5, 0x57, 0xc3, 0xc0, 0xea, 0xda, 0x36, 0x7d, 0x88, 0x3c, 0x0, 0x40, 0x22, 0xb, 0xd, 0x1a, 0x3f, 0x37, 0xe2, 0x89, 0x94, 0xc6, 0x97, 0xd, 0xaa, 0xcb, 0x7d, 0x4, 0x8b, 0x51},
+	},
+	// 53P
+	{
+		x: fp384{0xef, 0x49, 0xde, 0xfb, 0xc6, 0xdd, 0x1b, 0x3b, 0xcc, 0x15, 0x9, 0x8a, 0x26, 0x7c, 0xed, 0xda, 0xa2, 0x22, 0x4, 0xf, 0x61, 0x10, 0x1, 0xb, 0x16, 0x4b, 0xc5, 0xa7, 0x74, 0x5c, 0x48, 0xcf, 0xe2, 0xaa, 0xc3, 0x15, 0xe6, 0xc4, 0x2e, 0x64, 0xea, 0x83, 0xf3, 0xe0, 0x10, 0x8f, 0xba, 0xa8},
+		y: fp384{0x1, 0x85, 0x61, 0x95, 0xb4, 0x54, 0x20, 0x2a, 0x8b, 0xfa, 0x9e, 0x8, 0x42, 0x64, 0xec, 0xeb, 0x3e, 0xa8, 0x2f, 0x4e, 0x9a, 0xa1, 0x86, 0x57, 0x63, 0x99, 0x6, 0x39, 0xd1, 0x1a, 0xc7, 0xd2, 0xe2, 0x65, 0x17, 0x48, 0x9a, 0x3d, 0xc9, 0xad, 0x85, 0x94, 0xcc, 0x7e, 0xeb, 0xe3, 0xf2, 0xed},
+	},
+	// 55P
+	{
+		x: fp384{0x67, 0x33, 0x9f, 0x6, 0x60, 0x5f, 0xab, 0xbc, 0x3c, 0xec, 0x18, 0x17, 0xbc, 0x22, 0x66, 0xfd, 0xd6, 0x42, 0xa1, 0xe3, 0x67, 0x78, 0xfb, 0xa4, 0xb3, 0xae, 0x5f, 0x8, 0xbf, 0xd8, 0x78, 0x60, 0x4f, 0x55, 0xf4, 0x60, 0xda, 0xbf, 0x5c, 0xfa, 0x8, 0xd4, 0xc, 0x69, 0xd1, 0xd5, 0xfc, 0xb3},
+		y: fp384{0x84, 0x78, 0x1f, 0x28, 0x7d, 0xee, 0xbd, 0x4e, 0xa7, 0x63, 0xa, 0x18, 0xaa, 0x23, 0xaf, 0x82, 0x61, 0x9f, 0x7, 0x3d, 0x7c, 0x10, 0xe3, 0x8d, 0xf8, 0x34, 0x23, 0xbe, 0xcb, 0xb5, 0xc6, 0x17, 0x6, 0xfa, 0xd0, 0x97, 0x39, 0xe7, 0x91, 0x6a, 0xd4, 0xee, 0xce, 0x14, 0x73, 0x25, 0x60, 0x74},
+	},
+	// 57P
+	{
+		x: fp384{0x5c, 0x86, 0x7f, 0xf9, 0x1c, 0xa6, 0x4b, 0xb1, 0xd, 0x8b, 0x4b, 0x69, 0xc1, 0xe4, 0xba, 0x73, 0x62, 0xbf, 0x4b, 0xac, 0xdf, 0x67, 0x49, 0xa1, 0xe0, 0x46, 0xf4, 0x9b, 0x50, 0xd1, 0x9d, 0x1e, 0xef, 0xce, 0x99, 0x1c, 0xeb, 0xf3, 0x52, 0xc0, 0x89, 0xc1, 0x78, 0x7a, 0xa0, 0x7f, 0x4d, 0x81},
+		y: fp384{0x5d, 0xb0, 0x74, 0xab, 0x83, 0xa4, 0x1, 0xa1, 0x65, 0x7b, 0x73, 0xa1, 0x58, 0xc2, 0x88, 0x77, 0x3c, 0xa1, 0x9, 0xe8, 0xb7, 0xba, 0x60, 0xd, 0x5b, 0x1d, 0xc8, 0x73, 0xc4, 0x7b, 0x42, 0x8f, 0xfc, 0xc1, 0x52, 0x29, 0x55, 0x30, 0xe1, 0xd2, 0x63, 0xdf, 0x26, 0x4b, 0x9a, 0x3b, 0x82, 0xa},
+	},
+	// 59P
+	{
+		x: fp384{0xc9, 0x64, 0xbf, 0x27, 0xe2, 0x7c, 0x46, 0xaf, 0x4c, 0x97, 0x29, 0xf9, 0x97, 0x68, 0xca, 0xdf, 0x38, 0x27, 0x32, 0x5c, 0x59, 0x3b, 0x47, 0x64, 0x15, 0xe3, 0xd0, 0x1e, 0xcf, 0x17, 0xa9, 0x96, 0xb9, 0x4d, 0xe6, 0xd, 0x5b, 0x43, 0x3, 0x37, 0x46, 0xb6, 0x67, 0x92, 0x67, 0x39, 0xa0, 0x9b},
+		y: fp384{0xbe, 0x2f, 0x52, 0x3a, 0xae, 0x2a, 0xc, 0xdf, 0xf0, 0xef, 0x35, 0xb3, 0x41, 0xb7, 0xbd, 0x41, 0x3, 0x97, 0x5, 0x7b, 0xdd, 0x2e, 0xcf, 0xac, 0xce, 0x3c, 0x46, 0x28, 0x30, 0x4b, 0xb3, 0x6f, 0x19, 0xca, 0xe3, 0xd9, 0xb, 0xba, 0xd9, 0x96, 0xc1, 0x55, 0x46, 0x50, 0x12, 0x6f, 0x33, 0xff},
+	},
+	// 61P
+	{
+		x: fp384{0xe0, 0xa6, 0x60, 0xfc, 0xd3, 0x1f, 0xda, 0x48, 0xe8, 0x41, 0x22, 0x22, 0x34, 0x5a, 0xfb, 0x54, 0x80, 0xe0, 0x2a, 0x77, 0x4f, 0xe3, 0x35, 0x60, 0xd0, 0x82, 0x29, 0x33, 0xf2, 0x7f, 0xf7, 0x5f, 0xfd, 0x51, 0xfe, 0x0, 0x73, 0x46, 0x66, 0x23, 0x6, 0xa0, 0x6b, 0xef, 0x49, 0xa0, 0x3e, 0xc9},
+		y: fp384{0x66, 0x12, 0x38, 0x7d, 0x17, 0xf1, 0x40, 0x66, 0xac, 0xf4, 0xe9, 0x6a, 0xcd, 0x32, 0x4d, 0x39, 0xeb, 0x3, 0xd3, 0x70, 0x53, 0x88, 0xa7, 0xe6, 0x67, 0x57, 0x27, 0xe5, 0xff, 0x19, 0xda, 0xd, 0x23, 0x6d, 0x46, 0x1, 0x72, 0xc7, 0xa6, 0xb0, 0x29, 0x98, 0xc6, 0x1f, 0x45, 0x11, 0xcc, 0xc4},
+	},
+	// 63P
+	{
+		x: fp384{0xc0, 0x89, 0xed, 0xaa, 0xd7, 0xe6, 0xc0, 0xc5, 0x96, 0x18, 0x9a, 0x14, 0xd6, 0xea, 0xe8, 0x6c, 0x8f, 0x9f, 0x94, 0x8c, 0x45, 0xf7, 0x50, 0x7a, 0xaa, 0x71, 0x2b, 0x6e, 0xf7, 0x35, 0x7e, 0xcd, 0x7a, 0x9f, 0x4, 0x9a, 0x51, 0x9e, 0x15, 0xf6, 0x1e, 0x2d, 0xe5, 0xf1, 0xb0, 0xf0, 0x9b, 0x1c},
+		y: fp384{0x80, 0x2c, 0x20, 0x18, 0xf5, 0xc1, 0xb6, 0x3b, 0x1a, 0x7b, 0xcd, 0x1e, 0x62, 0x5f, 0x3a, 0x8d, 0x19, 0x7f, 0xd1, 0x88, 0xe8, 0x34, 0xb0, 0x3b, 0x8d, 0x4, 0xd4, 0x97, 0x49, 0xbd, 0x89, 0xdc, 0x22, 0xdf, 0x35, 0x37, 0x8e, 0x7b, 0xaf, 0xf5, 0xe8, 0x89, 0xa6, 0xa0, 0x12, 0x37, 0xbb, 0x52},
+	},
+	// 65P
+	{
+		x: fp384{0x79, 0x96, 0x9b, 0x83, 0x54, 0x94, 0x46, 0x8e, 0x9f, 0x27, 0x1d, 0xd, 0x3b, 0xa4, 0xcd, 0xbe, 0x80, 0x3c, 0xb6, 0xed, 0x15, 0xdc, 0x9e, 0xcf, 0x2, 0xf0, 0xd5, 0xbd, 0x8a, 0xec, 0x97, 0x45, 0x53, 0x22, 0xb, 0x65, 0xb2, 0x50, 0x3, 0x8b, 0x6f, 0x26, 0xd4, 0x5f, 0x6a, 0x3a, 0x4c, 0xb8},
+		y: fp384{0xf9, 0x79, 0xfc, 0x30, 0x3d, 0xd8, 0x16, 0xe, 0xd3, 0x95, 0xd9, 0x3a, 0x83, 0x87, 0xa4, 0xb6, 0x66, 0xc2, 0x2b, 0xde, 0x2c, 0x4b, 0x78, 0xab, 0xdd, 0x66, 0x9d, 0x88, 0x6d, 0x3d, 0x76, 0x19, 0x87, 0xf0, 0xf9, 0xc8, 0x24, 0x6c, 0x86, 0xa2, 0xc9, 0xb1, 0x5b, 0xa5, 0x28, 0x25, 0x6f, 0xea},
+	},
+	// 67P
+	{
+		x: fp384{0xca, 0x72, 0x17, 0x8b, 0xbc, 0x5c, 0xfc, 0x6e, 0x68, 0x4f, 0x63, 0xb, 0x3b, 0xdd, 0xc7, 0xea, 0x85, 0x61, 0x5d, 0xa5, 0xda, 0x5e, 0xd7, 0x65, 0xf7, 0xd8, 0xf3, 0x6e, 0x7e, 0x63, 0x6e, 0x55, 0x25, 0x9d, 0x90, 0x90, 0x4d, 0x3e, 0xaf, 0xf9, 0x5a, 0x3, 0x53, 0xe1, 0x48, 0xca, 0x62, 0xe4},
+		y: fp384{0xd1, 0x9e, 0x10, 0xa, 0x7b, 0x3b, 0x76, 0x52, 0x6, 0x5d, 0x78, 0x42, 0xa6, 0xb1, 0x4a, 0x10, 0xbc, 0xe4, 0x59, 0x3f, 0xed, 0x35, 0x7e, 0x1a, 0x3, 0xc0, 0xeb, 0xc6, 0x46, 0xb7, 0x90, 0x59, 0xf9, 0xc5, 0x62, 0x13, 0xf0, 0x6b, 0x6a, 0x9, 0x94, 0x49, 0x79, 0xac, 0x8a, 0xcb, 0x22, 0x83},
+	},
+	// 69P
+	{
+		x: fp384{0x52, 0x27, 0xc, 0x67, 0x74, 0xdf, 0xd3, 0xf8, 0x28, 0x5e, 0x11, 0xa1, 0x59, 0x28, 0xcb, 0x5c, 0x1b, 0x98, 0x19, 0xf, 0xaa, 0xc8, 0x66, 0xcc, 0x65, 0xfd, 0xab, 0x25, 0xb1, 0xc8, 0xbc, 0xd4, 0xca, 0x3c, 0xdd, 0x4f, 0x16, 0xee, 0x86, 0x2c, 0xf4, 0x35, 0xf7, 0xa3, 0x78, 0x5d, 0xd6, 0x59},
+		y: fp384{0xce, 0x55, 0xc, 0x7c, 0x28, 0xde, 0x5a, 0x3, 0x4d, 0x99, 0xd3, 0x45, 0x62, 0x9d, 0x76, 0x57, 0xa4, 0x23, 0xd4, 0x2b, 0x89, 0xe4, 0x3a, 0xd1, 0xbc, 0x66, 0xed, 0x82, 0x48, 0xee, 0xce, 0xa, 0x32, 0x7a, 0x16, 0x73, 0x8b, 0x9e, 0x2c, 0x6f, 0x7a, 0xbd, 0x1d, 0x27, 0x0, 0x1, 0xcd, 0xfb},
+	},
+	// 71P
+	{
+		x: fp384{0xb1, 0xfc, 0xfe, 0xef, 0x45, 0xce, 0x2e, 0xc4, 0x41, 0x14, 0xb1, 0xab, 0xb3, 0x31, 0x57, 0xbf, 0x92, 0xa, 0x8d, 0xe5, 0xcf, 0x15, 0xba, 0x93, 0x54, 0xac, 0x8, 0x35, 0x14, 0xde, 0xbb, 0x27, 0xda, 0x5d, 0x25, 0xfe, 0x38, 0x37, 0x12, 0x2b, 0x70, 0xcd, 0x7e, 0x53, 0x5a, 0xaa, 0x4f, 0xb},
+		y: fp384{0xc6, 0x83, 0xec, 0xdd, 0x84, 0xd0, 0x44, 0x6a, 0x3d, 0x52, 0x1, 0x8, 0x4d, 0x3c, 0x79, 0x86, 0x19, 0xe3, 0xb3, 0x25, 0x50, 0x28, 0x4f, 0x15, 0x3a, 0x37, 0x64, 0xce, 0xf1, 0xda, 0x44, 0x21, 0x66, 0x95, 0x13, 0x7, 0xee, 0x24, 0xb9, 0xbd, 0x1c, 0xd0, 0x2a, 0x73, 0x28, 0xea, 0xa7, 0xf9},
+	},
+	// 73P
+	{
+		x: fp384{0x2, 0xa7, 0x51, 0xd8, 0x32, 0x5c, 0x38, 0x43, 0x3b, 0x96, 0xe8, 0x1d, 0xb1, 0xa9, 0xc2, 0xa9, 0x24, 0x9b, 0x8b, 0xdf, 0xb, 0x23, 0x8d, 0x5b, 0xc2, 0x31, 0x37, 0x2d, 0x25, 0xa9, 0x29, 0x90, 0xd2, 0xa7, 0xca, 0xe8, 0x4d, 0xb0, 0x8d, 0xb0, 0x3c, 0x67, 0xf4, 0x2b, 0xe7, 0x83, 0x9d, 0xb8},
+		y: fp384{0x24, 0x44, 0xf2, 0xe1, 0xbf, 0x39, 0xfd, 0xa8, 0x16, 0xd6, 0xe8, 0xe1, 0xd6, 0xb6, 0x89, 0x9f, 0x6e, 0x21, 0x1d, 0x4f, 0x7b, 0xc8, 0x9f, 0xaf, 0x59, 0x5a, 0x26, 0x92, 0x3, 0x1e, 0xe2, 0x4, 0x73, 0x63, 0xb8, 0x87, 0x3, 0x74, 0x15, 0xb, 0x62, 0xa1, 0x98, 0x7c, 0x3b, 0xaf, 0x65, 0x6f},
+	},
+	// 75P
+	{
+		x: fp384{0xde, 0x3, 0x73, 0x86, 0x14, 0x40, 0x5d, 0x6b, 0xef, 0xb7, 0xa, 0x42, 0xa, 0xc4, 0xcb, 0xc8, 0x96, 0x9a, 0x54, 0x91, 0x89, 0xcf, 0x28, 0x5b, 0x66, 0x8f, 0x2f, 0x39, 0xb4, 0x31, 0x46, 0x5d, 0xc8, 0xb5, 0x67, 0xf3, 0x3d, 0xe2, 0x7e, 0x4a, 0x15, 0x7a, 0xca, 0xe6, 0xf, 0xae, 0xe0, 0xa1},
+		y: fp384{0x7c, 0xa2, 0x9f, 0x13, 0xe1, 0x5e, 0x65, 0x2a, 0x1, 0xb9, 0xfa, 0x50, 0xc4, 0xc2, 0x31, 0xa5, 0x71, 0xed, 0xa, 0x43, 0x69, 0xab, 0x62, 0x67, 0x1d, 0x2e, 0x40, 0xf0, 0xe3, 0x39, 0xe2, 0x64, 0x45, 0xe4, 0x7f, 0x95, 0x42, 0x0, 0x87, 0xd7, 0x62, 0x65, 0x7d, 0x41, 0x62, 0xd8, 0x42, 0xfd},
+	},
+	// 77P
+	{
+		x: fp384{0x3f, 0x1a, 0x50, 0x2a, 0xc1, 0x34, 0x21, 0x9f, 0xa7, 0x93, 0x47, 0x33, 0x40, 0x9b, 0x4a, 0x11, 0x25, 0x61, 0x2a, 0x21, 0xc0, 0xb6, 0xcc, 0x27, 0xa3, 0x78, 0xce, 0x98, 0xb9, 0x30, 0xa9, 0xc, 0x27, 0x26, 0xa1, 0x28, 0xb, 0x6, 0x2e, 0x74, 0x16, 0x98, 0x5c, 0xfa, 0x7, 0x36, 0xd2, 0x63},
+		y: fp384{0xdc, 0x91, 0x1f, 0xec, 0xa4, 0xcb, 0x4d, 0x77, 0x23, 0x1d, 0x4d, 0xf3, 0x2e, 0x7e, 0xcd, 0x34, 0x3d, 0x3c, 0xfd, 0x49, 0xe, 0x85, 0x0, 0x15, 0xb2, 0xcf, 0xc9, 0x30, 0x0, 0x95, 0x3, 0xdd, 0xa6, 0x41, 0x29, 0x57, 0xe5, 0xc3, 0x61, 0xce, 0x2e, 0xfd, 0x2c, 0x30, 0x75, 0x10, 0x4b, 0xd4},
+	},
+	// 79P
+	{
+		x: fp384{0x24, 0xc2, 0xa6, 0xe9, 0xd4, 0xd9, 0x11, 0xca, 0x85, 0x45, 0xb7, 0xc3, 0x48, 0xc2, 0xda, 0x2c, 0x71, 0x55, 0xca, 0x4, 0xa2, 0x1, 0x89, 0xe5, 0xf0, 0x1, 0x5d, 0xd1, 0x2d, 0x31, 0x1c, 0x49, 0x7c, 0xcb, 0x69, 0x70, 0x8a, 0x81, 0xcc, 0xb3, 0xda, 0x12, 0x39, 0xd5, 0xa5, 0x45, 0xb2, 0x23},
+		y: fp384{0x63, 0xb1, 0xb0, 0xa6, 0x8b, 0x83, 0xf7, 0x30, 0x52, 0x55, 0x77, 0x32, 0x3e, 0xeb, 0x52, 0xa0, 0xc1, 0x5e, 0xb9, 0xee, 0xe9, 0x43, 0x32, 0x40, 0xb3, 0x2e, 0x63, 0x8, 0x1b, 0x30, 0x7b, 0x61, 0xf9, 0x81, 0x2, 0xf3, 0xc9, 0x66, 0x1c, 0x94, 0x55, 0xb2, 0x7a, 0x1d, 0xf8, 0x28, 0x97, 0x4b},
+	},
+	// 81P
+	{
+		x: fp384{0x82, 0xf6, 0x6, 0xdb, 0xcb, 0xd3, 0xbd, 0x3c, 0x85, 0x87, 0xc0, 0x86, 0x3e, 0x47, 0x45, 0xde, 0xfb, 0x1b, 0x7b, 0xe0, 0x60, 0x35, 0xcb, 0xd8, 0xaf, 0x38, 0xf1, 0xea, 0x8f, 0x11, 0xc3, 0xf2, 0xaf, 0x6f, 0x43, 0x9f, 0x85, 0x8a, 0x23, 0x11, 0x4f, 0x34, 0xdf, 0x7c, 0xe3, 0xc2, 0x84, 0x9},
+		y: fp384{0x4f, 0x58, 0x82, 0xc3, 0x17, 0x3c, 0x8, 0xe1, 0x40, 0xa2, 0x6f, 0x73, 0xd4, 0x14, 0x9a, 0x95, 0x7d, 0x63, 0xf2, 0x18, 0xf0, 0xd2, 0xad, 0x56, 0x8d, 0x27, 0xdd, 0xe5, 0x5e, 0x7a, 0x4, 0x1, 0xa7, 0x6, 0x27, 0xae, 0x63, 0x8d, 0xe3, 0x5d, 0x7e, 0xb8, 0x45, 0x97, 0x60, 0xb7, 0xd7, 0x9d},
+	},
+	// 83P
+	{
+		x: fp384{0x71, 0x40, 0xe9, 0x44, 0xbf, 0xf0, 0x61, 0x8e, 0xb4, 0x5e, 0xf0, 0xd2, 0x7e, 0x84, 0xcf, 0x44, 0xeb, 0x94, 0x66, 0x4a, 0xd, 0xaa, 0x87, 0x84, 0xb5, 0xaa, 0xa4, 0xc7, 0xa1, 0x8c, 0xb8, 0xee, 0x26, 0x89, 0xa, 0x52, 0x3, 0xaa, 0x5b, 0xc2, 0x5, 0x78, 0x3d, 0xc0, 0x6a, 0xb1, 0x75, 0xa0},
+		y: fp384{0xc3, 0x70, 0xd9, 0x13, 0x8a, 0xa4, 0x57, 0xc3, 0x3e, 0x64, 0x9, 0x60, 0x70, 0x13, 0x3c, 0x4e, 0x29, 0x4, 0xe6, 0x49, 0x57, 0xa9, 0x21, 0xcf, 0xda, 0xbc, 0x51, 0x22, 0xba, 0x62, 0xa2, 0xa, 0xe4, 0x78, 0x3c, 0x56, 0xd0, 0x7c, 0x2a, 0xb7, 0xf9, 0x1c, 0xce, 0x69, 0xda, 0xfe, 0x3d, 0x77},
+	},
+	// 85P
+	{
+		x: fp384{0x2d, 0x76, 0x6, 0x9b, 0xdf, 0x2c, 0x5d, 0x93, 0x5a, 0x25, 0x7, 0x82, 0xb8, 0xbb, 0x48, 0x21, 0xd8, 0x53, 0x31, 0x5, 0xdd, 0xca, 0xbd, 0x7b, 0x57, 0x6a, 0x25, 0x73, 0xff, 0xaa, 0x53, 0xd9, 0x1, 0x6f, 0x4e, 0x11, 0xe1, 0x8f, 0xa0, 0xb0, 0x4d, 0x4d, 0xe6, 0x46, 0x54, 0x2, 0x35, 0xc8},
+		y: fp384{0x57, 0xc1, 0xdb, 0x0, 0xd8, 0xba, 0xcf, 0xe7, 0x69, 0xe9, 0xfb, 0x71, 0x2, 0xae, 0x2a, 0x39, 0x14, 0xe3, 0xeb, 0xb, 0x2a, 0xa7, 0x22, 0x74, 0xf2, 0x52, 0xaf, 0x2c, 0xd2, 0x55, 0xd4, 0xc3, 0x95, 0x51, 0x89, 0xe2, 0x9f, 0x83, 0x31, 0xa2, 0x13, 0xf2, 0x93, 0xc9, 0x92, 0x8d, 0x21, 0x6c},
+	},
+	// 87P
+	{
+		x: fp384{0x2e, 0x37, 0xa0, 0x4a, 0x2e, 0xa0, 0x11, 0x4f, 0x75, 0x77, 0x96, 0x10, 0x30, 0x47, 0x42, 0x59, 0x95, 0x91, 0x80, 0x8b, 0xba, 0xc1, 0xe, 0xdf, 0xf1, 0x3a, 0x3c, 0x9a, 0x8d, 0x92, 0xa, 0xf3, 0x2e, 0x6b, 0x7b, 0x38, 0x20, 0x3, 0x84, 0xc4, 0x22, 0xbb, 0x0, 0xa5, 0x17, 0x34, 0x1b, 0x1c},
+		y: fp384{0xf2, 0x66, 0x32, 0xbf, 0xc7, 0xe6, 0xe, 0x69, 0x81, 0x96, 0x90, 0xa7, 0x74, 0x6d, 0x24, 0x18, 0x8f, 0xa8, 0x84, 0xf9, 0x54, 0x24, 0xdf, 0xde, 0x9, 0x9f, 0x55, 0xe7, 0x75, 0x41, 0x94, 0x31, 0xb7, 0x4d, 0x7b, 0xe, 0x88, 0x81, 0xac, 0xbd, 0x68, 0xfe, 0x96, 0xe9, 0xae, 0x6f, 0x4, 0x9f},
+	},
+	// 89P
+	{
+		x: fp384{0xac, 0xd4, 0x71, 0x2d, 0x4b, 0x9, 0x62, 0xc, 0xe0, 0x63, 0xf1, 0x4b, 0xdc, 0x9f, 0xa4, 0x18, 0x1f, 0x72, 0x96, 0x0, 0xb, 0xf3, 0x3d, 0x46, 0x7b, 0x5b, 0xe5, 0xc8, 0x4a, 0x64, 0xd3, 0x67, 0xb6, 0xe2, 0xe0, 0x19, 0x9d, 0xd2, 0x3d, 0xd6, 0x61, 0x73, 0x4b, 0x16, 0xde, 0x5, 0xd1, 0xd0},
+		y: fp384{0x8e, 0x18, 0x17, 0x2, 0x4e, 0x5c, 0x86, 0xe5, 0x7e, 0xcf, 0x93, 0x20, 0x1b, 0xb7, 0x61, 0x78, 0x3c, 0x25, 0xaa, 0x2d, 0x51, 0xf0, 0xcc, 0x65, 0xc0, 0xe4, 0x4d, 0xb, 0x9, 0x1, 0x77, 0x14, 0xd9, 0x62, 0xb9, 0x40, 0x35, 0x24, 0x28, 0x1d, 0xf3, 0x37, 0xdf, 0xb8, 0x39, 0xe9, 0xc7, 0x1},
+	},
+	// 91P
+	{
+		x: fp384{0x58, 0x8, 0xba, 0x9c, 0x9c, 0x40, 0xea, 0x5d, 0x63, 0x3f, 0xae, 0x14, 0x1b, 0x42, 0xc2, 0x35, 0x8a, 0x61, 0xc2, 0xbb, 0x34, 0xe5, 0xf6, 0xa4, 0x5f, 0x4f, 0xd7, 0x42, 0x7d, 0x97, 0x4b, 0xb0, 0xb7, 0x3e, 0xdc, 0x59, 0x27, 0x38, 0xe7, 0xe7, 0xb0, 0x23, 0xf2, 0x8b, 0x34, 0x52, 0xf, 0xeb},
+		y: fp384{0x58, 0x51, 0xc7, 0xf, 0x67, 0x51, 0x1c, 0x99, 0x6d, 0x2c, 0xde, 0x3f, 0x1a, 0x81, 0x12, 0xd0, 0x3d, 0x34, 0x36, 0x92, 0x31, 0xb3, 0xd0, 0x9, 0xa0, 0xcb, 0xa2, 0x63, 0xc8, 0xe0, 0x78, 0xcb, 0x78, 0x84, 0xb8, 0x9a, 0xbd, 0xb3, 0x9, 0xb, 0xe2, 0xc6, 0x16, 0xf1, 0x3, 0xc7, 0xca, 0x47},
+	},
+	// 93P
+	{
+		x: fp384{0xaf, 0x80, 0x2d, 0xe3, 0x71, 0x4d, 0xd1, 0xeb, 0x5e, 0x67, 0x80, 0x53, 0x4f, 0xc2, 0x1c, 0x1b, 0xcd, 0x42, 0x61, 0xb1, 0x64, 0x47, 0x63, 0x1c, 0xe, 0xb0, 0xfd, 0x7c, 0xde, 0x45, 0x35, 0x7a, 0x54, 0x51, 0xd1, 0xcf, 0x89, 0x16, 0xf9, 0x2d, 0xd7, 0xa2, 0xa, 0x43, 0xb3, 0x55, 0x33, 0x81},
+		y: fp384{0x7e, 0xca, 0xf2, 0x85, 0xc9, 0xe2, 0xdc, 0x16, 0x79, 0xbb, 0x3a, 0xe0, 0xf7, 0x3, 0xe3, 0xd9, 0x98, 0x66, 0xb0, 0x3c, 0x10, 0xa8, 0x7c, 0xfe, 0xcb, 0xd, 0x67, 0x71, 0x5b, 0x42, 0x2a, 0x57, 0xe5, 0x68, 0xa2, 0x90, 0x54, 0x39, 0x1b, 0xc7, 0x9, 0x9d, 0xbf, 0x66, 0x8f, 0xf3, 0x71, 0xc0},
+	},
+	// 95P
+	{
+		x: fp384{0x91, 0x3c, 0xbc, 0xd, 0x63, 0xf2, 0xc0, 0xf, 0xb1, 0xcb, 0xc0, 0x9b, 0x16, 0xca, 0x74, 0x9f, 0x77, 0x89, 0xf9, 0xe, 0x9d, 0x7b, 0x60, 0x4a, 0x79, 0x2b, 0x7d, 0xa2, 0xef, 0xb, 0xe9, 0xb, 0xe1, 0x23, 0x7f, 0xad, 0xb5, 0xb, 0x7b, 0x25, 0xe4, 0xd1, 0xea, 0x2f, 0xe5, 0x2f, 0xf4, 0xb8},
+		y: fp384{0x92, 0xb5, 0x93, 0x5f, 0x31, 0xe4, 0x78, 0xde, 0x7d, 0x61, 0x79, 0xfd, 0xeb, 0xe7, 0x5f, 0x50, 0xfb, 0xf9, 0x99, 0xdd, 0x14, 0x3f, 0xcc, 0x45, 0x91, 0xb5, 0xc7, 0x3b, 0xe8, 0x64, 0xf, 0x8c, 0xf9, 0x93, 0xab, 0x55, 0xed, 0x4d, 0x36, 0x65, 0x6e, 0x28, 0xdf, 0x42, 0xa5, 0x4b, 0x6d, 0xbb},
+	},
+	// 97P
+	{
+		x: fp384{0xe2, 0x54, 0x5c, 0x7f, 0x5d, 0x3, 0xd2, 0x7c, 0x2c, 0x49, 0x49, 0x4a, 0x0, 0xdb, 0xf0, 0xc1, 0x98, 0x8f, 0x27, 0x65, 0x30, 0x3e, 0x27, 0x8f, 0x9d, 0x9d, 0xef, 0x6f, 0xd1, 0x1e, 0x24, 0x10, 0x16, 0x96, 0x6, 0xac, 0x1b, 0xe5, 0xb1, 0x87, 0x7f, 0x80, 0xd, 0x17, 0xcd, 0x1a, 0x8, 0x8c},
+		y: fp384{0x98, 0xb5, 0x73, 0x1c, 0xea, 0x51, 0x50, 0x0, 0xf4, 0x5b, 0x86, 0xd6, 0x12, 0x55, 0xeb, 0xe4, 0xd3, 0x5d, 0xe0, 0x30, 0xf4, 0x4e, 0xd2, 0xd7, 0x9e, 0xa3, 0x89, 0x78, 0xed, 0xe4, 0x47, 0xcb, 0x64, 0x69, 0xf5, 0xc4, 0x91, 0x24, 0x3e, 0x4c, 0x6, 0x30, 0xf0, 0xc4, 0x8e, 0xb7, 0xc6, 0x83},
+	},
+	// 99P
+	{
+		x: fp384{0xa1, 0x84, 0x5f, 0xb0, 0xa9, 0x35, 0x38, 0x6e, 0x4e, 0x17, 0xaa, 0x41, 0xf, 0x9e, 0x4f, 0xbb, 0x69, 0xa4, 0x8b, 0x70, 0x7c, 0x17, 0x41, 0x1b, 0xbd, 0xf8, 0xc8, 0x79, 0xb4, 0xe6, 0xb2, 0xb9, 0xbd, 0xd6, 0xd9, 0x82, 0x9, 0xae, 0x9c, 0xd4, 0x3a, 0x22, 0x28, 0xbb, 0x0, 0x5f, 0x8c, 0x64},
+		y: fp384{0xa5, 0xc4, 0x8c, 0x5d, 0x76, 0x85, 0xf4, 0x4, 0x8d, 0xa3, 0xa0, 0x81, 0xdd, 0x96, 0x30, 0xfe, 0xe1, 0x47, 0x82, 0x70, 0x8f, 0x13, 0x75, 0x66, 0x8, 0xea, 0xa0, 0xd1, 0xd8, 0x59, 0xf7, 0xd6, 0x98, 0xd, 0x19, 0x76, 0xb1, 0x93, 0x74, 0x1f, 0xbd, 0x63, 0x2d, 0x32, 0x8b, 0x69, 0xe1, 0x3},
+	},
+	// 101P
+	{
+		x: fp384{0xac, 0xde, 0x8a, 0x9b, 0xf6, 0xc6, 0x66, 0x8e, 0x70, 0x6d, 0xc6, 0x50, 0xfe, 0xf5, 0x39, 0xb5, 0x1a, 0xfb, 0xcc, 0x2e, 0x2c, 0xcd, 0xdd, 0x73, 0xfc, 0x5c, 0x8b, 0x8b, 0xad, 0x1f, 0x3b, 0xd7, 0x10, 0x87, 0xa1, 0x47, 0x35, 0x94, 0xdd, 0x9c, 0xdb, 0x14, 0xc8, 0x7b, 0xbf, 0x92, 0x23, 0x7e},
+		y: fp384{0xe8, 0x74, 0x8f, 0x6c, 0xc0, 0x93, 0x41, 0x91, 0x4d, 0xc0, 0x67, 0x1d, 0x21, 0xdc, 0xed, 0xff, 0x93, 0x86, 0xd6, 0xa, 0x85, 0x41, 0xef, 0x1f, 0x54, 0x80, 0x3e, 0xf5, 0x9a, 0x1d, 0x3e, 0xa7, 0x4, 0xc1, 0xe, 0x42, 0x6f, 0x65, 0x9b, 0x90, 0xde, 0xe1, 0x2, 0x17, 0x36, 0x2d, 0x87, 0x73},
+	},
+	// 103P
+	{
+		x: fp384{0x5f, 0x5d, 0x35, 0x21, 0xaa, 0xab, 0x4c, 0xd2, 0xbd, 0x2, 0xd4, 0xaf, 0xe, 0xb1, 0xcb, 0xdd, 0xe1, 0x1d, 0xc2, 0x29, 0x43, 0xd1, 0xf0, 0xd3, 0xfc, 0x84, 0x3d, 0xf2, 0x94, 0x5a, 0xd9, 0x1a, 0xd, 0x53, 0xda, 0xe3, 0x2, 0x79, 0x3a, 0x11, 0x48, 0x10, 0x67, 0x64, 0x8e, 0xa8, 0xd, 0x59},
+		y: fp384{0xda, 0xf0, 0x5b, 0x92, 0x82, 0x82, 0xa5, 0xf4, 0xb, 0x6e, 0x2e, 0xe6, 0xe7, 0xe4, 0x52, 0x1a, 0xfd, 0x4d, 0x6f, 0xd8, 0x4e, 0xbb, 0xeb, 0x97, 0xc3, 0xd1, 0xfa, 0x58, 0xc3, 0xd1, 0x1b, 0x60, 0x52, 0x5, 0xe4, 0x2d, 0xa6, 0xd5, 0xe2, 0xd6, 0xed, 0xdb, 0x73, 0x72, 0x37, 0x71, 0x9e, 0xc},
+	},
+	// 105P
+	{
+		x: fp384{0x45, 0x28, 0x80, 0xe5, 0x85, 0x19, 0xe9, 0xe6, 0xbc, 0x1, 0xe2, 0xa6, 0xae, 0xd6, 0x67, 0xc3, 0xbe, 0x23, 0x2c, 0xdd, 0xe5, 0x30, 0x7f, 0x7, 0xe3, 0x75, 0x50, 0x27, 0x9c, 0xf3, 0x2e, 0x86, 0x42, 0x65, 0x80, 0x1a, 0x44, 0x75, 0x2c, 0x2, 0x9c, 0xd0, 0xeb, 0x99, 0x3a, 0x3e, 0xab, 0xd0},
+		y: fp384{0xb8, 0x28, 0x90, 0xd9, 0x60, 0xef, 0x67, 0x7d, 0x6b, 0x13, 0xad, 0xa9, 0x4f, 0x36, 0xcf, 0xa5, 0x8c, 0xff, 0x1f, 0xa9, 0xa9, 0x23, 0x2c, 0x37, 0x60, 0x25, 0x20, 0x47, 0x95, 0x7a, 0xd5, 0xd3, 0x23, 0x19, 0x2f, 0x15, 0x45, 0xf1, 0xba, 0xce, 0xa5, 0x73, 0x89, 0x6d, 0x2c, 0xe7, 0x3a, 0xcc},
+	},
+	// 107P
+	{
+		x: fp384{0x23, 0x3f, 0x36, 0xf4, 0xe1, 0xe8, 0x18, 0xd7, 0x90, 0x14, 0x76, 0x4f, 0x20, 0x1e, 0xc2, 0x73, 0x46, 0x5d, 0x7, 0xa0, 0x25, 0xec, 0xc6, 0x27, 0xd0, 0x40, 0x3f, 0x75, 0x56, 0xf4, 0xd4, 0xcc, 0x22, 0x16, 0xa9, 0x60, 0x49, 0x4c, 0x99, 0x50, 0x48, 0xb, 0x74, 0x3f, 0x79, 0x4d, 0x96, 0x77},
+		y: fp384{0x2, 0xed, 0x47, 0xf6, 0xe2, 0x55, 0xc9, 0xf4, 0x79, 0x3d, 0x19, 0xe4, 0x9a, 0xc7, 0x4f, 0x84, 0x9f, 0x3f, 0x7f, 0xa2, 0xd1, 0x74, 0x83, 0x48, 0x63, 0x94, 0x65, 0xb8, 0x45, 0xad, 0xd6, 0x95, 0x39, 0x8e, 0x43, 0xc7, 0x78, 0x9f, 0xd9, 0xe1, 0xf2, 0xed, 0xfc, 0x2a, 0x17, 0xa7, 0x82, 0x51},
+	},
+	// 109P
+	{
+		x: fp384{0xfa, 0xb1, 0xde, 0xb2, 0x27, 0x2e, 0xfc, 0xe, 0x4b, 0x18, 0xc1, 0x3c, 0x83, 0x35, 0x7d, 0x9c, 0xc8, 0xbd, 0xdc, 0xa8, 0xf8, 0xc5, 0x41, 0x58, 0xbb, 0x3a, 0xd9, 0xf0, 0x8a, 0xa5, 0x11, 0xa9, 0x87, 0xf8, 0xcf, 0xb9, 0x33, 0x8c, 0xd1, 0x3c, 0x3, 0x24, 0x3f, 0xf1, 0xbb, 0x27, 0x3c, 0x6e},
+		y: fp384{0xe6, 0x3a, 0x53, 0xea, 0x12, 0x17, 0x39, 0x5b, 0x5, 0x4c, 0x29, 0x54, 0xb, 0xd9, 0xcd, 0x35, 0xf4, 0xda, 0x60, 0xf5, 0xb4, 0x7f, 0xb5, 0x2d, 0x1d, 0x41, 0xa1, 0xf5, 0xca, 0x33, 0xad, 0x75, 0x68, 0x75, 0x7c, 0x7f, 0x4e, 0x9a, 0xe1, 0x87, 0x5, 0x77, 0x8c, 0x19, 0x56, 0x6c, 0xc4, 0xf4},
+	},
+	// 111P
+	{
+		x: fp384{0xb8, 0x74, 0xbe, 0x5, 0x48, 0xb7, 0xb3, 0x8d, 0xab, 0x5f, 0x76, 0x0, 0x50, 0x80, 0xe0, 0x8, 0xd9, 0x7f, 0x44, 0x50, 0xb, 0x72, 0x44, 0x67, 0x3, 0xbe, 0x27, 0xc7, 0x12, 0x20, 0x55, 0x27, 0x7f, 0x66, 0x2, 0x8b, 0x51, 0x7b, 0x90, 0xc3, 0x14, 0xef, 0xbd, 0xb9, 0xbc, 0xaa, 0x58, 0xa1},
+		y: fp384{0x6f, 0xc5, 0x9c, 0xf4, 0x3, 0xfa, 0xdd, 0xaa, 0x96, 0xfb, 0x5, 0xe3, 0xe4, 0xbe, 0x95, 0x10, 0x19, 0x26, 0xc3, 0x93, 0xbc, 0x54, 0xff, 0xa2, 0x85, 0x26, 0xeb, 0x4a, 0xf9, 0xe1, 0xf8, 0xcc, 0xfe, 0xd9, 0x0, 0x23, 0xb8, 0x47, 0x4b, 0xc6, 0xa9, 0x9d, 0x27, 0x8, 0x68, 0x77, 0xca, 0x9},
+	},
+	// 113P
+	{
+		x: fp384{0x12, 0xda, 0xb, 0x9b, 0xb7, 0x86, 0x5b, 0xf8, 0x72, 0x35, 0xe3, 0xbb, 0xd1, 0x16, 0xc6, 0xd2, 0x7f, 0xd2, 0x2b, 0x85, 0xef, 0x15, 0x22, 0xe7, 0xc5, 0x7f, 0x9b, 0x13, 0x9, 0x5b, 0x81, 0xe9, 0xc2, 0xa0, 0x7f, 0x8d, 0x4, 0xdb, 0x5b, 0x4a, 0x86, 0xa9, 0x86, 0xff, 0x17, 0xcd, 0x9f, 0x86},
+		y: fp384{0xbe, 0xf6, 0xda, 0x91, 0x17, 0x52, 0x78, 0x32, 0x4, 0x4d, 0x66, 0xd6, 0xf1, 0x7, 0xc0, 0xb9, 0x29, 0x20, 0xb1, 0xe7, 0x2a, 0x72, 0x98, 0x69, 0x67, 0xbb, 0x31, 0xfc, 0xd9, 0xde, 0x7f, 0xbf, 0x57, 0x77, 0xb8, 0x31, 0x7c, 0xd1, 0xe, 0x3d, 0x4b, 0x94, 0xf7, 0x55, 0xf2, 0x3d, 0xb, 0xa1},
+	},
+	// 115P
+	{
+		x: fp384{0x56, 0x8f, 0x49, 0x34, 0x3b, 0x67, 0x4e, 0xaa, 0x6d, 0x45, 0x43, 0xa0, 0xb3, 0xf7, 0x20, 0x91, 0x26, 0x88, 0xa4, 0x26, 0xf3, 0x68, 0xe8, 0x33, 0xfd, 0x6b, 0x40, 0x32, 0xf4, 0xcc, 0x7a, 0xa9, 0x46, 0x7, 0xc5, 0x23, 0x41, 0x2a, 0x44, 0x84, 0x2d, 0x98, 0x50, 0x73, 0x65, 0x69, 0x4c, 0x27},
+		y: fp384{0xaa, 0x9e, 0xdc, 0x95, 0xfb, 0xb7, 0x6, 0x31, 0x41, 0xe2, 0x7a, 0xec, 0xb1, 0x1d, 0xbf, 0x3e, 0x86, 0x5b, 0x8a, 0x84, 0xb8, 0x39, 0xdc, 0x0, 0xc6, 0x2e, 0x31, 0xf6, 0x3a, 0x34, 0x9a, 0xdf, 0x3, 0x1f, 0x12, 0xcf, 0x32, 0x9e, 0x2, 0x75, 0xdb, 0x11, 0x5a, 0xcf, 0xf6, 0xbd, 0xc5, 0xc0},
+	},
+	// 117P
+	{
+		x: fp384{0x9a, 0x55, 0x23, 0x7, 0xa8, 0xe7, 0xcc, 0xfd, 0x70, 0xd0, 0x29, 0xa2, 0xe, 0xb3, 0x32, 0x95, 0x61, 0x79, 0x85, 0xfe, 0x94, 0x52, 0x3e, 0x61, 0x8d, 0x73, 0xea, 0x9a, 0x9a, 0x74, 0x9e, 0xad, 0x53, 0xba, 0xac, 0x23, 0xae, 0x6b, 0x7a, 0x51, 0x8b, 0x56, 0x23, 0x78, 0xcd, 0x74, 0x67, 0xf2},
+		y: fp384{0x4d, 0x11, 0x53, 0xae, 0xa1, 0x67, 0x7, 0x94, 0x7b, 0x5, 0x8c, 0xeb, 0x4b, 0x3a, 0xcb, 0xc6, 0x0, 0xf6, 0xae, 0x6, 0x5f, 0xc0, 0x99, 0x6d, 0x81, 0x84, 0x79, 0xb2, 0x8d, 0x9b, 0x72, 0xa6, 0x5b, 0x58, 0xf1, 0xbf, 0x82, 0x65, 0x54, 0x7a, 0x73, 0x97, 0xb0, 0x82, 0xb0, 0x9a, 0x50, 0x70},
+	},
+	// 119P
+	{
+		x: fp384{0xd1, 0xd8, 0x29, 0x73, 0xac, 0x95, 0x25, 0x73, 0xc4, 0xbc, 0x73, 0xab, 0x8d, 0x7, 0xf9, 0x59, 0xde, 0x9d, 0xcf, 0x21, 0xb4, 0xe7, 0x55, 0xcd, 0x27, 0xab, 0x5f, 0x87, 0xa1, 0xb, 0x63, 0xa4, 0xcd, 0xf4, 0x9c, 0xec, 0xb8, 0x7f, 0x16, 0x13, 0x77, 0x5, 0x8b, 0x99, 0x57, 0x5c, 0xfc, 0xd2},
+		y: fp384{0x6f, 0x1b, 0xf5, 0x5f, 0xc1, 0x60, 0x13, 0x76, 0xeb, 0x9c, 0xcf, 0x6, 0xf2, 0x96, 0xdb, 0xb2, 0x46, 0x8f, 0xdc, 0x99, 0x48, 0xa6, 0x77, 0xd6, 0xe5, 0xb7, 0x9, 0x91, 0xbc, 0xca, 0x9e, 0xeb, 0xa3, 0xb7, 0x21, 0x92, 0xac, 0xb1, 0x1b, 0x9a, 0xcd, 0xa5, 0x40, 0x8a, 0x28, 0x36, 0x65, 0xb1},
+	},
+	// 121P
+	{
+		x: fp384{0x8d, 0xfa, 0x9d, 0x18, 0x40, 0xba, 0x98, 0x51, 0x1e, 0xab, 0x96, 0xa8, 0xe3, 0x16, 0x9a, 0x8c, 0xe4, 0x44, 0x67, 0xba, 0xd6, 0xd5, 0x33, 0x6c, 0x8a, 0x77, 0x72, 0x77, 0xd4, 0xfb, 0x9a, 0xc2, 0xe0, 0xf7, 0x29, 0x93, 0x95, 0x3c, 0xdf, 0x65, 0x81, 0xdb, 0x91, 0x38, 0x1e, 0x3f, 0xcd, 0x79},
+		y: fp384{0x9b, 0x1, 0x84, 0xd7, 0xb, 0x8f, 0xaa, 0xca, 0x62, 0x8e, 0x2, 0xe9, 0x6b, 0x4f, 0x40, 0xf5, 0x85, 0x89, 0x4d, 0xae, 0x54, 0x7a, 0x50, 0x95, 0x1b, 0xf2, 0x16, 0xb7, 0xa8, 0x39, 0x1d, 0x9c, 0x7e, 0x5b, 0x26, 0xf8, 0xf9, 0xd, 0x3d, 0x47, 0x16, 0x9, 0x4d, 0xc6, 0xa1, 0xed, 0xae, 0x11},
+	},
+	// 123P
+	{
+		x: fp384{0x80, 0xb, 0x4c, 0xc, 0x48, 0x98, 0x11, 0x15, 0xfe, 0x18, 0x10, 0x2a, 0x4a, 0x7d, 0xb0, 0x46, 0x7b, 0x90, 0x80, 0xea, 0xeb, 0xc3, 0xa9, 0x14, 0x5, 0x44, 0x95, 0x42, 0xee, 0x5, 0x3d, 0x4b, 0xd2, 0x18, 0x4, 0x55, 0x78, 0xfd, 0xd6, 0xd4, 0xa6, 0x82, 0xdc, 0x21, 0x63, 0x4f, 0x4a, 0x8e},
+		y: fp384{0xd9, 0xb9, 0x78, 0xa1, 0xf7, 0xd7, 0xe4, 0x1b, 0x9f, 0x8c, 0x78, 0x70, 0x4, 0xba, 0xc6, 0x83, 0xe8, 0xf7, 0x30, 0x9f, 0x3e, 0xaf, 0x82, 0x5a, 0x7b, 0x44, 0x8f, 0x49, 0xf, 0xab, 0x86, 0x8a, 0x33, 0xcf, 0x5c, 0xc2, 0xec, 0xbc, 0xba, 0x3, 0xdd, 0x8a, 0x79, 0x1a, 0xed, 0x62, 0xc4, 0x74},
+	},
+	// 125P
+	{
+		x: fp384{0xbb, 0x44, 0xfb, 0x3c, 0xbc, 0xb8, 0x12, 0x96, 0xda, 0x6a, 0x9d, 0x71, 0x77, 0x56, 0xf2, 0x70, 0xe2, 0x14, 0xf6, 0x46, 0xaa, 0x65, 0xea, 0x50, 0x6d, 0x35, 0x50, 0x34, 0xcf, 0xa8, 0x36, 0x94, 0xac, 0x3, 0x67, 0x3, 0xad, 0xeb, 0xd6, 0x7a, 0xae, 0x48, 0xcf, 0x45, 0xb2, 0xda, 0xb2, 0x3},
+		y: fp384{0x1e, 0x6, 0x17, 0x41, 0x2a, 0x3d, 0x95, 0x21, 0xa4, 0x55, 0x4f, 0xed, 0x30, 0xb7, 0x3f, 0xdf, 0x8e, 0xab, 0x19, 0xe1, 0x41, 0x36, 0xf5, 0xec, 0xaa, 0x87, 0x91, 0x21, 0xbc, 0x41, 0x1f, 0x55, 0x2, 0x58, 0x9, 0xb0, 0x4b, 0xa7, 0xd5, 0x7c, 0xcb, 0x5c, 0xf3, 0x72, 0xf5, 0xbf, 0x33, 0x89},
+	},
+	// 127P
+	{
+		x: fp384{0xec, 0x1, 0xa1, 0xec, 0x46, 0x32, 0x75, 0xf7, 0xaf, 0x4, 0x96, 0x56, 0x4c, 0xfa, 0xac, 0x2a, 0x79, 0x62, 0x2c, 0x52, 0x34, 0x8f, 0xf2, 0xee, 0xf, 0x1e, 0x23, 0x74, 0x38, 0xe6, 0xfd, 0x96, 0x9d, 0xf0, 0xe0, 0xd6, 0x1b, 0xb1, 0x2b, 0xa9, 0xb4, 0x5d, 0x39, 0xf, 0x74, 0x4e, 0xe3, 0xbb},
+		y: fp384{0xf9, 0x3c, 0x94, 0xbf, 0xdd, 0x59, 0x6e, 0xaa, 0xaa, 0xd5, 0x8a, 0x1, 0xbe, 0xbd, 0x98, 0x56, 0x19, 0xc5, 0x67, 0xa4, 0x44, 0x2a, 0xd2, 0x88, 0xe, 0xb, 0x18, 0xad, 0x39, 0xe3, 0x29, 0x9e, 0x94, 0x2f, 0x7b, 0x36, 0x2e, 0x83, 0xd6, 0xf3, 0x69, 0x80, 0x94, 0xe3, 0x61, 0x2a, 0xe9, 0xc7},
+	},
+}
diff --git a/vendor/github.com/cloudflare/circl/hpke/aead.go b/vendor/github.com/cloudflare/circl/hpke/aead.go
new file mode 100644
index 00000000..baf147bb
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/hpke/aead.go
@@ -0,0 +1,103 @@
+package hpke
+
+import (
+	"crypto/cipher"
+	"fmt"
+)
+
+type encdecContext struct {
+	// Serialized parameters
+	suite              Suite
+	sharedSecret       []byte
+	secret             []byte
+	keyScheduleContext []byte
+	exporterSecret     []byte
+	key                []byte
+	baseNonce          []byte
+	sequenceNumber     []byte
+
+	// Operational parameters
+	cipher.AEAD
+	nonce []byte
+}
+
+type (
+	sealContext struct{ *encdecContext }
+	openContext struct{ *encdecContext }
+)
+
+// Export takes a context string exporterContext and a desired length (in
+// bytes), and produces a secret derived from the internal exporter secret
+// using the corresponding KDF Expand function. It panics if length is
+// greater than 255*N bytes, where N is the size (in bytes) of the KDF's
+// output.
+func (c *encdecContext) Export(exporterContext []byte, length uint) []byte {
+	maxLength := uint(255 * c.suite.kdfID.ExtractSize())
+	if length > maxLength {
+		panic(fmt.Errorf("output length must be lesser than %v bytes", maxLength))
+	}
+	return c.suite.labeledExpand(c.exporterSecret, []byte("sec"),
+		exporterContext, uint16(length))
+}
+
+func (c *encdecContext) Suite() Suite {
+	return c.suite
+}
+
+func (c *encdecContext) calcNonce() []byte {
+	for i := range c.baseNonce {
+		c.nonce[i] = c.baseNonce[i] ^ c.sequenceNumber[i]
+	}
+	return c.nonce
+}
+
+func (c *encdecContext) increment() error {
+	// tests whether the sequence number is all-ones, which prevents an
+	// overflow after the increment.
+	allOnes := byte(0xFF)
+	for i := range c.sequenceNumber {
+		allOnes &= c.sequenceNumber[i]
+	}
+	if allOnes == byte(0xFF) {
+		return ErrAEADSeqOverflows
+	}
+
+	// performs an increment by 1 and verifies whether the sequence overflows.
+	carry := uint(1)
+	for i := len(c.sequenceNumber) - 1; i >= 0; i-- {
+		sum := uint(c.sequenceNumber[i]) + carry
+		carry = sum >> 8
+		c.sequenceNumber[i] = byte(sum & 0xFF)
+	}
+	if carry != 0 {
+		return ErrAEADSeqOverflows
+	}
+	return nil
+}
+
+func (c *sealContext) Seal(pt, aad []byte) ([]byte, error) {
+	ct := c.AEAD.Seal(nil, c.calcNonce(), pt, aad)
+	err := c.increment()
+	if err != nil {
+		for i := range ct {
+			ct[i] = 0
+		}
+		return nil, err
+	}
+	return ct, nil
+}
+
+func (c *openContext) Open(ct, aad []byte) ([]byte, error) {
+	pt, err := c.AEAD.Open(nil, c.calcNonce(), ct, aad)
+	if err != nil {
+		return nil, err
+	}
+	err = c.increment()
+	if err != nil {
+		for i := range pt {
+			pt[i] = 0
+		}
+		return nil, err
+	}
+	return pt, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/hpke/algs.go b/vendor/github.com/cloudflare/circl/hpke/algs.go
new file mode 100644
index 00000000..a9fbc661
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/hpke/algs.go
@@ -0,0 +1,278 @@
+package hpke
+
+import (
+	"crypto"
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/elliptic"
+	_ "crypto/sha256" // Linking sha256.
+	_ "crypto/sha512" // Linking sha512.
+	"fmt"
+	"hash"
+	"io"
+
+	"github.com/cloudflare/circl/dh/x25519"
+	"github.com/cloudflare/circl/dh/x448"
+	"github.com/cloudflare/circl/ecc/p384"
+	"github.com/cloudflare/circl/kem"
+	"github.com/cloudflare/circl/kem/kyber/kyber768"
+	"golang.org/x/crypto/chacha20poly1305"
+	"golang.org/x/crypto/hkdf"
+)
+
+type KEM uint16
+
+//nolint:golint,stylecheck
+const (
+	// KEM_P256_HKDF_SHA256 is a KEM using P256 curve and HKDF with SHA-256.
+	KEM_P256_HKDF_SHA256 KEM = 0x10
+	// KEM_P384_HKDF_SHA384 is a KEM using P384 curve and HKDF with SHA-384.
+	KEM_P384_HKDF_SHA384 KEM = 0x11
+	// KEM_P521_HKDF_SHA512 is a KEM using P521 curve and HKDF with SHA-512.
+	KEM_P521_HKDF_SHA512 KEM = 0x12
+	// KEM_X25519_HKDF_SHA256 is a KEM using X25519 Diffie-Hellman function
+	// and HKDF with SHA-256.
+	KEM_X25519_HKDF_SHA256 KEM = 0x20
+	// KEM_X448_HKDF_SHA512 is a KEM using X448 Diffie-Hellman function and
+	// HKDF with SHA-512.
+	KEM_X448_HKDF_SHA512 KEM = 0x21
+	// KEM_X25519_KYBER768_DRAFT00 is a hybrid KEM built on DHKEM(X25519, HKDF-SHA256)
+	// and Kyber768Draft00
+	KEM_X25519_KYBER768_DRAFT00 KEM = 0x30
+)
+
+// IsValid returns true if the KEM identifier is supported by the HPKE package.
+func (k KEM) IsValid() bool {
+	switch k {
+	case KEM_P256_HKDF_SHA256,
+		KEM_P384_HKDF_SHA384,
+		KEM_P521_HKDF_SHA512,
+		KEM_X25519_HKDF_SHA256,
+		KEM_X448_HKDF_SHA512,
+		KEM_X25519_KYBER768_DRAFT00:
+		return true
+	default:
+		return false
+	}
+}
+
+// Scheme returns an instance of a KEM that supports authentication. Panics if
+// the KEM identifier is invalid.
+func (k KEM) Scheme() kem.AuthScheme {
+	switch k {
+	case KEM_P256_HKDF_SHA256:
+		return dhkemp256hkdfsha256
+	case KEM_P384_HKDF_SHA384:
+		return dhkemp384hkdfsha384
+	case KEM_P521_HKDF_SHA512:
+		return dhkemp521hkdfsha512
+	case KEM_X25519_HKDF_SHA256:
+		return dhkemx25519hkdfsha256
+	case KEM_X448_HKDF_SHA512:
+		return dhkemx448hkdfsha512
+	case KEM_X25519_KYBER768_DRAFT00:
+		return hybridkemX25519Kyber768
+	default:
+		panic(ErrInvalidKEM)
+	}
+}
+
+type KDF uint16
+
+//nolint:golint,stylecheck
+const (
+	// KDF_HKDF_SHA256 is a KDF using HKDF with SHA-256.
+	KDF_HKDF_SHA256 KDF = 0x01
+	// KDF_HKDF_SHA384 is a KDF using HKDF with SHA-384.
+	KDF_HKDF_SHA384 KDF = 0x02
+	// KDF_HKDF_SHA512 is a KDF using HKDF with SHA-512.
+	KDF_HKDF_SHA512 KDF = 0x03
+)
+
+func (k KDF) IsValid() bool {
+	switch k {
+	case KDF_HKDF_SHA256,
+		KDF_HKDF_SHA384,
+		KDF_HKDF_SHA512:
+		return true
+	default:
+		return false
+	}
+}
+
+// ExtractSize returns the size (in bytes) of the pseudorandom key produced
+// by KDF.Extract.
+func (k KDF) ExtractSize() int {
+	switch k {
+	case KDF_HKDF_SHA256:
+		return crypto.SHA256.Size()
+	case KDF_HKDF_SHA384:
+		return crypto.SHA384.Size()
+	case KDF_HKDF_SHA512:
+		return crypto.SHA512.Size()
+	default:
+		panic(ErrInvalidKDF)
+	}
+}
+
+// Extract derives a pseudorandom key from a high-entropy, secret input and a
+// salt. The size of the output is determined by KDF.ExtractSize.
+func (k KDF) Extract(secret, salt []byte) (pseudorandomKey []byte) {
+	return hkdf.Extract(k.hash(), secret, salt)
+}
+
+// Expand derives a variable length pseudorandom string from a pseudorandom key
+// and an information string. Panics if the pseudorandom key is less
+// than N bytes, or if the output length is greater than 255*N bytes,
+// where N is the size returned by KDF.Extract function.
+func (k KDF) Expand(pseudorandomKey, info []byte, outputLen uint) []byte {
+	extractSize := k.ExtractSize()
+	if len(pseudorandomKey) < extractSize {
+		panic(fmt.Errorf("pseudorandom key must be %v bytes", extractSize))
+	}
+	maxLength := uint(255 * extractSize)
+	if outputLen > maxLength {
+		panic(fmt.Errorf("output length must be less than %v bytes", maxLength))
+	}
+	output := make([]byte, outputLen)
+	rd := hkdf.Expand(k.hash(), pseudorandomKey[:extractSize], info)
+	_, err := io.ReadFull(rd, output)
+	if err != nil {
+		panic(err)
+	}
+	return output
+}
+
+func (k KDF) hash() func() hash.Hash {
+	switch k {
+	case KDF_HKDF_SHA256:
+		return crypto.SHA256.New
+	case KDF_HKDF_SHA384:
+		return crypto.SHA384.New
+	case KDF_HKDF_SHA512:
+		return crypto.SHA512.New
+	default:
+		panic(ErrInvalidKDF)
+	}
+}
+
+type AEAD uint16
+
+//nolint:golint,stylecheck
+const (
+	// AEAD_AES128GCM is AES-128 block cipher in Galois Counter Mode (GCM).
+	AEAD_AES128GCM AEAD = 0x01
+	// AEAD_AES256GCM is AES-256 block cipher in Galois Counter Mode (GCM).
+	AEAD_AES256GCM AEAD = 0x02
+	// AEAD_ChaCha20Poly1305 is ChaCha20 stream cipher and Poly1305 MAC.
+	AEAD_ChaCha20Poly1305 AEAD = 0x03
+)
+
+// New instantiates an AEAD cipher from the identifier, returns an error if the
+// identifier is not known.
+func (a AEAD) New(key []byte) (cipher.AEAD, error) {
+	switch a {
+	case AEAD_AES128GCM, AEAD_AES256GCM:
+		block, err := aes.NewCipher(key)
+		if err != nil {
+			return nil, err
+		}
+		return cipher.NewGCM(block)
+	case AEAD_ChaCha20Poly1305:
+		return chacha20poly1305.New(key)
+	default:
+		panic(ErrInvalidAEAD)
+	}
+}
+
+func (a AEAD) IsValid() bool {
+	switch a {
+	case AEAD_AES128GCM,
+		AEAD_AES256GCM,
+		AEAD_ChaCha20Poly1305:
+		return true
+	default:
+		return false
+	}
+}
+
+// KeySize returns the size in bytes of the keys used by the AEAD cipher.
+func (a AEAD) KeySize() uint {
+	switch a {
+	case AEAD_AES128GCM:
+		return 16
+	case AEAD_AES256GCM:
+		return 32
+	case AEAD_ChaCha20Poly1305:
+		return chacha20poly1305.KeySize
+	default:
+		panic(ErrInvalidAEAD)
+	}
+}
+
+// NonceSize returns the size in bytes of the nonce used by the AEAD cipher.
+func (a AEAD) NonceSize() uint {
+	switch a {
+	case AEAD_AES128GCM,
+		AEAD_AES256GCM,
+		AEAD_ChaCha20Poly1305:
+		return 12
+	default:
+		panic(ErrInvalidAEAD)
+	}
+}
+
+// CipherLen returns the length of a ciphertext corresponding to a message of
+// length mLen.
+func (a AEAD) CipherLen(mLen uint) uint {
+	switch a {
+	case AEAD_AES128GCM, AEAD_AES256GCM, AEAD_ChaCha20Poly1305:
+		return mLen + 16
+	default:
+		panic(ErrInvalidAEAD)
+	}
+}
+
+var (
+	dhkemp256hkdfsha256, dhkemp384hkdfsha384, dhkemp521hkdfsha512 shortKEM
+	dhkemx25519hkdfsha256, dhkemx448hkdfsha512                    xKEM
+	hybridkemX25519Kyber768                                       hybridKEM
+)
+
+func init() {
+	dhkemp256hkdfsha256.Curve = elliptic.P256()
+	dhkemp256hkdfsha256.dhKemBase.id = KEM_P256_HKDF_SHA256
+	dhkemp256hkdfsha256.dhKemBase.name = "HPKE_KEM_P256_HKDF_SHA256"
+	dhkemp256hkdfsha256.dhKemBase.Hash = crypto.SHA256
+	dhkemp256hkdfsha256.dhKemBase.dhKEM = dhkemp256hkdfsha256
+
+	dhkemp384hkdfsha384.Curve = p384.P384()
+	dhkemp384hkdfsha384.dhKemBase.id = KEM_P384_HKDF_SHA384
+	dhkemp384hkdfsha384.dhKemBase.name = "HPKE_KEM_P384_HKDF_SHA384"
+	dhkemp384hkdfsha384.dhKemBase.Hash = crypto.SHA384
+	dhkemp384hkdfsha384.dhKemBase.dhKEM = dhkemp384hkdfsha384
+
+	dhkemp521hkdfsha512.Curve = elliptic.P521()
+	dhkemp521hkdfsha512.dhKemBase.id = KEM_P521_HKDF_SHA512
+	dhkemp521hkdfsha512.dhKemBase.name = "HPKE_KEM_P521_HKDF_SHA512"
+	dhkemp521hkdfsha512.dhKemBase.Hash = crypto.SHA512
+	dhkemp521hkdfsha512.dhKemBase.dhKEM = dhkemp521hkdfsha512
+
+	dhkemx25519hkdfsha256.size = x25519.Size
+	dhkemx25519hkdfsha256.dhKemBase.id = KEM_X25519_HKDF_SHA256
+	dhkemx25519hkdfsha256.dhKemBase.name = "HPKE_KEM_X25519_HKDF_SHA256"
+	dhkemx25519hkdfsha256.dhKemBase.Hash = crypto.SHA256
+	dhkemx25519hkdfsha256.dhKemBase.dhKEM = dhkemx25519hkdfsha256
+
+	dhkemx448hkdfsha512.size = x448.Size
+	dhkemx448hkdfsha512.dhKemBase.id = KEM_X448_HKDF_SHA512
+	dhkemx448hkdfsha512.dhKemBase.name = "HPKE_KEM_X448_HKDF_SHA512"
+	dhkemx448hkdfsha512.dhKemBase.Hash = crypto.SHA512
+	dhkemx448hkdfsha512.dhKemBase.dhKEM = dhkemx448hkdfsha512
+
+	hybridkemX25519Kyber768.kemBase.id = KEM_X25519_KYBER768_DRAFT00
+	hybridkemX25519Kyber768.kemBase.name = "HPKE_KEM_X25519_KYBER768_HKDF_SHA256"
+	hybridkemX25519Kyber768.kemBase.Hash = crypto.SHA256
+	hybridkemX25519Kyber768.kemA = dhkemx25519hkdfsha256
+	hybridkemX25519Kyber768.kemB = kyber768.Scheme()
+}
diff --git a/vendor/github.com/cloudflare/circl/hpke/hpke.go b/vendor/github.com/cloudflare/circl/hpke/hpke.go
new file mode 100644
index 00000000..4075b285
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/hpke/hpke.go
@@ -0,0 +1,271 @@
+// Package hpke implements the Hybrid Public Key Encryption (HPKE) standard
+// specified by draft-irtf-cfrg-hpke-07.
+//
+// HPKE works for any combination of a public-key encapsulation mechanism
+// (KEM), a key derivation function (KDF), and an authenticated encryption
+// scheme with additional data (AEAD).
+//
+// Specification in
+// https://datatracker.ietf.org/doc/draft-irtf-cfrg-hpke
+//
+// BUG(cjpatton): This package does not implement the "Export-Only" mode of the
+// HPKE context. In particular, it does not recognize the AEAD codepoint
+// reserved for this purpose (0xFFFF).
+package hpke
+
+import (
+	"crypto/rand"
+	"encoding"
+	"errors"
+	"io"
+
+	"github.com/cloudflare/circl/kem"
+)
+
+const versionLabel = "HPKE-v1"
+
+// Context defines the capabilities of an HPKE context.
+type Context interface {
+	encoding.BinaryMarshaler
+	// Export takes a context string exporterContext and a desired length (in
+	// bytes), and produces a secret derived from the internal exporter secret
+	// using the corresponding KDF Expand function. It panics if length is
+	// greater than 255*N bytes, where N is the size (in bytes) of the KDF's
+	// output.
+	Export(exporterContext []byte, length uint) []byte
+	// Suite returns the cipher suite corresponding to this context.
+	Suite() Suite
+}
+
+// Sealer encrypts a plaintext using an AEAD encryption.
+type Sealer interface {
+	Context
+	// Seal takes a plaintext and associated data to produce a ciphertext.
+	// The nonce is handled by the Sealer and incremented after each call.
+	Seal(pt, aad []byte) (ct []byte, err error)
+}
+
+// Opener decrypts a ciphertext using an AEAD encryption.
+type Opener interface {
+	Context
+	// Open takes a ciphertext and associated data to recover, if successful,
+	// the plaintext. The nonce is handled by the Opener and incremented after
+	// each call.
+	Open(ct, aad []byte) (pt []byte, err error)
+}
+
+// modeID represents an HPKE variant.
+type modeID = uint8
+
+const (
+	// modeBase to enable encryption to the holder of a given KEM private key.
+	modeBase modeID = 0x00
+	// modePSK extends the base mode by allowing the Receiver to authenticate
+	// that the sender possessed a given pre-shared key (PSK).
+	modePSK modeID = 0x01
+	// modeAuth extends the base mode by allowing the Receiver to authenticate
+	// that the sender possessed a given KEM private key.
+	modeAuth modeID = 0x02
+	// modeAuthPSK provides a combination of the PSK and Auth modes.
+	modeAuthPSK modeID = 0x03
+)
+
+// Suite is an HPKE cipher suite consisting of a KEM, KDF, and AEAD algorithm.
+type Suite struct {
+	kemID  KEM
+	kdfID  KDF
+	aeadID AEAD
+}
+
+// NewSuite builds a Suite from a specified set of algorithms. Panics
+// if an algorithm identifier is not valid.
+func NewSuite(kemID KEM, kdfID KDF, aeadID AEAD) Suite {
+	s := Suite{kemID, kdfID, aeadID}
+	if !s.isValid() {
+		panic(ErrInvalidHPKESuite)
+	}
+	return s
+}
+
+type state struct {
+	Suite
+	modeID modeID
+	skS    kem.PrivateKey
+	pkS    kem.PublicKey
+	psk    []byte
+	pskID  []byte
+	info   []byte
+}
+
+// Sender performs hybrid public-key encryption.
+type Sender struct {
+	state
+	pkR kem.PublicKey
+}
+
+// NewSender creates a Sender with knowledge of the receiver's public-key.
+func (suite Suite) NewSender(pkR kem.PublicKey, info []byte) (*Sender, error) {
+	return &Sender{
+		state: state{Suite: suite, info: info},
+		pkR:   pkR,
+	}, nil
+}
+
+// Setup generates a new HPKE context used for Base Mode encryption.
+// Returns the Sealer and corresponding encapsulated key.
+func (s *Sender) Setup(rnd io.Reader) (enc []byte, seal Sealer, err error) {
+	s.modeID = modeBase
+	return s.allSetup(rnd)
+}
+
+// SetupAuth generates a new HPKE context used for Auth Mode encryption.
+// Returns the Sealer and corresponding encapsulated key.
+func (s *Sender) SetupAuth(rnd io.Reader, skS kem.PrivateKey) (
+	enc []byte, seal Sealer, err error,
+) {
+	s.modeID = modeAuth
+	s.state.skS = skS
+	return s.allSetup(rnd)
+}
+
+// SetupPSK generates a new HPKE context used for PSK Mode encryption.
+// Returns the Sealer and corresponding encapsulated key.
+func (s *Sender) SetupPSK(rnd io.Reader, psk, pskID []byte) (
+	enc []byte, seal Sealer, err error,
+) {
+	s.modeID = modePSK
+	s.state.psk = psk
+	s.state.pskID = pskID
+	return s.allSetup(rnd)
+}
+
+// SetupAuthPSK generates a new HPKE context used for Auth-PSK Mode encryption.
+// Returns the Sealer and corresponding encapsulated key.
+func (s *Sender) SetupAuthPSK(rnd io.Reader, skS kem.PrivateKey, psk, pskID []byte) (
+	enc []byte, seal Sealer, err error,
+) {
+	s.modeID = modeAuthPSK
+	s.state.skS = skS
+	s.state.psk = psk
+	s.state.pskID = pskID
+	return s.allSetup(rnd)
+}
+
+// Receiver performs hybrid public-key decryption.
+type Receiver struct {
+	state
+	skR kem.PrivateKey
+	enc []byte
+}
+
+// NewReceiver creates a Receiver with knowledge of a private key.
+func (suite Suite) NewReceiver(skR kem.PrivateKey, info []byte) (
+	*Receiver, error,
+) {
+	return &Receiver{state: state{Suite: suite, info: info}, skR: skR}, nil
+}
+
+// Setup generates a new HPKE context used for Base Mode encryption.
+// Setup takes an encapsulated key and returns an Opener.
+func (r *Receiver) Setup(enc []byte) (Opener, error) {
+	r.modeID = modeBase
+	r.enc = enc
+	return r.allSetup()
+}
+
+// SetupAuth generates a new HPKE context used for Auth Mode encryption.
+// SetupAuth takes an encapsulated key and a public key, and returns an Opener.
+func (r *Receiver) SetupAuth(enc []byte, pkS kem.PublicKey) (Opener, error) {
+	r.modeID = modeAuth
+	r.enc = enc
+	r.state.pkS = pkS
+	return r.allSetup()
+}
+
+// SetupPSK generates a new HPKE context used for PSK Mode encryption.
+// SetupPSK takes an encapsulated key, and a pre-shared key; and returns an
+// Opener.
+func (r *Receiver) SetupPSK(enc, psk, pskID []byte) (Opener, error) {
+	r.modeID = modePSK
+	r.enc = enc
+	r.state.psk = psk
+	r.state.pskID = pskID
+	return r.allSetup()
+}
+
+// SetupAuthPSK generates a new HPKE context used for Auth-PSK Mode encryption.
+// SetupAuthPSK takes an encapsulated key, a public key, and a pre-shared key;
+// and returns an Opener.
+func (r *Receiver) SetupAuthPSK(
+	enc, psk, pskID []byte, pkS kem.PublicKey,
+) (Opener, error) {
+	r.modeID = modeAuthPSK
+	r.enc = enc
+	r.state.psk = psk
+	r.state.pskID = pskID
+	r.state.pkS = pkS
+	return r.allSetup()
+}
+
+func (s *Sender) allSetup(rnd io.Reader) ([]byte, Sealer, error) {
+	scheme := s.kemID.Scheme()
+
+	if rnd == nil {
+		rnd = rand.Reader
+	}
+	seed := make([]byte, scheme.EncapsulationSeedSize())
+	_, err := io.ReadFull(rnd, seed)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var enc, ss []byte
+	switch s.modeID {
+	case modeBase, modePSK:
+		enc, ss, err = scheme.EncapsulateDeterministically(s.pkR, seed)
+	case modeAuth, modeAuthPSK:
+		enc, ss, err = scheme.AuthEncapsulateDeterministically(s.pkR, s.skS, seed)
+	}
+	if err != nil {
+		return nil, nil, err
+	}
+
+	ctx, err := s.keySchedule(ss, s.info, s.psk, s.pskID)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return enc, &sealContext{ctx}, nil
+}
+
+func (r *Receiver) allSetup() (Opener, error) {
+	var err error
+	var ss []byte
+	scheme := r.kemID.Scheme()
+	switch r.modeID {
+	case modeBase, modePSK:
+		ss, err = scheme.Decapsulate(r.skR, r.enc)
+	case modeAuth, modeAuthPSK:
+		ss, err = scheme.AuthDecapsulate(r.skR, r.enc, r.pkS)
+	}
+	if err != nil {
+		return nil, err
+	}
+
+	ctx, err := r.keySchedule(ss, r.info, r.psk, r.pskID)
+	if err != nil {
+		return nil, err
+	}
+	return &openContext{ctx}, nil
+}
+
+var (
+	ErrInvalidHPKESuite       = errors.New("hpke: invalid HPKE suite")
+	ErrInvalidKDF             = errors.New("hpke: invalid KDF identifier")
+	ErrInvalidKEM             = errors.New("hpke: invalid KEM identifier")
+	ErrInvalidAEAD            = errors.New("hpke: invalid AEAD identifier")
+	ErrInvalidKEMPublicKey    = errors.New("hpke: invalid KEM public key")
+	ErrInvalidKEMPrivateKey   = errors.New("hpke: invalid KEM private key")
+	ErrInvalidKEMSharedSecret = errors.New("hpke: invalid KEM shared secret")
+	ErrAEADSeqOverflows       = errors.New("hpke: AEAD sequence number overflows")
+)
diff --git a/vendor/github.com/cloudflare/circl/hpke/hybridkem.go b/vendor/github.com/cloudflare/circl/hpke/hybridkem.go
new file mode 100644
index 00000000..74e1ea6f
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/hpke/hybridkem.go
@@ -0,0 +1,232 @@
+package hpke
+
+// This file implements a hybrid KEM for HPKE using a simple concatenation
+// combiner.
+//
+// WARNING It is not safe to combine arbitrary KEMs using this combiner.
+// See the draft specification for more details:
+// https://bwesterb.github.io/draft-westerbaan-cfrg-hpke-xyber768d00/draft-westerbaan-cfrg-hpke-xyber768d00.html#name-security-considerations
+
+import (
+	"crypto/rand"
+
+	"github.com/cloudflare/circl/kem"
+)
+
+type hybridKEM struct {
+	kemBase
+	kemA kem.Scheme
+	kemB kem.Scheme
+}
+
+func (h hybridKEM) PrivateKeySize() int { return h.kemA.PrivateKeySize() + h.kemB.PrivateKeySize() }
+func (h hybridKEM) SeedSize() int       { return 32 }
+func (h hybridKEM) CiphertextSize() int { return h.kemA.CiphertextSize() + h.kemB.CiphertextSize() }
+func (h hybridKEM) PublicKeySize() int  { return h.kemA.PublicKeySize() + h.kemB.PublicKeySize() }
+func (h hybridKEM) EncapsulationSeedSize() int {
+	return h.kemA.EncapsulationSeedSize() + h.kemB.EncapsulationSeedSize()
+}
+func (h hybridKEM) SharedKeySize() int { return h.kemA.SharedKeySize() + h.kemB.SharedKeySize() }
+func (h hybridKEM) Name() string       { return h.name }
+
+func (h hybridKEM) AuthDecapsulate(skR kem.PrivateKey,
+	ct []byte,
+	pkS kem.PublicKey,
+) ([]byte, error) {
+	panic("AuthDecapsulate is not supported for this KEM")
+}
+
+func (h hybridKEM) AuthEncapsulate(pkr kem.PublicKey, sks kem.PrivateKey) (
+	ct []byte, ss []byte, err error,
+) {
+	panic("AuthEncapsulate is not supported for this KEM")
+}
+
+func (h hybridKEM) AuthEncapsulateDeterministically(pkr kem.PublicKey, sks kem.PrivateKey, seed []byte) (ct, ss []byte, err error) {
+	panic("AuthEncapsulateDeterministically is not supported for this KEM")
+}
+
+func (h hybridKEM) Encapsulate(pkr kem.PublicKey) (
+	ct []byte, ss []byte, err error,
+) {
+	panic("Encapsulate is not implemented")
+}
+
+func (h hybridKEM) Decapsulate(skr kem.PrivateKey, ct []byte) ([]byte, error) {
+	hybridSk := skr.(*hybridKEMPrivKey)
+	ssA, err := h.kemA.Decapsulate(hybridSk.privA, ct[0:h.kemA.CiphertextSize()])
+	if err != nil {
+		return nil, err
+	}
+	ssB, err := h.kemB.Decapsulate(hybridSk.privB, ct[h.kemA.CiphertextSize():])
+	if err != nil {
+		return nil, err
+	}
+
+	ss := append(ssA, ssB...)
+
+	return ss, nil
+}
+
+func (h hybridKEM) EncapsulateDeterministically(
+	pkr kem.PublicKey, seed []byte,
+) (ct, ss []byte, err error) {
+	hybridPk := pkr.(*hybridKEMPubKey)
+	encA, ssA, err := h.kemA.EncapsulateDeterministically(hybridPk.pubA, seed[0:h.kemA.EncapsulationSeedSize()])
+	if err != nil {
+		return nil, nil, err
+	}
+	encB, ssB, err := h.kemB.EncapsulateDeterministically(hybridPk.pubB, seed[h.kemA.EncapsulationSeedSize():])
+	if err != nil {
+		return nil, nil, err
+	}
+
+	ct = append(encA, encB...)
+	ss = append(ssA, ssB...)
+
+	return ct, ss, nil
+}
+
+type hybridKEMPrivKey struct {
+	scheme kem.Scheme
+	privA  kem.PrivateKey
+	privB  kem.PrivateKey
+}
+
+func (k *hybridKEMPrivKey) Scheme() kem.Scheme {
+	return k.scheme
+}
+
+func (k *hybridKEMPrivKey) MarshalBinary() ([]byte, error) {
+	skA, err := k.privA.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+	skB, err := k.privB.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+	return append(skA, skB...), nil
+}
+
+func (k *hybridKEMPrivKey) Equal(sk kem.PrivateKey) bool {
+	k1, ok := sk.(*hybridKEMPrivKey)
+	return ok &&
+		k.privA.Equal(k1.privA) &&
+		k.privB.Equal(k1.privB)
+}
+
+func (k *hybridKEMPrivKey) Public() kem.PublicKey {
+	return &hybridKEMPubKey{
+		scheme: k.scheme,
+		pubA:   k.privA.Public(),
+		pubB:   k.privB.Public(),
+	}
+}
+
+type hybridKEMPubKey struct {
+	scheme kem.Scheme
+	pubA   kem.PublicKey
+	pubB   kem.PublicKey
+}
+
+func (k *hybridKEMPubKey) Scheme() kem.Scheme {
+	return k.scheme
+}
+
+func (k hybridKEMPubKey) MarshalBinary() ([]byte, error) {
+	pkA, err := k.pubA.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+	pkB, err := k.pubB.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+	return append(pkA, pkB...), nil
+}
+
+func (k *hybridKEMPubKey) Equal(pk kem.PublicKey) bool {
+	k1, ok := pk.(*hybridKEMPubKey)
+	return ok &&
+		k.pubA.Equal(k1.pubA) &&
+		k.pubB.Equal(k1.pubB)
+}
+
+// Deterministically derives a keypair from a seed. If you're unsure,
+// you're better off using GenerateKey().
+//
+// Panics if seed is not of length SeedSize().
+func (h hybridKEM) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
+	// Implementation based on
+	// https://www.ietf.org/archive/id/draft-irtf-cfrg-hpke-07.html#name-derivekeypair
+	if len(seed) != h.SeedSize() {
+		panic(kem.ErrSeedSize)
+	}
+
+	outputSeedSize := h.kemA.SeedSize() + h.kemB.SeedSize()
+	dkpPrk := h.labeledExtract([]byte(""), []byte("dkp_prk"), seed)
+	bytes := h.labeledExpand(
+		dkpPrk,
+		[]byte("sk"),
+		nil,
+		uint16(outputSeedSize),
+	)
+	seedA := bytes[0:h.kemA.SeedSize()]
+	seedB := bytes[h.kemA.SeedSize():]
+	pubA, privA := h.kemA.DeriveKeyPair(seedA)
+	pubB, privB := h.kemB.DeriveKeyPair(seedB)
+
+	privKey := &hybridKEMPrivKey{
+		privA: privA,
+		privB: privB,
+	}
+	pubKey := &hybridKEMPubKey{
+		pubA: pubA,
+		pubB: pubB,
+	}
+
+	return pubKey, privKey
+}
+
+func (h hybridKEM) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
+	seed := make([]byte, h.SeedSize())
+	_, err := rand.Read(seed)
+	if err != nil {
+		return nil, nil, err
+	}
+	pk, sk := h.DeriveKeyPair(seed)
+	return pk, sk, nil
+}
+
+func (h hybridKEM) UnmarshalBinaryPrivateKey(data []byte) (kem.PrivateKey, error) {
+	skA, err := h.kemA.UnmarshalBinaryPrivateKey(data[0:h.kemA.PrivateKeySize()])
+	if err != nil {
+		return nil, err
+	}
+	skB, err := h.kemB.UnmarshalBinaryPrivateKey(data[h.kemA.PrivateKeySize():])
+	if err != nil {
+		return nil, err
+	}
+
+	return &hybridKEMPrivKey{
+		privA: skA,
+		privB: skB,
+	}, nil
+}
+
+func (h hybridKEM) UnmarshalBinaryPublicKey(data []byte) (kem.PublicKey, error) {
+	pkA, err := h.kemA.UnmarshalBinaryPublicKey(data[0:h.kemA.PublicKeySize()])
+	if err != nil {
+		return nil, err
+	}
+	pkB, err := h.kemB.UnmarshalBinaryPublicKey(data[h.kemA.PublicKeySize():])
+	if err != nil {
+		return nil, err
+	}
+
+	return &hybridKEMPubKey{
+		pubA: pkA,
+		pubB: pkB,
+	}, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/hpke/kembase.go b/vendor/github.com/cloudflare/circl/hpke/kembase.go
new file mode 100644
index 00000000..a15765f6
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/hpke/kembase.go
@@ -0,0 +1,241 @@
+package hpke
+
+import (
+	"crypto"
+	"crypto/rand"
+	"encoding/binary"
+	"io"
+
+	"github.com/cloudflare/circl/kem"
+	"golang.org/x/crypto/hkdf"
+)
+
+type dhKEM interface {
+	sizeDH() int
+	calcDH(dh []byte, sk kem.PrivateKey, pk kem.PublicKey) error
+	SeedSize() int
+	DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey)
+	UnmarshalBinaryPrivateKey(data []byte) (kem.PrivateKey, error)
+	UnmarshalBinaryPublicKey(data []byte) (kem.PublicKey, error)
+}
+
+type kemBase struct {
+	id   KEM
+	name string
+	crypto.Hash
+}
+
+type dhKemBase struct {
+	kemBase
+	dhKEM
+}
+
+func (k kemBase) Name() string       { return k.name }
+func (k kemBase) SharedKeySize() int { return k.Hash.Size() }
+
+func (k kemBase) getSuiteID() (sid [5]byte) {
+	sid[0], sid[1], sid[2] = 'K', 'E', 'M'
+	binary.BigEndian.PutUint16(sid[3:5], uint16(k.id))
+	return
+}
+
+func (k kemBase) extractExpand(dh, kemCtx []byte) []byte {
+	eaePkr := k.labeledExtract([]byte(""), []byte("eae_prk"), dh)
+	return k.labeledExpand(
+		eaePkr,
+		[]byte("shared_secret"),
+		kemCtx,
+		uint16(k.Size()),
+	)
+}
+
+func (k kemBase) labeledExtract(salt, label, info []byte) []byte {
+	suiteID := k.getSuiteID()
+	labeledIKM := append(append(append(append(
+		make([]byte, 0, len(versionLabel)+len(suiteID)+len(label)+len(info)),
+		versionLabel...),
+		suiteID[:]...),
+		label...),
+		info...)
+	return hkdf.Extract(k.New, labeledIKM, salt)
+}
+
+func (k kemBase) labeledExpand(prk, label, info []byte, l uint16) []byte {
+	suiteID := k.getSuiteID()
+	labeledInfo := make(
+		[]byte,
+		2,
+		2+len(versionLabel)+len(suiteID)+len(label)+len(info),
+	)
+	binary.BigEndian.PutUint16(labeledInfo[0:2], l)
+	labeledInfo = append(append(append(append(labeledInfo,
+		versionLabel...),
+		suiteID[:]...),
+		label...),
+		info...)
+	b := make([]byte, l)
+	rd := hkdf.Expand(k.New, prk, labeledInfo)
+	if _, err := io.ReadFull(rd, b); err != nil {
+		panic(err)
+	}
+	return b
+}
+
+func (k dhKemBase) AuthEncapsulate(pkr kem.PublicKey, sks kem.PrivateKey) (
+	ct []byte, ss []byte, err error,
+) {
+	seed := make([]byte, k.SeedSize())
+	_, err = io.ReadFull(rand.Reader, seed)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return k.authEncap(pkr, sks, seed)
+}
+
+func (k dhKemBase) Encapsulate(pkr kem.PublicKey) (
+	ct []byte, ss []byte, err error,
+) {
+	seed := make([]byte, k.SeedSize())
+	_, err = io.ReadFull(rand.Reader, seed)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return k.encap(pkr, seed)
+}
+
+func (k dhKemBase) AuthEncapsulateDeterministically(
+	pkr kem.PublicKey, sks kem.PrivateKey, seed []byte,
+) (ct, ss []byte, err error) {
+	return k.authEncap(pkr, sks, seed)
+}
+
+func (k dhKemBase) EncapsulateDeterministically(
+	pkr kem.PublicKey, seed []byte,
+) (ct, ss []byte, err error) {
+	return k.encap(pkr, seed)
+}
+
+func (k dhKemBase) encap(
+	pkR kem.PublicKey,
+	seed []byte,
+) (ct []byte, ss []byte, err error) {
+	dh := make([]byte, k.sizeDH())
+	enc, kemCtx, err := k.coreEncap(dh, pkR, seed)
+	if err != nil {
+		return nil, nil, err
+	}
+	ss = k.extractExpand(dh, kemCtx)
+	return enc, ss, nil
+}
+
+func (k dhKemBase) authEncap(
+	pkR kem.PublicKey,
+	skS kem.PrivateKey,
+	seed []byte,
+) (ct []byte, ss []byte, err error) {
+	dhLen := k.sizeDH()
+	dh := make([]byte, 2*dhLen)
+	enc, kemCtx, err := k.coreEncap(dh[:dhLen], pkR, seed)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	err = k.calcDH(dh[dhLen:], skS, pkR)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	pkS := skS.Public()
+	pkSm, err := pkS.MarshalBinary()
+	if err != nil {
+		return nil, nil, err
+	}
+	kemCtx = append(kemCtx, pkSm...)
+
+	ss = k.extractExpand(dh, kemCtx)
+	return enc, ss, nil
+}
+
+func (k dhKemBase) coreEncap(
+	dh []byte,
+	pkR kem.PublicKey,
+	seed []byte,
+) (enc []byte, kemCtx []byte, err error) {
+	pkE, skE := k.DeriveKeyPair(seed)
+	err = k.calcDH(dh, skE, pkR)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	enc, err = pkE.MarshalBinary()
+	if err != nil {
+		return nil, nil, err
+	}
+	pkRm, err := pkR.MarshalBinary()
+	if err != nil {
+		return nil, nil, err
+	}
+	kemCtx = append(append([]byte{}, enc...), pkRm...)
+
+	return enc, kemCtx, nil
+}
+
+func (k dhKemBase) Decapsulate(skr kem.PrivateKey, ct []byte) ([]byte, error) {
+	dh := make([]byte, k.sizeDH())
+	kemCtx, err := k.coreDecap(dh, skr, ct)
+	if err != nil {
+		return nil, err
+	}
+	return k.extractExpand(dh, kemCtx), nil
+}
+
+func (k dhKemBase) AuthDecapsulate(
+	skR kem.PrivateKey,
+	ct []byte,
+	pkS kem.PublicKey,
+) ([]byte, error) {
+	dhLen := k.sizeDH()
+	dh := make([]byte, 2*dhLen)
+	kemCtx, err := k.coreDecap(dh[:dhLen], skR, ct)
+	if err != nil {
+		return nil, err
+	}
+
+	err = k.calcDH(dh[dhLen:], skR, pkS)
+	if err != nil {
+		return nil, err
+	}
+
+	pkSm, err := pkS.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+	kemCtx = append(kemCtx, pkSm...)
+	return k.extractExpand(dh, kemCtx), nil
+}
+
+func (k dhKemBase) coreDecap(
+	dh []byte,
+	skR kem.PrivateKey,
+	ct []byte,
+) ([]byte, error) {
+	pkE, err := k.UnmarshalBinaryPublicKey(ct)
+	if err != nil {
+		return nil, err
+	}
+
+	err = k.calcDH(dh, skR, pkE)
+	if err != nil {
+		return nil, err
+	}
+
+	pkR := skR.Public()
+	pkRm, err := pkR.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+
+	return append(append([]byte{}, ct...), pkRm...), nil
+}
diff --git a/vendor/github.com/cloudflare/circl/hpke/marshal.go b/vendor/github.com/cloudflare/circl/hpke/marshal.go
new file mode 100644
index 00000000..4ce02eed
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/hpke/marshal.go
@@ -0,0 +1,151 @@
+package hpke
+
+import (
+	"errors"
+
+	"golang.org/x/crypto/cryptobyte"
+)
+
+// marshal serializes an HPKE context.
+func (c *encdecContext) marshal() ([]byte, error) {
+	var b cryptobyte.Builder
+	b.AddUint16(uint16(c.suite.kemID))
+	b.AddUint16(uint16(c.suite.kdfID))
+	b.AddUint16(uint16(c.suite.aeadID))
+	b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+		b.AddBytes(c.exporterSecret)
+	})
+	b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+		b.AddBytes(c.key)
+	})
+	b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+		b.AddBytes(c.baseNonce)
+	})
+	b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+		b.AddBytes(c.sequenceNumber)
+	})
+	return b.Bytes()
+}
+
+// unmarshalContext parses an HPKE context.
+func unmarshalContext(raw []byte) (*encdecContext, error) {
+	var (
+		err error
+		t   cryptobyte.String
+	)
+
+	c := new(encdecContext)
+	s := cryptobyte.String(raw)
+	if !s.ReadUint16((*uint16)(&c.suite.kemID)) ||
+		!s.ReadUint16((*uint16)(&c.suite.kdfID)) ||
+		!s.ReadUint16((*uint16)(&c.suite.aeadID)) ||
+		!s.ReadUint8LengthPrefixed(&t) ||
+		!t.ReadBytes(&c.exporterSecret, len(t)) ||
+		!s.ReadUint8LengthPrefixed(&t) ||
+		!t.ReadBytes(&c.key, len(t)) ||
+		!s.ReadUint8LengthPrefixed(&t) ||
+		!t.ReadBytes(&c.baseNonce, len(t)) ||
+		!s.ReadUint8LengthPrefixed(&t) ||
+		!t.ReadBytes(&c.sequenceNumber, len(t)) {
+		return nil, errors.New("failed to parse context")
+	}
+
+	if !c.suite.isValid() {
+		return nil, ErrInvalidHPKESuite
+	}
+
+	Nh := c.suite.kdfID.ExtractSize()
+	if len(c.exporterSecret) != Nh {
+		return nil, errors.New("invalid exporter secret length")
+	}
+
+	Nk := int(c.suite.aeadID.KeySize())
+	if len(c.key) != Nk {
+		return nil, errors.New("invalid key length")
+	}
+
+	c.AEAD, err = c.suite.aeadID.New(c.key)
+	if err != nil {
+		return nil, err
+	}
+
+	Nn := int(c.suite.aeadID.NonceSize())
+	if len(c.baseNonce) != Nn {
+		return nil, errors.New("invalid base nonce length")
+	}
+	if len(c.sequenceNumber) != Nn {
+		return nil, errors.New("invalid sequence number length")
+	}
+	c.nonce = make([]byte, Nn)
+
+	return c, nil
+}
+
+// MarshalBinary serializes an HPKE sealer according to the format specified
+// below. (Expressed in TLS syntax.) Note that this format is not defined by
+// the HPKE standard.
+//
+// enum { sealer(0), opener(1) } HpkeRole;
+//
+//	struct {
+//	    HpkeKemId kem_id;   // draft-irtf-cfrg-hpke-07
+//	    HpkeKdfId kdf_id;   // draft-irtf-cfrg-hpke-07
+//	    HpkeAeadId aead_id; // draft-irtf-cfrg-hpke-07
+//	    opaque exporter_secret<0..255>;
+//	    opaque key<0..255>;
+//	    opaque base_nonce<0..255>;
+//	    opaque seq<0..255>;
+//	} HpkeContext;
+//
+//	struct {
+//	  HpkeRole role = 0; // sealer
+//	  HpkeContext context;
+//	} HpkeSealer;
+func (c *sealContext) MarshalBinary() ([]byte, error) {
+	rawContext, err := c.encdecContext.marshal()
+	if err != nil {
+		return nil, err
+	}
+	return append([]byte{0}, rawContext...), nil
+}
+
+// UnmarshalSealer parses an HPKE sealer.
+func UnmarshalSealer(raw []byte) (Sealer, error) {
+	if raw[0] != 0 {
+		return nil, errors.New("incorrect role")
+	}
+	context, err := unmarshalContext(raw[1:])
+	if err != nil {
+		return nil, err
+	}
+	return &sealContext{context}, nil
+}
+
+// MarshalBinary serializes an HPKE opener according to the format specified
+// below. (Expressed in TLS syntax.) Note that this format is not defined by the
+// HPKE standard.
+//
+//	struct {
+//	  HpkeRole role = 1; // opener
+//	  HpkeContext context;
+//	} HpkeOpener;
+func (c *openContext) MarshalBinary() ([]byte, error) {
+	rawContext, err := c.encdecContext.marshal()
+	if err != nil {
+		return nil, err
+	}
+	return append([]byte{1}, rawContext...), nil
+}
+
+// UnmarshalOpener parses a serialized HPKE opener and returns the corresponding
+// Opener.
+func UnmarshalOpener(raw []byte) (Opener, error) {
+	if raw[0] != 1 {
+		return nil, errors.New("incorrect role")
+	}
+	context, err := unmarshalContext(raw[1:])
+	if err != nil {
+		return nil, err
+	}
+	return &openContext{context}, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/hpke/shortkem.go b/vendor/github.com/cloudflare/circl/hpke/shortkem.go
new file mode 100644
index 00000000..e5c55e99
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/hpke/shortkem.go
@@ -0,0 +1,170 @@
+package hpke
+
+import (
+	"crypto/elliptic"
+	"crypto/rand"
+	"crypto/subtle"
+	"fmt"
+	"math/big"
+
+	"github.com/cloudflare/circl/kem"
+)
+
+type shortKEM struct {
+	dhKemBase
+	elliptic.Curve
+}
+
+func (s shortKEM) PrivateKeySize() int        { return s.byteSize() }
+func (s shortKEM) SeedSize() int              { return s.byteSize() }
+func (s shortKEM) CiphertextSize() int        { return 1 + 2*s.byteSize() }
+func (s shortKEM) PublicKeySize() int         { return 1 + 2*s.byteSize() }
+func (s shortKEM) EncapsulationSeedSize() int { return s.byteSize() }
+
+func (s shortKEM) byteSize() int { return (s.Params().BitSize + 7) / 8 }
+
+func (s shortKEM) sizeDH() int { return s.byteSize() }
+func (s shortKEM) calcDH(dh []byte, sk kem.PrivateKey, pk kem.PublicKey) error {
+	PK := pk.(*shortKEMPubKey)
+	SK := sk.(*shortKEMPrivKey)
+	l := len(dh)
+	x, _ := s.ScalarMult(PK.x, PK.y, SK.priv) // only x-coordinate is used.
+	if x.Sign() == 0 {
+		return ErrInvalidKEMSharedSecret
+	}
+	b := x.Bytes()
+	copy(dh[l-len(b):l], b)
+	return nil
+}
+
+// Deterministically derives a keypair from a seed. If you're unsure,
+// you're better off using GenerateKey().
+//
+// Panics if seed is not of length SeedSize().
+func (s shortKEM) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
+	// Implementation based on
+	// https://www.ietf.org/archive/id/draft-irtf-cfrg-hpke-07.html#name-derivekeypair
+	if len(seed) != s.SeedSize() {
+		panic(kem.ErrSeedSize)
+	}
+
+	bitmask := byte(0xFF)
+	if s.Params().BitSize == 521 {
+		bitmask = 0x01
+	}
+
+	dkpPrk := s.labeledExtract([]byte(""), []byte("dkp_prk"), seed)
+	var bytes []byte
+	ctr := 0
+	for skBig := new(big.Int); skBig.Sign() == 0 || skBig.Cmp(s.Params().N) >= 0; ctr++ {
+		if ctr > 255 {
+			panic("derive key error")
+		}
+		bytes = s.labeledExpand(
+			dkpPrk,
+			[]byte("candidate"),
+			[]byte{byte(ctr)},
+			uint16(s.byteSize()),
+		)
+		bytes[0] &= bitmask
+		skBig.SetBytes(bytes)
+	}
+	l := s.PrivateKeySize()
+	sk := &shortKEMPrivKey{s, make([]byte, l), nil}
+	copy(sk.priv[l-len(bytes):], bytes)
+	return sk.Public(), sk
+}
+
+func (s shortKEM) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
+	sk, x, y, err := elliptic.GenerateKey(s, rand.Reader)
+	pub := &shortKEMPubKey{s, x, y}
+	return pub, &shortKEMPrivKey{s, sk, pub}, err
+}
+
+func (s shortKEM) UnmarshalBinaryPrivateKey(data []byte) (kem.PrivateKey, error) {
+	l := s.PrivateKeySize()
+	if len(data) < l {
+		return nil, ErrInvalidKEMPrivateKey
+	}
+	sk := &shortKEMPrivKey{s, make([]byte, l), nil}
+	copy(sk.priv[l-len(data):l], data[:l])
+	if !sk.validate() {
+		return nil, ErrInvalidKEMPrivateKey
+	}
+
+	return sk, nil
+}
+
+func (s shortKEM) UnmarshalBinaryPublicKey(data []byte) (kem.PublicKey, error) {
+	x, y := elliptic.Unmarshal(s, data)
+	if x == nil {
+		return nil, ErrInvalidKEMPublicKey
+	}
+	key := &shortKEMPubKey{s, x, y}
+	if !key.validate() {
+		return nil, ErrInvalidKEMPublicKey
+	}
+	return key, nil
+}
+
+type shortKEMPubKey struct {
+	scheme shortKEM
+	x, y   *big.Int
+}
+
+func (k *shortKEMPubKey) String() string {
+	return fmt.Sprintf("x: %v\ny: %v", k.x.Text(16), k.y.Text(16))
+}
+func (k *shortKEMPubKey) Scheme() kem.Scheme { return k.scheme }
+func (k *shortKEMPubKey) MarshalBinary() ([]byte, error) {
+	return elliptic.Marshal(k.scheme, k.x, k.y), nil
+}
+
+func (k *shortKEMPubKey) Equal(pk kem.PublicKey) bool {
+	k1, ok := pk.(*shortKEMPubKey)
+	return ok &&
+		k.scheme.Params().Name == k1.scheme.Params().Name &&
+		k.x.Cmp(k1.x) == 0 &&
+		k.y.Cmp(k1.y) == 0
+}
+
+func (k *shortKEMPubKey) validate() bool {
+	p := k.scheme.Params().P
+	notAtInfinity := k.x.Sign() > 0 && k.y.Sign() > 0
+	lessThanP := k.x.Cmp(p) < 0 && k.y.Cmp(p) < 0
+	onCurve := k.scheme.IsOnCurve(k.x, k.y)
+	return notAtInfinity && lessThanP && onCurve
+}
+
+type shortKEMPrivKey struct {
+	scheme shortKEM
+	priv   []byte
+	pub    *shortKEMPubKey
+}
+
+func (k *shortKEMPrivKey) String() string     { return fmt.Sprintf("%x", k.priv) }
+func (k *shortKEMPrivKey) Scheme() kem.Scheme { return k.scheme }
+func (k *shortKEMPrivKey) MarshalBinary() ([]byte, error) {
+	return append(make([]byte, 0, k.scheme.PrivateKeySize()), k.priv...), nil
+}
+
+func (k *shortKEMPrivKey) Equal(pk kem.PrivateKey) bool {
+	k1, ok := pk.(*shortKEMPrivKey)
+	return ok &&
+		k.scheme.Params().Name == k1.scheme.Params().Name &&
+		subtle.ConstantTimeCompare(k.priv, k1.priv) == 1
+}
+
+func (k *shortKEMPrivKey) Public() kem.PublicKey {
+	if k.pub == nil {
+		x, y := k.scheme.ScalarBaseMult(k.priv)
+		k.pub = &shortKEMPubKey{k.scheme, x, y}
+	}
+	return k.pub
+}
+
+func (k *shortKEMPrivKey) validate() bool {
+	n := new(big.Int).SetBytes(k.priv)
+	order := k.scheme.Curve.Params().N
+	return len(k.priv) == k.scheme.PrivateKeySize() && n.Cmp(order) < 0
+}
diff --git a/vendor/github.com/cloudflare/circl/hpke/util.go b/vendor/github.com/cloudflare/circl/hpke/util.go
new file mode 100644
index 00000000..c9fed4fc
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/hpke/util.go
@@ -0,0 +1,121 @@
+package hpke
+
+import (
+	"encoding/binary"
+	"errors"
+	"fmt"
+)
+
+func (st state) keySchedule(ss, info, psk, pskID []byte) (*encdecContext, error) {
+	if err := st.verifyPSKInputs(psk, pskID); err != nil {
+		return nil, err
+	}
+
+	pskIDHash := st.labeledExtract(nil, []byte("psk_id_hash"), pskID)
+	infoHash := st.labeledExtract(nil, []byte("info_hash"), info)
+	keySchCtx := append(append(
+		[]byte{st.modeID},
+		pskIDHash...),
+		infoHash...)
+
+	secret := st.labeledExtract(ss, []byte("secret"), psk)
+
+	Nk := uint16(st.aeadID.KeySize())
+	key := st.labeledExpand(secret, []byte("key"), keySchCtx, Nk)
+
+	aead, err := st.aeadID.New(key)
+	if err != nil {
+		return nil, err
+	}
+
+	Nn := uint16(aead.NonceSize())
+	baseNonce := st.labeledExpand(secret, []byte("base_nonce"), keySchCtx, Nn)
+	exporterSecret := st.labeledExpand(
+		secret,
+		[]byte("exp"),
+		keySchCtx,
+		uint16(st.kdfID.ExtractSize()),
+	)
+
+	return &encdecContext{
+		st.Suite,
+		ss,
+		secret,
+		keySchCtx,
+		exporterSecret,
+		key,
+		baseNonce,
+		make([]byte, Nn),
+		aead,
+		make([]byte, Nn),
+	}, nil
+}
+
+func (st state) verifyPSKInputs(psk, pskID []byte) error {
+	gotPSK := psk != nil
+	gotPSKID := pskID != nil
+	if gotPSK != gotPSKID {
+		return errors.New("inconsistent PSK inputs")
+	}
+	switch st.modeID {
+	case modeBase | modeAuth:
+		if gotPSK {
+			return errors.New("PSK input provided when not needed")
+		}
+	case modePSK | modeAuthPSK:
+		if !gotPSK {
+			return errors.New("missing required PSK input")
+		}
+	}
+	return nil
+}
+
+// Params returns the codepoints for the algorithms comprising the suite.
+func (suite Suite) Params() (KEM, KDF, AEAD) {
+	return suite.kemID, suite.kdfID, suite.aeadID
+}
+
+func (suite Suite) String() string {
+	return fmt.Sprintf(
+		"kem_id: %v kdf_id: %v aead_id: %v",
+		suite.kemID, suite.kdfID, suite.aeadID,
+	)
+}
+
+func (suite Suite) getSuiteID() (id [10]byte) {
+	id[0], id[1], id[2], id[3] = 'H', 'P', 'K', 'E'
+	binary.BigEndian.PutUint16(id[4:6], uint16(suite.kemID))
+	binary.BigEndian.PutUint16(id[6:8], uint16(suite.kdfID))
+	binary.BigEndian.PutUint16(id[8:10], uint16(suite.aeadID))
+	return
+}
+
+func (suite Suite) isValid() bool {
+	return suite.kemID.IsValid() &&
+		suite.kdfID.IsValid() &&
+		suite.aeadID.IsValid()
+}
+
+func (suite Suite) labeledExtract(salt, label, ikm []byte) []byte {
+	suiteID := suite.getSuiteID()
+	labeledIKM := append(append(append(append(
+		make([]byte, 0, len(versionLabel)+len(suiteID)+len(label)+len(ikm)),
+		versionLabel...),
+		suiteID[:]...),
+		label...),
+		ikm...)
+	return suite.kdfID.Extract(labeledIKM, salt)
+}
+
+func (suite Suite) labeledExpand(prk, label, info []byte, l uint16) []byte {
+	suiteID := suite.getSuiteID()
+	labeledInfo := make([]byte,
+		2, 2+len(versionLabel)+len(suiteID)+len(label)+len(info))
+	binary.BigEndian.PutUint16(labeledInfo[0:2], l)
+	labeledInfo = append(append(append(append(labeledInfo,
+		versionLabel...),
+		suiteID[:]...),
+		label...),
+		info...)
+	return suite.kdfID.Expand(prk, labeledInfo, uint(l))
+}
diff --git a/vendor/github.com/cloudflare/circl/hpke/xkem.go b/vendor/github.com/cloudflare/circl/hpke/xkem.go
new file mode 100644
index 00000000..f11ab6b3
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/hpke/xkem.go
@@ -0,0 +1,164 @@
+package hpke
+
+import (
+	"bytes"
+	"crypto/rand"
+	"crypto/subtle"
+	"fmt"
+	"io"
+
+	"github.com/cloudflare/circl/dh/x25519"
+	"github.com/cloudflare/circl/dh/x448"
+	"github.com/cloudflare/circl/kem"
+)
+
+type xKEM struct {
+	dhKemBase
+	size int
+}
+
+func (x xKEM) PrivateKeySize() int        { return x.size }
+func (x xKEM) SeedSize() int              { return x.size }
+func (x xKEM) CiphertextSize() int        { return x.size }
+func (x xKEM) PublicKeySize() int         { return x.size }
+func (x xKEM) EncapsulationSeedSize() int { return x.size }
+
+func (x xKEM) sizeDH() int { return x.size }
+func (x xKEM) calcDH(dh []byte, sk kem.PrivateKey, pk kem.PublicKey) error {
+	PK := pk.(*xKEMPubKey)
+	SK := sk.(*xKEMPrivKey)
+	switch x.size {
+	case x25519.Size:
+		var ss, sKey, pKey x25519.Key
+		copy(sKey[:], SK.priv)
+		copy(pKey[:], PK.pub)
+		if !x25519.Shared(&ss, &sKey, &pKey) {
+			return ErrInvalidKEMSharedSecret
+		}
+		copy(dh, ss[:])
+	case x448.Size:
+		var ss, sKey, pKey x448.Key
+		copy(sKey[:], SK.priv)
+		copy(pKey[:], PK.pub)
+		if !x448.Shared(&ss, &sKey, &pKey) {
+			return ErrInvalidKEMSharedSecret
+		}
+		copy(dh, ss[:])
+	}
+	return nil
+}
+
+// Deterministically derives a keypair from a seed. If you're unsure,
+// you're better off using GenerateKey().
+//
+// Panics if seed is not of length SeedSize().
+func (x xKEM) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
+	// Implementation based on
+	// https://www.ietf.org/archive/id/draft-irtf-cfrg-hpke-07.html#name-derivekeypair
+	if len(seed) != x.SeedSize() {
+		panic(kem.ErrSeedSize)
+	}
+	sk := &xKEMPrivKey{scheme: x, priv: make([]byte, x.size)}
+	dkpPrk := x.labeledExtract([]byte(""), []byte("dkp_prk"), seed)
+	bytes := x.labeledExpand(
+		dkpPrk,
+		[]byte("sk"),
+		nil,
+		uint16(x.PrivateKeySize()),
+	)
+	copy(sk.priv, bytes)
+	return sk.Public(), sk
+}
+
+func (x xKEM) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
+	sk := &xKEMPrivKey{scheme: x, priv: make([]byte, x.PrivateKeySize())}
+	_, err := io.ReadFull(rand.Reader, sk.priv)
+	if err != nil {
+		return nil, nil, err
+	}
+	return sk.Public(), sk, nil
+}
+
+func (x xKEM) UnmarshalBinaryPrivateKey(data []byte) (kem.PrivateKey, error) {
+	l := x.PrivateKeySize()
+	if len(data) < l {
+		return nil, ErrInvalidKEMPrivateKey
+	}
+	sk := &xKEMPrivKey{x, make([]byte, l), nil}
+	copy(sk.priv, data[:l])
+	if !sk.validate() {
+		return nil, ErrInvalidKEMPrivateKey
+	}
+	return sk, nil
+}
+
+func (x xKEM) UnmarshalBinaryPublicKey(data []byte) (kem.PublicKey, error) {
+	l := x.PublicKeySize()
+	if len(data) < l {
+		return nil, ErrInvalidKEMPublicKey
+	}
+	pk := &xKEMPubKey{x, make([]byte, l)}
+	copy(pk.pub, data[:l])
+	if !pk.validate() {
+		return nil, ErrInvalidKEMPublicKey
+	}
+	return pk, nil
+}
+
+type xKEMPubKey struct {
+	scheme xKEM
+	pub    []byte
+}
+
+func (k *xKEMPubKey) String() string     { return fmt.Sprintf("%x", k.pub) }
+func (k *xKEMPubKey) Scheme() kem.Scheme { return k.scheme }
+func (k *xKEMPubKey) MarshalBinary() ([]byte, error) {
+	return append(make([]byte, 0, k.scheme.PublicKeySize()), k.pub...), nil
+}
+
+func (k *xKEMPubKey) Equal(pk kem.PublicKey) bool {
+	k1, ok := pk.(*xKEMPubKey)
+	return ok &&
+		k.scheme.id == k1.scheme.id &&
+		bytes.Equal(k.pub, k1.pub)
+}
+func (k *xKEMPubKey) validate() bool { return len(k.pub) == k.scheme.PublicKeySize() }
+
+type xKEMPrivKey struct {
+	scheme xKEM
+	priv   []byte
+	pub    *xKEMPubKey
+}
+
+func (k *xKEMPrivKey) String() string     { return fmt.Sprintf("%x", k.priv) }
+func (k *xKEMPrivKey) Scheme() kem.Scheme { return k.scheme }
+func (k *xKEMPrivKey) MarshalBinary() ([]byte, error) {
+	return append(make([]byte, 0, k.scheme.PrivateKeySize()), k.priv...), nil
+}
+
+func (k *xKEMPrivKey) Equal(pk kem.PrivateKey) bool {
+	k1, ok := pk.(*xKEMPrivKey)
+	return ok &&
+		k.scheme.id == k1.scheme.id &&
+		subtle.ConstantTimeCompare(k.priv, k1.priv) == 1
+}
+
+func (k *xKEMPrivKey) Public() kem.PublicKey {
+	if k.pub == nil {
+		k.pub = &xKEMPubKey{scheme: k.scheme, pub: make([]byte, k.scheme.size)}
+		switch k.scheme.size {
+		case x25519.Size:
+			var sk, pk x25519.Key
+			copy(sk[:], k.priv)
+			x25519.KeyGen(&pk, &sk)
+			copy(k.pub.pub, pk[:])
+		case x448.Size:
+			var sk, pk x448.Key
+			copy(sk[:], k.priv)
+			x448.KeyGen(&pk, &sk)
+			copy(k.pub.pub, pk[:])
+		}
+	}
+	return k.pub
+}
+func (k *xKEMPrivKey) validate() bool { return len(k.priv) == k.scheme.PrivateKeySize() }
diff --git a/vendor/github.com/cloudflare/circl/internal/conv/conv.go b/vendor/github.com/cloudflare/circl/internal/conv/conv.go
new file mode 100644
index 00000000..649a8e93
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/conv/conv.go
@@ -0,0 +1,140 @@
+package conv
+
+import (
+	"encoding/binary"
+	"fmt"
+	"math/big"
+	"strings"
+)
+
+// BytesLe2Hex returns an hexadecimal string of a number stored in a
+// little-endian order slice x.
+func BytesLe2Hex(x []byte) string {
+	b := &strings.Builder{}
+	b.Grow(2*len(x) + 2)
+	fmt.Fprint(b, "0x")
+	if len(x) == 0 {
+		fmt.Fprint(b, "00")
+	}
+	for i := len(x) - 1; i >= 0; i-- {
+		fmt.Fprintf(b, "%02x", x[i])
+	}
+	return b.String()
+}
+
+// BytesLe2BigInt converts a little-endian slice x into a big-endian
+// math/big.Int.
+func BytesLe2BigInt(x []byte) *big.Int {
+	n := len(x)
+	b := new(big.Int)
+	if len(x) > 0 {
+		y := make([]byte, n)
+		for i := 0; i < n; i++ {
+			y[n-1-i] = x[i]
+		}
+		b.SetBytes(y)
+	}
+	return b
+}
+
+// BytesBe2Uint64Le converts a big-endian slice x to a little-endian slice of uint64.
+func BytesBe2Uint64Le(x []byte) []uint64 {
+	l := len(x)
+	z := make([]uint64, (l+7)/8)
+	blocks := l / 8
+	for i := 0; i < blocks; i++ {
+		z[i] = binary.BigEndian.Uint64(x[l-8*(i+1):])
+	}
+	remBytes := l % 8
+	for i := 0; i < remBytes; i++ {
+		z[blocks] |= uint64(x[l-1-8*blocks-i]) << uint(8*i)
+	}
+	return z
+}
+
+// BigInt2BytesLe stores a positive big.Int number x into a little-endian slice z.
+// The slice is modified if the bitlength of x <= 8*len(z) (padding with zeros).
+// If x does not fit in the slice or is negative, z is not modified.
+func BigInt2BytesLe(z []byte, x *big.Int) {
+	xLen := (x.BitLen() + 7) >> 3
+	zLen := len(z)
+	if zLen >= xLen && x.Sign() >= 0 {
+		y := x.Bytes()
+		for i := 0; i < xLen; i++ {
+			z[i] = y[xLen-1-i]
+		}
+		for i := xLen; i < zLen; i++ {
+			z[i] = 0
+		}
+	}
+}
+
+// Uint64Le2BigInt converts a little-endian slice x into a big number.
+func Uint64Le2BigInt(x []uint64) *big.Int {
+	n := len(x)
+	b := new(big.Int)
+	var bi big.Int
+	for i := n - 1; i >= 0; i-- {
+		bi.SetUint64(x[i])
+		b.Lsh(b, 64)
+		b.Add(b, &bi)
+	}
+	return b
+}
+
+// Uint64Le2BytesLe converts a little-endian slice x to a little-endian slice of bytes.
+func Uint64Le2BytesLe(x []uint64) []byte {
+	b := make([]byte, 8*len(x))
+	n := len(x)
+	for i := 0; i < n; i++ {
+		binary.LittleEndian.PutUint64(b[i*8:], x[i])
+	}
+	return b
+}
+
+// Uint64Le2BytesBe converts a little-endian slice x to a big-endian slice of bytes.
+func Uint64Le2BytesBe(x []uint64) []byte {
+	b := make([]byte, 8*len(x))
+	n := len(x)
+	for i := 0; i < n; i++ {
+		binary.BigEndian.PutUint64(b[i*8:], x[n-1-i])
+	}
+	return b
+}
+
+// Uint64Le2Hex returns an hexadecimal string of a number stored in a
+// little-endian order slice x.
+func Uint64Le2Hex(x []uint64) string {
+	b := new(strings.Builder)
+	b.Grow(16*len(x) + 2)
+	fmt.Fprint(b, "0x")
+	if len(x) == 0 {
+		fmt.Fprint(b, "00")
+	}
+	for i := len(x) - 1; i >= 0; i-- {
+		fmt.Fprintf(b, "%016x", x[i])
+	}
+	return b.String()
+}
+
+// BigInt2Uint64Le stores a positive big.Int number x into a little-endian slice z.
+// The slice is modified if the bitlength of x <= 8*len(z) (padding with zeros).
+// If x does not fit in the slice or is negative, z is not modified.
+func BigInt2Uint64Le(z []uint64, x *big.Int) {
+	xLen := (x.BitLen() + 63) >> 6 // number of 64-bit words
+	zLen := len(z)
+	if zLen >= xLen && x.Sign() > 0 {
+		var y, yi big.Int
+		y.Set(x)
+		two64 := big.NewInt(1)
+		two64.Lsh(two64, 64).Sub(two64, big.NewInt(1))
+		for i := 0; i < xLen; i++ {
+			yi.And(&y, two64)
+			z[i] = yi.Uint64()
+			y.Rsh(&y, 64)
+		}
+	}
+	for i := xLen; i < zLen; i++ {
+		z[i] = 0
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/doc.go b/vendor/github.com/cloudflare/circl/internal/sha3/doc.go
new file mode 100644
index 00000000..7e023090
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/doc.go
@@ -0,0 +1,62 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package sha3 implements the SHA-3 fixed-output-length hash functions and
+// the SHAKE variable-output-length hash functions defined by FIPS-202.
+//
+// Both types of hash function use the "sponge" construction and the Keccak
+// permutation. For a detailed specification see http://keccak.noekeon.org/
+//
+// # Guidance
+//
+// If you aren't sure what function you need, use SHAKE256 with at least 64
+// bytes of output. The SHAKE instances are faster than the SHA3 instances;
+// the latter have to allocate memory to conform to the hash.Hash interface.
+//
+// If you need a secret-key MAC (message authentication code), prepend the
+// secret key to the input, hash with SHAKE256 and read at least 32 bytes of
+// output.
+//
+// # Security strengths
+//
+// The SHA3-x (x equals 224, 256, 384, or 512) functions have a security
+// strength against preimage attacks of x bits. Since they only produce "x"
+// bits of output, their collision-resistance is only "x/2" bits.
+//
+// The SHAKE-256 and -128 functions have a generic security strength of 256 and
+// 128 bits against all attacks, provided that at least 2x bits of their output
+// is used.  Requesting more than 64 or 32 bytes of output, respectively, does
+// not increase the collision-resistance of the SHAKE functions.
+//
+// # The sponge construction
+//
+// A sponge builds a pseudo-random function from a public pseudo-random
+// permutation, by applying the permutation to a state of "rate + capacity"
+// bytes, but hiding "capacity" of the bytes.
+//
+// A sponge starts out with a zero state. To hash an input using a sponge, up
+// to "rate" bytes of the input are XORed into the sponge's state. The sponge
+// is then "full" and the permutation is applied to "empty" it. This process is
+// repeated until all the input has been "absorbed". The input is then padded.
+// The digest is "squeezed" from the sponge in the same way, except that output
+// is copied out instead of input being XORed in.
+//
+// A sponge is parameterized by its generic security strength, which is equal
+// to half its capacity; capacity + rate is equal to the permutation's width.
+// Since the KeccakF-1600 permutation is 1600 bits (200 bytes) wide, this means
+// that the security strength of a sponge instance is equal to (1600 - bitrate) / 2.
+//
+// # Recommendations
+//
+// The SHAKE functions are recommended for most new uses. They can produce
+// output of arbitrary length. SHAKE256, with an output length of at least
+// 64 bytes, provides 256-bit security against all attacks.  The Keccak team
+// recommends it for most applications upgrading from SHA2-512. (NIST chose a
+// much stronger, but much slower, sponge instance for SHA3-512.)
+//
+// The SHA-3 functions are "drop-in" replacements for the SHA-2 functions.
+// They produce output of the same length, with the same security strengths
+// against all attacks. This means, in particular, that SHA3-256 only has
+// 128-bit collision resistance, because its output length is 32 bytes.
+package sha3
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/hashes.go b/vendor/github.com/cloudflare/circl/internal/sha3/hashes.go
new file mode 100644
index 00000000..7d2365a7
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/hashes.go
@@ -0,0 +1,69 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// This file provides functions for creating instances of the SHA-3
+// and SHAKE hash functions, as well as utility functions for hashing
+// bytes.
+
+// New224 creates a new SHA3-224 hash.
+// Its generic security strength is 224 bits against preimage attacks,
+// and 112 bits against collision attacks.
+func New224() State {
+	return State{rate: 144, outputLen: 28, dsbyte: 0x06}
+}
+
+// New256 creates a new SHA3-256 hash.
+// Its generic security strength is 256 bits against preimage attacks,
+// and 128 bits against collision attacks.
+func New256() State {
+	return State{rate: 136, outputLen: 32, dsbyte: 0x06}
+}
+
+// New384 creates a new SHA3-384 hash.
+// Its generic security strength is 384 bits against preimage attacks,
+// and 192 bits against collision attacks.
+func New384() State {
+	return State{rate: 104, outputLen: 48, dsbyte: 0x06}
+}
+
+// New512 creates a new SHA3-512 hash.
+// Its generic security strength is 512 bits against preimage attacks,
+// and 256 bits against collision attacks.
+func New512() State {
+	return State{rate: 72, outputLen: 64, dsbyte: 0x06}
+}
+
+// Sum224 returns the SHA3-224 digest of the data.
+func Sum224(data []byte) (digest [28]byte) {
+	h := New224()
+	_, _ = h.Write(data)
+	h.Sum(digest[:0])
+	return
+}
+
+// Sum256 returns the SHA3-256 digest of the data.
+func Sum256(data []byte) (digest [32]byte) {
+	h := New256()
+	_, _ = h.Write(data)
+	h.Sum(digest[:0])
+	return
+}
+
+// Sum384 returns the SHA3-384 digest of the data.
+func Sum384(data []byte) (digest [48]byte) {
+	h := New384()
+	_, _ = h.Write(data)
+	h.Sum(digest[:0])
+	return
+}
+
+// Sum512 returns the SHA3-512 digest of the data.
+func Sum512(data []byte) (digest [64]byte) {
+	h := New512()
+	_, _ = h.Write(data)
+	h.Sum(digest[:0])
+	return
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/keccakf.go b/vendor/github.com/cloudflare/circl/internal/sha3/keccakf.go
new file mode 100644
index 00000000..1755fd1e
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/keccakf.go
@@ -0,0 +1,391 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// KeccakF1600 applies the Keccak permutation to a 1600b-wide
+// state represented as a slice of 25 uint64s.
+// If turbo is true, applies the 12-round variant instead of the
+// regular 24-round variant.
+// nolint:funlen
+func KeccakF1600(a *[25]uint64, turbo bool) {
+	// Implementation translated from Keccak-inplace.c
+	// in the keccak reference code.
+	var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64
+
+	i := 0
+
+	if turbo {
+		i = 12
+	}
+
+	for ; i < 24; i += 4 {
+		// Combines the 5 steps in each round into 2 steps.
+		// Unrolls 4 rounds per loop and spreads some steps across rounds.
+
+		// Round 1
+		bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+		bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+		bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+		bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+		bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+		d0 = bc4 ^ (bc1<<1 | bc1>>63)
+		d1 = bc0 ^ (bc2<<1 | bc2>>63)
+		d2 = bc1 ^ (bc3<<1 | bc3>>63)
+		d3 = bc2 ^ (bc4<<1 | bc4>>63)
+		d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+		bc0 = a[0] ^ d0
+		t = a[6] ^ d1
+		bc1 = t<<44 | t>>(64-44)
+		t = a[12] ^ d2
+		bc2 = t<<43 | t>>(64-43)
+		t = a[18] ^ d3
+		bc3 = t<<21 | t>>(64-21)
+		t = a[24] ^ d4
+		bc4 = t<<14 | t>>(64-14)
+		a[0] = bc0 ^ (bc2 &^ bc1) ^ RC[i]
+		a[6] = bc1 ^ (bc3 &^ bc2)
+		a[12] = bc2 ^ (bc4 &^ bc3)
+		a[18] = bc3 ^ (bc0 &^ bc4)
+		a[24] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[10] ^ d0
+		bc2 = t<<3 | t>>(64-3)
+		t = a[16] ^ d1
+		bc3 = t<<45 | t>>(64-45)
+		t = a[22] ^ d2
+		bc4 = t<<61 | t>>(64-61)
+		t = a[3] ^ d3
+		bc0 = t<<28 | t>>(64-28)
+		t = a[9] ^ d4
+		bc1 = t<<20 | t>>(64-20)
+		a[10] = bc0 ^ (bc2 &^ bc1)
+		a[16] = bc1 ^ (bc3 &^ bc2)
+		a[22] = bc2 ^ (bc4 &^ bc3)
+		a[3] = bc3 ^ (bc0 &^ bc4)
+		a[9] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[20] ^ d0
+		bc4 = t<<18 | t>>(64-18)
+		t = a[1] ^ d1
+		bc0 = t<<1 | t>>(64-1)
+		t = a[7] ^ d2
+		bc1 = t<<6 | t>>(64-6)
+		t = a[13] ^ d3
+		bc2 = t<<25 | t>>(64-25)
+		t = a[19] ^ d4
+		bc3 = t<<8 | t>>(64-8)
+		a[20] = bc0 ^ (bc2 &^ bc1)
+		a[1] = bc1 ^ (bc3 &^ bc2)
+		a[7] = bc2 ^ (bc4 &^ bc3)
+		a[13] = bc3 ^ (bc0 &^ bc4)
+		a[19] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[5] ^ d0
+		bc1 = t<<36 | t>>(64-36)
+		t = a[11] ^ d1
+		bc2 = t<<10 | t>>(64-10)
+		t = a[17] ^ d2
+		bc3 = t<<15 | t>>(64-15)
+		t = a[23] ^ d3
+		bc4 = t<<56 | t>>(64-56)
+		t = a[4] ^ d4
+		bc0 = t<<27 | t>>(64-27)
+		a[5] = bc0 ^ (bc2 &^ bc1)
+		a[11] = bc1 ^ (bc3 &^ bc2)
+		a[17] = bc2 ^ (bc4 &^ bc3)
+		a[23] = bc3 ^ (bc0 &^ bc4)
+		a[4] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[15] ^ d0
+		bc3 = t<<41 | t>>(64-41)
+		t = a[21] ^ d1
+		bc4 = t<<2 | t>>(64-2)
+		t = a[2] ^ d2
+		bc0 = t<<62 | t>>(64-62)
+		t = a[8] ^ d3
+		bc1 = t<<55 | t>>(64-55)
+		t = a[14] ^ d4
+		bc2 = t<<39 | t>>(64-39)
+		a[15] = bc0 ^ (bc2 &^ bc1)
+		a[21] = bc1 ^ (bc3 &^ bc2)
+		a[2] = bc2 ^ (bc4 &^ bc3)
+		a[8] = bc3 ^ (bc0 &^ bc4)
+		a[14] = bc4 ^ (bc1 &^ bc0)
+
+		// Round 2
+		bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+		bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+		bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+		bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+		bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+		d0 = bc4 ^ (bc1<<1 | bc1>>63)
+		d1 = bc0 ^ (bc2<<1 | bc2>>63)
+		d2 = bc1 ^ (bc3<<1 | bc3>>63)
+		d3 = bc2 ^ (bc4<<1 | bc4>>63)
+		d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+		bc0 = a[0] ^ d0
+		t = a[16] ^ d1
+		bc1 = t<<44 | t>>(64-44)
+		t = a[7] ^ d2
+		bc2 = t<<43 | t>>(64-43)
+		t = a[23] ^ d3
+		bc3 = t<<21 | t>>(64-21)
+		t = a[14] ^ d4
+		bc4 = t<<14 | t>>(64-14)
+		a[0] = bc0 ^ (bc2 &^ bc1) ^ RC[i+1]
+		a[16] = bc1 ^ (bc3 &^ bc2)
+		a[7] = bc2 ^ (bc4 &^ bc3)
+		a[23] = bc3 ^ (bc0 &^ bc4)
+		a[14] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[20] ^ d0
+		bc2 = t<<3 | t>>(64-3)
+		t = a[11] ^ d1
+		bc3 = t<<45 | t>>(64-45)
+		t = a[2] ^ d2
+		bc4 = t<<61 | t>>(64-61)
+		t = a[18] ^ d3
+		bc0 = t<<28 | t>>(64-28)
+		t = a[9] ^ d4
+		bc1 = t<<20 | t>>(64-20)
+		a[20] = bc0 ^ (bc2 &^ bc1)
+		a[11] = bc1 ^ (bc3 &^ bc2)
+		a[2] = bc2 ^ (bc4 &^ bc3)
+		a[18] = bc3 ^ (bc0 &^ bc4)
+		a[9] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[15] ^ d0
+		bc4 = t<<18 | t>>(64-18)
+		t = a[6] ^ d1
+		bc0 = t<<1 | t>>(64-1)
+		t = a[22] ^ d2
+		bc1 = t<<6 | t>>(64-6)
+		t = a[13] ^ d3
+		bc2 = t<<25 | t>>(64-25)
+		t = a[4] ^ d4
+		bc3 = t<<8 | t>>(64-8)
+		a[15] = bc0 ^ (bc2 &^ bc1)
+		a[6] = bc1 ^ (bc3 &^ bc2)
+		a[22] = bc2 ^ (bc4 &^ bc3)
+		a[13] = bc3 ^ (bc0 &^ bc4)
+		a[4] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[10] ^ d0
+		bc1 = t<<36 | t>>(64-36)
+		t = a[1] ^ d1
+		bc2 = t<<10 | t>>(64-10)
+		t = a[17] ^ d2
+		bc3 = t<<15 | t>>(64-15)
+		t = a[8] ^ d3
+		bc4 = t<<56 | t>>(64-56)
+		t = a[24] ^ d4
+		bc0 = t<<27 | t>>(64-27)
+		a[10] = bc0 ^ (bc2 &^ bc1)
+		a[1] = bc1 ^ (bc3 &^ bc2)
+		a[17] = bc2 ^ (bc4 &^ bc3)
+		a[8] = bc3 ^ (bc0 &^ bc4)
+		a[24] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[5] ^ d0
+		bc3 = t<<41 | t>>(64-41)
+		t = a[21] ^ d1
+		bc4 = t<<2 | t>>(64-2)
+		t = a[12] ^ d2
+		bc0 = t<<62 | t>>(64-62)
+		t = a[3] ^ d3
+		bc1 = t<<55 | t>>(64-55)
+		t = a[19] ^ d4
+		bc2 = t<<39 | t>>(64-39)
+		a[5] = bc0 ^ (bc2 &^ bc1)
+		a[21] = bc1 ^ (bc3 &^ bc2)
+		a[12] = bc2 ^ (bc4 &^ bc3)
+		a[3] = bc3 ^ (bc0 &^ bc4)
+		a[19] = bc4 ^ (bc1 &^ bc0)
+
+		// Round 3
+		bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+		bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+		bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+		bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+		bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+		d0 = bc4 ^ (bc1<<1 | bc1>>63)
+		d1 = bc0 ^ (bc2<<1 | bc2>>63)
+		d2 = bc1 ^ (bc3<<1 | bc3>>63)
+		d3 = bc2 ^ (bc4<<1 | bc4>>63)
+		d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+		bc0 = a[0] ^ d0
+		t = a[11] ^ d1
+		bc1 = t<<44 | t>>(64-44)
+		t = a[22] ^ d2
+		bc2 = t<<43 | t>>(64-43)
+		t = a[8] ^ d3
+		bc3 = t<<21 | t>>(64-21)
+		t = a[19] ^ d4
+		bc4 = t<<14 | t>>(64-14)
+		a[0] = bc0 ^ (bc2 &^ bc1) ^ RC[i+2]
+		a[11] = bc1 ^ (bc3 &^ bc2)
+		a[22] = bc2 ^ (bc4 &^ bc3)
+		a[8] = bc3 ^ (bc0 &^ bc4)
+		a[19] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[15] ^ d0
+		bc2 = t<<3 | t>>(64-3)
+		t = a[1] ^ d1
+		bc3 = t<<45 | t>>(64-45)
+		t = a[12] ^ d2
+		bc4 = t<<61 | t>>(64-61)
+		t = a[23] ^ d3
+		bc0 = t<<28 | t>>(64-28)
+		t = a[9] ^ d4
+		bc1 = t<<20 | t>>(64-20)
+		a[15] = bc0 ^ (bc2 &^ bc1)
+		a[1] = bc1 ^ (bc3 &^ bc2)
+		a[12] = bc2 ^ (bc4 &^ bc3)
+		a[23] = bc3 ^ (bc0 &^ bc4)
+		a[9] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[5] ^ d0
+		bc4 = t<<18 | t>>(64-18)
+		t = a[16] ^ d1
+		bc0 = t<<1 | t>>(64-1)
+		t = a[2] ^ d2
+		bc1 = t<<6 | t>>(64-6)
+		t = a[13] ^ d3
+		bc2 = t<<25 | t>>(64-25)
+		t = a[24] ^ d4
+		bc3 = t<<8 | t>>(64-8)
+		a[5] = bc0 ^ (bc2 &^ bc1)
+		a[16] = bc1 ^ (bc3 &^ bc2)
+		a[2] = bc2 ^ (bc4 &^ bc3)
+		a[13] = bc3 ^ (bc0 &^ bc4)
+		a[24] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[20] ^ d0
+		bc1 = t<<36 | t>>(64-36)
+		t = a[6] ^ d1
+		bc2 = t<<10 | t>>(64-10)
+		t = a[17] ^ d2
+		bc3 = t<<15 | t>>(64-15)
+		t = a[3] ^ d3
+		bc4 = t<<56 | t>>(64-56)
+		t = a[14] ^ d4
+		bc0 = t<<27 | t>>(64-27)
+		a[20] = bc0 ^ (bc2 &^ bc1)
+		a[6] = bc1 ^ (bc3 &^ bc2)
+		a[17] = bc2 ^ (bc4 &^ bc3)
+		a[3] = bc3 ^ (bc0 &^ bc4)
+		a[14] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[10] ^ d0
+		bc3 = t<<41 | t>>(64-41)
+		t = a[21] ^ d1
+		bc4 = t<<2 | t>>(64-2)
+		t = a[7] ^ d2
+		bc0 = t<<62 | t>>(64-62)
+		t = a[18] ^ d3
+		bc1 = t<<55 | t>>(64-55)
+		t = a[4] ^ d4
+		bc2 = t<<39 | t>>(64-39)
+		a[10] = bc0 ^ (bc2 &^ bc1)
+		a[21] = bc1 ^ (bc3 &^ bc2)
+		a[7] = bc2 ^ (bc4 &^ bc3)
+		a[18] = bc3 ^ (bc0 &^ bc4)
+		a[4] = bc4 ^ (bc1 &^ bc0)
+
+		// Round 4
+		bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+		bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+		bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+		bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+		bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+		d0 = bc4 ^ (bc1<<1 | bc1>>63)
+		d1 = bc0 ^ (bc2<<1 | bc2>>63)
+		d2 = bc1 ^ (bc3<<1 | bc3>>63)
+		d3 = bc2 ^ (bc4<<1 | bc4>>63)
+		d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+		bc0 = a[0] ^ d0
+		t = a[1] ^ d1
+		bc1 = t<<44 | t>>(64-44)
+		t = a[2] ^ d2
+		bc2 = t<<43 | t>>(64-43)
+		t = a[3] ^ d3
+		bc3 = t<<21 | t>>(64-21)
+		t = a[4] ^ d4
+		bc4 = t<<14 | t>>(64-14)
+		a[0] = bc0 ^ (bc2 &^ bc1) ^ RC[i+3]
+		a[1] = bc1 ^ (bc3 &^ bc2)
+		a[2] = bc2 ^ (bc4 &^ bc3)
+		a[3] = bc3 ^ (bc0 &^ bc4)
+		a[4] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[5] ^ d0
+		bc2 = t<<3 | t>>(64-3)
+		t = a[6] ^ d1
+		bc3 = t<<45 | t>>(64-45)
+		t = a[7] ^ d2
+		bc4 = t<<61 | t>>(64-61)
+		t = a[8] ^ d3
+		bc0 = t<<28 | t>>(64-28)
+		t = a[9] ^ d4
+		bc1 = t<<20 | t>>(64-20)
+		a[5] = bc0 ^ (bc2 &^ bc1)
+		a[6] = bc1 ^ (bc3 &^ bc2)
+		a[7] = bc2 ^ (bc4 &^ bc3)
+		a[8] = bc3 ^ (bc0 &^ bc4)
+		a[9] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[10] ^ d0
+		bc4 = t<<18 | t>>(64-18)
+		t = a[11] ^ d1
+		bc0 = t<<1 | t>>(64-1)
+		t = a[12] ^ d2
+		bc1 = t<<6 | t>>(64-6)
+		t = a[13] ^ d3
+		bc2 = t<<25 | t>>(64-25)
+		t = a[14] ^ d4
+		bc3 = t<<8 | t>>(64-8)
+		a[10] = bc0 ^ (bc2 &^ bc1)
+		a[11] = bc1 ^ (bc3 &^ bc2)
+		a[12] = bc2 ^ (bc4 &^ bc3)
+		a[13] = bc3 ^ (bc0 &^ bc4)
+		a[14] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[15] ^ d0
+		bc1 = t<<36 | t>>(64-36)
+		t = a[16] ^ d1
+		bc2 = t<<10 | t>>(64-10)
+		t = a[17] ^ d2
+		bc3 = t<<15 | t>>(64-15)
+		t = a[18] ^ d3
+		bc4 = t<<56 | t>>(64-56)
+		t = a[19] ^ d4
+		bc0 = t<<27 | t>>(64-27)
+		a[15] = bc0 ^ (bc2 &^ bc1)
+		a[16] = bc1 ^ (bc3 &^ bc2)
+		a[17] = bc2 ^ (bc4 &^ bc3)
+		a[18] = bc3 ^ (bc0 &^ bc4)
+		a[19] = bc4 ^ (bc1 &^ bc0)
+
+		t = a[20] ^ d0
+		bc3 = t<<41 | t>>(64-41)
+		t = a[21] ^ d1
+		bc4 = t<<2 | t>>(64-2)
+		t = a[22] ^ d2
+		bc0 = t<<62 | t>>(64-62)
+		t = a[23] ^ d3
+		bc1 = t<<55 | t>>(64-55)
+		t = a[24] ^ d4
+		bc2 = t<<39 | t>>(64-39)
+		a[20] = bc0 ^ (bc2 &^ bc1)
+		a[21] = bc1 ^ (bc3 &^ bc2)
+		a[22] = bc2 ^ (bc4 &^ bc3)
+		a[23] = bc3 ^ (bc0 &^ bc4)
+		a[24] = bc4 ^ (bc1 &^ bc0)
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/rc.go b/vendor/github.com/cloudflare/circl/internal/sha3/rc.go
new file mode 100644
index 00000000..6a3df42f
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/rc.go
@@ -0,0 +1,29 @@
+package sha3
+
+// RC stores the round constants for use in the ι step.
+var RC = [24]uint64{
+	0x0000000000000001,
+	0x0000000000008082,
+	0x800000000000808A,
+	0x8000000080008000,
+	0x000000000000808B,
+	0x0000000080000001,
+	0x8000000080008081,
+	0x8000000000008009,
+	0x000000000000008A,
+	0x0000000000000088,
+	0x0000000080008009,
+	0x000000008000000A,
+	0x000000008000808B,
+	0x800000000000008B,
+	0x8000000000008089,
+	0x8000000000008003,
+	0x8000000000008002,
+	0x8000000000000080,
+	0x000000000000800A,
+	0x800000008000000A,
+	0x8000000080008081,
+	0x8000000000008080,
+	0x0000000080000001,
+	0x8000000080008008,
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/sha3.go b/vendor/github.com/cloudflare/circl/internal/sha3/sha3.go
new file mode 100644
index 00000000..a0df5aa6
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/sha3.go
@@ -0,0 +1,200 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// spongeDirection indicates the direction bytes are flowing through the sponge.
+type spongeDirection int
+
+const (
+	// spongeAbsorbing indicates that the sponge is absorbing input.
+	spongeAbsorbing spongeDirection = iota
+	// spongeSqueezing indicates that the sponge is being squeezed.
+	spongeSqueezing
+)
+
+const (
+	// maxRate is the maximum size of the internal buffer. SHAKE-256
+	// currently needs the largest buffer.
+	maxRate = 168
+)
+
+func (d *State) buf() []byte {
+	return d.storage.asBytes()[d.bufo:d.bufe]
+}
+
+type State struct {
+	// Generic sponge components.
+	a    [25]uint64 // main state of the hash
+	rate int        // the number of bytes of state to use
+
+	bufo int // offset of buffer in storage
+	bufe int // end of buffer in storage
+
+	// dsbyte contains the "domain separation" bits and the first bit of
+	// the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
+	// SHA-3 and SHAKE functions by appending bitstrings to the message.
+	// Using a little-endian bit-ordering convention, these are "01" for SHA-3
+	// and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the
+	// padding rule from section 5.1 is applied to pad the message to a multiple
+	// of the rate, which involves adding a "1" bit, zero or more "0" bits, and
+	// a final "1" bit. We merge the first "1" bit from the padding into dsbyte,
+	// giving 00000110b (0x06) and 00011111b (0x1f).
+	// [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
+	//     "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
+	//      Extendable-Output Functions (May 2014)"
+	dsbyte byte
+
+	storage storageBuf
+
+	// Specific to SHA-3 and SHAKE.
+	outputLen int             // the default output size in bytes
+	state     spongeDirection // whether the sponge is absorbing or squeezing
+	turbo     bool            // Whether we're using 12 rounds instead of 24
+}
+
+// BlockSize returns the rate of sponge underlying this hash function.
+func (d *State) BlockSize() int { return d.rate }
+
+// Size returns the output size of the hash function in bytes.
+func (d *State) Size() int { return d.outputLen }
+
+// Reset clears the internal state by zeroing the sponge state and
+// the byte buffer, and setting Sponge.state to absorbing.
+func (d *State) Reset() {
+	// Zero the permutation's state.
+	for i := range d.a {
+		d.a[i] = 0
+	}
+	d.state = spongeAbsorbing
+	d.bufo = 0
+	d.bufe = 0
+}
+
+func (d *State) clone() *State {
+	ret := *d
+	return &ret
+}
+
+// permute applies the KeccakF-1600 permutation. It handles
+// any input-output buffering.
+func (d *State) permute() {
+	switch d.state {
+	case spongeAbsorbing:
+		// If we're absorbing, we need to xor the input into the state
+		// before applying the permutation.
+		xorIn(d, d.buf())
+		d.bufe = 0
+		d.bufo = 0
+		KeccakF1600(&d.a, d.turbo)
+	case spongeSqueezing:
+		// If we're squeezing, we need to apply the permutation before
+		// copying more output.
+		KeccakF1600(&d.a, d.turbo)
+		d.bufe = d.rate
+		d.bufo = 0
+		copyOut(d, d.buf())
+	}
+}
+
+// pads appends the domain separation bits in dsbyte, applies
+// the multi-bitrate 10..1 padding rule, and permutes the state.
+func (d *State) padAndPermute(dsbyte byte) {
+	// Pad with this instance's domain-separator bits. We know that there's
+	// at least one byte of space in d.buf() because, if it were full,
+	// permute would have been called to empty it. dsbyte also contains the
+	// first one bit for the padding. See the comment in the state struct.
+	zerosStart := d.bufe + 1
+	d.bufe = d.rate
+	buf := d.buf()
+	buf[zerosStart-1] = dsbyte
+	for i := zerosStart; i < d.rate; i++ {
+		buf[i] = 0
+	}
+	// This adds the final one bit for the padding. Because of the way that
+	// bits are numbered from the LSB upwards, the final bit is the MSB of
+	// the last byte.
+	buf[d.rate-1] ^= 0x80
+	// Apply the permutation
+	d.permute()
+	d.state = spongeSqueezing
+	d.bufe = d.rate
+	copyOut(d, buf)
+}
+
+// Write absorbs more data into the hash's state. It produces an error
+// if more data is written to the ShakeHash after writing
+func (d *State) Write(p []byte) (written int, err error) {
+	if d.state != spongeAbsorbing {
+		panic("sha3: write to sponge after read")
+	}
+	written = len(p)
+
+	for len(p) > 0 {
+		bufl := d.bufe - d.bufo
+		if bufl == 0 && len(p) >= d.rate {
+			// The fast path; absorb a full "rate" bytes of input and apply the permutation.
+			xorIn(d, p[:d.rate])
+			p = p[d.rate:]
+			KeccakF1600(&d.a, d.turbo)
+		} else {
+			// The slow path; buffer the input until we can fill the sponge, and then xor it in.
+			todo := d.rate - bufl
+			if todo > len(p) {
+				todo = len(p)
+			}
+			d.bufe += todo
+			buf := d.buf()
+			copy(buf[bufl:], p[:todo])
+			p = p[todo:]
+
+			// If the sponge is full, apply the permutation.
+			if d.bufe == d.rate {
+				d.permute()
+			}
+		}
+	}
+
+	return written, nil
+}
+
+// Read squeezes an arbitrary number of bytes from the sponge.
+func (d *State) Read(out []byte) (n int, err error) {
+	// If we're still absorbing, pad and apply the permutation.
+	if d.state == spongeAbsorbing {
+		d.padAndPermute(d.dsbyte)
+	}
+
+	n = len(out)
+
+	// Now, do the squeezing.
+	for len(out) > 0 {
+		buf := d.buf()
+		n := copy(out, buf)
+		d.bufo += n
+		out = out[n:]
+
+		// Apply the permutation if we've squeezed the sponge dry.
+		if d.bufo == d.bufe {
+			d.permute()
+		}
+	}
+
+	return
+}
+
+// Sum applies padding to the hash state and then squeezes out the desired
+// number of output bytes.
+func (d *State) Sum(in []byte) []byte {
+	// Make a copy of the original hash so that caller can keep writing
+	// and summing.
+	dup := d.clone()
+	hash := make([]byte, dup.outputLen)
+	_, _ = dup.Read(hash)
+	return append(in, hash...)
+}
+
+func (d *State) IsAbsorbing() bool {
+	return d.state == spongeAbsorbing
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/sha3_s390x.s b/vendor/github.com/cloudflare/circl/internal/sha3/sha3_s390x.s
new file mode 100644
index 00000000..8a4458f6
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/sha3_s390x.s
@@ -0,0 +1,33 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !gccgo,!appengine
+
+#include "textflag.h"
+
+// func kimd(function code, chain *[200]byte, src []byte)
+TEXT ·kimd(SB), NOFRAME|NOSPLIT, $0-40
+	MOVD function+0(FP), R0
+	MOVD chain+8(FP), R1
+	LMG  src+16(FP), R2, R3 // R2=base, R3=len
+
+continue:
+	WORD $0xB93E0002 // KIMD --, R2
+	BVS  continue    // continue if interrupted
+	MOVD $0, R0      // reset R0 for pre-go1.8 compilers
+	RET
+
+// func klmd(function code, chain *[200]byte, dst, src []byte)
+TEXT ·klmd(SB), NOFRAME|NOSPLIT, $0-64
+	// TODO: SHAKE support
+	MOVD function+0(FP), R0
+	MOVD chain+8(FP), R1
+	LMG  dst+16(FP), R2, R3 // R2=base, R3=len
+	LMG  src+40(FP), R4, R5 // R4=base, R5=len
+
+continue:
+	WORD $0xB93F0024 // KLMD R2, R4
+	BVS  continue    // continue if interrupted
+	MOVD $0, R0      // reset R0 for pre-go1.8 compilers
+	RET
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/shake.go b/vendor/github.com/cloudflare/circl/internal/sha3/shake.go
new file mode 100644
index 00000000..77817f75
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/shake.go
@@ -0,0 +1,119 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// This file defines the ShakeHash interface, and provides
+// functions for creating SHAKE and cSHAKE instances, as well as utility
+// functions for hashing bytes to arbitrary-length output.
+//
+//
+// SHAKE implementation is based on FIPS PUB 202 [1]
+// cSHAKE implementations is based on NIST SP 800-185 [2]
+//
+// [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
+// [2] https://doi.org/10.6028/NIST.SP.800-185
+
+import (
+	"io"
+)
+
+// ShakeHash defines the interface to hash functions that
+// support arbitrary-length output.
+type ShakeHash interface {
+	// Write absorbs more data into the hash's state. It panics if input is
+	// written to it after output has been read from it.
+	io.Writer
+
+	// Read reads more output from the hash; reading affects the hash's
+	// state. (ShakeHash.Read is thus very different from Hash.Sum)
+	// It never returns an error.
+	io.Reader
+
+	// Clone returns a copy of the ShakeHash in its current state.
+	Clone() ShakeHash
+
+	// Reset resets the ShakeHash to its initial state.
+	Reset()
+}
+
+// Consts for configuring initial SHA-3 state
+const (
+	dsbyteShake = 0x1f
+	rate128     = 168
+	rate256     = 136
+)
+
+// Clone returns copy of SHAKE context within its current state.
+func (d *State) Clone() ShakeHash {
+	return d.clone()
+}
+
+// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
+// Its generic security strength is 128 bits against all attacks if at
+// least 32 bytes of its output are used.
+func NewShake128() State {
+	return State{rate: rate128, dsbyte: dsbyteShake}
+}
+
+// NewTurboShake128 creates a new TurboSHAKE128 variable-output-length ShakeHash.
+// Its generic security strength is 128 bits against all attacks if at
+// least 32 bytes of its output are used.
+// D is the domain separation byte and must be between 0x01 and 0x7f inclusive.
+func NewTurboShake128(D byte) State {
+	if D == 0 || D > 0x7f {
+		panic("turboshake: D out of range")
+	}
+	return State{rate: rate128, dsbyte: D, turbo: true}
+}
+
+// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
+// Its generic security strength is 256 bits against all attacks if
+// at least 64 bytes of its output are used.
+func NewShake256() State {
+	return State{rate: rate256, dsbyte: dsbyteShake}
+}
+
+// NewTurboShake256 creates a new TurboSHAKE256 variable-output-length ShakeHash.
+// Its generic security strength is 256 bits against all attacks if
+// at least 64 bytes of its output are used.
+// D is the domain separation byte and must be between 0x01 and 0x7f inclusive.
+func NewTurboShake256(D byte) State {
+	if D == 0 || D > 0x7f {
+		panic("turboshake: D out of range")
+	}
+	return State{rate: rate256, dsbyte: D, turbo: true}
+}
+
+// ShakeSum128 writes an arbitrary-length digest of data into hash.
+func ShakeSum128(hash, data []byte) {
+	h := NewShake128()
+	_, _ = h.Write(data)
+	_, _ = h.Read(hash)
+}
+
+// ShakeSum256 writes an arbitrary-length digest of data into hash.
+func ShakeSum256(hash, data []byte) {
+	h := NewShake256()
+	_, _ = h.Write(data)
+	_, _ = h.Read(hash)
+}
+
+// TurboShakeSum128 writes an arbitrary-length digest of data into hash.
+func TurboShakeSum128(hash, data []byte, D byte) {
+	h := NewTurboShake128(D)
+	_, _ = h.Write(data)
+	_, _ = h.Read(hash)
+}
+
+// TurboShakeSum256 writes an arbitrary-length digest of data into hash.
+func TurboShakeSum256(hash, data []byte, D byte) {
+	h := NewTurboShake256(D)
+	_, _ = h.Write(data)
+	_, _ = h.Read(hash)
+}
+
+func (d *State) SwitchDS(D byte) {
+	d.dsbyte = D
+}
diff --git a/vendor/github.com/cloudflare/circl/internal/sha3/xor.go b/vendor/github.com/cloudflare/circl/internal/sha3/xor.go
new file mode 100644
index 00000000..1e213374
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/xor.go
@@ -0,0 +1,15 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (!amd64 && !386 && !ppc64le) || appengine
+// +build !amd64,!386,!ppc64le appengine
+
+package sha3
+
+// A storageBuf is an aligned array of maxRate bytes.
+type storageBuf [maxRate]byte
+
+func (b *storageBuf) asBytes() *[maxRate]byte {
+	return (*[maxRate]byte)(b)
+}
diff --git a/vendor/golang.org/x/crypto/sha3/xor_generic.go b/vendor/github.com/cloudflare/circl/internal/sha3/xor_generic.go
similarity index 59%
rename from vendor/golang.org/x/crypto/sha3/xor_generic.go
rename to vendor/github.com/cloudflare/circl/internal/sha3/xor_generic.go
index 8d947711..2b0c6617 100644
--- a/vendor/golang.org/x/crypto/sha3/xor_generic.go
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/xor_generic.go
@@ -2,14 +2,19 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build (!amd64 || appengine) && (!386 || appengine) && (!ppc64le || appengine)
+// +build !amd64 appengine
+// +build !386 appengine
+// +build !ppc64le appengine
+
 package sha3
 
 import "encoding/binary"
 
-// xorInGeneric xors the bytes in buf into the state; it
+// xorIn xors the bytes in buf into the state; it
 // makes no non-portable assumptions about memory layout
 // or alignment.
-func xorInGeneric(d *state, buf []byte) {
+func xorIn(d *State, buf []byte) {
 	n := len(buf) / 8
 
 	for i := 0; i < n; i++ {
@@ -19,8 +24,8 @@ func xorInGeneric(d *state, buf []byte) {
 	}
 }
 
-// copyOutGeneric copies uint64s to a byte buffer.
-func copyOutGeneric(d *state, b []byte) {
+// copyOut copies ulint64s to a byte buffer.
+func copyOut(d *State, b []byte) {
 	for i := 0; len(b) >= 8; i++ {
 		binary.LittleEndian.PutUint64(b, d.a[i])
 		b = b[8:]
diff --git a/vendor/golang.org/x/crypto/sha3/xor_unaligned.go b/vendor/github.com/cloudflare/circl/internal/sha3/xor_unaligned.go
similarity index 75%
rename from vendor/golang.org/x/crypto/sha3/xor_unaligned.go
rename to vendor/github.com/cloudflare/circl/internal/sha3/xor_unaligned.go
index 870e2d16..052fc8d3 100644
--- a/vendor/golang.org/x/crypto/sha3/xor_unaligned.go
+++ b/vendor/github.com/cloudflare/circl/internal/sha3/xor_unaligned.go
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (amd64 || 386 || ppc64le) && !purego
+//go:build (amd64 || 386 || ppc64le) && !appengine
+// +build amd64 386 ppc64le
+// +build !appengine
 
 package sha3
 
@@ -15,9 +17,9 @@ func (b *storageBuf) asBytes() *[maxRate]byte {
 	return (*[maxRate]byte)(unsafe.Pointer(b))
 }
 
-// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
+// xorInuses unaligned reads and writes to update d.a to contain d.a
 // XOR buf.
-func xorInUnaligned(d *state, buf []byte) {
+func xorIn(d *State, buf []byte) {
 	n := len(buf)
 	bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
 	if n >= 72 {
@@ -53,14 +55,7 @@ func xorInUnaligned(d *state, buf []byte) {
 	}
 }
 
-func copyOutUnaligned(d *state, buf []byte) {
+func copyOut(d *State, buf []byte) {
 	ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0]))
 	copy(buf, ab[:])
 }
-
-var (
-	xorIn   = xorInUnaligned
-	copyOut = copyOutUnaligned
-)
-
-const xorImplementationUnaligned = "unaligned"
diff --git a/vendor/github.com/cloudflare/circl/kem/hybrid/ckem.go b/vendor/github.com/cloudflare/circl/kem/hybrid/ckem.go
new file mode 100644
index 00000000..c0620e8d
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/kem/hybrid/ckem.go
@@ -0,0 +1,207 @@
+package hybrid
+
+// TODO move over to crypto/ecdh once we can assume Go 1.20.
+
+import (
+	"crypto/elliptic"
+	cryptoRand "crypto/rand"
+	"crypto/subtle"
+	"math/big"
+
+	"github.com/cloudflare/circl/kem"
+	"github.com/cloudflare/circl/xof"
+)
+
+type cPublicKey struct {
+	scheme *cScheme
+	x, y   *big.Int
+}
+type cPrivateKey struct {
+	scheme *cScheme
+	key    []byte
+}
+type cScheme struct {
+	curve elliptic.Curve
+}
+
+var p256Kem = &cScheme{elliptic.P256()}
+
+func (sch *cScheme) scSize() int {
+	return (sch.curve.Params().N.BitLen() + 7) / 8
+}
+
+func (sch *cScheme) ptSize() int {
+	return (sch.curve.Params().BitSize + 7) / 8
+}
+
+func (sch *cScheme) Name() string {
+	return sch.curve.Params().Name
+}
+
+func (sch *cScheme) PublicKeySize() int {
+	return 2*sch.ptSize() + 1
+}
+
+func (sch *cScheme) PrivateKeySize() int {
+	return sch.scSize()
+}
+
+func (sch *cScheme) SeedSize() int {
+	return sch.PrivateKeySize()
+}
+
+func (sch *cScheme) SharedKeySize() int {
+	return sch.ptSize()
+}
+
+func (sch *cScheme) CiphertextSize() int {
+	return sch.PublicKeySize()
+}
+
+func (sch *cScheme) EncapsulationSeedSize() int {
+	return sch.SeedSize()
+}
+
+func (sk *cPrivateKey) Scheme() kem.Scheme { return sk.scheme }
+func (pk *cPublicKey) Scheme() kem.Scheme  { return pk.scheme }
+
+func (sk *cPrivateKey) MarshalBinary() ([]byte, error) {
+	ret := make([]byte, len(sk.key))
+	copy(ret, sk.key)
+	return ret, nil
+}
+
+func (sk *cPrivateKey) Equal(other kem.PrivateKey) bool {
+	oth, ok := other.(*cPrivateKey)
+	if !ok {
+		return false
+	}
+	if oth.scheme != sk.scheme {
+		return false
+	}
+	return subtle.ConstantTimeCompare(oth.key, sk.key) == 1
+}
+
+func (sk *cPrivateKey) Public() kem.PublicKey {
+	x, y := sk.scheme.curve.ScalarBaseMult(sk.key)
+	return &cPublicKey{
+		sk.scheme,
+		x,
+		y,
+	}
+}
+
+func (pk *cPublicKey) Equal(other kem.PublicKey) bool {
+	oth, ok := other.(*cPublicKey)
+	if !ok {
+		return false
+	}
+	if oth.scheme != pk.scheme {
+		return false
+	}
+	return oth.x.Cmp(pk.x) == 0 && oth.y.Cmp(pk.y) == 0
+}
+
+func (pk *cPublicKey) MarshalBinary() ([]byte, error) {
+	return elliptic.Marshal(pk.scheme.curve, pk.x, pk.y), nil
+}
+
+func (sch *cScheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
+	seed := make([]byte, sch.SeedSize())
+	_, err := cryptoRand.Read(seed)
+	if err != nil {
+		return nil, nil, err
+	}
+	pk, sk := sch.DeriveKeyPair(seed)
+	return pk, sk, nil
+}
+
+func (sch *cScheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
+	if len(seed) != sch.SeedSize() {
+		panic(kem.ErrSeedSize)
+	}
+	h := xof.SHAKE256.New()
+	_, _ = h.Write(seed)
+	key, x, y, err := elliptic.GenerateKey(sch.curve, h)
+	if err != nil {
+		panic(err)
+	}
+
+	sk := cPrivateKey{scheme: sch, key: key}
+	pk := cPublicKey{scheme: sch, x: x, y: y}
+
+	return &pk, &sk
+}
+
+func (sch *cScheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) {
+	seed := make([]byte, sch.EncapsulationSeedSize())
+	_, err = cryptoRand.Read(seed)
+	if err != nil {
+		return
+	}
+	return sch.EncapsulateDeterministically(pk, seed)
+}
+
+func (pk *cPublicKey) X(sk *cPrivateKey) []byte {
+	if pk.scheme != sk.scheme {
+		panic(kem.ErrTypeMismatch)
+	}
+
+	sharedKey := make([]byte, pk.scheme.SharedKeySize())
+	xShared, _ := pk.scheme.curve.ScalarMult(pk.x, pk.y, sk.key)
+	xShared.FillBytes(sharedKey)
+	return sharedKey
+}
+
+func (sch *cScheme) EncapsulateDeterministically(
+	pk kem.PublicKey, seed []byte,
+) (ct, ss []byte, err error) {
+	if len(seed) != sch.EncapsulationSeedSize() {
+		return nil, nil, kem.ErrSeedSize
+	}
+	pub, ok := pk.(*cPublicKey)
+	if !ok || pub.scheme != sch {
+		return nil, nil, kem.ErrTypeMismatch
+	}
+
+	pk2, sk2 := sch.DeriveKeyPair(seed)
+	ss = pub.X(sk2.(*cPrivateKey))
+	ct, _ = pk2.MarshalBinary()
+	return
+}
+
+func (sch *cScheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
+	if len(ct) != sch.CiphertextSize() {
+		return nil, kem.ErrCiphertextSize
+	}
+
+	priv, ok := sk.(*cPrivateKey)
+	if !ok || priv.scheme != sch {
+		return nil, kem.ErrTypeMismatch
+	}
+
+	pk, err := sch.UnmarshalBinaryPublicKey(ct)
+	if err != nil {
+		return nil, err
+	}
+
+	ss := pk.(*cPublicKey).X(priv)
+	return ss, nil
+}
+
+func (sch *cScheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
+	if len(buf) != sch.PublicKeySize() {
+		return nil, kem.ErrPubKeySize
+	}
+	x, y := elliptic.Unmarshal(sch.curve, buf)
+	return &cPublicKey{sch, x, y}, nil
+}
+
+func (sch *cScheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
+	if len(buf) != sch.PrivateKeySize() {
+		return nil, kem.ErrPrivKeySize
+	}
+	ret := cPrivateKey{sch, make([]byte, sch.PrivateKeySize())}
+	copy(ret.key, buf)
+	return &ret, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/kem/hybrid/hybrid.go b/vendor/github.com/cloudflare/circl/kem/hybrid/hybrid.go
new file mode 100644
index 00000000..be8251c7
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/kem/hybrid/hybrid.go
@@ -0,0 +1,344 @@
+// Package hybrid defines several hybrid classical/quantum KEMs.
+//
+// KEMs are combined by simple concatenation of shared secrets, cipher texts,
+// public keys, etc, see
+//
+//	https://datatracker.ietf.org/doc/draft-ietf-tls-hybrid-design/
+//	https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Cr2.pdf
+//
+// Note that this is only fine if the shared secret is used in its entirety
+// in a next step, such as being hashed or used as key.
+//
+// For deriving a KEM keypair deterministically and encapsulating
+// deterministically, we expand a single seed to both using SHAKE256,
+// so that a non-uniform seed (such as a shared secret generated by a hybrid
+// KEM where one of the KEMs is weak) doesn't impact just one of the KEMs.
+//
+// Of our XOF (SHAKE256), we desire two security properties:
+//
+//  1. The internal state of the XOF should be big enough so that we
+//     do not loose entropy.
+//  2. From one of the new seeds, we shouldn't be able to derive
+//     the other or the original seed.
+//
+// SHAKE256, and all siblings in the SHA3 family, have a 200B internal
+// state, so (1) is fine if our seeds are less than 200B.
+// If SHAKE256 is computationally indistinguishable from a random
+// sponge, then it affords us 256b security against (2) by the
+// flat sponge claim [https://keccak.team/files/SpongeFunctions.pdf].
+// None of the implemented schemes claim more than 256b security
+// and so SHAKE256 will do fine.
+package hybrid
+
+import (
+	"errors"
+
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/kem"
+	"github.com/cloudflare/circl/kem/kyber/kyber1024"
+	"github.com/cloudflare/circl/kem/kyber/kyber512"
+	"github.com/cloudflare/circl/kem/kyber/kyber768"
+)
+
+var ErrUninitialized = errors.New("public or private key not initialized")
+
+// Returns the hybrid KEM of Kyber512Draft00 and X25519.
+func Kyber512X25519() kem.Scheme { return kyber512X }
+
+// Returns the hybrid KEM of Kyber768Draft00 and X25519.
+func Kyber768X25519() kem.Scheme { return kyber768X }
+
+// Returns the hybrid KEM of Kyber768Draft00 and X448.
+func Kyber768X448() kem.Scheme { return kyber768X4 }
+
+// Returns the hybrid KEM of Kyber1024Draft00 and X448.
+func Kyber1024X448() kem.Scheme { return kyber1024X }
+
+// Returns the hybrid KEM of Kyber768Draft00 and P-256.
+func P256Kyber768Draft00() kem.Scheme { return p256Kyber768Draft00 }
+
+var p256Kyber768Draft00 kem.Scheme = &scheme{
+	"P256Kyber768Draft00",
+	p256Kem,
+	kyber768.Scheme(),
+}
+
+var kyber512X kem.Scheme = &scheme{
+	"Kyber512-X25519",
+	x25519Kem,
+	kyber512.Scheme(),
+}
+
+var kyber768X kem.Scheme = &scheme{
+	"Kyber768-X25519",
+	x25519Kem,
+	kyber768.Scheme(),
+}
+
+var kyber768X4 kem.Scheme = &scheme{
+	"Kyber768-X448",
+	x448Kem,
+	kyber768.Scheme(),
+}
+
+var kyber1024X kem.Scheme = &scheme{
+	"Kyber1024-X448",
+	x448Kem,
+	kyber1024.Scheme(),
+}
+
+// Public key of a hybrid KEM.
+type publicKey struct {
+	scheme *scheme
+	first  kem.PublicKey
+	second kem.PublicKey
+}
+
+// Private key of a hybrid KEM.
+type privateKey struct {
+	scheme *scheme
+	first  kem.PrivateKey
+	second kem.PrivateKey
+}
+
+// Scheme for a hybrid KEM.
+type scheme struct {
+	name   string
+	first  kem.Scheme
+	second kem.Scheme
+}
+
+func (sch *scheme) Name() string { return sch.name }
+func (sch *scheme) PublicKeySize() int {
+	return sch.first.PublicKeySize() + sch.second.PublicKeySize()
+}
+
+func (sch *scheme) PrivateKeySize() int {
+	return sch.first.PrivateKeySize() + sch.second.PrivateKeySize()
+}
+
+func (sch *scheme) SeedSize() int {
+	first := sch.first.SeedSize()
+	second := sch.second.SeedSize()
+	ret := second
+	if first > second {
+		ret = first
+	}
+	return ret
+}
+
+func (sch *scheme) SharedKeySize() int {
+	return sch.first.SharedKeySize() + sch.second.SharedKeySize()
+}
+
+func (sch *scheme) CiphertextSize() int {
+	return sch.first.CiphertextSize() + sch.second.CiphertextSize()
+}
+
+func (sch *scheme) EncapsulationSeedSize() int {
+	first := sch.first.EncapsulationSeedSize()
+	second := sch.second.EncapsulationSeedSize()
+	ret := second
+	if first > second {
+		ret = first
+	}
+	return ret
+}
+
+func (sk *privateKey) Scheme() kem.Scheme { return sk.scheme }
+func (pk *publicKey) Scheme() kem.Scheme  { return pk.scheme }
+
+func (sk *privateKey) MarshalBinary() ([]byte, error) {
+	if sk.first == nil || sk.second == nil {
+		return nil, ErrUninitialized
+	}
+	first, err := sk.first.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+	second, err := sk.second.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+	return append(first, second...), nil
+}
+
+func (sk *privateKey) Equal(other kem.PrivateKey) bool {
+	oth, ok := other.(*privateKey)
+	if !ok {
+		return false
+	}
+	if sk.first == nil && sk.second == nil && oth.first == nil && oth.second == nil {
+		return true
+	}
+	if sk.first == nil || sk.second == nil || oth.first == nil || oth.second == nil {
+		return false
+	}
+	return sk.first.Equal(oth.first) && sk.second.Equal(oth.second)
+}
+
+func (sk *privateKey) Public() kem.PublicKey {
+	return &publicKey{sk.scheme, sk.first.Public(), sk.second.Public()}
+}
+
+func (pk *publicKey) Equal(other kem.PublicKey) bool {
+	oth, ok := other.(*publicKey)
+	if !ok {
+		return false
+	}
+	if pk.first == nil && pk.second == nil && oth.first == nil && oth.second == nil {
+		return true
+	}
+	if pk.first == nil || pk.second == nil || oth.first == nil || oth.second == nil {
+		return false
+	}
+	return pk.first.Equal(oth.first) && pk.second.Equal(oth.second)
+}
+
+func (pk *publicKey) MarshalBinary() ([]byte, error) {
+	if pk.first == nil || pk.second == nil {
+		return nil, ErrUninitialized
+	}
+	first, err := pk.first.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+	second, err := pk.second.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+	return append(first, second...), nil
+}
+
+func (sch *scheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
+	pk1, sk1, err := sch.first.GenerateKeyPair()
+	if err != nil {
+		return nil, nil, err
+	}
+	pk2, sk2, err := sch.second.GenerateKeyPair()
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return &publicKey{sch, pk1, pk2}, &privateKey{sch, sk1, sk2}, nil
+}
+
+func (sch *scheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
+	if len(seed) != sch.SeedSize() {
+		panic(kem.ErrSeedSize)
+	}
+	h := sha3.NewShake256()
+	_, _ = h.Write(seed)
+	first := make([]byte, sch.first.SeedSize())
+	second := make([]byte, sch.second.SeedSize())
+	_, _ = h.Read(first)
+	_, _ = h.Read(second)
+
+	pk1, sk1 := sch.first.DeriveKeyPair(first)
+	pk2, sk2 := sch.second.DeriveKeyPair(second)
+
+	return &publicKey{sch, pk1, pk2}, &privateKey{sch, sk1, sk2}
+}
+
+func (sch *scheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) {
+	pub, ok := pk.(*publicKey)
+	if !ok {
+		return nil, nil, kem.ErrTypeMismatch
+	}
+
+	ct1, ss1, err := sch.first.Encapsulate(pub.first)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	ct2, ss2, err := sch.second.Encapsulate(pub.second)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return append(ct1, ct2...), append(ss1, ss2...), nil
+}
+
+func (sch *scheme) EncapsulateDeterministically(
+	pk kem.PublicKey, seed []byte,
+) (ct, ss []byte, err error) {
+	if len(seed) != sch.EncapsulationSeedSize() {
+		return nil, nil, kem.ErrSeedSize
+	}
+
+	h := sha3.NewShake256()
+	_, _ = h.Write(seed)
+	first := make([]byte, sch.first.EncapsulationSeedSize())
+	second := make([]byte, sch.second.EncapsulationSeedSize())
+	_, _ = h.Read(first)
+	_, _ = h.Read(second)
+
+	pub, ok := pk.(*publicKey)
+	if !ok {
+		return nil, nil, kem.ErrTypeMismatch
+	}
+
+	ct1, ss1, err := sch.first.EncapsulateDeterministically(pub.first, first)
+	if err != nil {
+		return nil, nil, err
+	}
+	ct2, ss2, err := sch.second.EncapsulateDeterministically(pub.second, second)
+	if err != nil {
+		return nil, nil, err
+	}
+	return append(ct1, ct2...), append(ss1, ss2...), nil
+}
+
+func (sch *scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
+	if len(ct) != sch.CiphertextSize() {
+		return nil, kem.ErrCiphertextSize
+	}
+
+	priv, ok := sk.(*privateKey)
+	if !ok {
+		return nil, kem.ErrTypeMismatch
+	}
+
+	firstSize := sch.first.CiphertextSize()
+	ss1, err := sch.first.Decapsulate(priv.first, ct[:firstSize])
+	if err != nil {
+		return nil, err
+	}
+	ss2, err := sch.second.Decapsulate(priv.second, ct[firstSize:])
+	if err != nil {
+		return nil, err
+	}
+	return append(ss1, ss2...), nil
+}
+
+func (sch *scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
+	if len(buf) != sch.PublicKeySize() {
+		return nil, kem.ErrPubKeySize
+	}
+	firstSize := sch.first.PublicKeySize()
+	pk1, err := sch.first.UnmarshalBinaryPublicKey(buf[:firstSize])
+	if err != nil {
+		return nil, err
+	}
+	pk2, err := sch.second.UnmarshalBinaryPublicKey(buf[firstSize:])
+	if err != nil {
+		return nil, err
+	}
+	return &publicKey{sch, pk1, pk2}, nil
+}
+
+func (sch *scheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
+	if len(buf) != sch.PrivateKeySize() {
+		return nil, kem.ErrPrivKeySize
+	}
+	firstSize := sch.first.PrivateKeySize()
+	sk1, err := sch.first.UnmarshalBinaryPrivateKey(buf[:firstSize])
+	if err != nil {
+		return nil, err
+	}
+	sk2, err := sch.second.UnmarshalBinaryPrivateKey(buf[firstSize:])
+	if err != nil {
+		return nil, err
+	}
+	return &privateKey{sch, sk1, sk2}, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/kem/hybrid/xkem.go b/vendor/github.com/cloudflare/circl/kem/hybrid/xkem.go
new file mode 100644
index 00000000..919fb8a9
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/kem/hybrid/xkem.go
@@ -0,0 +1,208 @@
+package hybrid
+
+import (
+	"bytes"
+	cryptoRand "crypto/rand"
+	"crypto/subtle"
+
+	"github.com/cloudflare/circl/dh/x25519"
+	"github.com/cloudflare/circl/dh/x448"
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/kem"
+)
+
+type xPublicKey struct {
+	scheme *xScheme
+	key    []byte
+}
+type xPrivateKey struct {
+	scheme *xScheme
+	key    []byte
+}
+type xScheme struct {
+	size int
+}
+
+var (
+	x25519Kem = &xScheme{x25519.Size}
+	x448Kem   = &xScheme{x448.Size}
+)
+
+func (sch *xScheme) Name() string {
+	switch sch.size {
+	case x25519.Size:
+		return "X25519"
+	case x448.Size:
+		return "X448"
+	}
+	panic(kem.ErrTypeMismatch)
+}
+
+func (sch *xScheme) PublicKeySize() int         { return sch.size }
+func (sch *xScheme) PrivateKeySize() int        { return sch.size }
+func (sch *xScheme) SeedSize() int              { return sch.size }
+func (sch *xScheme) SharedKeySize() int         { return sch.size }
+func (sch *xScheme) CiphertextSize() int        { return sch.size }
+func (sch *xScheme) EncapsulationSeedSize() int { return sch.size }
+
+func (sk *xPrivateKey) Scheme() kem.Scheme { return sk.scheme }
+func (pk *xPublicKey) Scheme() kem.Scheme  { return pk.scheme }
+
+func (sk *xPrivateKey) MarshalBinary() ([]byte, error) {
+	ret := make([]byte, len(sk.key))
+	copy(ret, sk.key)
+	return ret, nil
+}
+
+func (sk *xPrivateKey) Equal(other kem.PrivateKey) bool {
+	oth, ok := other.(*xPrivateKey)
+	if !ok {
+		return false
+	}
+	if oth.scheme != sk.scheme {
+		return false
+	}
+	return subtle.ConstantTimeCompare(oth.key, sk.key) == 1
+}
+
+func (sk *xPrivateKey) Public() kem.PublicKey {
+	pk := xPublicKey{sk.scheme, make([]byte, sk.scheme.size)}
+	switch sk.scheme.size {
+	case x25519.Size:
+		var sk2, pk2 x25519.Key
+		copy(sk2[:], sk.key)
+		x25519.KeyGen(&pk2, &sk2)
+		copy(pk.key, pk2[:])
+	case x448.Size:
+		var sk2, pk2 x448.Key
+		copy(sk2[:], sk.key)
+		x448.KeyGen(&pk2, &sk2)
+		copy(pk.key, pk2[:])
+	}
+	return &pk
+}
+
+func (pk *xPublicKey) Equal(other kem.PublicKey) bool {
+	oth, ok := other.(*xPublicKey)
+	if !ok {
+		return false
+	}
+	if oth.scheme != pk.scheme {
+		return false
+	}
+	return bytes.Equal(oth.key, pk.key)
+}
+
+func (pk *xPublicKey) MarshalBinary() ([]byte, error) {
+	ret := make([]byte, pk.scheme.size)
+	copy(ret, pk.key)
+	return ret, nil
+}
+
+func (sch *xScheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
+	seed := make([]byte, sch.SeedSize())
+	_, err := cryptoRand.Read(seed)
+	if err != nil {
+		return nil, nil, err
+	}
+	pk, sk := sch.DeriveKeyPair(seed)
+	return pk, sk, nil
+}
+
+func (sch *xScheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
+	if len(seed) != sch.SeedSize() {
+		panic(kem.ErrSeedSize)
+	}
+	sk := xPrivateKey{scheme: sch, key: make([]byte, sch.size)}
+
+	h := sha3.NewShake256()
+	_, _ = h.Write(seed)
+	_, _ = h.Read(sk.key)
+
+	return sk.Public(), &sk
+}
+
+func (sch *xScheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) {
+	seed := make([]byte, sch.EncapsulationSeedSize())
+	_, err = cryptoRand.Read(seed)
+	if err != nil {
+		return
+	}
+	return sch.EncapsulateDeterministically(pk, seed)
+}
+
+func (pk *xPublicKey) X(sk *xPrivateKey) []byte {
+	if pk.scheme != sk.scheme {
+		panic(kem.ErrTypeMismatch)
+	}
+
+	switch pk.scheme.size {
+	case x25519.Size:
+		var ss2, pk2, sk2 x25519.Key
+		copy(pk2[:], pk.key)
+		copy(sk2[:], sk.key)
+		x25519.Shared(&ss2, &sk2, &pk2)
+		return ss2[:]
+	case x448.Size:
+		var ss2, pk2, sk2 x448.Key
+		copy(pk2[:], pk.key)
+		copy(sk2[:], sk.key)
+		x448.Shared(&ss2, &sk2, &pk2)
+		return ss2[:]
+	}
+	panic(kem.ErrTypeMismatch)
+}
+
+func (sch *xScheme) EncapsulateDeterministically(
+	pk kem.PublicKey, seed []byte,
+) (ct, ss []byte, err error) {
+	if len(seed) != sch.EncapsulationSeedSize() {
+		return nil, nil, kem.ErrSeedSize
+	}
+	pub, ok := pk.(*xPublicKey)
+	if !ok || pub.scheme != sch {
+		return nil, nil, kem.ErrTypeMismatch
+	}
+
+	pk2, sk2 := sch.DeriveKeyPair(seed)
+	ss = pub.X(sk2.(*xPrivateKey))
+	ct, _ = pk2.MarshalBinary()
+	return
+}
+
+func (sch *xScheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
+	if len(ct) != sch.CiphertextSize() {
+		return nil, kem.ErrCiphertextSize
+	}
+
+	priv, ok := sk.(*xPrivateKey)
+	if !ok || priv.scheme != sch {
+		return nil, kem.ErrTypeMismatch
+	}
+
+	pk, err := sch.UnmarshalBinaryPublicKey(ct)
+	if err != nil {
+		return nil, err
+	}
+
+	ss := pk.(*xPublicKey).X(priv)
+	return ss, nil
+}
+
+func (sch *xScheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
+	if len(buf) != sch.PublicKeySize() {
+		return nil, kem.ErrPubKeySize
+	}
+	ret := xPublicKey{sch, make([]byte, sch.size)}
+	copy(ret.key, buf)
+	return &ret, nil
+}
+
+func (sch *xScheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
+	if len(buf) != sch.PrivateKeySize() {
+		return nil, kem.ErrPrivKeySize
+	}
+	ret := xPrivateKey{sch, make([]byte, sch.size)}
+	copy(ret.key, buf)
+	return &ret, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/kem/kem.go b/vendor/github.com/cloudflare/circl/kem/kem.go
new file mode 100644
index 00000000..6ab0aa3b
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/kem/kem.go
@@ -0,0 +1,118 @@
+// Package kem provides a unified interface for KEM schemes.
+//
+// A register of schemes is available in the package
+//
+//	github.com/cloudflare/circl/kem/schemes
+package kem
+
+import (
+	"encoding"
+	"errors"
+)
+
+// A KEM public key
+type PublicKey interface {
+	// Returns the scheme for this public key
+	Scheme() Scheme
+
+	encoding.BinaryMarshaler
+	Equal(PublicKey) bool
+}
+
+// A KEM private key
+type PrivateKey interface {
+	// Returns the scheme for this private key
+	Scheme() Scheme
+
+	encoding.BinaryMarshaler
+	Equal(PrivateKey) bool
+	Public() PublicKey
+}
+
+// A Scheme represents a specific instance of a KEM.
+type Scheme interface {
+	// Name of the scheme
+	Name() string
+
+	// GenerateKeyPair creates a new key pair.
+	GenerateKeyPair() (PublicKey, PrivateKey, error)
+
+	// Encapsulate generates a shared key ss for the public key and
+	// encapsulates it into a ciphertext ct.
+	Encapsulate(pk PublicKey) (ct, ss []byte, err error)
+
+	// Returns the shared key encapsulated in ciphertext ct for the
+	// private key sk.
+	Decapsulate(sk PrivateKey, ct []byte) ([]byte, error)
+
+	// Unmarshals a PublicKey from the provided buffer.
+	UnmarshalBinaryPublicKey([]byte) (PublicKey, error)
+
+	// Unmarshals a PrivateKey from the provided buffer.
+	UnmarshalBinaryPrivateKey([]byte) (PrivateKey, error)
+
+	// Size of encapsulated keys.
+	CiphertextSize() int
+
+	// Size of established shared keys.
+	SharedKeySize() int
+
+	// Size of packed private keys.
+	PrivateKeySize() int
+
+	// Size of packed public keys.
+	PublicKeySize() int
+
+	// DeriveKeyPair deterministically derives a pair of keys from a seed.
+	// Panics if the length of seed is not equal to the value returned by
+	// SeedSize.
+	DeriveKeyPair(seed []byte) (PublicKey, PrivateKey)
+
+	// Size of seed used in DeriveKey
+	SeedSize() int
+
+	// EncapsulateDeterministically generates a shared key ss for the public
+	// key deterministically from the given seed and encapsulates it into
+	// a ciphertext ct. If unsure, you're better off using Encapsulate().
+	EncapsulateDeterministically(pk PublicKey, seed []byte) (
+		ct, ss []byte, err error)
+
+	// Size of seed used in EncapsulateDeterministically().
+	EncapsulationSeedSize() int
+}
+
+// AuthScheme represents a KEM that supports authenticated key encapsulation.
+type AuthScheme interface {
+	Scheme
+	AuthEncapsulate(pkr PublicKey, sks PrivateKey) (ct, ss []byte, err error)
+	AuthEncapsulateDeterministically(pkr PublicKey, sks PrivateKey, seed []byte) (ct, ss []byte, err error)
+	AuthDecapsulate(skr PrivateKey, ct []byte, pks PublicKey) ([]byte, error)
+}
+
+var (
+	// ErrTypeMismatch is the error used if types of, for instance, private
+	// and public keys don't match
+	ErrTypeMismatch = errors.New("types mismatch")
+
+	// ErrSeedSize is the error used if the provided seed is of the wrong
+	// size.
+	ErrSeedSize = errors.New("wrong seed size")
+
+	// ErrPubKeySize is the error used if the provided public key is of
+	// the wrong size.
+	ErrPubKeySize = errors.New("wrong size for public key")
+
+	// ErrCiphertextSize is the error used if the provided ciphertext
+	// is of the wrong size.
+	ErrCiphertextSize = errors.New("wrong size for ciphertext")
+
+	// ErrPrivKeySize is the error used if the provided private key is of
+	// the wrong size.
+	ErrPrivKeySize = errors.New("wrong size for private key")
+
+	// ErrPubKey is the error used if the provided public key is invalid.
+	ErrPubKey = errors.New("invalid public key")
+
+	// ErrCipherText is the error used if the provided ciphertext is invalid.
+	ErrCipherText = errors.New("invalid ciphertext")
+)
diff --git a/vendor/github.com/cloudflare/circl/kem/kyber/kyber1024/kyber.go b/vendor/github.com/cloudflare/circl/kem/kyber/kyber1024/kyber.go
new file mode 100644
index 00000000..42858452
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/kem/kyber/kyber1024/kyber.go
@@ -0,0 +1,404 @@
+// Code generated from pkg.templ.go. DO NOT EDIT.
+
+// Package kyber1024 implements the IND-CCA2 secure key encapsulation mechanism
+// Kyber1024.CCAKEM as submitted to round 3 of the NIST PQC competition and
+// described in
+//
+// https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
+package kyber1024
+
+import (
+	"bytes"
+	"crypto/subtle"
+	"io"
+
+	cryptoRand "crypto/rand"
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/kem"
+	cpapke "github.com/cloudflare/circl/pke/kyber/kyber1024"
+)
+
+const (
+	// Size of seed for NewKeyFromSeed
+	KeySeedSize = cpapke.KeySeedSize + 32
+
+	// Size of seed for EncapsulateTo.
+	EncapsulationSeedSize = 32
+
+	// Size of the established shared key.
+	SharedKeySize = 32
+
+	// Size of the encapsulated shared key.
+	CiphertextSize = cpapke.CiphertextSize
+
+	// Size of a packed public key.
+	PublicKeySize = cpapke.PublicKeySize
+
+	// Size of a packed private key.
+	PrivateKeySize = cpapke.PrivateKeySize + cpapke.PublicKeySize + 64
+)
+
+// Type of a Kyber1024.CCAKEM public key
+type PublicKey struct {
+	pk *cpapke.PublicKey
+
+	hpk [32]byte // H(pk)
+}
+
+// Type of a Kyber1024.CCAKEM private key
+type PrivateKey struct {
+	sk  *cpapke.PrivateKey
+	pk  *cpapke.PublicKey
+	hpk [32]byte // H(pk)
+	z   [32]byte
+}
+
+// NewKeyFromSeed derives a public/private keypair deterministically
+// from the given seed.
+//
+// Panics if seed is not of length KeySeedSize.
+func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
+	var sk PrivateKey
+	var pk PublicKey
+
+	if len(seed) != KeySeedSize {
+		panic("seed must be of length KeySeedSize")
+	}
+
+	pk.pk, sk.sk = cpapke.NewKeyFromSeed(seed[:cpapke.KeySeedSize])
+	sk.pk = pk.pk
+	copy(sk.z[:], seed[cpapke.KeySeedSize:])
+
+	// Compute H(pk)
+	var ppk [cpapke.PublicKeySize]byte
+	sk.pk.Pack(ppk[:])
+	h := sha3.New256()
+	h.Write(ppk[:])
+	h.Read(sk.hpk[:])
+	copy(pk.hpk[:], sk.hpk[:])
+
+	return &pk, &sk
+}
+
+// GenerateKeyPair generates public and private keys using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKeyPair(rand io.Reader) (*PublicKey, *PrivateKey, error) {
+	var seed [KeySeedSize]byte
+	if rand == nil {
+		rand = cryptoRand.Reader
+	}
+	_, err := io.ReadFull(rand, seed[:])
+	if err != nil {
+		return nil, nil, err
+	}
+	pk, sk := NewKeyFromSeed(seed[:])
+	return pk, sk, nil
+}
+
+// EncapsulateTo generates a shared key and ciphertext that contains it
+// for the public key using randomness from seed and writes the shared key
+// to ss and ciphertext to ct.
+//
+// Panics if ss, ct or seed are not of length SharedKeySize, CiphertextSize
+// and EncapsulationSeedSize respectively.
+//
+// seed may be nil, in which case crypto/rand.Reader is used to generate one.
+func (pk *PublicKey) EncapsulateTo(ct, ss []byte, seed []byte) {
+	if seed == nil {
+		seed = make([]byte, EncapsulationSeedSize)
+		if _, err := cryptoRand.Read(seed[:]); err != nil {
+			panic(err)
+		}
+	} else {
+		if len(seed) != EncapsulationSeedSize {
+			panic("seed must be of length EncapsulationSeedSize")
+		}
+	}
+
+	if len(ct) != CiphertextSize {
+		panic("ct must be of length CiphertextSize")
+	}
+
+	if len(ss) != SharedKeySize {
+		panic("ss must be of length SharedKeySize")
+	}
+
+	// m = H(seed)
+	var m [32]byte
+	h := sha3.New256()
+	h.Write(seed[:])
+	h.Read(m[:])
+
+	// (K', r) = G(m ‖ H(pk))
+	var kr [64]byte
+	g := sha3.New512()
+	g.Write(m[:])
+	g.Write(pk.hpk[:])
+	g.Read(kr[:])
+
+	// c = Kyber.CPAPKE.Enc(pk, m, r)
+	pk.pk.EncryptTo(ct, m[:], kr[32:])
+
+	// Compute H(c) and put in second slot of kr, which will be (K', H(c)).
+	h.Reset()
+	h.Write(ct[:CiphertextSize])
+	h.Read(kr[32:])
+
+	// K = KDF(K' ‖ H(c))
+	kdf := sha3.NewShake256()
+	kdf.Write(kr[:])
+	kdf.Read(ss[:SharedKeySize])
+}
+
+// DecapsulateTo computes the shared key which is encapsulated in ct
+// for the private key.
+//
+// Panics if ct or ss are not of length CiphertextSize and SharedKeySize
+// respectively.
+func (sk *PrivateKey) DecapsulateTo(ss, ct []byte) {
+	if len(ct) != CiphertextSize {
+		panic("ct must be of length CiphertextSize")
+	}
+
+	if len(ss) != SharedKeySize {
+		panic("ss must be of length SharedKeySize")
+	}
+
+	// m' = Kyber.CPAPKE.Dec(sk, ct)
+	var m2 [32]byte
+	sk.sk.DecryptTo(m2[:], ct)
+
+	// (K'', r') = G(m' ‖ H(pk))
+	var kr2 [64]byte
+	g := sha3.New512()
+	g.Write(m2[:])
+	g.Write(sk.hpk[:])
+	g.Read(kr2[:])
+
+	// c' = Kyber.CPAPKE.Enc(pk, m', r')
+	var ct2 [CiphertextSize]byte
+	sk.pk.EncryptTo(ct2[:], m2[:], kr2[32:])
+
+	// Compute H(c) and put in second slot of kr2, which will be (K'', H(c)).
+	h := sha3.New256()
+	h.Write(ct[:CiphertextSize])
+	h.Read(kr2[32:])
+
+	// Replace K'' by  z in the first slot of kr2 if c ≠ c'.
+	subtle.ConstantTimeCopy(
+		1-subtle.ConstantTimeCompare(ct, ct2[:]),
+		kr2[:32],
+		sk.z[:],
+	)
+
+	// K = KDF(K''/z, H(c))
+	kdf := sha3.NewShake256()
+	kdf.Write(kr2[:])
+	kdf.Read(ss[:SharedKeySize])
+}
+
+// Packs sk to buf.
+//
+// Panics if buf is not of size PrivateKeySize.
+func (sk *PrivateKey) Pack(buf []byte) {
+	if len(buf) != PrivateKeySize {
+		panic("buf must be of length PrivateKeySize")
+	}
+
+	sk.sk.Pack(buf[:cpapke.PrivateKeySize])
+	buf = buf[cpapke.PrivateKeySize:]
+	sk.pk.Pack(buf[:cpapke.PublicKeySize])
+	buf = buf[cpapke.PublicKeySize:]
+	copy(buf, sk.hpk[:])
+	buf = buf[32:]
+	copy(buf, sk.z[:])
+}
+
+// Unpacks sk from buf.
+//
+// Panics if buf is not of size PrivateKeySize.
+func (sk *PrivateKey) Unpack(buf []byte) {
+	if len(buf) != PrivateKeySize {
+		panic("buf must be of length PrivateKeySize")
+	}
+
+	sk.sk = new(cpapke.PrivateKey)
+	sk.sk.Unpack(buf[:cpapke.PrivateKeySize])
+	buf = buf[cpapke.PrivateKeySize:]
+	sk.pk = new(cpapke.PublicKey)
+	sk.pk.Unpack(buf[:cpapke.PublicKeySize])
+	buf = buf[cpapke.PublicKeySize:]
+	copy(sk.hpk[:], buf[:32])
+	copy(sk.z[:], buf[32:])
+}
+
+// Packs pk to buf.
+//
+// Panics if buf is not of size PublicKeySize.
+func (pk *PublicKey) Pack(buf []byte) {
+	if len(buf) != PublicKeySize {
+		panic("buf must be of length PublicKeySize")
+	}
+
+	pk.pk.Pack(buf)
+}
+
+// Unpacks pk from buf.
+//
+// Panics if buf is not of size PublicKeySize.
+func (pk *PublicKey) Unpack(buf []byte) {
+	if len(buf) != PublicKeySize {
+		panic("buf must be of length PublicKeySize")
+	}
+
+	pk.pk = new(cpapke.PublicKey)
+	pk.pk.Unpack(buf)
+
+	// Compute cached H(pk)
+	h := sha3.New256()
+	h.Write(buf)
+	h.Read(pk.hpk[:])
+}
+
+// Boilerplate down below for the KEM scheme API.
+
+type scheme struct{}
+
+var sch kem.Scheme = &scheme{}
+
+// Scheme returns a KEM interface.
+func Scheme() kem.Scheme { return sch }
+
+func (*scheme) Name() string               { return "Kyber1024" }
+func (*scheme) PublicKeySize() int         { return PublicKeySize }
+func (*scheme) PrivateKeySize() int        { return PrivateKeySize }
+func (*scheme) SeedSize() int              { return KeySeedSize }
+func (*scheme) SharedKeySize() int         { return SharedKeySize }
+func (*scheme) CiphertextSize() int        { return CiphertextSize }
+func (*scheme) EncapsulationSeedSize() int { return EncapsulationSeedSize }
+
+func (sk *PrivateKey) Scheme() kem.Scheme { return sch }
+func (pk *PublicKey) Scheme() kem.Scheme  { return sch }
+
+func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
+	var ret [PrivateKeySize]byte
+	sk.Pack(ret[:])
+	return ret[:], nil
+}
+
+func (sk *PrivateKey) Equal(other kem.PrivateKey) bool {
+	oth, ok := other.(*PrivateKey)
+	if !ok {
+		return false
+	}
+	if sk.pk == nil && oth.pk == nil {
+		return true
+	}
+	if sk.pk == nil || oth.pk == nil {
+		return false
+	}
+	if !bytes.Equal(sk.hpk[:], oth.hpk[:]) ||
+		subtle.ConstantTimeCompare(sk.z[:], oth.z[:]) != 1 {
+		return false
+	}
+	return sk.sk.Equal(oth.sk)
+}
+
+func (pk *PublicKey) Equal(other kem.PublicKey) bool {
+	oth, ok := other.(*PublicKey)
+	if !ok {
+		return false
+	}
+	if pk.pk == nil && oth.pk == nil {
+		return true
+	}
+	if pk.pk == nil || oth.pk == nil {
+		return false
+	}
+	return bytes.Equal(pk.hpk[:], oth.hpk[:])
+}
+
+func (sk *PrivateKey) Public() kem.PublicKey {
+	pk := new(PublicKey)
+	pk.pk = sk.pk
+	copy(pk.hpk[:], sk.hpk[:])
+	return pk
+}
+
+func (pk *PublicKey) MarshalBinary() ([]byte, error) {
+	var ret [PublicKeySize]byte
+	pk.Pack(ret[:])
+	return ret[:], nil
+}
+
+func (*scheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
+	return GenerateKeyPair(cryptoRand.Reader)
+}
+
+func (*scheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
+	if len(seed) != KeySeedSize {
+		panic(kem.ErrSeedSize)
+	}
+	return NewKeyFromSeed(seed[:])
+}
+
+func (*scheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) {
+	ct = make([]byte, CiphertextSize)
+	ss = make([]byte, SharedKeySize)
+
+	pub, ok := pk.(*PublicKey)
+	if !ok {
+		return nil, nil, kem.ErrTypeMismatch
+	}
+	pub.EncapsulateTo(ct, ss, nil)
+	return
+}
+
+func (*scheme) EncapsulateDeterministically(pk kem.PublicKey, seed []byte) (
+	ct, ss []byte, err error) {
+	if len(seed) != EncapsulationSeedSize {
+		return nil, nil, kem.ErrSeedSize
+	}
+
+	ct = make([]byte, CiphertextSize)
+	ss = make([]byte, SharedKeySize)
+
+	pub, ok := pk.(*PublicKey)
+	if !ok {
+		return nil, nil, kem.ErrTypeMismatch
+	}
+	pub.EncapsulateTo(ct, ss, seed)
+	return
+}
+
+func (*scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
+	if len(ct) != CiphertextSize {
+		return nil, kem.ErrCiphertextSize
+	}
+
+	priv, ok := sk.(*PrivateKey)
+	if !ok {
+		return nil, kem.ErrTypeMismatch
+	}
+	ss := make([]byte, SharedKeySize)
+	priv.DecapsulateTo(ss, ct)
+	return ss, nil
+}
+
+func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
+	if len(buf) != PublicKeySize {
+		return nil, kem.ErrPubKeySize
+	}
+	var ret PublicKey
+	ret.Unpack(buf)
+	return &ret, nil
+}
+
+func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
+	if len(buf) != PrivateKeySize {
+		return nil, kem.ErrPrivKeySize
+	}
+	var ret PrivateKey
+	ret.Unpack(buf)
+	return &ret, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/kem/kyber/kyber512/kyber.go b/vendor/github.com/cloudflare/circl/kem/kyber/kyber512/kyber.go
new file mode 100644
index 00000000..c250d78c
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/kem/kyber/kyber512/kyber.go
@@ -0,0 +1,404 @@
+// Code generated from pkg.templ.go. DO NOT EDIT.
+
+// Package kyber512 implements the IND-CCA2 secure key encapsulation mechanism
+// Kyber512.CCAKEM as submitted to round 3 of the NIST PQC competition and
+// described in
+//
+// https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
+package kyber512
+
+import (
+	"bytes"
+	"crypto/subtle"
+	"io"
+
+	cryptoRand "crypto/rand"
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/kem"
+	cpapke "github.com/cloudflare/circl/pke/kyber/kyber512"
+)
+
+const (
+	// Size of seed for NewKeyFromSeed
+	KeySeedSize = cpapke.KeySeedSize + 32
+
+	// Size of seed for EncapsulateTo.
+	EncapsulationSeedSize = 32
+
+	// Size of the established shared key.
+	SharedKeySize = 32
+
+	// Size of the encapsulated shared key.
+	CiphertextSize = cpapke.CiphertextSize
+
+	// Size of a packed public key.
+	PublicKeySize = cpapke.PublicKeySize
+
+	// Size of a packed private key.
+	PrivateKeySize = cpapke.PrivateKeySize + cpapke.PublicKeySize + 64
+)
+
+// Type of a Kyber512.CCAKEM public key
+type PublicKey struct {
+	pk *cpapke.PublicKey
+
+	hpk [32]byte // H(pk)
+}
+
+// Type of a Kyber512.CCAKEM private key
+type PrivateKey struct {
+	sk  *cpapke.PrivateKey
+	pk  *cpapke.PublicKey
+	hpk [32]byte // H(pk)
+	z   [32]byte
+}
+
+// NewKeyFromSeed derives a public/private keypair deterministically
+// from the given seed.
+//
+// Panics if seed is not of length KeySeedSize.
+func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
+	var sk PrivateKey
+	var pk PublicKey
+
+	if len(seed) != KeySeedSize {
+		panic("seed must be of length KeySeedSize")
+	}
+
+	pk.pk, sk.sk = cpapke.NewKeyFromSeed(seed[:cpapke.KeySeedSize])
+	sk.pk = pk.pk
+	copy(sk.z[:], seed[cpapke.KeySeedSize:])
+
+	// Compute H(pk)
+	var ppk [cpapke.PublicKeySize]byte
+	sk.pk.Pack(ppk[:])
+	h := sha3.New256()
+	h.Write(ppk[:])
+	h.Read(sk.hpk[:])
+	copy(pk.hpk[:], sk.hpk[:])
+
+	return &pk, &sk
+}
+
+// GenerateKeyPair generates public and private keys using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKeyPair(rand io.Reader) (*PublicKey, *PrivateKey, error) {
+	var seed [KeySeedSize]byte
+	if rand == nil {
+		rand = cryptoRand.Reader
+	}
+	_, err := io.ReadFull(rand, seed[:])
+	if err != nil {
+		return nil, nil, err
+	}
+	pk, sk := NewKeyFromSeed(seed[:])
+	return pk, sk, nil
+}
+
+// EncapsulateTo generates a shared key and ciphertext that contains it
+// for the public key using randomness from seed and writes the shared key
+// to ss and ciphertext to ct.
+//
+// Panics if ss, ct or seed are not of length SharedKeySize, CiphertextSize
+// and EncapsulationSeedSize respectively.
+//
+// seed may be nil, in which case crypto/rand.Reader is used to generate one.
+func (pk *PublicKey) EncapsulateTo(ct, ss []byte, seed []byte) {
+	if seed == nil {
+		seed = make([]byte, EncapsulationSeedSize)
+		if _, err := cryptoRand.Read(seed[:]); err != nil {
+			panic(err)
+		}
+	} else {
+		if len(seed) != EncapsulationSeedSize {
+			panic("seed must be of length EncapsulationSeedSize")
+		}
+	}
+
+	if len(ct) != CiphertextSize {
+		panic("ct must be of length CiphertextSize")
+	}
+
+	if len(ss) != SharedKeySize {
+		panic("ss must be of length SharedKeySize")
+	}
+
+	// m = H(seed)
+	var m [32]byte
+	h := sha3.New256()
+	h.Write(seed[:])
+	h.Read(m[:])
+
+	// (K', r) = G(m ‖ H(pk))
+	var kr [64]byte
+	g := sha3.New512()
+	g.Write(m[:])
+	g.Write(pk.hpk[:])
+	g.Read(kr[:])
+
+	// c = Kyber.CPAPKE.Enc(pk, m, r)
+	pk.pk.EncryptTo(ct, m[:], kr[32:])
+
+	// Compute H(c) and put in second slot of kr, which will be (K', H(c)).
+	h.Reset()
+	h.Write(ct[:CiphertextSize])
+	h.Read(kr[32:])
+
+	// K = KDF(K' ‖ H(c))
+	kdf := sha3.NewShake256()
+	kdf.Write(kr[:])
+	kdf.Read(ss[:SharedKeySize])
+}
+
+// DecapsulateTo computes the shared key which is encapsulated in ct
+// for the private key.
+//
+// Panics if ct or ss are not of length CiphertextSize and SharedKeySize
+// respectively.
+func (sk *PrivateKey) DecapsulateTo(ss, ct []byte) {
+	if len(ct) != CiphertextSize {
+		panic("ct must be of length CiphertextSize")
+	}
+
+	if len(ss) != SharedKeySize {
+		panic("ss must be of length SharedKeySize")
+	}
+
+	// m' = Kyber.CPAPKE.Dec(sk, ct)
+	var m2 [32]byte
+	sk.sk.DecryptTo(m2[:], ct)
+
+	// (K'', r') = G(m' ‖ H(pk))
+	var kr2 [64]byte
+	g := sha3.New512()
+	g.Write(m2[:])
+	g.Write(sk.hpk[:])
+	g.Read(kr2[:])
+
+	// c' = Kyber.CPAPKE.Enc(pk, m', r')
+	var ct2 [CiphertextSize]byte
+	sk.pk.EncryptTo(ct2[:], m2[:], kr2[32:])
+
+	// Compute H(c) and put in second slot of kr2, which will be (K'', H(c)).
+	h := sha3.New256()
+	h.Write(ct[:CiphertextSize])
+	h.Read(kr2[32:])
+
+	// Replace K'' by  z in the first slot of kr2 if c ≠ c'.
+	subtle.ConstantTimeCopy(
+		1-subtle.ConstantTimeCompare(ct, ct2[:]),
+		kr2[:32],
+		sk.z[:],
+	)
+
+	// K = KDF(K''/z, H(c))
+	kdf := sha3.NewShake256()
+	kdf.Write(kr2[:])
+	kdf.Read(ss[:SharedKeySize])
+}
+
+// Packs sk to buf.
+//
+// Panics if buf is not of size PrivateKeySize.
+func (sk *PrivateKey) Pack(buf []byte) {
+	if len(buf) != PrivateKeySize {
+		panic("buf must be of length PrivateKeySize")
+	}
+
+	sk.sk.Pack(buf[:cpapke.PrivateKeySize])
+	buf = buf[cpapke.PrivateKeySize:]
+	sk.pk.Pack(buf[:cpapke.PublicKeySize])
+	buf = buf[cpapke.PublicKeySize:]
+	copy(buf, sk.hpk[:])
+	buf = buf[32:]
+	copy(buf, sk.z[:])
+}
+
+// Unpacks sk from buf.
+//
+// Panics if buf is not of size PrivateKeySize.
+func (sk *PrivateKey) Unpack(buf []byte) {
+	if len(buf) != PrivateKeySize {
+		panic("buf must be of length PrivateKeySize")
+	}
+
+	sk.sk = new(cpapke.PrivateKey)
+	sk.sk.Unpack(buf[:cpapke.PrivateKeySize])
+	buf = buf[cpapke.PrivateKeySize:]
+	sk.pk = new(cpapke.PublicKey)
+	sk.pk.Unpack(buf[:cpapke.PublicKeySize])
+	buf = buf[cpapke.PublicKeySize:]
+	copy(sk.hpk[:], buf[:32])
+	copy(sk.z[:], buf[32:])
+}
+
+// Packs pk to buf.
+//
+// Panics if buf is not of size PublicKeySize.
+func (pk *PublicKey) Pack(buf []byte) {
+	if len(buf) != PublicKeySize {
+		panic("buf must be of length PublicKeySize")
+	}
+
+	pk.pk.Pack(buf)
+}
+
+// Unpacks pk from buf.
+//
+// Panics if buf is not of size PublicKeySize.
+func (pk *PublicKey) Unpack(buf []byte) {
+	if len(buf) != PublicKeySize {
+		panic("buf must be of length PublicKeySize")
+	}
+
+	pk.pk = new(cpapke.PublicKey)
+	pk.pk.Unpack(buf)
+
+	// Compute cached H(pk)
+	h := sha3.New256()
+	h.Write(buf)
+	h.Read(pk.hpk[:])
+}
+
+// Boilerplate down below for the KEM scheme API.
+
+type scheme struct{}
+
+var sch kem.Scheme = &scheme{}
+
+// Scheme returns a KEM interface.
+func Scheme() kem.Scheme { return sch }
+
+func (*scheme) Name() string               { return "Kyber512" }
+func (*scheme) PublicKeySize() int         { return PublicKeySize }
+func (*scheme) PrivateKeySize() int        { return PrivateKeySize }
+func (*scheme) SeedSize() int              { return KeySeedSize }
+func (*scheme) SharedKeySize() int         { return SharedKeySize }
+func (*scheme) CiphertextSize() int        { return CiphertextSize }
+func (*scheme) EncapsulationSeedSize() int { return EncapsulationSeedSize }
+
+func (sk *PrivateKey) Scheme() kem.Scheme { return sch }
+func (pk *PublicKey) Scheme() kem.Scheme  { return sch }
+
+func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
+	var ret [PrivateKeySize]byte
+	sk.Pack(ret[:])
+	return ret[:], nil
+}
+
+func (sk *PrivateKey) Equal(other kem.PrivateKey) bool {
+	oth, ok := other.(*PrivateKey)
+	if !ok {
+		return false
+	}
+	if sk.pk == nil && oth.pk == nil {
+		return true
+	}
+	if sk.pk == nil || oth.pk == nil {
+		return false
+	}
+	if !bytes.Equal(sk.hpk[:], oth.hpk[:]) ||
+		subtle.ConstantTimeCompare(sk.z[:], oth.z[:]) != 1 {
+		return false
+	}
+	return sk.sk.Equal(oth.sk)
+}
+
+func (pk *PublicKey) Equal(other kem.PublicKey) bool {
+	oth, ok := other.(*PublicKey)
+	if !ok {
+		return false
+	}
+	if pk.pk == nil && oth.pk == nil {
+		return true
+	}
+	if pk.pk == nil || oth.pk == nil {
+		return false
+	}
+	return bytes.Equal(pk.hpk[:], oth.hpk[:])
+}
+
+func (sk *PrivateKey) Public() kem.PublicKey {
+	pk := new(PublicKey)
+	pk.pk = sk.pk
+	copy(pk.hpk[:], sk.hpk[:])
+	return pk
+}
+
+func (pk *PublicKey) MarshalBinary() ([]byte, error) {
+	var ret [PublicKeySize]byte
+	pk.Pack(ret[:])
+	return ret[:], nil
+}
+
+func (*scheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
+	return GenerateKeyPair(cryptoRand.Reader)
+}
+
+func (*scheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
+	if len(seed) != KeySeedSize {
+		panic(kem.ErrSeedSize)
+	}
+	return NewKeyFromSeed(seed[:])
+}
+
+func (*scheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) {
+	ct = make([]byte, CiphertextSize)
+	ss = make([]byte, SharedKeySize)
+
+	pub, ok := pk.(*PublicKey)
+	if !ok {
+		return nil, nil, kem.ErrTypeMismatch
+	}
+	pub.EncapsulateTo(ct, ss, nil)
+	return
+}
+
+func (*scheme) EncapsulateDeterministically(pk kem.PublicKey, seed []byte) (
+	ct, ss []byte, err error) {
+	if len(seed) != EncapsulationSeedSize {
+		return nil, nil, kem.ErrSeedSize
+	}
+
+	ct = make([]byte, CiphertextSize)
+	ss = make([]byte, SharedKeySize)
+
+	pub, ok := pk.(*PublicKey)
+	if !ok {
+		return nil, nil, kem.ErrTypeMismatch
+	}
+	pub.EncapsulateTo(ct, ss, seed)
+	return
+}
+
+func (*scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
+	if len(ct) != CiphertextSize {
+		return nil, kem.ErrCiphertextSize
+	}
+
+	priv, ok := sk.(*PrivateKey)
+	if !ok {
+		return nil, kem.ErrTypeMismatch
+	}
+	ss := make([]byte, SharedKeySize)
+	priv.DecapsulateTo(ss, ct)
+	return ss, nil
+}
+
+func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
+	if len(buf) != PublicKeySize {
+		return nil, kem.ErrPubKeySize
+	}
+	var ret PublicKey
+	ret.Unpack(buf)
+	return &ret, nil
+}
+
+func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
+	if len(buf) != PrivateKeySize {
+		return nil, kem.ErrPrivKeySize
+	}
+	var ret PrivateKey
+	ret.Unpack(buf)
+	return &ret, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/kem/kyber/kyber768/kyber.go b/vendor/github.com/cloudflare/circl/kem/kyber/kyber768/kyber.go
new file mode 100644
index 00000000..832d9b37
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/kem/kyber/kyber768/kyber.go
@@ -0,0 +1,404 @@
+// Code generated from pkg.templ.go. DO NOT EDIT.
+
+// Package kyber768 implements the IND-CCA2 secure key encapsulation mechanism
+// Kyber768.CCAKEM as submitted to round 3 of the NIST PQC competition and
+// described in
+//
+// https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
+package kyber768
+
+import (
+	"bytes"
+	"crypto/subtle"
+	"io"
+
+	cryptoRand "crypto/rand"
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/kem"
+	cpapke "github.com/cloudflare/circl/pke/kyber/kyber768"
+)
+
+const (
+	// Size of seed for NewKeyFromSeed
+	KeySeedSize = cpapke.KeySeedSize + 32
+
+	// Size of seed for EncapsulateTo.
+	EncapsulationSeedSize = 32
+
+	// Size of the established shared key.
+	SharedKeySize = 32
+
+	// Size of the encapsulated shared key.
+	CiphertextSize = cpapke.CiphertextSize
+
+	// Size of a packed public key.
+	PublicKeySize = cpapke.PublicKeySize
+
+	// Size of a packed private key.
+	PrivateKeySize = cpapke.PrivateKeySize + cpapke.PublicKeySize + 64
+)
+
+// Type of a Kyber768.CCAKEM public key
+type PublicKey struct {
+	pk *cpapke.PublicKey
+
+	hpk [32]byte // H(pk)
+}
+
+// Type of a Kyber768.CCAKEM private key
+type PrivateKey struct {
+	sk  *cpapke.PrivateKey
+	pk  *cpapke.PublicKey
+	hpk [32]byte // H(pk)
+	z   [32]byte
+}
+
+// NewKeyFromSeed derives a public/private keypair deterministically
+// from the given seed.
+//
+// Panics if seed is not of length KeySeedSize.
+func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
+	var sk PrivateKey
+	var pk PublicKey
+
+	if len(seed) != KeySeedSize {
+		panic("seed must be of length KeySeedSize")
+	}
+
+	pk.pk, sk.sk = cpapke.NewKeyFromSeed(seed[:cpapke.KeySeedSize])
+	sk.pk = pk.pk
+	copy(sk.z[:], seed[cpapke.KeySeedSize:])
+
+	// Compute H(pk)
+	var ppk [cpapke.PublicKeySize]byte
+	sk.pk.Pack(ppk[:])
+	h := sha3.New256()
+	h.Write(ppk[:])
+	h.Read(sk.hpk[:])
+	copy(pk.hpk[:], sk.hpk[:])
+
+	return &pk, &sk
+}
+
+// GenerateKeyPair generates public and private keys using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKeyPair(rand io.Reader) (*PublicKey, *PrivateKey, error) {
+	var seed [KeySeedSize]byte
+	if rand == nil {
+		rand = cryptoRand.Reader
+	}
+	_, err := io.ReadFull(rand, seed[:])
+	if err != nil {
+		return nil, nil, err
+	}
+	pk, sk := NewKeyFromSeed(seed[:])
+	return pk, sk, nil
+}
+
+// EncapsulateTo generates a shared key and ciphertext that contains it
+// for the public key using randomness from seed and writes the shared key
+// to ss and ciphertext to ct.
+//
+// Panics if ss, ct or seed are not of length SharedKeySize, CiphertextSize
+// and EncapsulationSeedSize respectively.
+//
+// seed may be nil, in which case crypto/rand.Reader is used to generate one.
+func (pk *PublicKey) EncapsulateTo(ct, ss []byte, seed []byte) {
+	if seed == nil {
+		seed = make([]byte, EncapsulationSeedSize)
+		if _, err := cryptoRand.Read(seed[:]); err != nil {
+			panic(err)
+		}
+	} else {
+		if len(seed) != EncapsulationSeedSize {
+			panic("seed must be of length EncapsulationSeedSize")
+		}
+	}
+
+	if len(ct) != CiphertextSize {
+		panic("ct must be of length CiphertextSize")
+	}
+
+	if len(ss) != SharedKeySize {
+		panic("ss must be of length SharedKeySize")
+	}
+
+	// m = H(seed)
+	var m [32]byte
+	h := sha3.New256()
+	h.Write(seed[:])
+	h.Read(m[:])
+
+	// (K', r) = G(m ‖ H(pk))
+	var kr [64]byte
+	g := sha3.New512()
+	g.Write(m[:])
+	g.Write(pk.hpk[:])
+	g.Read(kr[:])
+
+	// c = Kyber.CPAPKE.Enc(pk, m, r)
+	pk.pk.EncryptTo(ct, m[:], kr[32:])
+
+	// Compute H(c) and put in second slot of kr, which will be (K', H(c)).
+	h.Reset()
+	h.Write(ct[:CiphertextSize])
+	h.Read(kr[32:])
+
+	// K = KDF(K' ‖ H(c))
+	kdf := sha3.NewShake256()
+	kdf.Write(kr[:])
+	kdf.Read(ss[:SharedKeySize])
+}
+
+// DecapsulateTo computes the shared key which is encapsulated in ct
+// for the private key.
+//
+// Panics if ct or ss are not of length CiphertextSize and SharedKeySize
+// respectively.
+func (sk *PrivateKey) DecapsulateTo(ss, ct []byte) {
+	if len(ct) != CiphertextSize {
+		panic("ct must be of length CiphertextSize")
+	}
+
+	if len(ss) != SharedKeySize {
+		panic("ss must be of length SharedKeySize")
+	}
+
+	// m' = Kyber.CPAPKE.Dec(sk, ct)
+	var m2 [32]byte
+	sk.sk.DecryptTo(m2[:], ct)
+
+	// (K'', r') = G(m' ‖ H(pk))
+	var kr2 [64]byte
+	g := sha3.New512()
+	g.Write(m2[:])
+	g.Write(sk.hpk[:])
+	g.Read(kr2[:])
+
+	// c' = Kyber.CPAPKE.Enc(pk, m', r')
+	var ct2 [CiphertextSize]byte
+	sk.pk.EncryptTo(ct2[:], m2[:], kr2[32:])
+
+	// Compute H(c) and put in second slot of kr2, which will be (K'', H(c)).
+	h := sha3.New256()
+	h.Write(ct[:CiphertextSize])
+	h.Read(kr2[32:])
+
+	// Replace K'' by  z in the first slot of kr2 if c ≠ c'.
+	subtle.ConstantTimeCopy(
+		1-subtle.ConstantTimeCompare(ct, ct2[:]),
+		kr2[:32],
+		sk.z[:],
+	)
+
+	// K = KDF(K''/z, H(c))
+	kdf := sha3.NewShake256()
+	kdf.Write(kr2[:])
+	kdf.Read(ss[:SharedKeySize])
+}
+
+// Packs sk to buf.
+//
+// Panics if buf is not of size PrivateKeySize.
+func (sk *PrivateKey) Pack(buf []byte) {
+	if len(buf) != PrivateKeySize {
+		panic("buf must be of length PrivateKeySize")
+	}
+
+	sk.sk.Pack(buf[:cpapke.PrivateKeySize])
+	buf = buf[cpapke.PrivateKeySize:]
+	sk.pk.Pack(buf[:cpapke.PublicKeySize])
+	buf = buf[cpapke.PublicKeySize:]
+	copy(buf, sk.hpk[:])
+	buf = buf[32:]
+	copy(buf, sk.z[:])
+}
+
+// Unpacks sk from buf.
+//
+// Panics if buf is not of size PrivateKeySize.
+func (sk *PrivateKey) Unpack(buf []byte) {
+	if len(buf) != PrivateKeySize {
+		panic("buf must be of length PrivateKeySize")
+	}
+
+	sk.sk = new(cpapke.PrivateKey)
+	sk.sk.Unpack(buf[:cpapke.PrivateKeySize])
+	buf = buf[cpapke.PrivateKeySize:]
+	sk.pk = new(cpapke.PublicKey)
+	sk.pk.Unpack(buf[:cpapke.PublicKeySize])
+	buf = buf[cpapke.PublicKeySize:]
+	copy(sk.hpk[:], buf[:32])
+	copy(sk.z[:], buf[32:])
+}
+
+// Packs pk to buf.
+//
+// Panics if buf is not of size PublicKeySize.
+func (pk *PublicKey) Pack(buf []byte) {
+	if len(buf) != PublicKeySize {
+		panic("buf must be of length PublicKeySize")
+	}
+
+	pk.pk.Pack(buf)
+}
+
+// Unpacks pk from buf.
+//
+// Panics if buf is not of size PublicKeySize.
+func (pk *PublicKey) Unpack(buf []byte) {
+	if len(buf) != PublicKeySize {
+		panic("buf must be of length PublicKeySize")
+	}
+
+	pk.pk = new(cpapke.PublicKey)
+	pk.pk.Unpack(buf)
+
+	// Compute cached H(pk)
+	h := sha3.New256()
+	h.Write(buf)
+	h.Read(pk.hpk[:])
+}
+
+// Boilerplate down below for the KEM scheme API.
+
+type scheme struct{}
+
+var sch kem.Scheme = &scheme{}
+
+// Scheme returns a KEM interface.
+func Scheme() kem.Scheme { return sch }
+
+func (*scheme) Name() string               { return "Kyber768" }
+func (*scheme) PublicKeySize() int         { return PublicKeySize }
+func (*scheme) PrivateKeySize() int        { return PrivateKeySize }
+func (*scheme) SeedSize() int              { return KeySeedSize }
+func (*scheme) SharedKeySize() int         { return SharedKeySize }
+func (*scheme) CiphertextSize() int        { return CiphertextSize }
+func (*scheme) EncapsulationSeedSize() int { return EncapsulationSeedSize }
+
+func (sk *PrivateKey) Scheme() kem.Scheme { return sch }
+func (pk *PublicKey) Scheme() kem.Scheme  { return sch }
+
+func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
+	var ret [PrivateKeySize]byte
+	sk.Pack(ret[:])
+	return ret[:], nil
+}
+
+func (sk *PrivateKey) Equal(other kem.PrivateKey) bool {
+	oth, ok := other.(*PrivateKey)
+	if !ok {
+		return false
+	}
+	if sk.pk == nil && oth.pk == nil {
+		return true
+	}
+	if sk.pk == nil || oth.pk == nil {
+		return false
+	}
+	if !bytes.Equal(sk.hpk[:], oth.hpk[:]) ||
+		subtle.ConstantTimeCompare(sk.z[:], oth.z[:]) != 1 {
+		return false
+	}
+	return sk.sk.Equal(oth.sk)
+}
+
+func (pk *PublicKey) Equal(other kem.PublicKey) bool {
+	oth, ok := other.(*PublicKey)
+	if !ok {
+		return false
+	}
+	if pk.pk == nil && oth.pk == nil {
+		return true
+	}
+	if pk.pk == nil || oth.pk == nil {
+		return false
+	}
+	return bytes.Equal(pk.hpk[:], oth.hpk[:])
+}
+
+func (sk *PrivateKey) Public() kem.PublicKey {
+	pk := new(PublicKey)
+	pk.pk = sk.pk
+	copy(pk.hpk[:], sk.hpk[:])
+	return pk
+}
+
+func (pk *PublicKey) MarshalBinary() ([]byte, error) {
+	var ret [PublicKeySize]byte
+	pk.Pack(ret[:])
+	return ret[:], nil
+}
+
+func (*scheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
+	return GenerateKeyPair(cryptoRand.Reader)
+}
+
+func (*scheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
+	if len(seed) != KeySeedSize {
+		panic(kem.ErrSeedSize)
+	}
+	return NewKeyFromSeed(seed[:])
+}
+
+func (*scheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) {
+	ct = make([]byte, CiphertextSize)
+	ss = make([]byte, SharedKeySize)
+
+	pub, ok := pk.(*PublicKey)
+	if !ok {
+		return nil, nil, kem.ErrTypeMismatch
+	}
+	pub.EncapsulateTo(ct, ss, nil)
+	return
+}
+
+func (*scheme) EncapsulateDeterministically(pk kem.PublicKey, seed []byte) (
+	ct, ss []byte, err error) {
+	if len(seed) != EncapsulationSeedSize {
+		return nil, nil, kem.ErrSeedSize
+	}
+
+	ct = make([]byte, CiphertextSize)
+	ss = make([]byte, SharedKeySize)
+
+	pub, ok := pk.(*PublicKey)
+	if !ok {
+		return nil, nil, kem.ErrTypeMismatch
+	}
+	pub.EncapsulateTo(ct, ss, seed)
+	return
+}
+
+func (*scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
+	if len(ct) != CiphertextSize {
+		return nil, kem.ErrCiphertextSize
+	}
+
+	priv, ok := sk.(*PrivateKey)
+	if !ok {
+		return nil, kem.ErrTypeMismatch
+	}
+	ss := make([]byte, SharedKeySize)
+	priv.DecapsulateTo(ss, ct)
+	return ss, nil
+}
+
+func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
+	if len(buf) != PublicKeySize {
+		return nil, kem.ErrPubKeySize
+	}
+	var ret PublicKey
+	ret.Unpack(buf)
+	return &ret, nil
+}
+
+func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
+	if len(buf) != PrivateKeySize {
+		return nil, kem.ErrPrivKeySize
+	}
+	var ret PrivateKey
+	ret.Unpack(buf)
+	return &ret, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/math/fp25519/fp.go b/vendor/github.com/cloudflare/circl/math/fp25519/fp.go
new file mode 100644
index 00000000..57a50ff5
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp25519/fp.go
@@ -0,0 +1,205 @@
+// Package fp25519 provides prime field arithmetic over GF(2^255-19).
+package fp25519
+
+import (
+	"errors"
+
+	"github.com/cloudflare/circl/internal/conv"
+)
+
+// Size in bytes of an element.
+const Size = 32
+
+// Elt is a prime field element.
+type Elt [Size]byte
+
+func (e Elt) String() string { return conv.BytesLe2Hex(e[:]) }
+
+// p is the prime modulus 2^255-19.
+var p = Elt{
+	0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
+}
+
+// P returns the prime modulus 2^255-19.
+func P() Elt { return p }
+
+// ToBytes stores in b the little-endian byte representation of x.
+func ToBytes(b []byte, x *Elt) error {
+	if len(b) != Size {
+		return errors.New("wrong size")
+	}
+	Modp(x)
+	copy(b, x[:])
+	return nil
+}
+
+// IsZero returns true if x is equal to 0.
+func IsZero(x *Elt) bool { Modp(x); return *x == Elt{} }
+
+// SetOne assigns x=1.
+func SetOne(x *Elt) { *x = Elt{}; x[0] = 1 }
+
+// Neg calculates z = -x.
+func Neg(z, x *Elt) { Sub(z, &p, x) }
+
+// InvSqrt calculates z = sqrt(x/y) iff x/y is a quadratic-residue, which is
+// indicated by returning isQR = true. Otherwise, when x/y is a quadratic
+// non-residue, z will have an undetermined value and isQR = false.
+func InvSqrt(z, x, y *Elt) (isQR bool) {
+	sqrtMinusOne := &Elt{
+		0xb0, 0xa0, 0x0e, 0x4a, 0x27, 0x1b, 0xee, 0xc4,
+		0x78, 0xe4, 0x2f, 0xad, 0x06, 0x18, 0x43, 0x2f,
+		0xa7, 0xd7, 0xfb, 0x3d, 0x99, 0x00, 0x4d, 0x2b,
+		0x0b, 0xdf, 0xc1, 0x4f, 0x80, 0x24, 0x83, 0x2b,
+	}
+	t0, t1, t2, t3 := &Elt{}, &Elt{}, &Elt{}, &Elt{}
+
+	Mul(t0, x, y)   // t0 = u*v
+	Sqr(t1, y)      // t1 = v^2
+	Mul(t2, t0, t1) // t2 = u*v^3
+	Sqr(t0, t1)     // t0 = v^4
+	Mul(t1, t0, t2) // t1 = u*v^7
+
+	var Tab [4]*Elt
+	Tab[0] = &Elt{}
+	Tab[1] = &Elt{}
+	Tab[2] = t3
+	Tab[3] = t1
+
+	*Tab[0] = *t1
+	Sqr(Tab[0], Tab[0])
+	Sqr(Tab[1], Tab[0])
+	Sqr(Tab[1], Tab[1])
+	Mul(Tab[1], Tab[1], Tab[3])
+	Mul(Tab[0], Tab[0], Tab[1])
+	Sqr(Tab[0], Tab[0])
+	Mul(Tab[0], Tab[0], Tab[1])
+	Sqr(Tab[1], Tab[0])
+	for i := 0; i < 4; i++ {
+		Sqr(Tab[1], Tab[1])
+	}
+	Mul(Tab[1], Tab[1], Tab[0])
+	Sqr(Tab[2], Tab[1])
+	for i := 0; i < 4; i++ {
+		Sqr(Tab[2], Tab[2])
+	}
+	Mul(Tab[2], Tab[2], Tab[0])
+	Sqr(Tab[1], Tab[2])
+	for i := 0; i < 14; i++ {
+		Sqr(Tab[1], Tab[1])
+	}
+	Mul(Tab[1], Tab[1], Tab[2])
+	Sqr(Tab[2], Tab[1])
+	for i := 0; i < 29; i++ {
+		Sqr(Tab[2], Tab[2])
+	}
+	Mul(Tab[2], Tab[2], Tab[1])
+	Sqr(Tab[1], Tab[2])
+	for i := 0; i < 59; i++ {
+		Sqr(Tab[1], Tab[1])
+	}
+	Mul(Tab[1], Tab[1], Tab[2])
+	for i := 0; i < 5; i++ {
+		Sqr(Tab[1], Tab[1])
+	}
+	Mul(Tab[1], Tab[1], Tab[0])
+	Sqr(Tab[2], Tab[1])
+	for i := 0; i < 124; i++ {
+		Sqr(Tab[2], Tab[2])
+	}
+	Mul(Tab[2], Tab[2], Tab[1])
+	Sqr(Tab[2], Tab[2])
+	Sqr(Tab[2], Tab[2])
+	Mul(Tab[2], Tab[2], Tab[3])
+
+	Mul(z, t3, t2) // z = xy^(p+3)/8 = xy^3*(xy^7)^(p-5)/8
+	// Checking whether y z^2 == x
+	Sqr(t0, z)     // t0 = z^2
+	Mul(t0, t0, y) // t0 = yz^2
+	Sub(t1, t0, x) // t1 = t0-u
+	Add(t2, t0, x) // t2 = t0+u
+	if IsZero(t1) {
+		return true
+	} else if IsZero(t2) {
+		Mul(z, z, sqrtMinusOne) // z = z*sqrt(-1)
+		return true
+	} else {
+		return false
+	}
+}
+
+// Inv calculates z = 1/x mod p.
+func Inv(z, x *Elt) {
+	x0, x1, x2 := &Elt{}, &Elt{}, &Elt{}
+	Sqr(x1, x)
+	Sqr(x0, x1)
+	Sqr(x0, x0)
+	Mul(x0, x0, x)
+	Mul(z, x0, x1)
+	Sqr(x1, z)
+	Mul(x0, x0, x1)
+	Sqr(x1, x0)
+	for i := 0; i < 4; i++ {
+		Sqr(x1, x1)
+	}
+	Mul(x0, x0, x1)
+	Sqr(x1, x0)
+	for i := 0; i < 9; i++ {
+		Sqr(x1, x1)
+	}
+	Mul(x1, x1, x0)
+	Sqr(x2, x1)
+	for i := 0; i < 19; i++ {
+		Sqr(x2, x2)
+	}
+	Mul(x2, x2, x1)
+	for i := 0; i < 10; i++ {
+		Sqr(x2, x2)
+	}
+	Mul(x2, x2, x0)
+	Sqr(x0, x2)
+	for i := 0; i < 49; i++ {
+		Sqr(x0, x0)
+	}
+	Mul(x0, x0, x2)
+	Sqr(x1, x0)
+	for i := 0; i < 99; i++ {
+		Sqr(x1, x1)
+	}
+	Mul(x1, x1, x0)
+	for i := 0; i < 50; i++ {
+		Sqr(x1, x1)
+	}
+	Mul(x1, x1, x2)
+	for i := 0; i < 5; i++ {
+		Sqr(x1, x1)
+	}
+	Mul(z, z, x1)
+}
+
+// Cmov assigns y to x if n is 1.
+func Cmov(x, y *Elt, n uint) { cmov(x, y, n) }
+
+// Cswap interchanges x and y if n is 1.
+func Cswap(x, y *Elt, n uint) { cswap(x, y, n) }
+
+// Add calculates z = x+y mod p.
+func Add(z, x, y *Elt) { add(z, x, y) }
+
+// Sub calculates z = x-y mod p.
+func Sub(z, x, y *Elt) { sub(z, x, y) }
+
+// AddSub calculates (x,y) = (x+y mod p, x-y mod p).
+func AddSub(x, y *Elt) { addsub(x, y) }
+
+// Mul calculates z = x*y mod p.
+func Mul(z, x, y *Elt) { mul(z, x, y) }
+
+// Sqr calculates z = x^2 mod p.
+func Sqr(z, x *Elt) { sqr(z, x) }
+
+// Modp ensures that z is between [0,p-1].
+func Modp(z *Elt) { modp(z) }
diff --git a/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.go b/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.go
new file mode 100644
index 00000000..057f0d28
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.go
@@ -0,0 +1,45 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+package fp25519
+
+import (
+	"golang.org/x/sys/cpu"
+)
+
+var hasBmi2Adx = cpu.X86.HasBMI2 && cpu.X86.HasADX
+
+var _ = hasBmi2Adx
+
+func cmov(x, y *Elt, n uint)  { cmovAmd64(x, y, n) }
+func cswap(x, y *Elt, n uint) { cswapAmd64(x, y, n) }
+func add(z, x, y *Elt)        { addAmd64(z, x, y) }
+func sub(z, x, y *Elt)        { subAmd64(z, x, y) }
+func addsub(x, y *Elt)        { addsubAmd64(x, y) }
+func mul(z, x, y *Elt)        { mulAmd64(z, x, y) }
+func sqr(z, x *Elt)           { sqrAmd64(z, x) }
+func modp(z *Elt)             { modpAmd64(z) }
+
+//go:noescape
+func cmovAmd64(x, y *Elt, n uint)
+
+//go:noescape
+func cswapAmd64(x, y *Elt, n uint)
+
+//go:noescape
+func addAmd64(z, x, y *Elt)
+
+//go:noescape
+func subAmd64(z, x, y *Elt)
+
+//go:noescape
+func addsubAmd64(x, y *Elt)
+
+//go:noescape
+func mulAmd64(z, x, y *Elt)
+
+//go:noescape
+func sqrAmd64(z, x *Elt)
+
+//go:noescape
+func modpAmd64(z *Elt)
diff --git a/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.h b/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.h
new file mode 100644
index 00000000..b884b584
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.h
@@ -0,0 +1,351 @@
+// This code was imported from https://github.com/armfazh/rfc7748_precomputed
+
+// CHECK_BMI2ADX triggers bmi2adx if supported,
+// otherwise it fallbacks to legacy code.
+#define CHECK_BMI2ADX(label, legacy, bmi2adx) \
+    CMPB ·hasBmi2Adx(SB), $0  \
+    JE label                  \
+    bmi2adx                   \
+    RET                       \
+    label:                    \
+    legacy                    \
+    RET
+
+// cselect is a conditional move
+// if b=1: it copies y into x;
+// if b=0: x remains with the same value;
+// if b<> 0,1: undefined.
+// Uses: AX, DX, FLAGS
+// Instr: x86_64, cmov
+#define cselect(x,y,b) \
+    TESTQ b, b \
+    MOVQ  0+x, AX; MOVQ  0+y, DX; CMOVQNE DX, AX; MOVQ AX,  0+x; \
+    MOVQ  8+x, AX; MOVQ  8+y, DX; CMOVQNE DX, AX; MOVQ AX,  8+x; \
+    MOVQ 16+x, AX; MOVQ 16+y, DX; CMOVQNE DX, AX; MOVQ AX, 16+x; \
+    MOVQ 24+x, AX; MOVQ 24+y, DX; CMOVQNE DX, AX; MOVQ AX, 24+x;
+
+// cswap is a conditional swap
+// if b=1: x,y <- y,x;
+// if b=0: x,y remain with the same values;
+// if b<> 0,1: undefined.
+// Uses: AX, DX, R8, FLAGS
+// Instr: x86_64, cmov
+#define cswap(x,y,b) \
+    TESTQ b, b \
+    MOVQ  0+x, AX; MOVQ AX, R8; MOVQ  0+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX,  0+x; MOVQ DX,  0+y; \
+    MOVQ  8+x, AX; MOVQ AX, R8; MOVQ  8+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX,  8+x; MOVQ DX,  8+y; \
+    MOVQ 16+x, AX; MOVQ AX, R8; MOVQ 16+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 16+x; MOVQ DX, 16+y; \
+    MOVQ 24+x, AX; MOVQ AX, R8; MOVQ 24+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 24+x; MOVQ DX, 24+y;
+
+// additionLeg adds x and y and stores in z
+// Uses: AX, DX, R8-R11, FLAGS
+// Instr: x86_64, cmov
+#define additionLeg(z,x,y) \
+    MOVL $38, AX; \
+    MOVL  $0, DX; \
+    MOVQ  0+x,  R8;  ADDQ  0+y,  R8; \
+    MOVQ  8+x,  R9;  ADCQ  8+y,  R9; \
+    MOVQ 16+x, R10;  ADCQ 16+y, R10; \
+    MOVQ 24+x, R11;  ADCQ 24+y, R11; \
+    CMOVQCS AX, DX;    \
+    ADDQ DX,  R8; \
+    ADCQ $0,  R9;  MOVQ  R9,  8+z; \
+    ADCQ $0, R10;  MOVQ R10, 16+z; \
+    ADCQ $0, R11;  MOVQ R11, 24+z; \
+    MOVL $0,  DX; \
+    CMOVQCS AX, DX; \
+    ADDQ DX,  R8;  MOVQ  R8,  0+z;
+
+// additionAdx adds x and y and stores in z
+// Uses: AX, DX, R8-R11, FLAGS
+// Instr: x86_64, cmov, adx
+#define additionAdx(z,x,y) \
+    MOVL $38, AX; \
+    XORL  DX, DX; \
+    MOVQ  0+x,  R8;  ADCXQ  0+y,  R8; \
+    MOVQ  8+x,  R9;  ADCXQ  8+y,  R9; \
+    MOVQ 16+x, R10;  ADCXQ 16+y, R10; \
+    MOVQ 24+x, R11;  ADCXQ 24+y, R11; \
+    CMOVQCS AX, DX ; \
+    XORL  AX,  AX; \
+    ADCXQ DX,  R8; \
+    ADCXQ AX,  R9;  MOVQ  R9,  8+z; \
+    ADCXQ AX, R10;  MOVQ R10, 16+z; \
+    ADCXQ AX, R11;  MOVQ R11, 24+z; \
+    MOVL $38,  DX; \
+    CMOVQCS DX, AX; \
+    ADDQ  AX,  R8;  MOVQ  R8,  0+z;
+
+// subtraction subtracts y from x and stores in z
+// Uses: AX, DX, R8-R11, FLAGS
+// Instr: x86_64, cmov
+#define subtraction(z,x,y) \
+    MOVL   $38,  AX; \
+    MOVQ  0+x,  R8;  SUBQ  0+y,  R8; \
+    MOVQ  8+x,  R9;  SBBQ  8+y,  R9; \
+    MOVQ 16+x, R10;  SBBQ 16+y, R10; \
+    MOVQ 24+x, R11;  SBBQ 24+y, R11; \
+    MOVL $0, DX; \
+    CMOVQCS AX, DX; \
+    SUBQ  DX,  R8; \
+    SBBQ  $0,  R9;  MOVQ  R9,  8+z; \
+    SBBQ  $0, R10;  MOVQ R10, 16+z; \
+    SBBQ  $0, R11;  MOVQ R11, 24+z; \
+    MOVL  $0,  DX; \
+    CMOVQCS AX, DX; \
+    SUBQ  DX,  R8;  MOVQ  R8,  0+z;
+
+// integerMulAdx multiplies x and y and stores in z
+// Uses: AX, DX, R8-R15, FLAGS
+// Instr: x86_64, bmi2, adx
+#define integerMulAdx(z,x,y) \
+    MOVL    $0,R15; \
+    MOVQ   0+y, DX;       XORL  AX,  AX; \
+    MULXQ  0+x, AX,  R8;  MOVQ  AX, 0+z; \
+    MULXQ  8+x, AX,  R9;  ADCXQ AX,  R8; \
+    MULXQ 16+x, AX, R10;  ADCXQ AX,  R9; \
+    MULXQ 24+x, AX, R11;  ADCXQ AX, R10; \
+    MOVL $0, AX;;;;;;;;;  ADCXQ AX, R11; \
+    MOVQ   8+y, DX;       XORL   AX,  AX; \
+    MULXQ  0+x, AX, R12;  ADCXQ  R8,  AX;  MOVQ  AX,  8+z; \
+    MULXQ  8+x, AX, R13;  ADCXQ  R9, R12;  ADOXQ AX, R12; \
+    MULXQ 16+x, AX, R14;  ADCXQ R10, R13;  ADOXQ AX, R13; \
+    MULXQ 24+x, AX, R15;  ADCXQ R11, R14;  ADOXQ AX, R14; \
+    MOVL $0, AX;;;;;;;;;  ADCXQ  AX, R15;  ADOXQ AX, R15; \
+    MOVQ  16+y, DX;       XORL   AX,  AX; \
+    MULXQ  0+x, AX,  R8;  ADCXQ R12,  AX;  MOVQ  AX, 16+z; \
+    MULXQ  8+x, AX,  R9;  ADCXQ R13,  R8;  ADOXQ AX,  R8; \
+    MULXQ 16+x, AX, R10;  ADCXQ R14,  R9;  ADOXQ AX,  R9; \
+    MULXQ 24+x, AX, R11;  ADCXQ R15, R10;  ADOXQ AX, R10; \
+    MOVL $0, AX;;;;;;;;;  ADCXQ  AX, R11;  ADOXQ AX, R11; \
+    MOVQ  24+y, DX;       XORL   AX,  AX; \
+    MULXQ  0+x, AX, R12;  ADCXQ  R8,  AX;  MOVQ  AX, 24+z; \
+    MULXQ  8+x, AX, R13;  ADCXQ  R9, R12;  ADOXQ AX, R12;  MOVQ R12, 32+z; \
+    MULXQ 16+x, AX, R14;  ADCXQ R10, R13;  ADOXQ AX, R13;  MOVQ R13, 40+z; \
+    MULXQ 24+x, AX, R15;  ADCXQ R11, R14;  ADOXQ AX, R14;  MOVQ R14, 48+z; \
+    MOVL $0, AX;;;;;;;;;  ADCXQ  AX, R15;  ADOXQ AX, R15;  MOVQ R15, 56+z;
+
+// integerMulLeg multiplies x and y and stores in z
+// Uses: AX, DX, R8-R15, FLAGS
+// Instr: x86_64
+#define integerMulLeg(z,x,y) \
+    MOVQ  0+y, R8; \
+    MOVQ  0+x, AX; MULQ R8; MOVQ AX, 0+z; MOVQ DX, R15; \
+    MOVQ  8+x, AX; MULQ R8; MOVQ AX, R13; MOVQ DX, R10; \
+    MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; \
+    MOVQ 24+x, AX; MULQ R8; \
+    ADDQ R13, R15; \
+    ADCQ R14, R10;  MOVQ R10, 16+z; \
+    ADCQ  AX, R11;  MOVQ R11, 24+z; \
+    ADCQ  $0,  DX;  MOVQ  DX, 32+z; \
+    MOVQ  8+y, R8; \
+    MOVQ  0+x, AX; MULQ R8; MOVQ AX, R12; MOVQ DX,  R9; \
+    MOVQ  8+x, AX; MULQ R8; MOVQ AX, R13; MOVQ DX, R10; \
+    MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; \
+    MOVQ 24+x, AX; MULQ R8; \
+    ADDQ R12, R15; MOVQ R15,  8+z; \
+    ADCQ R13,  R9; \
+    ADCQ R14, R10; \
+    ADCQ  AX, R11; \
+    ADCQ  $0,  DX; \
+    ADCQ 16+z,  R9;  MOVQ  R9,  R15; \
+    ADCQ 24+z, R10;  MOVQ R10, 24+z; \
+    ADCQ 32+z, R11;  MOVQ R11, 32+z; \
+    ADCQ   $0,  DX;  MOVQ  DX, 40+z; \
+    MOVQ 16+y, R8; \
+    MOVQ  0+x, AX; MULQ R8; MOVQ AX, R12; MOVQ DX,  R9; \
+    MOVQ  8+x, AX; MULQ R8; MOVQ AX, R13; MOVQ DX, R10; \
+    MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; \
+    MOVQ 24+x, AX; MULQ R8; \
+    ADDQ R12, R15;  MOVQ R15, 16+z; \
+    ADCQ R13,  R9; \
+    ADCQ R14, R10; \
+    ADCQ  AX, R11; \
+    ADCQ  $0,  DX; \
+    ADCQ 24+z,  R9;  MOVQ  R9,  R15; \
+    ADCQ 32+z, R10;  MOVQ R10, 32+z; \
+    ADCQ 40+z, R11;  MOVQ R11, 40+z; \
+    ADCQ   $0,  DX;  MOVQ  DX, 48+z; \
+    MOVQ 24+y, R8; \
+    MOVQ  0+x, AX; MULQ R8; MOVQ AX, R12; MOVQ DX,  R9; \
+    MOVQ  8+x, AX; MULQ R8; MOVQ AX, R13; MOVQ DX, R10; \
+    MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; \
+    MOVQ 24+x, AX; MULQ R8; \
+    ADDQ R12, R15; MOVQ R15, 24+z; \
+    ADCQ R13,  R9; \
+    ADCQ R14, R10; \
+    ADCQ  AX, R11; \
+    ADCQ  $0,  DX; \
+    ADCQ 32+z,  R9;  MOVQ  R9, 32+z; \
+    ADCQ 40+z, R10;  MOVQ R10, 40+z; \
+    ADCQ 48+z, R11;  MOVQ R11, 48+z; \
+    ADCQ   $0,  DX;  MOVQ  DX, 56+z;
+
+// integerSqrLeg squares x and stores in z
+// Uses: AX, CX, DX, R8-R15, FLAGS
+// Instr: x86_64
+#define integerSqrLeg(z,x) \
+    MOVQ  0+x, R8; \
+    MOVQ  8+x, AX; MULQ R8; MOVQ AX,  R9; MOVQ DX, R10; /* A[0]*A[1] */ \
+    MOVQ 16+x, AX; MULQ R8; MOVQ AX, R14; MOVQ DX, R11; /* A[0]*A[2] */ \
+    MOVQ 24+x, AX; MULQ R8; MOVQ AX, R15; MOVQ DX, R12; /* A[0]*A[3] */ \
+    MOVQ 24+x, R8; \
+    MOVQ  8+x, AX; MULQ R8; MOVQ AX,  CX; MOVQ DX, R13; /* A[3]*A[1] */ \
+    MOVQ 16+x, AX; MULQ R8; /* A[3]*A[2] */ \
+    \
+    ADDQ R14, R10;\
+    ADCQ R15, R11; MOVL $0, R15;\
+    ADCQ  CX, R12;\
+    ADCQ  AX, R13;\
+    ADCQ  $0,  DX; MOVQ DX, R14;\
+    MOVQ 8+x, AX; MULQ 16+x;\
+    \
+    ADDQ AX, R11;\
+    ADCQ DX, R12;\
+    ADCQ $0, R13;\
+    ADCQ $0, R14;\
+    ADCQ $0, R15;\
+    \
+    SHLQ $1, R14, R15; MOVQ R15, 56+z;\
+    SHLQ $1, R13, R14; MOVQ R14, 48+z;\
+    SHLQ $1, R12, R13; MOVQ R13, 40+z;\
+    SHLQ $1, R11, R12; MOVQ R12, 32+z;\
+    SHLQ $1, R10, R11; MOVQ R11, 24+z;\
+    SHLQ $1,  R9, R10; MOVQ R10, 16+z;\
+    SHLQ $1,  R9;      MOVQ  R9,  8+z;\
+    \
+    MOVQ  0+x,AX; MULQ AX; MOVQ AX, 0+z; MOVQ DX,  R9;\
+    MOVQ  8+x,AX; MULQ AX; MOVQ AX, R10; MOVQ DX, R11;\
+    MOVQ 16+x,AX; MULQ AX; MOVQ AX, R12; MOVQ DX, R13;\
+    MOVQ 24+x,AX; MULQ AX; MOVQ AX, R14; MOVQ DX, R15;\
+    \
+    ADDQ  8+z,  R9; MOVQ  R9,  8+z;\
+    ADCQ 16+z, R10; MOVQ R10, 16+z;\
+    ADCQ 24+z, R11; MOVQ R11, 24+z;\
+    ADCQ 32+z, R12; MOVQ R12, 32+z;\
+    ADCQ 40+z, R13; MOVQ R13, 40+z;\
+    ADCQ 48+z, R14; MOVQ R14, 48+z;\
+    ADCQ 56+z, R15; MOVQ R15, 56+z;
+
+// integerSqrAdx squares x and stores in z
+// Uses: AX, CX, DX, R8-R15, FLAGS
+// Instr: x86_64, bmi2, adx
+#define integerSqrAdx(z,x) \
+    MOVQ   0+x,  DX; /* A[0] */ \
+    MULXQ  8+x,  R8, R14; /* A[1]*A[0] */  XORL  R15, R15; \
+    MULXQ 16+x,  R9, R10; /* A[2]*A[0] */  ADCXQ R14,  R9; \
+    MULXQ 24+x,  AX,  CX; /* A[3]*A[0] */  ADCXQ  AX, R10; \
+    MOVQ  24+x,  DX; /* A[3] */ \
+    MULXQ  8+x, R11, R12; /* A[1]*A[3] */  ADCXQ  CX, R11; \
+    MULXQ 16+x,  AX, R13; /* A[2]*A[3] */  ADCXQ  AX, R12; \
+    MOVQ   8+x,  DX; /* A[1] */            ADCXQ R15, R13; \
+    MULXQ 16+x,  AX,  CX; /* A[2]*A[1] */  MOVL   $0, R14; \
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  ADCXQ R15, R14; \
+    XORL  R15, R15; \
+    ADOXQ  AX, R10;  ADCXQ  R8,  R8; \
+    ADOXQ  CX, R11;  ADCXQ  R9,  R9; \
+    ADOXQ R15, R12;  ADCXQ R10, R10; \
+    ADOXQ R15, R13;  ADCXQ R11, R11; \
+    ADOXQ R15, R14;  ADCXQ R12, R12; \
+    ;;;;;;;;;;;;;;;  ADCXQ R13, R13; \
+    ;;;;;;;;;;;;;;;  ADCXQ R14, R14; \
+    MOVQ  0+x, DX;  MULXQ DX, AX, CX; /* A[0]^2 */ \
+    ;;;;;;;;;;;;;;;  MOVQ  AX,  0+z; \
+    ADDQ CX,  R8;    MOVQ  R8,  8+z; \
+    MOVQ  8+x, DX;  MULXQ DX, AX, CX; /* A[1]^2 */ \
+    ADCQ AX,  R9;    MOVQ  R9, 16+z; \
+    ADCQ CX, R10;    MOVQ R10, 24+z; \
+    MOVQ 16+x, DX;  MULXQ DX, AX, CX; /* A[2]^2 */ \
+    ADCQ AX, R11;    MOVQ R11, 32+z; \
+    ADCQ CX, R12;    MOVQ R12, 40+z; \
+    MOVQ 24+x, DX;  MULXQ DX, AX, CX; /* A[3]^2 */ \
+    ADCQ AX, R13;    MOVQ R13, 48+z; \
+    ADCQ CX, R14;    MOVQ R14, 56+z;
+
+// reduceFromDouble finds z congruent to x modulo p such that 0<z<2^256
+// Uses: AX, DX, R8-R13, FLAGS
+// Instr: x86_64
+#define reduceFromDoubleLeg(z,x) \
+    /* 2*C = 38 = 2^256 */ \
+    MOVL $38, AX; MULQ 32+x; MOVQ AX,  R8; MOVQ DX,  R9; /* C*C[4] */ \
+    MOVL $38, AX; MULQ 40+x; MOVQ AX, R12; MOVQ DX, R10; /* C*C[5] */ \
+    MOVL $38, AX; MULQ 48+x; MOVQ AX, R13; MOVQ DX, R11; /* C*C[6] */ \
+    MOVL $38, AX; MULQ 56+x; /* C*C[7] */ \
+    ADDQ R12,  R9; \
+    ADCQ R13, R10; \
+    ADCQ  AX, R11; \
+    ADCQ  $0,  DX; \
+    ADDQ  0+x,  R8; \
+    ADCQ  8+x,  R9; \
+    ADCQ 16+x, R10; \
+    ADCQ 24+x, R11; \
+    ADCQ    $0, DX; \
+    MOVL $38, AX; \
+    IMULQ AX, DX; /* C*C[4], CF=0, OF=0 */ \
+    ADDQ DX,  R8; \
+    ADCQ $0,  R9; MOVQ  R9,  8+z; \
+    ADCQ $0, R10; MOVQ R10, 16+z; \
+    ADCQ $0, R11; MOVQ R11, 24+z; \
+    MOVL $0,  DX; \
+    CMOVQCS AX, DX; \
+    ADDQ DX,  R8; MOVQ  R8,  0+z;
+
+// reduceFromDoubleAdx finds z congruent to x modulo p such that 0<z<2^256
+// Uses: AX, DX, R8-R13, FLAGS
+// Instr: x86_64, bmi2, adx
+#define reduceFromDoubleAdx(z,x) \
+    MOVL    $38,  DX; /* 2*C = 38 = 2^256 */ \
+    MULXQ 32+x,  R8, R10; /* C*C[4] */  XORL AX, AX;     ADOXQ  0+x,  R8; \
+    MULXQ 40+x,  R9, R11; /* C*C[5] */  ADCXQ R10,  R9;  ADOXQ  8+x,  R9; \
+    MULXQ 48+x, R10, R13; /* C*C[6] */  ADCXQ R11, R10;  ADOXQ 16+x, R10; \
+    MULXQ 56+x, R11, R12; /* C*C[7] */  ADCXQ R13, R11;  ADOXQ 24+x, R11; \
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  ADCXQ  AX, R12;  ADOXQ   AX, R12; \
+    IMULQ  DX, R12; /* C*C[4], CF=0, OF=0 */ \
+    ADCXQ R12, R8; \
+    ADCXQ AX,  R9; MOVQ  R9,  8+z; \
+    ADCXQ AX, R10; MOVQ R10, 16+z; \
+    ADCXQ AX, R11; MOVQ R11, 24+z; \
+    MOVL  $0, R12; \
+    CMOVQCS DX, R12; \
+    ADDQ R12,  R8; MOVQ  R8,  0+z;
+
+// addSub calculates two operations: x,y = x+y,x-y
+// Uses: AX, DX, R8-R15, FLAGS
+#define addSub(x,y) \
+    MOVL $38, AX; \
+    XORL  DX, DX; \
+    MOVQ  0+x,  R8;  MOVQ  R8, R12;  ADDQ  0+y,  R8; \
+    MOVQ  8+x,  R9;  MOVQ  R9, R13;  ADCQ  8+y,  R9; \
+    MOVQ 16+x, R10;  MOVQ R10, R14;  ADCQ 16+y, R10; \
+    MOVQ 24+x, R11;  MOVQ R11, R15;  ADCQ 24+y, R11; \
+    CMOVQCS AX, DX; \
+    XORL AX,  AX; \
+    ADDQ DX,  R8; \
+    ADCQ $0,  R9; \
+    ADCQ $0, R10; \
+    ADCQ $0, R11; \
+    MOVL $38, DX; \
+    CMOVQCS DX, AX; \
+    ADDQ  AX, R8; \
+    MOVL $38, AX; \
+    SUBQ  0+y, R12; \
+    SBBQ  8+y, R13; \
+    SBBQ 16+y, R14; \
+    SBBQ 24+y, R15; \
+    MOVL $0, DX; \
+    CMOVQCS AX, DX; \
+    SUBQ DX, R12; \
+    SBBQ $0, R13; \
+    SBBQ $0, R14; \
+    SBBQ $0, R15; \
+    MOVL $0,  DX; \
+    CMOVQCS AX, DX; \
+    SUBQ DX, R12; \
+    MOVQ  R8,  0+x; \
+    MOVQ  R9,  8+x; \
+    MOVQ R10, 16+x; \
+    MOVQ R11, 24+x; \
+    MOVQ R12,  0+y; \
+    MOVQ R13,  8+y; \
+    MOVQ R14, 16+y; \
+    MOVQ R15, 24+y;
diff --git a/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s b/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s
new file mode 100644
index 00000000..1fcc2dee
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp25519/fp_amd64.s
@@ -0,0 +1,112 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+#include "textflag.h"
+#include "fp_amd64.h"
+
+// func cmovAmd64(x, y *Elt, n uint)
+TEXT ·cmovAmd64(SB),NOSPLIT,$0-24
+    MOVQ x+0(FP), DI
+    MOVQ y+8(FP), SI
+    MOVQ n+16(FP), BX
+    cselect(0(DI),0(SI),BX)
+    RET
+
+// func cswapAmd64(x, y *Elt, n uint)
+TEXT ·cswapAmd64(SB),NOSPLIT,$0-24
+    MOVQ x+0(FP), DI
+    MOVQ y+8(FP), SI
+    MOVQ n+16(FP), BX
+    cswap(0(DI),0(SI),BX)
+    RET
+
+// func subAmd64(z, x, y *Elt)
+TEXT ·subAmd64(SB),NOSPLIT,$0-24
+    MOVQ z+0(FP), DI
+    MOVQ x+8(FP), SI
+    MOVQ y+16(FP), BX
+    subtraction(0(DI),0(SI),0(BX))
+    RET
+
+// func addsubAmd64(x, y *Elt)
+TEXT ·addsubAmd64(SB),NOSPLIT,$0-16
+    MOVQ x+0(FP), DI
+    MOVQ y+8(FP), SI
+    addSub(0(DI),0(SI))
+    RET
+
+#define addLegacy \
+    additionLeg(0(DI),0(SI),0(BX))
+#define addBmi2Adx \
+    additionAdx(0(DI),0(SI),0(BX))
+
+#define mulLegacy \
+    integerMulLeg(0(SP),0(SI),0(BX)) \
+    reduceFromDoubleLeg(0(DI),0(SP))
+#define mulBmi2Adx \
+    integerMulAdx(0(SP),0(SI),0(BX)) \
+    reduceFromDoubleAdx(0(DI),0(SP))
+
+#define sqrLegacy \
+    integerSqrLeg(0(SP),0(SI)) \
+    reduceFromDoubleLeg(0(DI),0(SP))
+#define sqrBmi2Adx \
+    integerSqrAdx(0(SP),0(SI)) \
+    reduceFromDoubleAdx(0(DI),0(SP))
+
+// func addAmd64(z, x, y *Elt)
+TEXT ·addAmd64(SB),NOSPLIT,$0-24
+    MOVQ z+0(FP), DI
+    MOVQ x+8(FP), SI
+    MOVQ y+16(FP), BX
+    CHECK_BMI2ADX(LADD, addLegacy, addBmi2Adx)
+
+// func mulAmd64(z, x, y *Elt)
+TEXT ·mulAmd64(SB),NOSPLIT,$64-24
+    MOVQ z+0(FP), DI
+    MOVQ x+8(FP), SI
+    MOVQ y+16(FP), BX
+    CHECK_BMI2ADX(LMUL, mulLegacy, mulBmi2Adx)
+
+// func sqrAmd64(z, x *Elt)
+TEXT ·sqrAmd64(SB),NOSPLIT,$64-16
+    MOVQ z+0(FP), DI
+    MOVQ x+8(FP), SI
+    CHECK_BMI2ADX(LSQR, sqrLegacy, sqrBmi2Adx)
+
+// func modpAmd64(z *Elt)
+TEXT ·modpAmd64(SB),NOSPLIT,$0-8
+    MOVQ z+0(FP), DI
+
+    MOVQ   (DI),  R8
+    MOVQ  8(DI),  R9
+    MOVQ 16(DI), R10
+    MOVQ 24(DI), R11
+
+    MOVL $19, AX
+    MOVL $38, CX
+
+    BTRQ $63, R11 // PUT BIT 255 IN CARRY FLAG AND CLEAR
+    CMOVLCC AX, CX // C[255] ? 38 : 19
+
+    // ADD EITHER 19 OR 38 TO C
+    ADDQ CX,  R8
+    ADCQ $0,  R9
+    ADCQ $0, R10
+    ADCQ $0, R11
+
+    // TEST FOR BIT 255 AGAIN; ONLY TRIGGERED ON OVERFLOW MODULO 2^255-19
+    MOVL     $0,  CX
+    CMOVLPL  AX,  CX // C[255] ? 0 : 19
+    BTRQ    $63, R11 // CLEAR BIT 255
+
+    // SUBTRACT 19 IF NECESSARY
+    SUBQ CX,  R8
+    MOVQ  R8,   (DI)
+    SBBQ $0,  R9
+    MOVQ  R9,  8(DI)
+    SBBQ $0, R10
+    MOVQ R10, 16(DI)
+    SBBQ $0, R11
+    MOVQ R11, 24(DI)
+    RET
diff --git a/vendor/github.com/cloudflare/circl/math/fp25519/fp_generic.go b/vendor/github.com/cloudflare/circl/math/fp25519/fp_generic.go
new file mode 100644
index 00000000..32bc582a
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp25519/fp_generic.go
@@ -0,0 +1,317 @@
+package fp25519
+
+import (
+	"encoding/binary"
+	"math/bits"
+)
+
+func cmovGeneric(x, y *Elt, n uint) {
+	m := -uint64(n & 0x1)
+	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+
+	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+
+	x0 = (x0 &^ m) | (y0 & m)
+	x1 = (x1 &^ m) | (y1 & m)
+	x2 = (x2 &^ m) | (y2 & m)
+	x3 = (x3 &^ m) | (y3 & m)
+
+	binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
+	binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
+	binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
+	binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
+}
+
+func cswapGeneric(x, y *Elt, n uint) {
+	m := -uint64(n & 0x1)
+	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+
+	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+
+	t0 := m & (x0 ^ y0)
+	t1 := m & (x1 ^ y1)
+	t2 := m & (x2 ^ y2)
+	t3 := m & (x3 ^ y3)
+	x0 ^= t0
+	x1 ^= t1
+	x2 ^= t2
+	x3 ^= t3
+	y0 ^= t0
+	y1 ^= t1
+	y2 ^= t2
+	y3 ^= t3
+
+	binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
+	binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
+	binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
+	binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
+
+	binary.LittleEndian.PutUint64(y[0*8:1*8], y0)
+	binary.LittleEndian.PutUint64(y[1*8:2*8], y1)
+	binary.LittleEndian.PutUint64(y[2*8:3*8], y2)
+	binary.LittleEndian.PutUint64(y[3*8:4*8], y3)
+}
+
+func addGeneric(z, x, y *Elt) {
+	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+
+	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+
+	z0, c0 := bits.Add64(x0, y0, 0)
+	z1, c1 := bits.Add64(x1, y1, c0)
+	z2, c2 := bits.Add64(x2, y2, c1)
+	z3, c3 := bits.Add64(x3, y3, c2)
+
+	z0, c0 = bits.Add64(z0, (-c3)&38, 0)
+	z1, c1 = bits.Add64(z1, 0, c0)
+	z2, c2 = bits.Add64(z2, 0, c1)
+	z3, c3 = bits.Add64(z3, 0, c2)
+	z0, _ = bits.Add64(z0, (-c3)&38, 0)
+
+	binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
+	binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
+	binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
+	binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
+}
+
+func subGeneric(z, x, y *Elt) {
+	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+
+	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+
+	z0, c0 := bits.Sub64(x0, y0, 0)
+	z1, c1 := bits.Sub64(x1, y1, c0)
+	z2, c2 := bits.Sub64(x2, y2, c1)
+	z3, c3 := bits.Sub64(x3, y3, c2)
+
+	z0, c0 = bits.Sub64(z0, (-c3)&38, 0)
+	z1, c1 = bits.Sub64(z1, 0, c0)
+	z2, c2 = bits.Sub64(z2, 0, c1)
+	z3, c3 = bits.Sub64(z3, 0, c2)
+	z0, _ = bits.Sub64(z0, (-c3)&38, 0)
+
+	binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
+	binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
+	binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
+	binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
+}
+
+func addsubGeneric(x, y *Elt) {
+	z := &Elt{}
+	addGeneric(z, x, y)
+	subGeneric(y, x, y)
+	*x = *z
+}
+
+func mulGeneric(z, x, y *Elt) {
+	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+
+	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+
+	yi := y0
+	h0, l0 := bits.Mul64(x0, yi)
+	h1, l1 := bits.Mul64(x1, yi)
+	h2, l2 := bits.Mul64(x2, yi)
+	h3, l3 := bits.Mul64(x3, yi)
+
+	z0 := l0
+	a0, c0 := bits.Add64(h0, l1, 0)
+	a1, c1 := bits.Add64(h1, l2, c0)
+	a2, c2 := bits.Add64(h2, l3, c1)
+	a3, _ := bits.Add64(h3, 0, c2)
+
+	yi = y1
+	h0, l0 = bits.Mul64(x0, yi)
+	h1, l1 = bits.Mul64(x1, yi)
+	h2, l2 = bits.Mul64(x2, yi)
+	h3, l3 = bits.Mul64(x3, yi)
+
+	z1, c0 := bits.Add64(a0, l0, 0)
+	h0, c1 = bits.Add64(h0, l1, c0)
+	h1, c2 = bits.Add64(h1, l2, c1)
+	h2, c3 := bits.Add64(h2, l3, c2)
+	h3, _ = bits.Add64(h3, 0, c3)
+
+	a0, c0 = bits.Add64(a1, h0, 0)
+	a1, c1 = bits.Add64(a2, h1, c0)
+	a2, c2 = bits.Add64(a3, h2, c1)
+	a3, _ = bits.Add64(0, h3, c2)
+
+	yi = y2
+	h0, l0 = bits.Mul64(x0, yi)
+	h1, l1 = bits.Mul64(x1, yi)
+	h2, l2 = bits.Mul64(x2, yi)
+	h3, l3 = bits.Mul64(x3, yi)
+
+	z2, c0 := bits.Add64(a0, l0, 0)
+	h0, c1 = bits.Add64(h0, l1, c0)
+	h1, c2 = bits.Add64(h1, l2, c1)
+	h2, c3 = bits.Add64(h2, l3, c2)
+	h3, _ = bits.Add64(h3, 0, c3)
+
+	a0, c0 = bits.Add64(a1, h0, 0)
+	a1, c1 = bits.Add64(a2, h1, c0)
+	a2, c2 = bits.Add64(a3, h2, c1)
+	a3, _ = bits.Add64(0, h3, c2)
+
+	yi = y3
+	h0, l0 = bits.Mul64(x0, yi)
+	h1, l1 = bits.Mul64(x1, yi)
+	h2, l2 = bits.Mul64(x2, yi)
+	h3, l3 = bits.Mul64(x3, yi)
+
+	z3, c0 := bits.Add64(a0, l0, 0)
+	h0, c1 = bits.Add64(h0, l1, c0)
+	h1, c2 = bits.Add64(h1, l2, c1)
+	h2, c3 = bits.Add64(h2, l3, c2)
+	h3, _ = bits.Add64(h3, 0, c3)
+
+	z4, c0 := bits.Add64(a1, h0, 0)
+	z5, c1 := bits.Add64(a2, h1, c0)
+	z6, c2 := bits.Add64(a3, h2, c1)
+	z7, _ := bits.Add64(0, h3, c2)
+
+	red64(z, z0, z1, z2, z3, z4, z5, z6, z7)
+}
+
+func sqrGeneric(z, x *Elt) {
+	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+
+	h0, a0 := bits.Mul64(x0, x1)
+	h1, l1 := bits.Mul64(x0, x2)
+	h2, l2 := bits.Mul64(x0, x3)
+	h3, l3 := bits.Mul64(x3, x1)
+	h4, l4 := bits.Mul64(x3, x2)
+	h, l := bits.Mul64(x1, x2)
+
+	a1, c0 := bits.Add64(l1, h0, 0)
+	a2, c1 := bits.Add64(l2, h1, c0)
+	a3, c2 := bits.Add64(l3, h2, c1)
+	a4, c3 := bits.Add64(l4, h3, c2)
+	a5, _ := bits.Add64(h4, 0, c3)
+
+	a2, c0 = bits.Add64(a2, l, 0)
+	a3, c1 = bits.Add64(a3, h, c0)
+	a4, c2 = bits.Add64(a4, 0, c1)
+	a5, c3 = bits.Add64(a5, 0, c2)
+	a6, _ := bits.Add64(0, 0, c3)
+
+	a0, c0 = bits.Add64(a0, a0, 0)
+	a1, c1 = bits.Add64(a1, a1, c0)
+	a2, c2 = bits.Add64(a2, a2, c1)
+	a3, c3 = bits.Add64(a3, a3, c2)
+	a4, c4 := bits.Add64(a4, a4, c3)
+	a5, c5 := bits.Add64(a5, a5, c4)
+	a6, _ = bits.Add64(a6, a6, c5)
+
+	b1, b0 := bits.Mul64(x0, x0)
+	b3, b2 := bits.Mul64(x1, x1)
+	b5, b4 := bits.Mul64(x2, x2)
+	b7, b6 := bits.Mul64(x3, x3)
+
+	b1, c0 = bits.Add64(b1, a0, 0)
+	b2, c1 = bits.Add64(b2, a1, c0)
+	b3, c2 = bits.Add64(b3, a2, c1)
+	b4, c3 = bits.Add64(b4, a3, c2)
+	b5, c4 = bits.Add64(b5, a4, c3)
+	b6, c5 = bits.Add64(b6, a5, c4)
+	b7, _ = bits.Add64(b7, a6, c5)
+
+	red64(z, b0, b1, b2, b3, b4, b5, b6, b7)
+}
+
+func modpGeneric(x *Elt) {
+	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+
+	// CX = C[255] ? 38 : 19
+	cx := uint64(19) << (x3 >> 63)
+	// PUT BIT 255 IN CARRY FLAG AND CLEAR
+	x3 &^= 1 << 63
+
+	x0, c0 := bits.Add64(x0, cx, 0)
+	x1, c1 := bits.Add64(x1, 0, c0)
+	x2, c2 := bits.Add64(x2, 0, c1)
+	x3, _ = bits.Add64(x3, 0, c2)
+
+	// TEST FOR BIT 255 AGAIN; ONLY TRIGGERED ON OVERFLOW MODULO 2^255-19
+	// cx = C[255] ? 0 : 19
+	cx = uint64(19) &^ (-(x3 >> 63))
+	// CLEAR BIT 255
+	x3 &^= 1 << 63
+
+	x0, c0 = bits.Sub64(x0, cx, 0)
+	x1, c1 = bits.Sub64(x1, 0, c0)
+	x2, c2 = bits.Sub64(x2, 0, c1)
+	x3, _ = bits.Sub64(x3, 0, c2)
+
+	binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
+	binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
+	binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
+	binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
+}
+
+func red64(z *Elt, x0, x1, x2, x3, x4, x5, x6, x7 uint64) {
+	h0, l0 := bits.Mul64(x4, 38)
+	h1, l1 := bits.Mul64(x5, 38)
+	h2, l2 := bits.Mul64(x6, 38)
+	h3, l3 := bits.Mul64(x7, 38)
+
+	l1, c0 := bits.Add64(h0, l1, 0)
+	l2, c1 := bits.Add64(h1, l2, c0)
+	l3, c2 := bits.Add64(h2, l3, c1)
+	l4, _ := bits.Add64(h3, 0, c2)
+
+	l0, c0 = bits.Add64(l0, x0, 0)
+	l1, c1 = bits.Add64(l1, x1, c0)
+	l2, c2 = bits.Add64(l2, x2, c1)
+	l3, c3 := bits.Add64(l3, x3, c2)
+	l4, _ = bits.Add64(l4, 0, c3)
+
+	_, l4 = bits.Mul64(l4, 38)
+	l0, c0 = bits.Add64(l0, l4, 0)
+	z1, c1 := bits.Add64(l1, 0, c0)
+	z2, c2 := bits.Add64(l2, 0, c1)
+	z3, c3 := bits.Add64(l3, 0, c2)
+	z0, _ := bits.Add64(l0, (-c3)&38, 0)
+
+	binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
+	binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
+	binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
+	binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
+}
diff --git a/vendor/github.com/cloudflare/circl/math/fp25519/fp_noasm.go b/vendor/github.com/cloudflare/circl/math/fp25519/fp_noasm.go
new file mode 100644
index 00000000..26ca4d01
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp25519/fp_noasm.go
@@ -0,0 +1,13 @@
+//go:build !amd64 || purego
+// +build !amd64 purego
+
+package fp25519
+
+func cmov(x, y *Elt, n uint)  { cmovGeneric(x, y, n) }
+func cswap(x, y *Elt, n uint) { cswapGeneric(x, y, n) }
+func add(z, x, y *Elt)        { addGeneric(z, x, y) }
+func sub(z, x, y *Elt)        { subGeneric(z, x, y) }
+func addsub(x, y *Elt)        { addsubGeneric(x, y) }
+func mul(z, x, y *Elt)        { mulGeneric(z, x, y) }
+func sqr(z, x *Elt)           { sqrGeneric(z, x) }
+func modp(z *Elt)             { modpGeneric(z) }
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fp.go b/vendor/github.com/cloudflare/circl/math/fp448/fp.go
new file mode 100644
index 00000000..a5e36600
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp.go
@@ -0,0 +1,164 @@
+// Package fp448 provides prime field arithmetic over GF(2^448-2^224-1).
+package fp448
+
+import (
+	"errors"
+
+	"github.com/cloudflare/circl/internal/conv"
+)
+
+// Size in bytes of an element.
+const Size = 56
+
+// Elt is a prime field element.
+type Elt [Size]byte
+
+func (e Elt) String() string { return conv.BytesLe2Hex(e[:]) }
+
+// p is the prime modulus 2^448-2^224-1.
+var p = Elt{
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+}
+
+// P returns the prime modulus 2^448-2^224-1.
+func P() Elt { return p }
+
+// ToBytes stores in b the little-endian byte representation of x.
+func ToBytes(b []byte, x *Elt) error {
+	if len(b) != Size {
+		return errors.New("wrong size")
+	}
+	Modp(x)
+	copy(b, x[:])
+	return nil
+}
+
+// IsZero returns true if x is equal to 0.
+func IsZero(x *Elt) bool { Modp(x); return *x == Elt{} }
+
+// IsOne returns true if x is equal to 1.
+func IsOne(x *Elt) bool { Modp(x); return *x == Elt{1} }
+
+// SetOne assigns x=1.
+func SetOne(x *Elt) { *x = Elt{1} }
+
+// One returns the 1 element.
+func One() (x Elt) { x = Elt{1}; return }
+
+// Neg calculates z = -x.
+func Neg(z, x *Elt) { Sub(z, &p, x) }
+
+// Modp ensures that z is between [0,p-1].
+func Modp(z *Elt) { Sub(z, z, &p) }
+
+// InvSqrt calculates z = sqrt(x/y) iff x/y is a quadratic-residue. If so,
+// isQR = true; otherwise, isQR = false, since x/y is a quadratic non-residue,
+// and z = sqrt(-x/y).
+func InvSqrt(z, x, y *Elt) (isQR bool) {
+	// First note that x^(2(k+1)) = x^(p-1)/2 * x = legendre(x) * x
+	// so that's x if x is a quadratic residue and -x otherwise.
+	// Next, y^(6k+3) = y^(4k+2) * y^(2k+1) = y^(p-1) * y^((p-1)/2) = legendre(y).
+	// So the z we compute satisfies z^2 y = x^(2(k+1)) y^(6k+3) = legendre(x)*legendre(y).
+	// Thus if x and y are quadratic residues, then z is indeed sqrt(x/y).
+	t0, t1 := &Elt{}, &Elt{}
+	Mul(t0, x, y)         // x*y
+	Sqr(t1, y)            // y^2
+	Mul(t1, t0, t1)       // x*y^3
+	powPminus3div4(z, t1) // (x*y^3)^k
+	Mul(z, z, t0)         // z = x*y*(x*y^3)^k = x^(k+1) * y^(3k+1)
+
+	// Check if x/y is a quadratic residue
+	Sqr(t0, z)     // z^2
+	Mul(t0, t0, y) // y*z^2
+	Sub(t0, t0, x) // y*z^2-x
+	return IsZero(t0)
+}
+
+// Inv calculates z = 1/x mod p.
+func Inv(z, x *Elt) {
+	// Calculates z = x^(4k+1) = x^(p-3+1) = x^(p-2) = x^-1, where k = (p-3)/4.
+	t := &Elt{}
+	powPminus3div4(t, x) // t = x^k
+	Sqr(t, t)            // t = x^2k
+	Sqr(t, t)            // t = x^4k
+	Mul(z, t, x)         // z = x^(4k+1)
+}
+
+// powPminus3div4 calculates z = x^k mod p, where k = (p-3)/4.
+func powPminus3div4(z, x *Elt) {
+	x0, x1 := &Elt{}, &Elt{}
+	Sqr(z, x)
+	Mul(z, z, x)
+	Sqr(x0, z)
+	Mul(x0, x0, x)
+	Sqr(z, x0)
+	Sqr(z, z)
+	Sqr(z, z)
+	Mul(z, z, x0)
+	Sqr(x1, z)
+	for i := 0; i < 5; i++ {
+		Sqr(x1, x1)
+	}
+	Mul(x1, x1, z)
+	Sqr(z, x1)
+	for i := 0; i < 11; i++ {
+		Sqr(z, z)
+	}
+	Mul(z, z, x1)
+	Sqr(z, z)
+	Sqr(z, z)
+	Sqr(z, z)
+	Mul(z, z, x0)
+	Sqr(x1, z)
+	for i := 0; i < 26; i++ {
+		Sqr(x1, x1)
+	}
+	Mul(x1, x1, z)
+	Sqr(z, x1)
+	for i := 0; i < 53; i++ {
+		Sqr(z, z)
+	}
+	Mul(z, z, x1)
+	Sqr(z, z)
+	Sqr(z, z)
+	Sqr(z, z)
+	Mul(z, z, x0)
+	Sqr(x1, z)
+	for i := 0; i < 110; i++ {
+		Sqr(x1, x1)
+	}
+	Mul(x1, x1, z)
+	Sqr(z, x1)
+	Mul(z, z, x)
+	for i := 0; i < 223; i++ {
+		Sqr(z, z)
+	}
+	Mul(z, z, x1)
+}
+
+// Cmov assigns y to x if n is 1.
+func Cmov(x, y *Elt, n uint) { cmov(x, y, n) }
+
+// Cswap interchanges x and y if n is 1.
+func Cswap(x, y *Elt, n uint) { cswap(x, y, n) }
+
+// Add calculates z = x+y mod p.
+func Add(z, x, y *Elt) { add(z, x, y) }
+
+// Sub calculates z = x-y mod p.
+func Sub(z, x, y *Elt) { sub(z, x, y) }
+
+// AddSub calculates (x,y) = (x+y mod p, x-y mod p).
+func AddSub(x, y *Elt) { addsub(x, y) }
+
+// Mul calculates z = x*y mod p.
+func Mul(z, x, y *Elt) { mul(z, x, y) }
+
+// Sqr calculates z = x^2 mod p.
+func Sqr(z, x *Elt) { sqr(z, x) }
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.go b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.go
new file mode 100644
index 00000000..6a12209a
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.go
@@ -0,0 +1,43 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+package fp448
+
+import (
+	"golang.org/x/sys/cpu"
+)
+
+var hasBmi2Adx = cpu.X86.HasBMI2 && cpu.X86.HasADX
+
+var _ = hasBmi2Adx
+
+func cmov(x, y *Elt, n uint)  { cmovAmd64(x, y, n) }
+func cswap(x, y *Elt, n uint) { cswapAmd64(x, y, n) }
+func add(z, x, y *Elt)        { addAmd64(z, x, y) }
+func sub(z, x, y *Elt)        { subAmd64(z, x, y) }
+func addsub(x, y *Elt)        { addsubAmd64(x, y) }
+func mul(z, x, y *Elt)        { mulAmd64(z, x, y) }
+func sqr(z, x *Elt)           { sqrAmd64(z, x) }
+
+/* Functions defined in fp_amd64.s */
+
+//go:noescape
+func cmovAmd64(x, y *Elt, n uint)
+
+//go:noescape
+func cswapAmd64(x, y *Elt, n uint)
+
+//go:noescape
+func addAmd64(z, x, y *Elt)
+
+//go:noescape
+func subAmd64(z, x, y *Elt)
+
+//go:noescape
+func addsubAmd64(x, y *Elt)
+
+//go:noescape
+func mulAmd64(z, x, y *Elt)
+
+//go:noescape
+func sqrAmd64(z, x *Elt)
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.h b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.h
new file mode 100644
index 00000000..536fe5bd
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.h
@@ -0,0 +1,591 @@
+// This code was imported from https://github.com/armfazh/rfc7748_precomputed
+
+// CHECK_BMI2ADX triggers bmi2adx if supported,
+// otherwise it fallbacks to legacy code.
+#define CHECK_BMI2ADX(label, legacy, bmi2adx) \
+    CMPB ·hasBmi2Adx(SB), $0  \
+    JE label                  \
+    bmi2adx                   \
+    RET                       \
+    label:                    \
+    legacy                    \
+    RET
+
+// cselect is a conditional move
+// if b=1: it copies y into x;
+// if b=0: x remains with the same value;
+// if b<> 0,1: undefined.
+// Uses: AX, DX, FLAGS
+// Instr: x86_64, cmov
+#define cselect(x,y,b) \
+    TESTQ b, b \
+    MOVQ  0+x, AX; MOVQ  0+y, DX; CMOVQNE DX, AX; MOVQ AX,  0+x; \
+    MOVQ  8+x, AX; MOVQ  8+y, DX; CMOVQNE DX, AX; MOVQ AX,  8+x; \
+    MOVQ 16+x, AX; MOVQ 16+y, DX; CMOVQNE DX, AX; MOVQ AX, 16+x; \
+    MOVQ 24+x, AX; MOVQ 24+y, DX; CMOVQNE DX, AX; MOVQ AX, 24+x; \
+    MOVQ 32+x, AX; MOVQ 32+y, DX; CMOVQNE DX, AX; MOVQ AX, 32+x; \
+    MOVQ 40+x, AX; MOVQ 40+y, DX; CMOVQNE DX, AX; MOVQ AX, 40+x; \
+    MOVQ 48+x, AX; MOVQ 48+y, DX; CMOVQNE DX, AX; MOVQ AX, 48+x;
+
+// cswap is a conditional swap
+// if b=1: x,y <- y,x;
+// if b=0: x,y remain with the same values;
+// if b<> 0,1: undefined.
+// Uses: AX, DX, R8, FLAGS
+// Instr: x86_64, cmov
+#define cswap(x,y,b) \
+    TESTQ b, b \
+    MOVQ  0+x, AX; MOVQ AX, R8; MOVQ  0+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX,  0+x; MOVQ DX,  0+y; \
+    MOVQ  8+x, AX; MOVQ AX, R8; MOVQ  8+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX,  8+x; MOVQ DX,  8+y; \
+    MOVQ 16+x, AX; MOVQ AX, R8; MOVQ 16+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 16+x; MOVQ DX, 16+y; \
+    MOVQ 24+x, AX; MOVQ AX, R8; MOVQ 24+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 24+x; MOVQ DX, 24+y; \
+    MOVQ 32+x, AX; MOVQ AX, R8; MOVQ 32+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 32+x; MOVQ DX, 32+y; \
+    MOVQ 40+x, AX; MOVQ AX, R8; MOVQ 40+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 40+x; MOVQ DX, 40+y; \
+    MOVQ 48+x, AX; MOVQ AX, R8; MOVQ 48+y, DX; CMOVQNE DX, AX; CMOVQNE R8, DX; MOVQ AX, 48+x; MOVQ DX, 48+y;
+
+// additionLeg adds x and y and stores in z
+// Uses: AX, DX, R8-R14, FLAGS
+// Instr: x86_64
+#define additionLeg(z,x,y) \
+    MOVQ  0+x,  R8;  ADDQ  0+y,  R8; \
+    MOVQ  8+x,  R9;  ADCQ  8+y,  R9; \
+    MOVQ 16+x, R10;  ADCQ 16+y, R10; \
+    MOVQ 24+x, R11;  ADCQ 24+y, R11; \
+    MOVQ 32+x, R12;  ADCQ 32+y, R12; \
+    MOVQ 40+x, R13;  ADCQ 40+y, R13; \
+    MOVQ 48+x, R14;  ADCQ 48+y, R14; \
+    MOVQ   $0,  AX;  ADCQ   $0,  AX; \
+    MOVQ AX,  DX; \
+    SHLQ $32, DX; \
+    ADDQ AX,  R8; MOVQ  $0, AX; \
+    ADCQ $0,  R9; \
+    ADCQ $0, R10; \
+    ADCQ DX, R11; \
+    ADCQ $0, R12; \
+    ADCQ $0, R13; \
+    ADCQ $0, R14; \
+    ADCQ $0,  AX; \
+    MOVQ AX,  DX; \
+    SHLQ $32, DX; \
+    ADDQ AX,  R8;  MOVQ  R8,  0+z; \
+    ADCQ $0,  R9;  MOVQ  R9,  8+z; \
+    ADCQ $0, R10;  MOVQ R10, 16+z; \
+    ADCQ DX, R11;  MOVQ R11, 24+z; \
+    ADCQ $0, R12;  MOVQ R12, 32+z; \
+    ADCQ $0, R13;  MOVQ R13, 40+z; \
+    ADCQ $0, R14;  MOVQ R14, 48+z;
+
+
+// additionAdx adds x and y and stores in z
+// Uses: AX, DX, R8-R15, FLAGS
+// Instr: x86_64, adx
+#define additionAdx(z,x,y) \
+    MOVL $32, R15; \
+    XORL DX, DX; \
+    MOVQ  0+x,  R8;  ADCXQ  0+y,  R8; \
+    MOVQ  8+x,  R9;  ADCXQ  8+y,  R9; \
+    MOVQ 16+x, R10;  ADCXQ 16+y, R10; \
+    MOVQ 24+x, R11;  ADCXQ 24+y, R11; \
+    MOVQ 32+x, R12;  ADCXQ 32+y, R12; \
+    MOVQ 40+x, R13;  ADCXQ 40+y, R13; \
+    MOVQ 48+x, R14;  ADCXQ 48+y, R14; \
+    ;;;;;;;;;;;;;;;  ADCXQ   DX,  DX; \
+    XORL AX, AX; \
+    ADCXQ DX,  R8; SHLXQ R15, DX, DX; \
+    ADCXQ AX,  R9; \
+    ADCXQ AX, R10; \
+    ADCXQ DX, R11; \
+    ADCXQ AX, R12; \
+    ADCXQ AX, R13; \
+    ADCXQ AX, R14; \
+    ADCXQ AX,  AX; \
+    XORL  DX,  DX; \
+    ADCXQ AX,  R8;  MOVQ  R8,  0+z; SHLXQ R15, AX, AX; \
+    ADCXQ DX,  R9;  MOVQ  R9,  8+z; \
+    ADCXQ DX, R10;  MOVQ R10, 16+z; \
+    ADCXQ AX, R11;  MOVQ R11, 24+z; \
+    ADCXQ DX, R12;  MOVQ R12, 32+z; \
+    ADCXQ DX, R13;  MOVQ R13, 40+z; \
+    ADCXQ DX, R14;  MOVQ R14, 48+z;
+
+// subtraction subtracts y from x and stores in z
+// Uses: AX, DX, R8-R14, FLAGS
+// Instr: x86_64
+#define subtraction(z,x,y) \
+    MOVQ  0+x,  R8;  SUBQ  0+y,  R8; \
+    MOVQ  8+x,  R9;  SBBQ  8+y,  R9; \
+    MOVQ 16+x, R10;  SBBQ 16+y, R10; \
+    MOVQ 24+x, R11;  SBBQ 24+y, R11; \
+    MOVQ 32+x, R12;  SBBQ 32+y, R12; \
+    MOVQ 40+x, R13;  SBBQ 40+y, R13; \
+    MOVQ 48+x, R14;  SBBQ 48+y, R14; \
+    MOVQ   $0,  AX;  SETCS AX; \
+    MOVQ AX,  DX; \
+    SHLQ $32, DX; \
+    SUBQ AX,  R8; MOVQ  $0, AX; \
+    SBBQ $0,  R9; \
+    SBBQ $0, R10; \
+    SBBQ DX, R11; \
+    SBBQ $0, R12; \
+    SBBQ $0, R13; \
+    SBBQ $0, R14; \
+    SETCS AX; \
+    MOVQ AX,  DX; \
+    SHLQ $32, DX; \
+    SUBQ AX,  R8;  MOVQ  R8,  0+z; \
+    SBBQ $0,  R9;  MOVQ  R9,  8+z; \
+    SBBQ $0, R10;  MOVQ R10, 16+z; \
+    SBBQ DX, R11;  MOVQ R11, 24+z; \
+    SBBQ $0, R12;  MOVQ R12, 32+z; \
+    SBBQ $0, R13;  MOVQ R13, 40+z; \
+    SBBQ $0, R14;  MOVQ R14, 48+z;
+
+// maddBmi2Adx multiplies x and y and accumulates in z
+// Uses: AX, DX, R15, FLAGS
+// Instr: x86_64, bmi2, adx
+#define maddBmi2Adx(z,x,y,i,r0,r1,r2,r3,r4,r5,r6) \
+    MOVQ   i+y, DX; XORL AX, AX; \
+    MULXQ  0+x, AX, R8;  ADOXQ AX, r0;  ADCXQ R8, r1; MOVQ r0,i+z; \
+    MULXQ  8+x, AX, r0;  ADOXQ AX, r1;  ADCXQ r0, r2; MOVQ $0, R8; \
+    MULXQ 16+x, AX, r0;  ADOXQ AX, r2;  ADCXQ r0, r3; \
+    MULXQ 24+x, AX, r0;  ADOXQ AX, r3;  ADCXQ r0, r4; \
+    MULXQ 32+x, AX, r0;  ADOXQ AX, r4;  ADCXQ r0, r5; \
+    MULXQ 40+x, AX, r0;  ADOXQ AX, r5;  ADCXQ r0, r6; \
+    MULXQ 48+x, AX, r0;  ADOXQ AX, r6;  ADCXQ R8, r0; \
+    ;;;;;;;;;;;;;;;;;;;  ADOXQ R8, r0;
+
+// integerMulAdx multiplies x and y and stores in z
+// Uses: AX, DX, R8-R15, FLAGS
+// Instr: x86_64, bmi2, adx
+#define integerMulAdx(z,x,y) \
+    MOVL    $0,R15; \
+    MOVQ   0+y, DX;  XORL AX, AX;  MOVQ $0, R8; \
+    MULXQ  0+x, AX,  R9;  MOVQ  AX, 0+z; \
+    MULXQ  8+x, AX, R10;  ADCXQ AX,  R9; \
+    MULXQ 16+x, AX, R11;  ADCXQ AX, R10; \
+    MULXQ 24+x, AX, R12;  ADCXQ AX, R11; \
+    MULXQ 32+x, AX, R13;  ADCXQ AX, R12; \
+    MULXQ 40+x, AX, R14;  ADCXQ AX, R13; \
+    MULXQ 48+x, AX, R15;  ADCXQ AX, R14; \
+    ;;;;;;;;;;;;;;;;;;;;  ADCXQ R8, R15; \
+    maddBmi2Adx(z,x,y, 8, R9,R10,R11,R12,R13,R14,R15) \
+    maddBmi2Adx(z,x,y,16,R10,R11,R12,R13,R14,R15, R9) \
+    maddBmi2Adx(z,x,y,24,R11,R12,R13,R14,R15, R9,R10) \
+    maddBmi2Adx(z,x,y,32,R12,R13,R14,R15, R9,R10,R11) \
+    maddBmi2Adx(z,x,y,40,R13,R14,R15, R9,R10,R11,R12) \
+    maddBmi2Adx(z,x,y,48,R14,R15, R9,R10,R11,R12,R13) \
+    MOVQ R15,  56+z; \
+    MOVQ  R9,  64+z; \
+    MOVQ R10,  72+z; \
+    MOVQ R11,  80+z; \
+    MOVQ R12,  88+z; \
+    MOVQ R13,  96+z; \
+    MOVQ R14, 104+z;
+
+// maddLegacy multiplies x and y and accumulates in z
+// Uses: AX, DX, R15, FLAGS
+// Instr: x86_64
+#define maddLegacy(z,x,y,i) \
+    MOVQ  i+y, R15; \
+    MOVQ  0+x, AX; MULQ R15; MOVQ AX,  R8; ;;;;;;;;;;;; MOVQ DX,  R9; \
+    MOVQ  8+x, AX; MULQ R15; ADDQ AX,  R9; ADCQ $0, DX; MOVQ DX, R10; \
+    MOVQ 16+x, AX; MULQ R15; ADDQ AX, R10; ADCQ $0, DX; MOVQ DX, R11; \
+    MOVQ 24+x, AX; MULQ R15; ADDQ AX, R11; ADCQ $0, DX; MOVQ DX, R12; \
+    MOVQ 32+x, AX; MULQ R15; ADDQ AX, R12; ADCQ $0, DX; MOVQ DX, R13; \
+    MOVQ 40+x, AX; MULQ R15; ADDQ AX, R13; ADCQ $0, DX; MOVQ DX, R14; \
+    MOVQ 48+x, AX; MULQ R15; ADDQ AX, R14; ADCQ $0, DX; \
+    ADDQ  0+i+z,  R8; MOVQ  R8,  0+i+z; \
+    ADCQ  8+i+z,  R9; MOVQ  R9,  8+i+z; \
+    ADCQ 16+i+z, R10; MOVQ R10, 16+i+z; \
+    ADCQ 24+i+z, R11; MOVQ R11, 24+i+z; \
+    ADCQ 32+i+z, R12; MOVQ R12, 32+i+z; \
+    ADCQ 40+i+z, R13; MOVQ R13, 40+i+z; \
+    ADCQ 48+i+z, R14; MOVQ R14, 48+i+z; \
+    ADCQ     $0,  DX; MOVQ  DX, 56+i+z;
+
+// integerMulLeg multiplies x and y and stores in z
+// Uses: AX, DX, R8-R15, FLAGS
+// Instr: x86_64
+#define integerMulLeg(z,x,y) \
+    MOVQ  0+y, R15; \
+    MOVQ  0+x, AX; MULQ R15; MOVQ AX, 0+z; ;;;;;;;;;;;; MOVQ DX,  R8; \
+    MOVQ  8+x, AX; MULQ R15; ADDQ AX,  R8; ADCQ $0, DX; MOVQ DX,  R9; MOVQ  R8,  8+z; \
+    MOVQ 16+x, AX; MULQ R15; ADDQ AX,  R9; ADCQ $0, DX; MOVQ DX, R10; MOVQ  R9, 16+z; \
+    MOVQ 24+x, AX; MULQ R15; ADDQ AX, R10; ADCQ $0, DX; MOVQ DX, R11; MOVQ R10, 24+z; \
+    MOVQ 32+x, AX; MULQ R15; ADDQ AX, R11; ADCQ $0, DX; MOVQ DX, R12; MOVQ R11, 32+z; \
+    MOVQ 40+x, AX; MULQ R15; ADDQ AX, R12; ADCQ $0, DX; MOVQ DX, R13; MOVQ R12, 40+z; \
+    MOVQ 48+x, AX; MULQ R15; ADDQ AX, R13; ADCQ $0, DX; MOVQ DX,56+z; MOVQ R13, 48+z; \
+    maddLegacy(z,x,y, 8) \
+    maddLegacy(z,x,y,16) \
+    maddLegacy(z,x,y,24) \
+    maddLegacy(z,x,y,32) \
+    maddLegacy(z,x,y,40) \
+    maddLegacy(z,x,y,48)
+
+// integerSqrLeg squares x and stores in z
+// Uses: AX, CX, DX, R8-R15, FLAGS
+// Instr: x86_64
+#define integerSqrLeg(z,x) \
+    XORL R15, R15; \
+    MOVQ  0+x, CX; \
+    MOVQ   CX, AX; MULQ CX; MOVQ AX, 0+z; MOVQ DX, R8; \
+    ADDQ   CX, CX; ADCQ $0, R15; \
+    MOVQ  8+x, AX; MULQ CX; ADDQ AX,  R8; ADCQ $0, DX; MOVQ DX,  R9; MOVQ R8, 8+z; \
+    MOVQ 16+x, AX; MULQ CX; ADDQ AX,  R9; ADCQ $0, DX; MOVQ DX, R10; \
+    MOVQ 24+x, AX; MULQ CX; ADDQ AX, R10; ADCQ $0, DX; MOVQ DX, R11; \
+    MOVQ 32+x, AX; MULQ CX; ADDQ AX, R11; ADCQ $0, DX; MOVQ DX, R12; \
+    MOVQ 40+x, AX; MULQ CX; ADDQ AX, R12; ADCQ $0, DX; MOVQ DX, R13; \
+    MOVQ 48+x, AX; MULQ CX; ADDQ AX, R13; ADCQ $0, DX; MOVQ DX, R14; \
+    \
+    MOVQ  8+x, CX; \
+    MOVQ   CX, AX; ADDQ R15, CX; MOVQ $0, R15; ADCQ $0, R15; \
+    ;;;;;;;;;;;;;; MULQ CX; ADDQ  AX, R9; ADCQ $0, DX; MOVQ R9,16+z; \
+    MOVQ  R15, AX; NEGQ AX; ANDQ 8+x, AX; ADDQ AX, DX; ADCQ $0, R11; MOVQ DX, R8; \
+    ADDQ  8+x, CX; ADCQ $0, R15; \
+    MOVQ 16+x, AX; MULQ CX; ADDQ AX, R10; ADCQ $0, DX; ADDQ R8, R10; ADCQ $0, DX; MOVQ DX, R8; MOVQ R10, 24+z; \
+    MOVQ 24+x, AX; MULQ CX; ADDQ AX, R11; ADCQ $0, DX; ADDQ R8, R11; ADCQ $0, DX; MOVQ DX, R8; \
+    MOVQ 32+x, AX; MULQ CX; ADDQ AX, R12; ADCQ $0, DX; ADDQ R8, R12; ADCQ $0, DX; MOVQ DX, R8; \
+    MOVQ 40+x, AX; MULQ CX; ADDQ AX, R13; ADCQ $0, DX; ADDQ R8, R13; ADCQ $0, DX; MOVQ DX, R8; \
+    MOVQ 48+x, AX; MULQ CX; ADDQ AX, R14; ADCQ $0, DX; ADDQ R8, R14; ADCQ $0, DX; MOVQ DX, R9; \
+    \
+    MOVQ 16+x, CX; \
+    MOVQ   CX, AX; ADDQ R15, CX; MOVQ $0, R15; ADCQ $0, R15; \
+    ;;;;;;;;;;;;;; MULQ CX; ADDQ AX, R11; ADCQ $0, DX; MOVQ R11, 32+z; \
+    MOVQ  R15, AX; NEGQ AX; ANDQ 16+x,AX; ADDQ AX, DX; ADCQ $0, R13; MOVQ DX, R8; \
+    ADDQ 16+x, CX; ADCQ $0, R15; \
+    MOVQ 24+x, AX; MULQ CX; ADDQ AX, R12; ADCQ $0, DX; ADDQ R8, R12; ADCQ $0, DX; MOVQ DX, R8; MOVQ R12, 40+z; \
+    MOVQ 32+x, AX; MULQ CX; ADDQ AX, R13; ADCQ $0, DX; ADDQ R8, R13; ADCQ $0, DX; MOVQ DX, R8; \
+    MOVQ 40+x, AX; MULQ CX; ADDQ AX, R14; ADCQ $0, DX; ADDQ R8, R14; ADCQ $0, DX; MOVQ DX, R8; \
+    MOVQ 48+x, AX; MULQ CX; ADDQ AX,  R9; ADCQ $0, DX; ADDQ R8,  R9; ADCQ $0, DX; MOVQ DX,R10; \
+    \
+    MOVQ 24+x, CX; \
+    MOVQ   CX, AX; ADDQ R15, CX; MOVQ $0, R15; ADCQ $0, R15; \
+    ;;;;;;;;;;;;;; MULQ CX; ADDQ AX, R13; ADCQ $0, DX; MOVQ R13, 48+z; \
+    MOVQ  R15, AX; NEGQ AX; ANDQ 24+x,AX; ADDQ AX, DX; ADCQ $0,  R9; MOVQ DX, R8; \
+    ADDQ 24+x, CX; ADCQ $0, R15; \
+    MOVQ 32+x, AX; MULQ CX; ADDQ AX, R14; ADCQ $0, DX; ADDQ R8, R14; ADCQ $0, DX; MOVQ DX, R8; MOVQ R14, 56+z; \
+    MOVQ 40+x, AX; MULQ CX; ADDQ AX,  R9; ADCQ $0, DX; ADDQ R8,  R9; ADCQ $0, DX; MOVQ DX, R8; \
+    MOVQ 48+x, AX; MULQ CX; ADDQ AX, R10; ADCQ $0, DX; ADDQ R8, R10; ADCQ $0, DX; MOVQ DX,R11; \
+    \
+    MOVQ 32+x, CX; \
+    MOVQ   CX, AX; ADDQ R15, CX; MOVQ $0, R15; ADCQ $0, R15; \
+    ;;;;;;;;;;;;;; MULQ CX; ADDQ AX,  R9; ADCQ $0, DX; MOVQ R9, 64+z; \
+    MOVQ  R15, AX; NEGQ AX; ANDQ 32+x,AX; ADDQ AX, DX; ADCQ $0, R11; MOVQ DX, R8; \
+    ADDQ 32+x, CX; ADCQ $0, R15; \
+    MOVQ 40+x, AX; MULQ CX; ADDQ AX, R10; ADCQ $0, DX; ADDQ R8, R10; ADCQ $0, DX; MOVQ DX, R8; MOVQ R10, 72+z; \
+    MOVQ 48+x, AX; MULQ CX; ADDQ AX, R11; ADCQ $0, DX; ADDQ R8, R11; ADCQ $0, DX; MOVQ DX,R12; \
+    \
+    XORL R13, R13; \
+    XORL R14, R14; \
+    MOVQ 40+x, CX; \
+    MOVQ   CX, AX; ADDQ R15, CX; MOVQ $0, R15; ADCQ $0, R15; \
+    ;;;;;;;;;;;;;; MULQ CX; ADDQ AX, R11; ADCQ $0, DX; MOVQ R11, 80+z; \
+    MOVQ  R15, AX; NEGQ AX; ANDQ 40+x,AX; ADDQ AX, DX; ADCQ $0, R13; MOVQ DX, R8; \
+    ADDQ 40+x, CX; ADCQ $0, R15; \
+    MOVQ 48+x, AX; MULQ CX; ADDQ AX, R12; ADCQ $0, DX; ADDQ R8, R12; ADCQ $0, DX; MOVQ DX, R8; MOVQ R12, 88+z; \
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ADDQ R8, R13; ADCQ $0,R14; \
+    \
+    XORL   R9, R9; \
+    MOVQ 48+x, CX; \
+    MOVQ   CX, AX; ADDQ R15, CX; MOVQ $0, R15; ADCQ $0, R15; \
+    ;;;;;;;;;;;;;; MULQ CX; ADDQ AX, R13; ADCQ $0, DX; MOVQ R13, 96+z; \
+    MOVQ  R15, AX; NEGQ AX; ANDQ 48+x,AX; ADDQ AX, DX; ADCQ $0, R9; MOVQ DX, R8; \
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ADDQ R8,R14; ADCQ $0, R9; MOVQ R14, 104+z;
+
+
+// integerSqrAdx squares x and stores in z
+// Uses: AX, CX, DX, R8-R15, FLAGS
+// Instr: x86_64, bmi2, adx
+#define integerSqrAdx(z,x) \
+    XORL R15, R15; \
+    MOVQ  0+x, DX; \
+    ;;;;;;;;;;;;;; MULXQ DX, AX, R8; MOVQ AX, 0+z; \
+    ADDQ   DX, DX; ADCQ $0, R15; CLC; \
+    MULXQ  8+x, AX,  R9; ADCXQ AX,  R8; MOVQ R8, 8+z; \
+    MULXQ 16+x, AX, R10; ADCXQ AX,  R9; MOVQ $0, R8;\
+    MULXQ 24+x, AX, R11; ADCXQ AX, R10; \
+    MULXQ 32+x, AX, R12; ADCXQ AX, R11; \
+    MULXQ 40+x, AX, R13; ADCXQ AX, R12; \
+    MULXQ 48+x, AX, R14; ADCXQ AX, R13; \
+    ;;;;;;;;;;;;;;;;;;;; ADCXQ R8, R14; \
+    \
+    MOVQ  8+x, DX; \
+    MOVQ   DX, AX; ADDQ R15, DX; MOVQ $0, R15; ADCQ  $0, R15; \
+    MULXQ AX,  AX, CX; \
+    MOVQ R15,  R8; NEGQ R8; ANDQ 8+x, R8; \
+    ADDQ AX,  R9; MOVQ R9, 16+z; \
+    ADCQ CX,  R8; \
+    ADCQ $0, R11; \
+    ADDQ  8+x,  DX; \
+    ADCQ   $0, R15; \
+    XORL R9, R9; ;;;;;;;;;;;;;;;;;;;;; ADOXQ R8, R10; \
+    MULXQ 16+x, AX, CX; ADCXQ AX, R10; ADOXQ CX, R11; MOVQ R10, 24+z; \
+    MULXQ 24+x, AX, CX; ADCXQ AX, R11; ADOXQ CX, R12; MOVQ  $0, R10; \
+    MULXQ 32+x, AX, CX; ADCXQ AX, R12; ADOXQ CX, R13; \
+    MULXQ 40+x, AX, CX; ADCXQ AX, R13; ADOXQ CX, R14; \
+    MULXQ 48+x, AX, CX; ADCXQ AX, R14; ADOXQ CX,  R9; \
+    ;;;;;;;;;;;;;;;;;;; ADCXQ R10, R9; \
+    \
+    MOVQ 16+x, DX; \
+    MOVQ   DX, AX; ADDQ R15, DX; MOVQ $0, R15; ADCQ  $0, R15; \
+    MULXQ AX,  AX, CX; \
+    MOVQ R15,  R8; NEGQ R8; ANDQ 16+x, R8; \
+    ADDQ AX, R11; MOVQ R11, 32+z; \
+    ADCQ CX,  R8; \
+    ADCQ $0, R13; \
+    ADDQ 16+x,  DX; \
+    ADCQ   $0, R15; \
+    XORL R11, R11; ;;;;;;;;;;;;;;;;;;; ADOXQ R8, R12; \
+    MULXQ 24+x, AX, CX; ADCXQ AX, R12; ADOXQ CX, R13; MOVQ R12, 40+z; \
+    MULXQ 32+x, AX, CX; ADCXQ AX, R13; ADOXQ CX, R14; MOVQ  $0, R12; \
+    MULXQ 40+x, AX, CX; ADCXQ AX, R14; ADOXQ CX,  R9; \
+    MULXQ 48+x, AX, CX; ADCXQ AX,  R9; ADOXQ CX, R10; \
+    ;;;;;;;;;;;;;;;;;;; ADCXQ R11,R10; \
+    \
+    MOVQ 24+x, DX; \
+    MOVQ   DX, AX; ADDQ R15, DX; MOVQ $0, R15; ADCQ  $0, R15; \
+    MULXQ AX,  AX, CX; \
+    MOVQ R15,  R8; NEGQ R8; ANDQ 24+x, R8; \
+    ADDQ AX, R13; MOVQ R13, 48+z; \
+    ADCQ CX,  R8; \
+    ADCQ $0,  R9; \
+    ADDQ 24+x,  DX; \
+    ADCQ   $0, R15; \
+    XORL R13, R13; ;;;;;;;;;;;;;;;;;;; ADOXQ R8, R14; \
+    MULXQ 32+x, AX, CX; ADCXQ AX, R14; ADOXQ CX,  R9; MOVQ R14, 56+z; \
+    MULXQ 40+x, AX, CX; ADCXQ AX,  R9; ADOXQ CX, R10; MOVQ  $0, R14; \
+    MULXQ 48+x, AX, CX; ADCXQ AX, R10; ADOXQ CX, R11; \
+    ;;;;;;;;;;;;;;;;;;; ADCXQ R12,R11; \
+    \
+    MOVQ 32+x, DX; \
+    MOVQ   DX, AX; ADDQ R15, DX; MOVQ $0, R15; ADCQ  $0, R15; \
+    MULXQ AX,  AX, CX; \
+    MOVQ R15,  R8; NEGQ R8; ANDQ 32+x, R8; \
+    ADDQ AX,  R9; MOVQ R9, 64+z; \
+    ADCQ CX,  R8; \
+    ADCQ $0, R11; \
+    ADDQ 32+x,  DX; \
+    ADCQ   $0, R15; \
+    XORL R9, R9; ;;;;;;;;;;;;;;;;;;;;; ADOXQ R8, R10; \
+    MULXQ 40+x, AX, CX; ADCXQ AX, R10; ADOXQ CX, R11; MOVQ R10, 72+z; \
+    MULXQ 48+x, AX, CX; ADCXQ AX, R11; ADOXQ CX, R12; \
+    ;;;;;;;;;;;;;;;;;;; ADCXQ R13,R12; \
+    \
+    MOVQ 40+x, DX; \
+    MOVQ   DX, AX; ADDQ R15, DX; MOVQ $0, R15; ADCQ  $0, R15; \
+    MULXQ AX,  AX, CX; \
+    MOVQ R15,  R8; NEGQ R8; ANDQ 40+x, R8; \
+    ADDQ AX, R11; MOVQ R11, 80+z; \
+    ADCQ CX,  R8; \
+    ADCQ $0, R13; \
+    ADDQ 40+x,  DX; \
+    ADCQ   $0, R15; \
+    XORL R11, R11; ;;;;;;;;;;;;;;;;;;; ADOXQ R8, R12; \
+    MULXQ 48+x, AX, CX; ADCXQ AX, R12; ADOXQ CX, R13; MOVQ R12, 88+z; \
+    ;;;;;;;;;;;;;;;;;;; ADCXQ R14,R13; \
+    \
+    MOVQ 48+x, DX; \
+    MOVQ   DX, AX; ADDQ R15, DX; MOVQ $0, R15; ADCQ  $0, R15; \
+    MULXQ AX,  AX, CX; \
+    MOVQ R15,  R8; NEGQ R8; ANDQ 48+x, R8; \
+    XORL R10, R10; ;;;;;;;;;;;;;; ADOXQ CX, R14; \
+    ;;;;;;;;;;;;;; ADCXQ AX, R13; ;;;;;;;;;;;;;; MOVQ R13, 96+z; \
+    ;;;;;;;;;;;;;; ADCXQ R8, R14; MOVQ R14, 104+z;
+
+// reduceFromDoubleLeg finds a z=x modulo p such that z<2^448 and stores in z
+// Uses: AX, R8-R15, FLAGS
+// Instr: x86_64
+#define reduceFromDoubleLeg(z,x) \
+    /* (   ,2C13,2C12,2C11,2C10|C10,C9,C8, C7) + (C6,...,C0) */ \
+    /* (r14, r13, r12, r11,     r10,r9,r8,r15) */ \
+    MOVQ 80+x,AX; MOVQ AX,R10; \
+    MOVQ $0xFFFFFFFF00000000, R8; \
+    ANDQ R8,R10; \
+    \
+    MOVQ $0,R14; \
+    MOVQ 104+x,R13; SHLQ $1,R13,R14; \
+    MOVQ  96+x,R12; SHLQ $1,R12,R13; \
+    MOVQ  88+x,R11; SHLQ $1,R11,R12; \
+    MOVQ  72+x, R9; SHLQ $1,R10,R11; \
+    MOVQ  64+x, R8; SHLQ $1,R10; \
+    MOVQ $0xFFFFFFFF,R15; ANDQ R15,AX; ORQ AX,R10; \
+    MOVQ  56+x,R15; \
+    \
+    ADDQ  0+x,R15; MOVQ R15, 0+z; MOVQ  56+x,R15; \
+    ADCQ  8+x, R8; MOVQ  R8, 8+z; MOVQ  64+x, R8; \
+    ADCQ 16+x, R9; MOVQ  R9,16+z; MOVQ  72+x, R9; \
+    ADCQ 24+x,R10; MOVQ R10,24+z; MOVQ  80+x,R10; \
+    ADCQ 32+x,R11; MOVQ R11,32+z; MOVQ  88+x,R11; \
+    ADCQ 40+x,R12; MOVQ R12,40+z; MOVQ  96+x,R12; \
+    ADCQ 48+x,R13; MOVQ R13,48+z; MOVQ 104+x,R13; \
+    ADCQ   $0,R14; \
+    /* (c10c9,c9c8,c8c7,c7c13,c13c12,c12c11,c11c10) + (c6,...,c0) */ \
+    /* (   r9,  r8, r15,  r13,   r12,   r11,   r10) */ \
+    MOVQ R10, AX; \
+    SHRQ $32,R11,R10; \
+    SHRQ $32,R12,R11; \
+    SHRQ $32,R13,R12; \
+    SHRQ $32,R15,R13; \
+    SHRQ $32, R8,R15; \
+    SHRQ $32, R9, R8; \
+    SHRQ $32, AX, R9; \
+    \
+    ADDQ  0+z,R10; \
+    ADCQ  8+z,R11; \
+    ADCQ 16+z,R12; \
+    ADCQ 24+z,R13; \
+    ADCQ 32+z,R15; \
+    ADCQ 40+z, R8; \
+    ADCQ 48+z, R9; \
+    ADCQ   $0,R14; \
+    /* ( c7) + (c6,...,c0) */ \
+    /* (r14) */ \
+    MOVQ R14, AX; SHLQ $32, AX; \
+    ADDQ R14,R10; MOVQ  $0,R14; \
+    ADCQ  $0,R11; \
+    ADCQ  $0,R12; \
+    ADCQ  AX,R13; \
+    ADCQ  $0,R15; \
+    ADCQ  $0, R8; \
+    ADCQ  $0, R9; \
+    ADCQ  $0,R14; \
+    /* ( c7) + (c6,...,c0) */ \
+    /* (r14) */ \
+    MOVQ R14, AX; SHLQ $32,AX; \
+    ADDQ R14,R10; MOVQ R10, 0+z; \
+    ADCQ  $0,R11; MOVQ R11, 8+z; \
+    ADCQ  $0,R12; MOVQ R12,16+z; \
+    ADCQ  AX,R13; MOVQ R13,24+z; \
+    ADCQ  $0,R15; MOVQ R15,32+z; \
+    ADCQ  $0, R8; MOVQ  R8,40+z; \
+    ADCQ  $0, R9; MOVQ  R9,48+z;
+
+// reduceFromDoubleAdx finds a z=x modulo p such that z<2^448 and stores in z
+// Uses: AX, R8-R15, FLAGS
+// Instr: x86_64, adx
+#define reduceFromDoubleAdx(z,x) \
+    /* (   ,2C13,2C12,2C11,2C10|C10,C9,C8, C7) + (C6,...,C0) */ \
+    /* (r14, r13, r12, r11,     r10,r9,r8,r15) */ \
+    MOVQ 80+x,AX; MOVQ AX,R10; \
+    MOVQ $0xFFFFFFFF00000000, R8; \
+    ANDQ R8,R10; \
+    \
+    MOVQ $0,R14; \
+    MOVQ 104+x,R13; SHLQ $1,R13,R14; \
+    MOVQ  96+x,R12; SHLQ $1,R12,R13; \
+    MOVQ  88+x,R11; SHLQ $1,R11,R12; \
+    MOVQ  72+x, R9; SHLQ $1,R10,R11; \
+    MOVQ  64+x, R8; SHLQ $1,R10; \
+    MOVQ $0xFFFFFFFF,R15; ANDQ R15,AX; ORQ AX,R10; \
+    MOVQ  56+x,R15; \
+    \
+    XORL AX,AX; \
+    ADCXQ  0+x,R15; MOVQ R15, 0+z; MOVQ  56+x,R15; \
+    ADCXQ  8+x, R8; MOVQ  R8, 8+z; MOVQ  64+x, R8; \
+    ADCXQ 16+x, R9; MOVQ  R9,16+z; MOVQ  72+x, R9; \
+    ADCXQ 24+x,R10; MOVQ R10,24+z; MOVQ  80+x,R10; \
+    ADCXQ 32+x,R11; MOVQ R11,32+z; MOVQ  88+x,R11; \
+    ADCXQ 40+x,R12; MOVQ R12,40+z; MOVQ  96+x,R12; \
+    ADCXQ 48+x,R13; MOVQ R13,48+z; MOVQ 104+x,R13; \
+    ADCXQ   AX,R14; \
+    /* (c10c9,c9c8,c8c7,c7c13,c13c12,c12c11,c11c10) + (c6,...,c0) */ \
+    /* (   r9,  r8, r15,  r13,   r12,   r11,   r10) */ \
+    MOVQ R10, AX; \
+    SHRQ $32,R11,R10; \
+    SHRQ $32,R12,R11; \
+    SHRQ $32,R13,R12; \
+    SHRQ $32,R15,R13; \
+    SHRQ $32, R8,R15; \
+    SHRQ $32, R9, R8; \
+    SHRQ $32, AX, R9; \
+    \
+    XORL AX,AX; \
+    ADCXQ  0+z,R10; \
+    ADCXQ  8+z,R11; \
+    ADCXQ 16+z,R12; \
+    ADCXQ 24+z,R13; \
+    ADCXQ 32+z,R15; \
+    ADCXQ 40+z, R8; \
+    ADCXQ 48+z, R9; \
+    ADCXQ   AX,R14; \
+    /* ( c7) + (c6,...,c0) */ \
+    /* (r14) */ \
+    MOVQ R14, AX; SHLQ $32, AX; \
+    CLC; \
+    ADCXQ R14,R10; MOVQ $0,R14; \
+    ADCXQ R14,R11; \
+    ADCXQ R14,R12; \
+    ADCXQ  AX,R13; \
+    ADCXQ R14,R15; \
+    ADCXQ R14, R8; \
+    ADCXQ R14, R9; \
+    ADCXQ R14,R14; \
+    /* ( c7) + (c6,...,c0) */ \
+    /* (r14) */ \
+    MOVQ R14, AX; SHLQ $32, AX; \
+    CLC; \
+    ADCXQ R14,R10; MOVQ R10, 0+z; MOVQ $0,R14; \
+    ADCXQ R14,R11; MOVQ R11, 8+z; \
+    ADCXQ R14,R12; MOVQ R12,16+z; \
+    ADCXQ  AX,R13; MOVQ R13,24+z; \
+    ADCXQ R14,R15; MOVQ R15,32+z; \
+    ADCXQ R14, R8; MOVQ  R8,40+z; \
+    ADCXQ R14, R9; MOVQ  R9,48+z;
+
+// addSub calculates two operations: x,y = x+y,x-y
+// Uses: AX, DX, R8-R15, FLAGS
+#define addSub(x,y) \
+    MOVQ  0+x,  R8;  ADDQ  0+y,  R8; \
+    MOVQ  8+x,  R9;  ADCQ  8+y,  R9; \
+    MOVQ 16+x, R10;  ADCQ 16+y, R10; \
+    MOVQ 24+x, R11;  ADCQ 24+y, R11; \
+    MOVQ 32+x, R12;  ADCQ 32+y, R12; \
+    MOVQ 40+x, R13;  ADCQ 40+y, R13; \
+    MOVQ 48+x, R14;  ADCQ 48+y, R14; \
+    MOVQ   $0,  AX;  ADCQ   $0,  AX; \
+    MOVQ AX,  DX; \
+    SHLQ $32, DX; \
+    ADDQ AX,  R8; MOVQ  $0, AX; \
+    ADCQ $0,  R9; \
+    ADCQ $0, R10; \
+    ADCQ DX, R11; \
+    ADCQ $0, R12; \
+    ADCQ $0, R13; \
+    ADCQ $0, R14; \
+    ADCQ $0,  AX; \
+    MOVQ AX,  DX; \
+    SHLQ $32, DX; \
+    ADDQ AX,  R8;  MOVQ  0+x,AX; MOVQ  R8,  0+x; MOVQ AX,  R8; \
+    ADCQ $0,  R9;  MOVQ  8+x,AX; MOVQ  R9,  8+x; MOVQ AX,  R9; \
+    ADCQ $0, R10;  MOVQ 16+x,AX; MOVQ R10, 16+x; MOVQ AX, R10; \
+    ADCQ DX, R11;  MOVQ 24+x,AX; MOVQ R11, 24+x; MOVQ AX, R11; \
+    ADCQ $0, R12;  MOVQ 32+x,AX; MOVQ R12, 32+x; MOVQ AX, R12; \
+    ADCQ $0, R13;  MOVQ 40+x,AX; MOVQ R13, 40+x; MOVQ AX, R13; \
+    ADCQ $0, R14;  MOVQ 48+x,AX; MOVQ R14, 48+x; MOVQ AX, R14; \
+    SUBQ  0+y,  R8; \
+    SBBQ  8+y,  R9; \
+    SBBQ 16+y, R10; \
+    SBBQ 24+y, R11; \
+    SBBQ 32+y, R12; \
+    SBBQ 40+y, R13; \
+    SBBQ 48+y, R14; \
+    MOVQ   $0,  AX;  SETCS AX; \
+    MOVQ AX,  DX; \
+    SHLQ $32, DX; \
+    SUBQ AX,  R8; MOVQ  $0, AX; \
+    SBBQ $0,  R9; \
+    SBBQ $0, R10; \
+    SBBQ DX, R11; \
+    SBBQ $0, R12; \
+    SBBQ $0, R13; \
+    SBBQ $0, R14; \
+    SETCS AX; \
+    MOVQ AX,  DX; \
+    SHLQ $32, DX; \
+    SUBQ AX,  R8;  MOVQ  R8,  0+y; \
+    SBBQ $0,  R9;  MOVQ  R9,  8+y; \
+    SBBQ $0, R10;  MOVQ R10, 16+y; \
+    SBBQ DX, R11;  MOVQ R11, 24+y; \
+    SBBQ $0, R12;  MOVQ R12, 32+y; \
+    SBBQ $0, R13;  MOVQ R13, 40+y; \
+    SBBQ $0, R14;  MOVQ R14, 48+y;
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s
new file mode 100644
index 00000000..3f1f07c9
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp_amd64.s
@@ -0,0 +1,75 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+#include "textflag.h"
+#include "fp_amd64.h"
+
+// func cmovAmd64(x, y *Elt, n uint)
+TEXT ·cmovAmd64(SB),NOSPLIT,$0-24
+    MOVQ x+0(FP), DI
+    MOVQ y+8(FP), SI
+    MOVQ n+16(FP), BX
+    cselect(0(DI),0(SI),BX)
+    RET
+
+// func cswapAmd64(x, y *Elt, n uint)
+TEXT ·cswapAmd64(SB),NOSPLIT,$0-24
+    MOVQ x+0(FP), DI
+    MOVQ y+8(FP), SI
+    MOVQ n+16(FP), BX
+    cswap(0(DI),0(SI),BX)
+    RET
+
+// func subAmd64(z, x, y *Elt)
+TEXT ·subAmd64(SB),NOSPLIT,$0-24
+    MOVQ z+0(FP), DI
+    MOVQ x+8(FP), SI
+    MOVQ y+16(FP), BX
+    subtraction(0(DI),0(SI),0(BX))
+    RET
+
+// func addsubAmd64(x, y *Elt)
+TEXT ·addsubAmd64(SB),NOSPLIT,$0-16
+    MOVQ x+0(FP), DI
+    MOVQ y+8(FP), SI
+    addSub(0(DI),0(SI))
+    RET
+
+#define addLegacy \
+    additionLeg(0(DI),0(SI),0(BX))
+#define addBmi2Adx \
+    additionAdx(0(DI),0(SI),0(BX))
+
+#define mulLegacy \
+    integerMulLeg(0(SP),0(SI),0(BX)) \
+    reduceFromDoubleLeg(0(DI),0(SP))
+#define mulBmi2Adx \
+    integerMulAdx(0(SP),0(SI),0(BX)) \
+    reduceFromDoubleAdx(0(DI),0(SP))
+
+#define sqrLegacy \
+    integerSqrLeg(0(SP),0(SI)) \
+    reduceFromDoubleLeg(0(DI),0(SP))
+#define sqrBmi2Adx \
+    integerSqrAdx(0(SP),0(SI)) \
+    reduceFromDoubleAdx(0(DI),0(SP))
+
+// func addAmd64(z, x, y *Elt)
+TEXT ·addAmd64(SB),NOSPLIT,$0-24
+    MOVQ z+0(FP), DI
+    MOVQ x+8(FP), SI
+    MOVQ y+16(FP), BX
+    CHECK_BMI2ADX(LADD, addLegacy, addBmi2Adx)
+
+// func mulAmd64(z, x, y *Elt)
+TEXT ·mulAmd64(SB),NOSPLIT,$112-24
+    MOVQ z+0(FP), DI
+    MOVQ x+8(FP), SI
+    MOVQ y+16(FP), BX
+    CHECK_BMI2ADX(LMUL, mulLegacy, mulBmi2Adx)
+
+// func sqrAmd64(z, x *Elt)
+TEXT ·sqrAmd64(SB),NOSPLIT,$112-16
+    MOVQ z+0(FP), DI
+    MOVQ x+8(FP), SI
+    CHECK_BMI2ADX(LSQR, sqrLegacy, sqrBmi2Adx)
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fp_generic.go b/vendor/github.com/cloudflare/circl/math/fp448/fp_generic.go
new file mode 100644
index 00000000..47a0b632
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp_generic.go
@@ -0,0 +1,339 @@
+package fp448
+
+import (
+	"encoding/binary"
+	"math/bits"
+)
+
+func cmovGeneric(x, y *Elt, n uint) {
+	m := -uint64(n & 0x1)
+	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+	x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
+	x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
+	x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
+
+	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+	y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
+	y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
+	y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
+
+	x0 = (x0 &^ m) | (y0 & m)
+	x1 = (x1 &^ m) | (y1 & m)
+	x2 = (x2 &^ m) | (y2 & m)
+	x3 = (x3 &^ m) | (y3 & m)
+	x4 = (x4 &^ m) | (y4 & m)
+	x5 = (x5 &^ m) | (y5 & m)
+	x6 = (x6 &^ m) | (y6 & m)
+
+	binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
+	binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
+	binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
+	binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
+	binary.LittleEndian.PutUint64(x[4*8:5*8], x4)
+	binary.LittleEndian.PutUint64(x[5*8:6*8], x5)
+	binary.LittleEndian.PutUint64(x[6*8:7*8], x6)
+}
+
+func cswapGeneric(x, y *Elt, n uint) {
+	m := -uint64(n & 0x1)
+	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+	x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
+	x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
+	x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
+
+	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+	y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
+	y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
+	y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
+
+	t0 := m & (x0 ^ y0)
+	t1 := m & (x1 ^ y1)
+	t2 := m & (x2 ^ y2)
+	t3 := m & (x3 ^ y3)
+	t4 := m & (x4 ^ y4)
+	t5 := m & (x5 ^ y5)
+	t6 := m & (x6 ^ y6)
+	x0 ^= t0
+	x1 ^= t1
+	x2 ^= t2
+	x3 ^= t3
+	x4 ^= t4
+	x5 ^= t5
+	x6 ^= t6
+	y0 ^= t0
+	y1 ^= t1
+	y2 ^= t2
+	y3 ^= t3
+	y4 ^= t4
+	y5 ^= t5
+	y6 ^= t6
+
+	binary.LittleEndian.PutUint64(x[0*8:1*8], x0)
+	binary.LittleEndian.PutUint64(x[1*8:2*8], x1)
+	binary.LittleEndian.PutUint64(x[2*8:3*8], x2)
+	binary.LittleEndian.PutUint64(x[3*8:4*8], x3)
+	binary.LittleEndian.PutUint64(x[4*8:5*8], x4)
+	binary.LittleEndian.PutUint64(x[5*8:6*8], x5)
+	binary.LittleEndian.PutUint64(x[6*8:7*8], x6)
+
+	binary.LittleEndian.PutUint64(y[0*8:1*8], y0)
+	binary.LittleEndian.PutUint64(y[1*8:2*8], y1)
+	binary.LittleEndian.PutUint64(y[2*8:3*8], y2)
+	binary.LittleEndian.PutUint64(y[3*8:4*8], y3)
+	binary.LittleEndian.PutUint64(y[4*8:5*8], y4)
+	binary.LittleEndian.PutUint64(y[5*8:6*8], y5)
+	binary.LittleEndian.PutUint64(y[6*8:7*8], y6)
+}
+
+func addGeneric(z, x, y *Elt) {
+	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+	x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
+	x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
+	x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
+
+	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+	y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
+	y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
+	y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
+
+	z0, c0 := bits.Add64(x0, y0, 0)
+	z1, c1 := bits.Add64(x1, y1, c0)
+	z2, c2 := bits.Add64(x2, y2, c1)
+	z3, c3 := bits.Add64(x3, y3, c2)
+	z4, c4 := bits.Add64(x4, y4, c3)
+	z5, c5 := bits.Add64(x5, y5, c4)
+	z6, z7 := bits.Add64(x6, y6, c5)
+
+	z0, c0 = bits.Add64(z0, z7, 0)
+	z1, c1 = bits.Add64(z1, 0, c0)
+	z2, c2 = bits.Add64(z2, 0, c1)
+	z3, c3 = bits.Add64(z3, z7<<32, c2)
+	z4, c4 = bits.Add64(z4, 0, c3)
+	z5, c5 = bits.Add64(z5, 0, c4)
+	z6, z7 = bits.Add64(z6, 0, c5)
+
+	z0, c0 = bits.Add64(z0, z7, 0)
+	z1, c1 = bits.Add64(z1, 0, c0)
+	z2, c2 = bits.Add64(z2, 0, c1)
+	z3, c3 = bits.Add64(z3, z7<<32, c2)
+	z4, c4 = bits.Add64(z4, 0, c3)
+	z5, c5 = bits.Add64(z5, 0, c4)
+	z6, _ = bits.Add64(z6, 0, c5)
+
+	binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
+	binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
+	binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
+	binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
+	binary.LittleEndian.PutUint64(z[4*8:5*8], z4)
+	binary.LittleEndian.PutUint64(z[5*8:6*8], z5)
+	binary.LittleEndian.PutUint64(z[6*8:7*8], z6)
+}
+
+func subGeneric(z, x, y *Elt) {
+	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+	x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
+	x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
+	x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
+
+	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+	y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
+	y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
+	y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
+
+	z0, c0 := bits.Sub64(x0, y0, 0)
+	z1, c1 := bits.Sub64(x1, y1, c0)
+	z2, c2 := bits.Sub64(x2, y2, c1)
+	z3, c3 := bits.Sub64(x3, y3, c2)
+	z4, c4 := bits.Sub64(x4, y4, c3)
+	z5, c5 := bits.Sub64(x5, y5, c4)
+	z6, z7 := bits.Sub64(x6, y6, c5)
+
+	z0, c0 = bits.Sub64(z0, z7, 0)
+	z1, c1 = bits.Sub64(z1, 0, c0)
+	z2, c2 = bits.Sub64(z2, 0, c1)
+	z3, c3 = bits.Sub64(z3, z7<<32, c2)
+	z4, c4 = bits.Sub64(z4, 0, c3)
+	z5, c5 = bits.Sub64(z5, 0, c4)
+	z6, z7 = bits.Sub64(z6, 0, c5)
+
+	z0, c0 = bits.Sub64(z0, z7, 0)
+	z1, c1 = bits.Sub64(z1, 0, c0)
+	z2, c2 = bits.Sub64(z2, 0, c1)
+	z3, c3 = bits.Sub64(z3, z7<<32, c2)
+	z4, c4 = bits.Sub64(z4, 0, c3)
+	z5, c5 = bits.Sub64(z5, 0, c4)
+	z6, _ = bits.Sub64(z6, 0, c5)
+
+	binary.LittleEndian.PutUint64(z[0*8:1*8], z0)
+	binary.LittleEndian.PutUint64(z[1*8:2*8], z1)
+	binary.LittleEndian.PutUint64(z[2*8:3*8], z2)
+	binary.LittleEndian.PutUint64(z[3*8:4*8], z3)
+	binary.LittleEndian.PutUint64(z[4*8:5*8], z4)
+	binary.LittleEndian.PutUint64(z[5*8:6*8], z5)
+	binary.LittleEndian.PutUint64(z[6*8:7*8], z6)
+}
+
+func addsubGeneric(x, y *Elt) {
+	z := &Elt{}
+	addGeneric(z, x, y)
+	subGeneric(y, x, y)
+	*x = *z
+}
+
+func mulGeneric(z, x, y *Elt) {
+	x0 := binary.LittleEndian.Uint64(x[0*8 : 1*8])
+	x1 := binary.LittleEndian.Uint64(x[1*8 : 2*8])
+	x2 := binary.LittleEndian.Uint64(x[2*8 : 3*8])
+	x3 := binary.LittleEndian.Uint64(x[3*8 : 4*8])
+	x4 := binary.LittleEndian.Uint64(x[4*8 : 5*8])
+	x5 := binary.LittleEndian.Uint64(x[5*8 : 6*8])
+	x6 := binary.LittleEndian.Uint64(x[6*8 : 7*8])
+
+	y0 := binary.LittleEndian.Uint64(y[0*8 : 1*8])
+	y1 := binary.LittleEndian.Uint64(y[1*8 : 2*8])
+	y2 := binary.LittleEndian.Uint64(y[2*8 : 3*8])
+	y3 := binary.LittleEndian.Uint64(y[3*8 : 4*8])
+	y4 := binary.LittleEndian.Uint64(y[4*8 : 5*8])
+	y5 := binary.LittleEndian.Uint64(y[5*8 : 6*8])
+	y6 := binary.LittleEndian.Uint64(y[6*8 : 7*8])
+
+	yy := [7]uint64{y0, y1, y2, y3, y4, y5, y6}
+	zz := [7]uint64{}
+
+	yi := yy[0]
+	h0, l0 := bits.Mul64(x0, yi)
+	h1, l1 := bits.Mul64(x1, yi)
+	h2, l2 := bits.Mul64(x2, yi)
+	h3, l3 := bits.Mul64(x3, yi)
+	h4, l4 := bits.Mul64(x4, yi)
+	h5, l5 := bits.Mul64(x5, yi)
+	h6, l6 := bits.Mul64(x6, yi)
+
+	zz[0] = l0
+	a0, c0 := bits.Add64(h0, l1, 0)
+	a1, c1 := bits.Add64(h1, l2, c0)
+	a2, c2 := bits.Add64(h2, l3, c1)
+	a3, c3 := bits.Add64(h3, l4, c2)
+	a4, c4 := bits.Add64(h4, l5, c3)
+	a5, c5 := bits.Add64(h5, l6, c4)
+	a6, _ := bits.Add64(h6, 0, c5)
+
+	for i := 1; i < 7; i++ {
+		yi = yy[i]
+		h0, l0 = bits.Mul64(x0, yi)
+		h1, l1 = bits.Mul64(x1, yi)
+		h2, l2 = bits.Mul64(x2, yi)
+		h3, l3 = bits.Mul64(x3, yi)
+		h4, l4 = bits.Mul64(x4, yi)
+		h5, l5 = bits.Mul64(x5, yi)
+		h6, l6 = bits.Mul64(x6, yi)
+
+		zz[i], c0 = bits.Add64(a0, l0, 0)
+		a0, c1 = bits.Add64(a1, l1, c0)
+		a1, c2 = bits.Add64(a2, l2, c1)
+		a2, c3 = bits.Add64(a3, l3, c2)
+		a3, c4 = bits.Add64(a4, l4, c3)
+		a4, c5 = bits.Add64(a5, l5, c4)
+		a5, a6 = bits.Add64(a6, l6, c5)
+
+		a0, c0 = bits.Add64(a0, h0, 0)
+		a1, c1 = bits.Add64(a1, h1, c0)
+		a2, c2 = bits.Add64(a2, h2, c1)
+		a3, c3 = bits.Add64(a3, h3, c2)
+		a4, c4 = bits.Add64(a4, h4, c3)
+		a5, c5 = bits.Add64(a5, h5, c4)
+		a6, _ = bits.Add64(a6, h6, c5)
+	}
+	red64(z, &zz, &[7]uint64{a0, a1, a2, a3, a4, a5, a6})
+}
+
+func sqrGeneric(z, x *Elt) { mulGeneric(z, x, x) }
+
+func red64(z *Elt, l, h *[7]uint64) {
+	/* (2C13, 2C12, 2C11, 2C10|C10, C9, C8, C7) + (C6,...,C0) */
+	h0 := h[0]
+	h1 := h[1]
+	h2 := h[2]
+	h3 := ((h[3] & (0xFFFFFFFF << 32)) << 1) | (h[3] & 0xFFFFFFFF)
+	h4 := (h[3] >> 63) | (h[4] << 1)
+	h5 := (h[4] >> 63) | (h[5] << 1)
+	h6 := (h[5] >> 63) | (h[6] << 1)
+	h7 := (h[6] >> 63)
+
+	l0, c0 := bits.Add64(h0, l[0], 0)
+	l1, c1 := bits.Add64(h1, l[1], c0)
+	l2, c2 := bits.Add64(h2, l[2], c1)
+	l3, c3 := bits.Add64(h3, l[3], c2)
+	l4, c4 := bits.Add64(h4, l[4], c3)
+	l5, c5 := bits.Add64(h5, l[5], c4)
+	l6, c6 := bits.Add64(h6, l[6], c5)
+	l7, _ := bits.Add64(h7, 0, c6)
+
+	/* (C10C9, C9C8,C8C7,C7C13,C13C12,C12C11,C11C10) + (C6,...,C0) */
+	h0 = (h[3] >> 32) | (h[4] << 32)
+	h1 = (h[4] >> 32) | (h[5] << 32)
+	h2 = (h[5] >> 32) | (h[6] << 32)
+	h3 = (h[6] >> 32) | (h[0] << 32)
+	h4 = (h[0] >> 32) | (h[1] << 32)
+	h5 = (h[1] >> 32) | (h[2] << 32)
+	h6 = (h[2] >> 32) | (h[3] << 32)
+
+	l0, c0 = bits.Add64(l0, h0, 0)
+	l1, c1 = bits.Add64(l1, h1, c0)
+	l2, c2 = bits.Add64(l2, h2, c1)
+	l3, c3 = bits.Add64(l3, h3, c2)
+	l4, c4 = bits.Add64(l4, h4, c3)
+	l5, c5 = bits.Add64(l5, h5, c4)
+	l6, c6 = bits.Add64(l6, h6, c5)
+	l7, _ = bits.Add64(l7, 0, c6)
+
+	/* (C7) + (C6,...,C0) */
+	l0, c0 = bits.Add64(l0, l7, 0)
+	l1, c1 = bits.Add64(l1, 0, c0)
+	l2, c2 = bits.Add64(l2, 0, c1)
+	l3, c3 = bits.Add64(l3, l7<<32, c2)
+	l4, c4 = bits.Add64(l4, 0, c3)
+	l5, c5 = bits.Add64(l5, 0, c4)
+	l6, l7 = bits.Add64(l6, 0, c5)
+
+	/* (C7) + (C6,...,C0) */
+	l0, c0 = bits.Add64(l0, l7, 0)
+	l1, c1 = bits.Add64(l1, 0, c0)
+	l2, c2 = bits.Add64(l2, 0, c1)
+	l3, c3 = bits.Add64(l3, l7<<32, c2)
+	l4, c4 = bits.Add64(l4, 0, c3)
+	l5, c5 = bits.Add64(l5, 0, c4)
+	l6, _ = bits.Add64(l6, 0, c5)
+
+	binary.LittleEndian.PutUint64(z[0*8:1*8], l0)
+	binary.LittleEndian.PutUint64(z[1*8:2*8], l1)
+	binary.LittleEndian.PutUint64(z[2*8:3*8], l2)
+	binary.LittleEndian.PutUint64(z[3*8:4*8], l3)
+	binary.LittleEndian.PutUint64(z[4*8:5*8], l4)
+	binary.LittleEndian.PutUint64(z[5*8:6*8], l5)
+	binary.LittleEndian.PutUint64(z[6*8:7*8], l6)
+}
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fp_noasm.go b/vendor/github.com/cloudflare/circl/math/fp448/fp_noasm.go
new file mode 100644
index 00000000..a62225d2
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fp_noasm.go
@@ -0,0 +1,12 @@
+//go:build !amd64 || purego
+// +build !amd64 purego
+
+package fp448
+
+func cmov(x, y *Elt, n uint)  { cmovGeneric(x, y, n) }
+func cswap(x, y *Elt, n uint) { cswapGeneric(x, y, n) }
+func add(z, x, y *Elt)        { addGeneric(z, x, y) }
+func sub(z, x, y *Elt)        { subGeneric(z, x, y) }
+func addsub(x, y *Elt)        { addsubGeneric(x, y) }
+func mul(z, x, y *Elt)        { mulGeneric(z, x, y) }
+func sqr(z, x *Elt)           { sqrGeneric(z, x) }
diff --git a/vendor/github.com/cloudflare/circl/math/fp448/fuzzer.go b/vendor/github.com/cloudflare/circl/math/fp448/fuzzer.go
new file mode 100644
index 00000000..2d7afc80
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/fp448/fuzzer.go
@@ -0,0 +1,75 @@
+//go:build gofuzz
+// +build gofuzz
+
+// How to run the fuzzer:
+//
+//	$ go get -u github.com/dvyukov/go-fuzz/go-fuzz
+//	$ go get -u github.com/dvyukov/go-fuzz/go-fuzz-build
+//	$ go-fuzz-build -libfuzzer -func FuzzReduction -o lib.a
+//	$ clang -fsanitize=fuzzer lib.a -o fu.exe
+//	$ ./fu.exe
+package fp448
+
+import (
+	"encoding/binary"
+	"fmt"
+	"math/big"
+
+	"github.com/cloudflare/circl/internal/conv"
+)
+
+// FuzzReduction is a fuzzer target for red64 function, which reduces t
+// (112 bits) to a number t' (56 bits) congruent modulo p448.
+func FuzzReduction(data []byte) int {
+	if len(data) != 2*Size {
+		return -1
+	}
+	var got, want Elt
+	var lo, hi [7]uint64
+	a := data[:Size]
+	b := data[Size:]
+	lo[0] = binary.LittleEndian.Uint64(a[0*8 : 1*8])
+	lo[1] = binary.LittleEndian.Uint64(a[1*8 : 2*8])
+	lo[2] = binary.LittleEndian.Uint64(a[2*8 : 3*8])
+	lo[3] = binary.LittleEndian.Uint64(a[3*8 : 4*8])
+	lo[4] = binary.LittleEndian.Uint64(a[4*8 : 5*8])
+	lo[5] = binary.LittleEndian.Uint64(a[5*8 : 6*8])
+	lo[6] = binary.LittleEndian.Uint64(a[6*8 : 7*8])
+
+	hi[0] = binary.LittleEndian.Uint64(b[0*8 : 1*8])
+	hi[1] = binary.LittleEndian.Uint64(b[1*8 : 2*8])
+	hi[2] = binary.LittleEndian.Uint64(b[2*8 : 3*8])
+	hi[3] = binary.LittleEndian.Uint64(b[3*8 : 4*8])
+	hi[4] = binary.LittleEndian.Uint64(b[4*8 : 5*8])
+	hi[5] = binary.LittleEndian.Uint64(b[5*8 : 6*8])
+	hi[6] = binary.LittleEndian.Uint64(b[6*8 : 7*8])
+
+	red64(&got, &lo, &hi)
+
+	t := conv.BytesLe2BigInt(data[:2*Size])
+
+	two448 := big.NewInt(1)
+	two448.Lsh(two448, 448) // 2^448
+	mask448 := big.NewInt(1)
+	mask448.Sub(two448, mask448) // 2^448-1
+	two224plus1 := big.NewInt(1)
+	two224plus1.Lsh(two224plus1, 224)
+	two224plus1.Add(two224plus1, big.NewInt(1)) // 2^224+1
+
+	var loBig, hiBig big.Int
+	for t.Cmp(two448) >= 0 {
+		loBig.And(t, mask448)
+		hiBig.Rsh(t, 448)
+		t.Mul(&hiBig, two224plus1)
+		t.Add(t, &loBig)
+	}
+	conv.BigInt2BytesLe(want[:], t)
+
+	if got != want {
+		fmt.Printf("in:   %v\n", conv.BytesLe2BigInt(data[:2*Size]))
+		fmt.Printf("got:  %v\n", got)
+		fmt.Printf("want: %v\n", want)
+		panic("error found")
+	}
+	return 1
+}
diff --git a/vendor/github.com/cloudflare/circl/math/mlsbset/mlsbset.go b/vendor/github.com/cloudflare/circl/math/mlsbset/mlsbset.go
new file mode 100644
index 00000000..a43851b8
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/mlsbset/mlsbset.go
@@ -0,0 +1,122 @@
+// Package mlsbset provides a constant-time exponentiation method with precomputation.
+//
+// References: "Efficient and secure algorithms for GLV-based scalar
+// multiplication and their implementation on GLV–GLS curves" by (Faz-Hernandez et al.)
+//   - https://doi.org/10.1007/s13389-014-0085-7
+//   - https://eprint.iacr.org/2013/158
+package mlsbset
+
+import (
+	"errors"
+	"fmt"
+	"math/big"
+
+	"github.com/cloudflare/circl/internal/conv"
+)
+
+// EltG is a group element.
+type EltG interface{}
+
+// EltP is a precomputed group element.
+type EltP interface{}
+
+// Group defines the operations required by MLSBSet exponentiation method.
+type Group interface {
+	Identity() EltG                    // Returns the identity of the group.
+	Sqr(x EltG)                        // Calculates x = x^2.
+	Mul(x EltG, y EltP)                // Calculates x = x*y.
+	NewEltP() EltP                     // Returns an arbitrary precomputed element.
+	ExtendedEltP() EltP                // Returns the precomputed element x^(2^(w*d)).
+	Lookup(a EltP, v uint, s, u int32) // Sets a = s*T[v][u].
+}
+
+// Params contains the parameters of the encoding.
+type Params struct {
+	T uint // T is the maximum size (in bits) of exponents.
+	V uint // V is the number of tables.
+	W uint // W is the window size.
+	E uint // E is the number of digits per table.
+	D uint // D is the number of digits in total.
+	L uint // L is the length of the code.
+}
+
+// Encoder allows to convert integers into valid powers.
+type Encoder struct{ p Params }
+
+// New produces an encoder of the MLSBSet algorithm.
+func New(t, v, w uint) (Encoder, error) {
+	if !(t > 1 && v >= 1 && w >= 2) {
+		return Encoder{}, errors.New("t>1, v>=1, w>=2")
+	}
+	e := (t + w*v - 1) / (w * v)
+	d := e * v
+	l := d * w
+	return Encoder{Params{t, v, w, e, d, l}}, nil
+}
+
+// Encode converts an odd integer k into a valid power for exponentiation.
+func (m Encoder) Encode(k []byte) (*Power, error) {
+	if len(k) == 0 {
+		return nil, errors.New("empty slice")
+	}
+	if !(len(k) <= int(m.p.L+7)>>3) {
+		return nil, errors.New("k too big")
+	}
+	if k[0]%2 == 0 {
+		return nil, errors.New("k must be odd")
+	}
+	ap := int((m.p.L+7)/8) - len(k)
+	k = append(k, make([]byte, ap)...)
+	s := m.signs(k)
+	b := make([]int32, m.p.L-m.p.D)
+	c := conv.BytesLe2BigInt(k)
+	c.Rsh(c, m.p.D)
+	var bi big.Int
+	for i := m.p.D; i < m.p.L; i++ {
+		c0 := int32(c.Bit(0))
+		b[i-m.p.D] = s[i%m.p.D] * c0
+		bi.SetInt64(int64(b[i-m.p.D] >> 1))
+		c.Rsh(c, 1)
+		c.Sub(c, &bi)
+	}
+	carry := int(c.Int64())
+	return &Power{m, s, b, carry}, nil
+}
+
+// signs calculates the set of signs.
+func (m Encoder) signs(k []byte) []int32 {
+	s := make([]int32, m.p.D)
+	s[m.p.D-1] = 1
+	for i := uint(1); i < m.p.D; i++ {
+		ki := int32((k[i>>3] >> (i & 0x7)) & 0x1)
+		s[i-1] = 2*ki - 1
+	}
+	return s
+}
+
+// GetParams returns the complementary parameters of the encoding.
+func (m Encoder) GetParams() Params { return m.p }
+
+// tableSize returns the size of each table.
+func (m Encoder) tableSize() uint { return 1 << (m.p.W - 1) }
+
+// Elts returns the total number of elements that must be precomputed.
+func (m Encoder) Elts() uint { return m.p.V * m.tableSize() }
+
+// IsExtended returns true if the element x^(2^(wd)) must be calculated.
+func (m Encoder) IsExtended() bool { q := m.p.T / (m.p.V * m.p.W); return m.p.T == q*m.p.V*m.p.W }
+
+// Ops returns the number of squares and multiplications executed during an exponentiation.
+func (m Encoder) Ops() (S uint, M uint) {
+	S = m.p.E
+	M = m.p.E * m.p.V
+	if m.IsExtended() {
+		M++
+	}
+	return
+}
+
+func (m Encoder) String() string {
+	return fmt.Sprintf("T: %v W: %v V: %v e: %v d: %v l: %v wv|t: %v",
+		m.p.T, m.p.W, m.p.V, m.p.E, m.p.D, m.p.L, m.IsExtended())
+}
diff --git a/vendor/github.com/cloudflare/circl/math/mlsbset/power.go b/vendor/github.com/cloudflare/circl/math/mlsbset/power.go
new file mode 100644
index 00000000..3f214c30
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/mlsbset/power.go
@@ -0,0 +1,64 @@
+package mlsbset
+
+import "fmt"
+
+// Power is a valid exponent produced by the MLSBSet encoding algorithm.
+type Power struct {
+	set Encoder // parameters of code.
+	s   []int32 // set of signs.
+	b   []int32 // set of digits.
+	c   int     // carry is {0,1}.
+}
+
+// Exp is calculates x^k, where x is a predetermined element of a group G.
+func (p *Power) Exp(G Group) EltG {
+	a, b := G.Identity(), G.NewEltP()
+	for e := int(p.set.p.E - 1); e >= 0; e-- {
+		G.Sqr(a)
+		for v := uint(0); v < p.set.p.V; v++ {
+			sgnElt, idElt := p.Digit(v, uint(e))
+			G.Lookup(b, v, sgnElt, idElt)
+			G.Mul(a, b)
+		}
+	}
+	if p.set.IsExtended() && p.c == 1 {
+		G.Mul(a, G.ExtendedEltP())
+	}
+	return a
+}
+
+// Digit returns the (v,e)-th digit and its sign.
+func (p *Power) Digit(v, e uint) (sgn, dig int32) {
+	sgn = p.bit(0, v, e)
+	dig = 0
+	for i := p.set.p.W - 1; i > 0; i-- {
+		dig = 2*dig + p.bit(i, v, e)
+	}
+	mask := dig >> 31
+	dig = (dig + mask) ^ mask
+	return sgn, dig
+}
+
+// bit returns the (w,v,e)-th bit of the code.
+func (p *Power) bit(w, v, e uint) int32 {
+	if !(w < p.set.p.W &&
+		v < p.set.p.V &&
+		e < p.set.p.E) {
+		panic(fmt.Errorf("indexes outside (%v,%v,%v)", w, v, e))
+	}
+	if w == 0 {
+		return p.s[p.set.p.E*v+e]
+	}
+	return p.b[p.set.p.D*(w-1)+p.set.p.E*v+e]
+}
+
+func (p *Power) String() string {
+	dig := ""
+	for j := uint(0); j < p.set.p.V; j++ {
+		for i := uint(0); i < p.set.p.E; i++ {
+			s, d := p.Digit(j, i)
+			dig += fmt.Sprintf("(%2v,%2v) = %+2v %+2v\n", j, i, s, d)
+		}
+	}
+	return fmt.Sprintf("len: %v\ncarry: %v\ndigits:\n%v", len(p.b)+len(p.s), p.c, dig)
+}
diff --git a/vendor/github.com/cloudflare/circl/math/primes.go b/vendor/github.com/cloudflare/circl/math/primes.go
new file mode 100644
index 00000000..158fd83a
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/primes.go
@@ -0,0 +1,34 @@
+package math
+
+import (
+	"crypto/rand"
+	"io"
+	"math/big"
+)
+
+// IsSafePrime reports whether p is (probably) a safe prime.
+// The prime p=2*q+1 is safe prime if both p and q are primes.
+// Note that ProbablyPrime is not suitable for judging primes
+// that an adversary may have crafted to fool the test.
+func IsSafePrime(p *big.Int) bool {
+	pdiv2 := new(big.Int).Rsh(p, 1)
+	return p.ProbablyPrime(20) && pdiv2.ProbablyPrime(20)
+}
+
+// SafePrime returns a number of the given bit length that is a safe prime with high probability.
+// The number returned p=2*q+1 is a safe prime if both p and q are primes.
+// SafePrime will return error for any error returned by rand.Read or if bits < 2.
+func SafePrime(random io.Reader, bits int) (*big.Int, error) {
+	one := big.NewInt(1)
+	p := new(big.Int)
+	for {
+		q, err := rand.Prime(random, bits-1)
+		if err != nil {
+			return nil, err
+		}
+		p.Lsh(q, 1).Add(p, one)
+		if p.ProbablyPrime(20) {
+			return p, nil
+		}
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/math/wnaf.go b/vendor/github.com/cloudflare/circl/math/wnaf.go
new file mode 100644
index 00000000..94a1ec50
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/math/wnaf.go
@@ -0,0 +1,84 @@
+// Package math provides some utility functions for big integers.
+package math
+
+import "math/big"
+
+// SignedDigit obtains the signed-digit recoding of n and returns a list L of
+// digits such that n = sum( L[i]*2^(i*(w-1)) ), and each L[i] is an odd number
+// in the set {±1, ±3, ..., ±2^(w-1)-1}. The third parameter ensures that the
+// output has ceil(l/(w-1)) digits.
+//
+// Restrictions:
+//   - n is odd and n > 0.
+//   - 1 < w < 32.
+//   - l >= bit length of n.
+//
+// References:
+//   - Alg.6 in "Exponent Recoding and Regular Exponentiation Algorithms"
+//     by Joye-Tunstall. http://doi.org/10.1007/978-3-642-02384-2_21
+//   - Alg.6 in "Selecting Elliptic Curves for Cryptography: An Efficiency and
+//     Security Analysis" by Bos et al. http://doi.org/10.1007/s13389-015-0097-y
+func SignedDigit(n *big.Int, w, l uint) []int32 {
+	if n.Sign() <= 0 || n.Bit(0) == 0 {
+		panic("n must be non-zero, odd, and positive")
+	}
+	if w <= 1 || w >= 32 {
+		panic("Verify that 1 < w < 32")
+	}
+	if uint(n.BitLen()) > l {
+		panic("n is too big to fit in l digits")
+	}
+	lenN := (l + (w - 1) - 1) / (w - 1) // ceil(l/(w-1))
+	L := make([]int32, lenN+1)
+	var k, v big.Int
+	k.Set(n)
+
+	var i uint
+	for i = 0; i < lenN; i++ {
+		words := k.Bits()
+		value := int32(words[0] & ((1 << w) - 1))
+		value -= int32(1) << (w - 1)
+		L[i] = value
+		v.SetInt64(int64(value))
+		k.Sub(&k, &v)
+		k.Rsh(&k, w-1)
+	}
+	L[i] = int32(k.Int64())
+	return L
+}
+
+// OmegaNAF obtains the window-w Non-Adjacent Form of a positive number n and
+// 1 < w < 32. The returned slice L holds n = sum( L[i]*2^i ).
+//
+// Reference:
+//   - Alg.9 "Efficient arithmetic on Koblitz curves" by Solinas.
+//     http://doi.org/10.1023/A:1008306223194
+func OmegaNAF(n *big.Int, w uint) (L []int32) {
+	if n.Sign() < 0 {
+		panic("n must be positive")
+	}
+	if w <= 1 || w >= 32 {
+		panic("Verify that 1 < w < 32")
+	}
+
+	L = make([]int32, n.BitLen()+1)
+	var k, v big.Int
+	k.Set(n)
+
+	i := 0
+	for ; k.Sign() > 0; i++ {
+		value := int32(0)
+		if k.Bit(0) == 1 {
+			words := k.Bits()
+			value = int32(words[0] & ((1 << w) - 1))
+			if value >= (int32(1) << (w - 1)) {
+				value -= int32(1) << w
+			}
+			v.SetInt64(int64(value))
+			k.Sub(&k, &v)
+		}
+		L[i] = value
+		k.Rsh(&k, 1)
+	}
+	return L[:i]
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.go b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.go
new file mode 100644
index 00000000..2c96563c
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.go
@@ -0,0 +1,302 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+package common
+
+import (
+	"golang.org/x/sys/cpu"
+)
+
+// ZetasAVX2 contains all ζ used in NTT (like the Zetas array), but also
+// the values int16(zeta * 62209) for each zeta, which is used in
+// Montgomery reduction.  There is some duplication and reordering as
+// compared to Zetas to make it more convenient for use with AVX2.
+var ZetasAVX2 = [...]int16{
+	// level 1: int16(Zetas[1]*62209) and Zetas[1]
+	31499, 2571,
+
+	// level 2
+	//
+	// int16(Zetas[2]*62209), Zetas[2], int16(Zetas[3]*62209), Zetas[3]
+	14746, 2970, 788, 1812,
+
+	// level 3, like level 2.
+	13525, 1493, -12402, 1422, 28191, 287, -16694, 202,
+
+	0, 0, // padding
+
+	// layer 4. offset: 1*16
+	//
+	// The precomputed multiplication and zetas are grouped by 16 at a
+	// time as used in the set of butterflies, etc.
+	-20906, -20906, -20906, -20906, -20906, -20906, -20906, -20906,
+	27758, 27758, 27758, 27758, 27758, 27758, 27758, 27758,
+	3158, 3158, 3158, 3158, 3158, 3158, 3158, 3158,
+	622, 622, 622, 622, 622, 622, 622, 622,
+	-3799, -3799, -3799, -3799, -3799, -3799, -3799, -3799,
+	-15690, -15690, -15690, -15690, -15690, -15690, -15690, -15690,
+	1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577,
+	182, 182, 182, 182, 182, 182, 182, 182,
+	10690, 10690, 10690, 10690, 10690, 10690, 10690, 10690,
+	1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
+	962, 962, 962, 962, 962, 962, 962, 962,
+	2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127,
+	-11201, -11201, -11201, -11201, -11201, -11201, -11201, -11201,
+	31164, 31164, 31164, 31164, 31164, 31164, 31164, 31164,
+	1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855,
+	1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468,
+
+	// layer 5. offset: 9*16
+	-5827, -5827, -5827, -5827, 17364, 17364, 17364, 17364,
+	-26360, -26360, -26360, -26360, -29057, -29057, -29057, -29057,
+	573, 573, 573, 573, 2004, 2004, 2004, 2004,
+	264, 264, 264, 264, 383, 383, 383, 383,
+	5572, 5572, 5572, 5572, -1102, -1102, -1102, -1102,
+	21439, 21439, 21439, 21439, -26241, -26241, -26241, -26241,
+	2500, 2500, 2500, 2500, 1458, 1458, 1458, 1458,
+	1727, 1727, 1727, 1727, 3199, 3199, 3199, 3199,
+	-28072, -28072, -28072, -28072, 24313, 24313, 24313, 24313,
+	-10532, -10532, -10532, -10532, 8800, 8800, 8800, 8800,
+	2648, 2648, 2648, 2648, 1017, 1017, 1017, 1017,
+	732, 732, 732, 732, 608, 608, 608, 608,
+	18427, 18427, 18427, 18427, 8859, 8859, 8859, 8859,
+	26676, 26676, 26676, 26676, -16162, -16162, -16162, -16162,
+	1787, 1787, 1787, 1787, 411, 411, 411, 411,
+	3124, 3124, 3124, 3124, 1758, 1758, 1758, 1758,
+
+	// layer 6. offset: 17*16
+	-5689, -5689, -6516, -6516, 1497, 1497, 30967, 30967,
+	-23564, -23564, 20179, 20179, 20711, 20711, 25081, 25081,
+	1223, 1223, 652, 652, 2777, 2777, 1015, 1015,
+	2036, 2036, 1491, 1491, 3047, 3047, 1785, 1785,
+	-12796, -12796, 26617, 26617, 16065, 16065, -12441, -12441,
+	9135, 9135, -649, -649, -25986, -25986, 27837, 27837,
+	516, 516, 3321, 3321, 3009, 3009, 2663, 2663,
+	1711, 1711, 2167, 2167, 126, 126, 1469, 1469,
+	19884, 19884, -28249, -28249, -15886, -15886, -8898, -8898,
+	-28309, -28309, 9076, 9076, -30198, -30198, 18250, 18250,
+	2476, 2476, 3239, 3239, 3058, 3058, 830, 830,
+	107, 107, 1908, 1908, 3082, 3082, 2378, 2378,
+	13427, 13427, 14017, 14017, -29155, -29155, -12756, -12756,
+	16832, 16832, 4312, 4312, -24155, -24155, -17914, -17914,
+	2931, 2931, 961, 961, 1821, 1821, 2604, 2604,
+	448, 448, 2264, 2264, 677, 677, 2054, 2054,
+
+	// layer 7. offset: 25*16
+	-334, 11182, -11477, 13387, -32226, -14233, 20494, -21655,
+	-27738, 13131, 945, -4586, -14882, 23093, 6182, 5493,
+	2226, 430, 555, 843, 2078, 871, 1550, 105,
+	422, 587, 177, 3094, 3038, 2869, 1574, 1653,
+	32011, -32502, 10631, 30318, 29176, -18741, -28761, 12639,
+	-18485, 20100, 17561, 18525, -14430, 19529, -5275, -12618,
+	3083, 778, 1159, 3182, 2552, 1483, 2727, 1119,
+	1739, 644, 2457, 349, 418, 329, 3173, 3254,
+	-31183, 20297, 25435, 2146, -7382, 15356, 24392, -32384,
+	-20926, -6279, 10946, -14902, 24215, -11044, 16990, 14470,
+	817, 1097, 603, 610, 1322, 2044, 1864, 384,
+	2114, 3193, 1218, 1994, 2455, 220, 2142, 1670,
+	10336, -21497, -7933, -20198, -22501, 23211, 10907, -17442,
+	31637, -23859, 28644, -20257, 23998, 7757, -17422, 23132,
+	2144, 1799, 2051, 794, 1819, 2475, 2459, 478,
+	3221, 3021, 996, 991, 958, 1869, 1522, 1628,
+
+	// layer 1 inverse
+	23132, -17422, 7757, 23998, -20257, 28644, -23859, 31637,
+	-17442, 10907, 23211, -22501, -20198, -7933, -21497, 10336,
+	1628, 1522, 1869, 958, 991, 996, 3021, 3221,
+	478, 2459, 2475, 1819, 794, 2051, 1799, 2144,
+	14470, 16990, -11044, 24215, -14902, 10946, -6279, -20926,
+	-32384, 24392, 15356, -7382, 2146, 25435, 20297, -31183,
+	1670, 2142, 220, 2455, 1994, 1218, 3193, 2114,
+	384, 1864, 2044, 1322, 610, 603, 1097, 817,
+	-12618, -5275, 19529, -14430, 18525, 17561, 20100, -18485,
+	12639, -28761, -18741, 29176, 30318, 10631, -32502, 32011,
+	3254, 3173, 329, 418, 349, 2457, 644, 1739,
+	1119, 2727, 1483, 2552, 3182, 1159, 778, 3083,
+	5493, 6182, 23093, -14882, -4586, 945, 13131, -27738,
+	-21655, 20494, -14233, -32226, 13387, -11477, 11182, -334,
+	1653, 1574, 2869, 3038, 3094, 177, 587, 422,
+	105, 1550, 871, 2078, 843, 555, 430, 2226,
+
+	// layer 2 inverse
+	-17914, -17914, -24155, -24155, 4312, 4312, 16832, 16832,
+	-12756, -12756, -29155, -29155, 14017, 14017, 13427, 13427,
+	2054, 2054, 677, 677, 2264, 2264, 448, 448,
+	2604, 2604, 1821, 1821, 961, 961, 2931, 2931,
+	18250, 18250, -30198, -30198, 9076, 9076, -28309, -28309,
+	-8898, -8898, -15886, -15886, -28249, -28249, 19884, 19884,
+	2378, 2378, 3082, 3082, 1908, 1908, 107, 107,
+	830, 830, 3058, 3058, 3239, 3239, 2476, 2476,
+	27837, 27837, -25986, -25986, -649, -649, 9135, 9135,
+	-12441, -12441, 16065, 16065, 26617, 26617, -12796, -12796,
+	1469, 1469, 126, 126, 2167, 2167, 1711, 1711,
+	2663, 2663, 3009, 3009, 3321, 3321, 516, 516,
+	25081, 25081, 20711, 20711, 20179, 20179, -23564, -23564,
+	30967, 30967, 1497, 1497, -6516, -6516, -5689, -5689,
+	1785, 1785, 3047, 3047, 1491, 1491, 2036, 2036,
+	1015, 1015, 2777, 2777, 652, 652, 1223, 1223,
+
+	// layer 3 inverse
+	-16162, -16162, -16162, -16162, 26676, 26676, 26676, 26676,
+	8859, 8859, 8859, 8859, 18427, 18427, 18427, 18427,
+	1758, 1758, 1758, 1758, 3124, 3124, 3124, 3124,
+	411, 411, 411, 411, 1787, 1787, 1787, 1787,
+	8800, 8800, 8800, 8800, -10532, -10532, -10532, -10532,
+	24313, 24313, 24313, 24313, -28072, -28072, -28072, -28072,
+	608, 608, 608, 608, 732, 732, 732, 732,
+	1017, 1017, 1017, 1017, 2648, 2648, 2648, 2648,
+	-26241, -26241, -26241, -26241, 21439, 21439, 21439, 21439,
+	-1102, -1102, -1102, -1102, 5572, 5572, 5572, 5572,
+	3199, 3199, 3199, 3199, 1727, 1727, 1727, 1727,
+	1458, 1458, 1458, 1458, 2500, 2500, 2500, 2500,
+	-29057, -29057, -29057, -29057, -26360, -26360, -26360, -26360,
+	17364, 17364, 17364, 17364, -5827, -5827, -5827, -5827,
+	383, 383, 383, 383, 264, 264, 264, 264,
+	2004, 2004, 2004, 2004, 573, 573, 573, 573,
+
+	// layer 4 inverse
+	31164, 31164, 31164, 31164, 31164, 31164, 31164, 31164,
+	-11201, -11201, -11201, -11201, -11201, -11201, -11201, -11201,
+	1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468,
+	1855, 1855, 1855, 1855, 1855, 1855, 1855, 1855,
+	1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359,
+	10690, 10690, 10690, 10690, 10690, 10690, 10690, 10690,
+	2127, 2127, 2127, 2127, 2127, 2127, 2127, 2127,
+	962, 962, 962, 962, 962, 962, 962, 962,
+	-15690, -15690, -15690, -15690, -15690, -15690, -15690, -15690,
+	-3799, -3799, -3799, -3799, -3799, -3799, -3799, -3799,
+	182, 182, 182, 182, 182, 182, 182, 182,
+	1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577,
+	27758, 27758, 27758, 27758, 27758, 27758, 27758, 27758,
+	-20906, -20906, -20906, -20906, -20906, -20906, -20906, -20906,
+	622, 622, 622, 622, 622, 622, 622, 622,
+	3158, 3158, 3158, 3158, 3158, 3158, 3158, 3158,
+
+	// layer 5 inverse
+	-16694, 202, 28191, 287, -12402, 1422, 13525, 1493,
+
+	// layer 6 inverse
+	788, 1812, 14746, 2970,
+
+	// layer 7 inverse
+	31499, 2571,
+}
+
+// Sets p to a + b.  Does not normalize coefficients.
+func (p *Poly) Add(a, b *Poly) {
+	if cpu.X86.HasAVX2 {
+		addAVX2(
+			(*[N]int16)(p),
+			(*[N]int16)(a),
+			(*[N]int16)(b),
+		)
+	} else {
+		p.addGeneric(a, b)
+	}
+}
+
+// Sets p to a - b.  Does not normalize coefficients.
+func (p *Poly) Sub(a, b *Poly) {
+	if cpu.X86.HasAVX2 {
+		subAVX2(
+			(*[N]int16)(p),
+			(*[N]int16)(a),
+			(*[N]int16)(b),
+		)
+	} else {
+		p.subGeneric(a, b)
+	}
+}
+
+// Executes an in-place forward "NTT" on p.
+//
+// Assumes the coefficients are in absolute value ≤q.  The resulting
+// coefficients are in absolute value ≤7q.  If the input is in Montgomery
+// form, then the result is in Montgomery form and so (by linearity of the NTT)
+// if the input is in regular form, then the result is also in regular form.
+// The order of coefficients will be "tangled". These can be put back into
+// their proper order by calling Detangle().
+func (p *Poly) NTT() {
+	if cpu.X86.HasAVX2 {
+		nttAVX2((*[N]int16)(p))
+	} else {
+		p.nttGeneric()
+	}
+}
+
+// Executes an in-place inverse "NTT" on p and multiply by the Montgomery
+// factor R.
+//
+// Requires coefficients to be in "tangled" order, see Tangle().
+// Assumes the coefficients are in absolute value ≤q.  The resulting
+// coefficients are in absolute value ≤q.  If the input is in Montgomery
+// form, then the result is in Montgomery form and so (by linearity)
+// if the input is in regular form, then the result is also in regular form.
+func (p *Poly) InvNTT() {
+	if cpu.X86.HasAVX2 {
+		invNttAVX2((*[N]int16)(p))
+	} else {
+		p.invNTTGeneric()
+	}
+}
+
+// Sets p to the "pointwise" multiplication of a and b.
+//
+// That is: InvNTT(p) = InvNTT(a) * InvNTT(b).  Assumes a and b are in
+// Montgomery form.  Products between coefficients of a and b must be strictly
+// bounded in absolute value by 2¹⁵q.  p will be in Montgomery form and
+// bounded in absolute value by 2q.
+//
+// Requires a and b to be in "tangled" order, see Tangle().  p will be in
+// tangled order as well.
+func (p *Poly) MulHat(a, b *Poly) {
+	if cpu.X86.HasAVX2 {
+		mulHatAVX2(
+			(*[N]int16)(p),
+			(*[N]int16)(a),
+			(*[N]int16)(b),
+		)
+	} else {
+		p.mulHatGeneric(a, b)
+	}
+}
+
+// Puts p into the right form to be used with (among others) InvNTT().
+func (p *Poly) Tangle() {
+	if cpu.X86.HasAVX2 {
+		tangleAVX2((*[N]int16)(p))
+	}
+
+	// When AVX2 is not available, we use the standard order.
+}
+
+// Puts p back into standard form.
+func (p *Poly) Detangle() {
+	if cpu.X86.HasAVX2 {
+		detangleAVX2((*[N]int16)(p))
+	}
+
+	// When AVX2 is not available, we use the standard order.
+}
+
+// Almost normalizes coefficients.
+//
+// Ensures each coefficient is in {0, …, q}.
+func (p *Poly) BarrettReduce() {
+	if cpu.X86.HasAVX2 {
+		barrettReduceAVX2((*[N]int16)(p))
+	} else {
+		p.barrettReduceGeneric()
+	}
+}
+
+// Normalizes coefficients.
+//
+// Ensures each coefficient is in {0, …, q-1}.
+func (p *Poly) Normalize() {
+	if cpu.X86.HasAVX2 {
+		normalizeAVX2((*[N]int16)(p))
+	} else {
+		p.normalizeGeneric()
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.s b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.s
new file mode 100644
index 00000000..5c7536b7
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/amd64.s
@@ -0,0 +1,2354 @@
+// Code generated by command: go run src.go -out ../amd64.s -stubs ../stubs_amd64.go -pkg common. DO NOT EDIT.
+
+//go:build amd64 && !purego
+
+#include "textflag.h"
+
+// func addAVX2(p *[256]int16, a *[256]int16, b *[256]int16)
+// Requires: AVX, AVX2
+TEXT ·addAVX2(SB), NOSPLIT, $0-24
+	MOVQ    p+0(FP), AX
+	MOVQ    a+8(FP), CX
+	MOVQ    b+16(FP), DX
+	VMOVDQU (CX), Y0
+	VMOVDQU 32(CX), Y2
+	VMOVDQU 64(CX), Y4
+	VMOVDQU 96(CX), Y6
+	VMOVDQU 128(CX), Y8
+	VMOVDQU 160(CX), Y10
+	VMOVDQU 192(CX), Y12
+	VMOVDQU 224(CX), Y14
+	VMOVDQU (DX), Y1
+	VMOVDQU 32(DX), Y3
+	VMOVDQU 64(DX), Y5
+	VMOVDQU 96(DX), Y7
+	VMOVDQU 128(DX), Y9
+	VMOVDQU 160(DX), Y11
+	VMOVDQU 192(DX), Y13
+	VMOVDQU 224(DX), Y15
+	VPADDW  Y0, Y1, Y1
+	VPADDW  Y2, Y3, Y3
+	VPADDW  Y4, Y5, Y5
+	VPADDW  Y6, Y7, Y7
+	VPADDW  Y8, Y9, Y9
+	VPADDW  Y10, Y11, Y11
+	VPADDW  Y12, Y13, Y13
+	VPADDW  Y14, Y15, Y15
+	VMOVDQU Y1, (AX)
+	VMOVDQU Y3, 32(AX)
+	VMOVDQU Y5, 64(AX)
+	VMOVDQU Y7, 96(AX)
+	VMOVDQU Y9, 128(AX)
+	VMOVDQU Y11, 160(AX)
+	VMOVDQU Y13, 192(AX)
+	VMOVDQU Y15, 224(AX)
+	VMOVDQU 256(CX), Y0
+	VMOVDQU 288(CX), Y2
+	VMOVDQU 320(CX), Y4
+	VMOVDQU 352(CX), Y6
+	VMOVDQU 384(CX), Y8
+	VMOVDQU 416(CX), Y10
+	VMOVDQU 448(CX), Y12
+	VMOVDQU 480(CX), Y14
+	VMOVDQU 256(DX), Y1
+	VMOVDQU 288(DX), Y3
+	VMOVDQU 320(DX), Y5
+	VMOVDQU 352(DX), Y7
+	VMOVDQU 384(DX), Y9
+	VMOVDQU 416(DX), Y11
+	VMOVDQU 448(DX), Y13
+	VMOVDQU 480(DX), Y15
+	VPADDW  Y0, Y1, Y1
+	VPADDW  Y2, Y3, Y3
+	VPADDW  Y4, Y5, Y5
+	VPADDW  Y6, Y7, Y7
+	VPADDW  Y8, Y9, Y9
+	VPADDW  Y10, Y11, Y11
+	VPADDW  Y12, Y13, Y13
+	VPADDW  Y14, Y15, Y15
+	VMOVDQU Y1, 256(AX)
+	VMOVDQU Y3, 288(AX)
+	VMOVDQU Y5, 320(AX)
+	VMOVDQU Y7, 352(AX)
+	VMOVDQU Y9, 384(AX)
+	VMOVDQU Y11, 416(AX)
+	VMOVDQU Y13, 448(AX)
+	VMOVDQU Y15, 480(AX)
+	RET
+
+// func subAVX2(p *[256]int16, a *[256]int16, b *[256]int16)
+// Requires: AVX, AVX2
+TEXT ·subAVX2(SB), NOSPLIT, $0-24
+	MOVQ    p+0(FP), AX
+	MOVQ    a+8(FP), CX
+	MOVQ    b+16(FP), DX
+	VMOVDQU (CX), Y0
+	VMOVDQU 32(CX), Y2
+	VMOVDQU 64(CX), Y4
+	VMOVDQU 96(CX), Y6
+	VMOVDQU 128(CX), Y8
+	VMOVDQU 160(CX), Y10
+	VMOVDQU 192(CX), Y12
+	VMOVDQU 224(CX), Y14
+	VMOVDQU (DX), Y1
+	VMOVDQU 32(DX), Y3
+	VMOVDQU 64(DX), Y5
+	VMOVDQU 96(DX), Y7
+	VMOVDQU 128(DX), Y9
+	VMOVDQU 160(DX), Y11
+	VMOVDQU 192(DX), Y13
+	VMOVDQU 224(DX), Y15
+	VPSUBW  Y1, Y0, Y1
+	VPSUBW  Y3, Y2, Y3
+	VPSUBW  Y5, Y4, Y5
+	VPSUBW  Y7, Y6, Y7
+	VPSUBW  Y9, Y8, Y9
+	VPSUBW  Y11, Y10, Y11
+	VPSUBW  Y13, Y12, Y13
+	VPSUBW  Y15, Y14, Y15
+	VMOVDQU Y1, (AX)
+	VMOVDQU Y3, 32(AX)
+	VMOVDQU Y5, 64(AX)
+	VMOVDQU Y7, 96(AX)
+	VMOVDQU Y9, 128(AX)
+	VMOVDQU Y11, 160(AX)
+	VMOVDQU Y13, 192(AX)
+	VMOVDQU Y15, 224(AX)
+	VMOVDQU 256(CX), Y0
+	VMOVDQU 288(CX), Y2
+	VMOVDQU 320(CX), Y4
+	VMOVDQU 352(CX), Y6
+	VMOVDQU 384(CX), Y8
+	VMOVDQU 416(CX), Y10
+	VMOVDQU 448(CX), Y12
+	VMOVDQU 480(CX), Y14
+	VMOVDQU 256(DX), Y1
+	VMOVDQU 288(DX), Y3
+	VMOVDQU 320(DX), Y5
+	VMOVDQU 352(DX), Y7
+	VMOVDQU 384(DX), Y9
+	VMOVDQU 416(DX), Y11
+	VMOVDQU 448(DX), Y13
+	VMOVDQU 480(DX), Y15
+	VPSUBW  Y1, Y0, Y1
+	VPSUBW  Y3, Y2, Y3
+	VPSUBW  Y5, Y4, Y5
+	VPSUBW  Y7, Y6, Y7
+	VPSUBW  Y9, Y8, Y9
+	VPSUBW  Y11, Y10, Y11
+	VPSUBW  Y13, Y12, Y13
+	VPSUBW  Y15, Y14, Y15
+	VMOVDQU Y1, 256(AX)
+	VMOVDQU Y3, 288(AX)
+	VMOVDQU Y5, 320(AX)
+	VMOVDQU Y7, 352(AX)
+	VMOVDQU Y9, 384(AX)
+	VMOVDQU Y11, 416(AX)
+	VMOVDQU Y13, 448(AX)
+	VMOVDQU Y15, 480(AX)
+	RET
+
+// func nttAVX2(p *[256]int16)
+// Requires: AVX, AVX2
+TEXT ·nttAVX2(SB), NOSPLIT, $0-8
+	MOVQ         p+0(FP), AX
+	LEAQ         ·ZetasAVX2+0(SB), CX
+	MOVL         $0x00000d01, DX
+	VMOVD        DX, X0
+	VPBROADCASTW X0, Y15
+	VPBROADCASTW (CX), Y0
+	VPBROADCASTW 2(CX), Y1
+	VMOVDQU      (AX), Y7
+	VMOVDQU      32(AX), Y8
+	VMOVDQU      64(AX), Y9
+	VMOVDQU      96(AX), Y10
+	VMOVDQU      256(AX), Y11
+	VMOVDQU      288(AX), Y12
+	VMOVDQU      320(AX), Y13
+	VMOVDQU      352(AX), Y14
+	VPMULLW      Y11, Y0, Y2
+	VPMULLW      Y12, Y0, Y3
+	VPMULLW      Y13, Y0, Y4
+	VPMULLW      Y14, Y0, Y5
+	VPMULHW      Y11, Y1, Y11
+	VPMULHW      Y12, Y1, Y12
+	VPMULHW      Y13, Y1, Y13
+	VPMULHW      Y14, Y1, Y14
+	VPMULHW      Y2, Y15, Y2
+	VPMULHW      Y3, Y15, Y3
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPSUBW       Y2, Y11, Y2
+	VPSUBW       Y3, Y12, Y3
+	VPSUBW       Y4, Y13, Y4
+	VPSUBW       Y5, Y14, Y5
+	VPSUBW       Y2, Y7, Y11
+	VPSUBW       Y3, Y8, Y12
+	VPSUBW       Y4, Y9, Y13
+	VPSUBW       Y5, Y10, Y14
+	VPADDW       Y2, Y7, Y7
+	VPADDW       Y3, Y8, Y8
+	VPADDW       Y4, Y9, Y9
+	VPADDW       Y5, Y10, Y10
+	VMOVDQU      Y7, (AX)
+	VMOVDQU      Y8, 32(AX)
+	VMOVDQU      Y9, 64(AX)
+	VMOVDQU      Y10, 96(AX)
+	VMOVDQU      Y11, 256(AX)
+	VMOVDQU      Y12, 288(AX)
+	VMOVDQU      Y13, 320(AX)
+	VMOVDQU      Y14, 352(AX)
+	VMOVDQU      128(AX), Y7
+	VMOVDQU      160(AX), Y8
+	VMOVDQU      192(AX), Y9
+	VMOVDQU      224(AX), Y10
+	VMOVDQU      384(AX), Y11
+	VMOVDQU      416(AX), Y12
+	VMOVDQU      448(AX), Y13
+	VMOVDQU      480(AX), Y14
+	VPMULLW      Y11, Y0, Y2
+	VPMULLW      Y12, Y0, Y3
+	VPMULLW      Y13, Y0, Y4
+	VPMULLW      Y14, Y0, Y5
+	VPMULHW      Y11, Y1, Y11
+	VPMULHW      Y12, Y1, Y12
+	VPMULHW      Y13, Y1, Y13
+	VPMULHW      Y14, Y1, Y14
+	VPMULHW      Y2, Y15, Y2
+	VPMULHW      Y3, Y15, Y3
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPSUBW       Y2, Y11, Y2
+	VPSUBW       Y3, Y12, Y3
+	VPSUBW       Y4, Y13, Y4
+	VPSUBW       Y5, Y14, Y5
+	VPSUBW       Y2, Y7, Y11
+	VPSUBW       Y3, Y8, Y12
+	VPSUBW       Y4, Y9, Y13
+	VPSUBW       Y5, Y10, Y14
+	VPADDW       Y2, Y7, Y7
+	VPADDW       Y3, Y8, Y8
+	VPADDW       Y4, Y9, Y9
+	VPADDW       Y5, Y10, Y10
+	VMOVDQU      Y7, 128(AX)
+	VMOVDQU      Y8, 160(AX)
+	VMOVDQU      Y9, 192(AX)
+	VMOVDQU      Y10, 224(AX)
+	VMOVDQU      Y11, 384(AX)
+	VMOVDQU      Y12, 416(AX)
+	VMOVDQU      Y13, 448(AX)
+	VMOVDQU      Y14, 480(AX)
+	VPBROADCASTW 4(CX), Y0
+	VPBROADCASTW 6(CX), Y1
+	VMOVDQU      (AX), Y7
+	VMOVDQU      32(AX), Y8
+	VMOVDQU      64(AX), Y9
+	VMOVDQU      96(AX), Y10
+	VMOVDQU      128(AX), Y11
+	VMOVDQU      160(AX), Y12
+	VMOVDQU      192(AX), Y13
+	VMOVDQU      224(AX), Y14
+	VPMULLW      Y11, Y0, Y2
+	VPMULLW      Y12, Y0, Y3
+	VPMULLW      Y13, Y0, Y4
+	VPMULLW      Y14, Y0, Y5
+	VPMULHW      Y11, Y1, Y11
+	VPMULHW      Y12, Y1, Y12
+	VPMULHW      Y13, Y1, Y13
+	VPMULHW      Y14, Y1, Y14
+	VPMULHW      Y2, Y15, Y2
+	VPMULHW      Y3, Y15, Y3
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPSUBW       Y2, Y11, Y2
+	VPSUBW       Y3, Y12, Y3
+	VPSUBW       Y4, Y13, Y4
+	VPSUBW       Y5, Y14, Y5
+	VPSUBW       Y2, Y7, Y11
+	VPSUBW       Y3, Y8, Y12
+	VPSUBW       Y4, Y9, Y13
+	VPSUBW       Y5, Y10, Y14
+	VPADDW       Y2, Y7, Y7
+	VPADDW       Y3, Y8, Y8
+	VPADDW       Y4, Y9, Y9
+	VPADDW       Y5, Y10, Y10
+	VPBROADCASTW 12(CX), Y0
+	VPBROADCASTW 14(CX), Y1
+	VPBROADCASTW 16(CX), Y2
+	VPBROADCASTW 18(CX), Y3
+	VPMULLW      Y9, Y0, Y4
+	VPMULLW      Y10, Y0, Y5
+	VPMULLW      Y13, Y2, Y6
+	VPMULLW      Y14, Y2, Y0
+	VPMULHW      Y9, Y1, Y9
+	VPMULHW      Y10, Y1, Y10
+	VPMULHW      Y13, Y3, Y13
+	VPMULHW      Y14, Y3, Y14
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPMULHW      Y6, Y15, Y6
+	VPMULHW      Y0, Y15, Y0
+	VPSUBW       Y4, Y9, Y4
+	VPSUBW       Y5, Y10, Y5
+	VPSUBW       Y6, Y13, Y6
+	VPSUBW       Y0, Y14, Y0
+	VPSUBW       Y4, Y7, Y9
+	VPSUBW       Y5, Y8, Y10
+	VPSUBW       Y6, Y11, Y13
+	VPSUBW       Y0, Y12, Y14
+	VPADDW       Y4, Y7, Y7
+	VPADDW       Y5, Y8, Y8
+	VPADDW       Y6, Y11, Y11
+	VPADDW       Y0, Y12, Y12
+	VMOVDQU      32(CX), Y0
+	VMOVDQU      64(CX), Y1
+	VMOVDQU      96(CX), Y2
+	VMOVDQU      128(CX), Y3
+	VPERM2I128   $0x20, Y9, Y7, Y4
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y4, Y7
+	VPERM2I128   $0x20, Y10, Y8, Y4
+	VPERM2I128   $0x31, Y10, Y8, Y10
+	VMOVDQA      Y4, Y8
+	VPERM2I128   $0x20, Y13, Y11, Y4
+	VPERM2I128   $0x31, Y13, Y11, Y13
+	VMOVDQA      Y4, Y11
+	VPERM2I128   $0x20, Y14, Y12, Y4
+	VPERM2I128   $0x31, Y14, Y12, Y14
+	VMOVDQA      Y4, Y12
+	VPMULLW      Y8, Y0, Y4
+	VPMULLW      Y10, Y0, Y5
+	VPMULLW      Y12, Y2, Y6
+	VPMULLW      Y14, Y2, Y0
+	VPMULHW      Y8, Y1, Y8
+	VPMULHW      Y10, Y1, Y10
+	VPMULHW      Y12, Y3, Y12
+	VPMULHW      Y14, Y3, Y14
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPMULHW      Y6, Y15, Y6
+	VPMULHW      Y0, Y15, Y0
+	VPSUBW       Y4, Y8, Y4
+	VPSUBW       Y5, Y10, Y5
+	VPSUBW       Y6, Y12, Y6
+	VPSUBW       Y0, Y14, Y0
+	VPSUBW       Y4, Y7, Y8
+	VPSUBW       Y5, Y9, Y10
+	VPSUBW       Y6, Y11, Y12
+	VPSUBW       Y0, Y13, Y14
+	VPADDW       Y4, Y7, Y7
+	VPADDW       Y5, Y9, Y9
+	VPADDW       Y6, Y11, Y11
+	VPADDW       Y0, Y13, Y13
+	VMOVDQU      288(CX), Y0
+	VMOVDQU      320(CX), Y1
+	VMOVDQU      352(CX), Y2
+	VMOVDQU      384(CX), Y3
+	VPUNPCKLQDQ  Y8, Y7, Y4
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y4, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y4
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y4, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y4
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y4, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y4
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y4, Y13
+	VPMULLW      Y9, Y0, Y4
+	VPMULLW      Y10, Y0, Y5
+	VPMULLW      Y13, Y2, Y6
+	VPMULLW      Y14, Y2, Y0
+	VPMULHW      Y9, Y1, Y9
+	VPMULHW      Y10, Y1, Y10
+	VPMULHW      Y13, Y3, Y13
+	VPMULHW      Y14, Y3, Y14
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPMULHW      Y6, Y15, Y6
+	VPMULHW      Y0, Y15, Y0
+	VPSUBW       Y4, Y9, Y4
+	VPSUBW       Y5, Y10, Y5
+	VPSUBW       Y6, Y13, Y6
+	VPSUBW       Y0, Y14, Y0
+	VPSUBW       Y4, Y7, Y9
+	VPSUBW       Y5, Y8, Y10
+	VPSUBW       Y6, Y11, Y13
+	VPSUBW       Y0, Y12, Y14
+	VPADDW       Y4, Y7, Y7
+	VPADDW       Y5, Y8, Y8
+	VPADDW       Y6, Y11, Y11
+	VPADDW       Y0, Y12, Y12
+	VMOVDQU      544(CX), Y0
+	VMOVDQU      576(CX), Y1
+	VMOVDQU      608(CX), Y2
+	VMOVDQU      640(CX), Y3
+	VMOVSLDUP    Y9, Y4
+	VPBLENDD     $0xaa, Y4, Y7, Y4
+	VPSRLQ       $0x20, Y7, Y7
+	VPBLENDD     $0xaa, Y9, Y7, Y9
+	VMOVDQA      Y4, Y7
+	VMOVSLDUP    Y10, Y4
+	VPBLENDD     $0xaa, Y4, Y8, Y4
+	VPSRLQ       $0x20, Y8, Y8
+	VPBLENDD     $0xaa, Y10, Y8, Y10
+	VMOVDQA      Y4, Y8
+	VMOVSLDUP    Y13, Y4
+	VPBLENDD     $0xaa, Y4, Y11, Y4
+	VPSRLQ       $0x20, Y11, Y11
+	VPBLENDD     $0xaa, Y13, Y11, Y13
+	VMOVDQA      Y4, Y11
+	VMOVSLDUP    Y14, Y4
+	VPBLENDD     $0xaa, Y4, Y12, Y4
+	VPSRLQ       $0x20, Y12, Y12
+	VPBLENDD     $0xaa, Y14, Y12, Y14
+	VMOVDQA      Y4, Y12
+	VPMULLW      Y8, Y0, Y4
+	VPMULLW      Y10, Y0, Y5
+	VPMULLW      Y12, Y2, Y6
+	VPMULLW      Y14, Y2, Y0
+	VPMULHW      Y8, Y1, Y8
+	VPMULHW      Y10, Y1, Y10
+	VPMULHW      Y12, Y3, Y12
+	VPMULHW      Y14, Y3, Y14
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPMULHW      Y6, Y15, Y6
+	VPMULHW      Y0, Y15, Y0
+	VPSUBW       Y4, Y8, Y4
+	VPSUBW       Y5, Y10, Y5
+	VPSUBW       Y6, Y12, Y6
+	VPSUBW       Y0, Y14, Y0
+	VPSUBW       Y4, Y7, Y8
+	VPSUBW       Y5, Y9, Y10
+	VPSUBW       Y6, Y11, Y12
+	VPSUBW       Y0, Y13, Y14
+	VPADDW       Y4, Y7, Y7
+	VPADDW       Y5, Y9, Y9
+	VPADDW       Y6, Y11, Y11
+	VPADDW       Y0, Y13, Y13
+	VMOVDQU      800(CX), Y0
+	VMOVDQU      832(CX), Y1
+	VMOVDQU      864(CX), Y2
+	VMOVDQU      896(CX), Y3
+	VPSLLD       $0x10, Y8, Y4
+	VPBLENDW     $0xaa, Y4, Y7, Y4
+	VPSRLD       $0x10, Y7, Y7
+	VPBLENDW     $0xaa, Y8, Y7, Y8
+	VMOVDQA      Y4, Y7
+	VPSLLD       $0x10, Y10, Y4
+	VPBLENDW     $0xaa, Y4, Y9, Y4
+	VPSRLD       $0x10, Y9, Y9
+	VPBLENDW     $0xaa, Y10, Y9, Y10
+	VMOVDQA      Y4, Y9
+	VPSLLD       $0x10, Y12, Y4
+	VPBLENDW     $0xaa, Y4, Y11, Y4
+	VPSRLD       $0x10, Y11, Y11
+	VPBLENDW     $0xaa, Y12, Y11, Y12
+	VMOVDQA      Y4, Y11
+	VPSLLD       $0x10, Y14, Y4
+	VPBLENDW     $0xaa, Y4, Y13, Y4
+	VPSRLD       $0x10, Y13, Y13
+	VPBLENDW     $0xaa, Y14, Y13, Y14
+	VMOVDQA      Y4, Y13
+	VPMULLW      Y9, Y0, Y4
+	VPMULLW      Y10, Y0, Y5
+	VPMULLW      Y13, Y2, Y6
+	VPMULLW      Y14, Y2, Y0
+	VPMULHW      Y9, Y1, Y9
+	VPMULHW      Y10, Y1, Y10
+	VPMULHW      Y13, Y3, Y13
+	VPMULHW      Y14, Y3, Y14
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPMULHW      Y6, Y15, Y6
+	VPMULHW      Y0, Y15, Y0
+	VPSUBW       Y4, Y9, Y4
+	VPSUBW       Y5, Y10, Y5
+	VPSUBW       Y6, Y13, Y6
+	VPSUBW       Y0, Y14, Y0
+	VPSUBW       Y4, Y7, Y9
+	VPSUBW       Y5, Y8, Y10
+	VPSUBW       Y6, Y11, Y13
+	VPSUBW       Y0, Y12, Y14
+	VPADDW       Y4, Y7, Y7
+	VPADDW       Y5, Y8, Y8
+	VPADDW       Y6, Y11, Y11
+	VPADDW       Y0, Y12, Y12
+	VMOVDQU      Y7, (AX)
+	VMOVDQU      Y8, 32(AX)
+	VMOVDQU      Y9, 64(AX)
+	VMOVDQU      Y10, 96(AX)
+	VMOVDQU      Y11, 128(AX)
+	VMOVDQU      Y12, 160(AX)
+	VMOVDQU      Y13, 192(AX)
+	VMOVDQU      Y14, 224(AX)
+	VPBROADCASTW 8(CX), Y0
+	VPBROADCASTW 10(CX), Y1
+	VMOVDQU      256(AX), Y7
+	VMOVDQU      288(AX), Y8
+	VMOVDQU      320(AX), Y9
+	VMOVDQU      352(AX), Y10
+	VMOVDQU      384(AX), Y11
+	VMOVDQU      416(AX), Y12
+	VMOVDQU      448(AX), Y13
+	VMOVDQU      480(AX), Y14
+	VPMULLW      Y11, Y0, Y2
+	VPMULLW      Y12, Y0, Y3
+	VPMULLW      Y13, Y0, Y4
+	VPMULLW      Y14, Y0, Y5
+	VPMULHW      Y11, Y1, Y11
+	VPMULHW      Y12, Y1, Y12
+	VPMULHW      Y13, Y1, Y13
+	VPMULHW      Y14, Y1, Y14
+	VPMULHW      Y2, Y15, Y2
+	VPMULHW      Y3, Y15, Y3
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPSUBW       Y2, Y11, Y2
+	VPSUBW       Y3, Y12, Y3
+	VPSUBW       Y4, Y13, Y4
+	VPSUBW       Y5, Y14, Y5
+	VPSUBW       Y2, Y7, Y11
+	VPSUBW       Y3, Y8, Y12
+	VPSUBW       Y4, Y9, Y13
+	VPSUBW       Y5, Y10, Y14
+	VPADDW       Y2, Y7, Y7
+	VPADDW       Y3, Y8, Y8
+	VPADDW       Y4, Y9, Y9
+	VPADDW       Y5, Y10, Y10
+	VPBROADCASTW 20(CX), Y0
+	VPBROADCASTW 22(CX), Y1
+	VPBROADCASTW 24(CX), Y2
+	VPBROADCASTW 26(CX), Y3
+	VPMULLW      Y9, Y0, Y4
+	VPMULLW      Y10, Y0, Y5
+	VPMULLW      Y13, Y2, Y6
+	VPMULLW      Y14, Y2, Y0
+	VPMULHW      Y9, Y1, Y9
+	VPMULHW      Y10, Y1, Y10
+	VPMULHW      Y13, Y3, Y13
+	VPMULHW      Y14, Y3, Y14
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPMULHW      Y6, Y15, Y6
+	VPMULHW      Y0, Y15, Y0
+	VPSUBW       Y4, Y9, Y4
+	VPSUBW       Y5, Y10, Y5
+	VPSUBW       Y6, Y13, Y6
+	VPSUBW       Y0, Y14, Y0
+	VPSUBW       Y4, Y7, Y9
+	VPSUBW       Y5, Y8, Y10
+	VPSUBW       Y6, Y11, Y13
+	VPSUBW       Y0, Y12, Y14
+	VPADDW       Y4, Y7, Y7
+	VPADDW       Y5, Y8, Y8
+	VPADDW       Y6, Y11, Y11
+	VPADDW       Y0, Y12, Y12
+	VMOVDQU      160(CX), Y0
+	VMOVDQU      192(CX), Y1
+	VMOVDQU      224(CX), Y2
+	VMOVDQU      256(CX), Y3
+	VPERM2I128   $0x20, Y9, Y7, Y4
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y4, Y7
+	VPERM2I128   $0x20, Y10, Y8, Y4
+	VPERM2I128   $0x31, Y10, Y8, Y10
+	VMOVDQA      Y4, Y8
+	VPERM2I128   $0x20, Y13, Y11, Y4
+	VPERM2I128   $0x31, Y13, Y11, Y13
+	VMOVDQA      Y4, Y11
+	VPERM2I128   $0x20, Y14, Y12, Y4
+	VPERM2I128   $0x31, Y14, Y12, Y14
+	VMOVDQA      Y4, Y12
+	VPMULLW      Y8, Y0, Y4
+	VPMULLW      Y10, Y0, Y5
+	VPMULLW      Y12, Y2, Y6
+	VPMULLW      Y14, Y2, Y0
+	VPMULHW      Y8, Y1, Y8
+	VPMULHW      Y10, Y1, Y10
+	VPMULHW      Y12, Y3, Y12
+	VPMULHW      Y14, Y3, Y14
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPMULHW      Y6, Y15, Y6
+	VPMULHW      Y0, Y15, Y0
+	VPSUBW       Y4, Y8, Y4
+	VPSUBW       Y5, Y10, Y5
+	VPSUBW       Y6, Y12, Y6
+	VPSUBW       Y0, Y14, Y0
+	VPSUBW       Y4, Y7, Y8
+	VPSUBW       Y5, Y9, Y10
+	VPSUBW       Y6, Y11, Y12
+	VPSUBW       Y0, Y13, Y14
+	VPADDW       Y4, Y7, Y7
+	VPADDW       Y5, Y9, Y9
+	VPADDW       Y6, Y11, Y11
+	VPADDW       Y0, Y13, Y13
+	VMOVDQU      416(CX), Y0
+	VMOVDQU      448(CX), Y1
+	VMOVDQU      480(CX), Y2
+	VMOVDQU      512(CX), Y3
+	VPUNPCKLQDQ  Y8, Y7, Y4
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y4, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y4
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y4, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y4
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y4, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y4
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y4, Y13
+	VPMULLW      Y9, Y0, Y4
+	VPMULLW      Y10, Y0, Y5
+	VPMULLW      Y13, Y2, Y6
+	VPMULLW      Y14, Y2, Y0
+	VPMULHW      Y9, Y1, Y9
+	VPMULHW      Y10, Y1, Y10
+	VPMULHW      Y13, Y3, Y13
+	VPMULHW      Y14, Y3, Y14
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPMULHW      Y6, Y15, Y6
+	VPMULHW      Y0, Y15, Y0
+	VPSUBW       Y4, Y9, Y4
+	VPSUBW       Y5, Y10, Y5
+	VPSUBW       Y6, Y13, Y6
+	VPSUBW       Y0, Y14, Y0
+	VPSUBW       Y4, Y7, Y9
+	VPSUBW       Y5, Y8, Y10
+	VPSUBW       Y6, Y11, Y13
+	VPSUBW       Y0, Y12, Y14
+	VPADDW       Y4, Y7, Y7
+	VPADDW       Y5, Y8, Y8
+	VPADDW       Y6, Y11, Y11
+	VPADDW       Y0, Y12, Y12
+	VMOVDQU      672(CX), Y0
+	VMOVDQU      704(CX), Y1
+	VMOVDQU      736(CX), Y2
+	VMOVDQU      768(CX), Y3
+	VMOVSLDUP    Y9, Y4
+	VPBLENDD     $0xaa, Y4, Y7, Y4
+	VPSRLQ       $0x20, Y7, Y7
+	VPBLENDD     $0xaa, Y9, Y7, Y9
+	VMOVDQA      Y4, Y7
+	VMOVSLDUP    Y10, Y4
+	VPBLENDD     $0xaa, Y4, Y8, Y4
+	VPSRLQ       $0x20, Y8, Y8
+	VPBLENDD     $0xaa, Y10, Y8, Y10
+	VMOVDQA      Y4, Y8
+	VMOVSLDUP    Y13, Y4
+	VPBLENDD     $0xaa, Y4, Y11, Y4
+	VPSRLQ       $0x20, Y11, Y11
+	VPBLENDD     $0xaa, Y13, Y11, Y13
+	VMOVDQA      Y4, Y11
+	VMOVSLDUP    Y14, Y4
+	VPBLENDD     $0xaa, Y4, Y12, Y4
+	VPSRLQ       $0x20, Y12, Y12
+	VPBLENDD     $0xaa, Y14, Y12, Y14
+	VMOVDQA      Y4, Y12
+	VPMULLW      Y8, Y0, Y4
+	VPMULLW      Y10, Y0, Y5
+	VPMULLW      Y12, Y2, Y6
+	VPMULLW      Y14, Y2, Y0
+	VPMULHW      Y8, Y1, Y8
+	VPMULHW      Y10, Y1, Y10
+	VPMULHW      Y12, Y3, Y12
+	VPMULHW      Y14, Y3, Y14
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPMULHW      Y6, Y15, Y6
+	VPMULHW      Y0, Y15, Y0
+	VPSUBW       Y4, Y8, Y4
+	VPSUBW       Y5, Y10, Y5
+	VPSUBW       Y6, Y12, Y6
+	VPSUBW       Y0, Y14, Y0
+	VPSUBW       Y4, Y7, Y8
+	VPSUBW       Y5, Y9, Y10
+	VPSUBW       Y6, Y11, Y12
+	VPSUBW       Y0, Y13, Y14
+	VPADDW       Y4, Y7, Y7
+	VPADDW       Y5, Y9, Y9
+	VPADDW       Y6, Y11, Y11
+	VPADDW       Y0, Y13, Y13
+	VMOVDQU      928(CX), Y0
+	VMOVDQU      960(CX), Y1
+	VMOVDQU      992(CX), Y2
+	VMOVDQU      1024(CX), Y3
+	VPSLLD       $0x10, Y8, Y4
+	VPBLENDW     $0xaa, Y4, Y7, Y4
+	VPSRLD       $0x10, Y7, Y7
+	VPBLENDW     $0xaa, Y8, Y7, Y8
+	VMOVDQA      Y4, Y7
+	VPSLLD       $0x10, Y10, Y4
+	VPBLENDW     $0xaa, Y4, Y9, Y4
+	VPSRLD       $0x10, Y9, Y9
+	VPBLENDW     $0xaa, Y10, Y9, Y10
+	VMOVDQA      Y4, Y9
+	VPSLLD       $0x10, Y12, Y4
+	VPBLENDW     $0xaa, Y4, Y11, Y4
+	VPSRLD       $0x10, Y11, Y11
+	VPBLENDW     $0xaa, Y12, Y11, Y12
+	VMOVDQA      Y4, Y11
+	VPSLLD       $0x10, Y14, Y4
+	VPBLENDW     $0xaa, Y4, Y13, Y4
+	VPSRLD       $0x10, Y13, Y13
+	VPBLENDW     $0xaa, Y14, Y13, Y14
+	VMOVDQA      Y4, Y13
+	VPMULLW      Y9, Y0, Y4
+	VPMULLW      Y10, Y0, Y5
+	VPMULLW      Y13, Y2, Y6
+	VPMULLW      Y14, Y2, Y0
+	VPMULHW      Y9, Y1, Y9
+	VPMULHW      Y10, Y1, Y10
+	VPMULHW      Y13, Y3, Y13
+	VPMULHW      Y14, Y3, Y14
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPMULHW      Y6, Y15, Y6
+	VPMULHW      Y0, Y15, Y0
+	VPSUBW       Y4, Y9, Y4
+	VPSUBW       Y5, Y10, Y5
+	VPSUBW       Y6, Y13, Y6
+	VPSUBW       Y0, Y14, Y0
+	VPSUBW       Y4, Y7, Y9
+	VPSUBW       Y5, Y8, Y10
+	VPSUBW       Y6, Y11, Y13
+	VPSUBW       Y0, Y12, Y14
+	VPADDW       Y4, Y7, Y7
+	VPADDW       Y5, Y8, Y8
+	VPADDW       Y6, Y11, Y11
+	VPADDW       Y0, Y12, Y12
+	VMOVDQU      Y7, 256(AX)
+	VMOVDQU      Y8, 288(AX)
+	VMOVDQU      Y9, 320(AX)
+	VMOVDQU      Y10, 352(AX)
+	VMOVDQU      Y11, 384(AX)
+	VMOVDQU      Y12, 416(AX)
+	VMOVDQU      Y13, 448(AX)
+	VMOVDQU      Y14, 480(AX)
+	RET
+
+// func invNttAVX2(p *[256]int16)
+// Requires: AVX, AVX2
+TEXT ·invNttAVX2(SB), NOSPLIT, $0-8
+	MOVQ         p+0(FP), AX
+	LEAQ         ·ZetasAVX2+0(SB), CX
+	MOVL         $0x00000d01, DX
+	VMOVD        DX, X0
+	VPBROADCASTW X0, Y15
+	VMOVDQU      (AX), Y7
+	VMOVDQU      32(AX), Y8
+	VMOVDQU      64(AX), Y9
+	VMOVDQU      96(AX), Y10
+	VMOVDQU      128(AX), Y11
+	VMOVDQU      160(AX), Y12
+	VMOVDQU      192(AX), Y13
+	VMOVDQU      224(AX), Y14
+	VMOVDQU      1056(CX), Y0
+	VMOVDQU      1088(CX), Y1
+	VMOVDQU      1120(CX), Y2
+	VMOVDQU      1152(CX), Y3
+	VPSUBW       Y7, Y9, Y4
+	VPSUBW       Y8, Y10, Y5
+	VPSUBW       Y11, Y13, Y6
+	VPADDW       Y7, Y9, Y7
+	VPADDW       Y8, Y10, Y8
+	VPADDW       Y11, Y13, Y11
+	VPMULLW      Y4, Y0, Y9
+	VPMULLW      Y5, Y0, Y10
+	VPSUBW       Y12, Y14, Y0
+	VPMULLW      Y6, Y2, Y13
+	VPADDW       Y12, Y14, Y12
+	VPMULLW      Y0, Y2, Y14
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y6, Y3, Y6
+	VPMULHW      Y0, Y3, Y0
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y13, Y15, Y13
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y9, Y4, Y9
+	VPSUBW       Y10, Y5, Y10
+	VPSUBW       Y13, Y6, Y13
+	VPSUBW       Y14, Y0, Y14
+	VMOVDQU      1312(CX), Y0
+	VMOVDQU      1344(CX), Y1
+	VMOVDQU      1376(CX), Y2
+	VMOVDQU      1408(CX), Y3
+	VPSLLD       $0x10, Y8, Y4
+	VPBLENDW     $0xaa, Y4, Y7, Y4
+	VPSRLD       $0x10, Y7, Y7
+	VPBLENDW     $0xaa, Y8, Y7, Y8
+	VMOVDQA      Y4, Y7
+	VPSLLD       $0x10, Y10, Y4
+	VPBLENDW     $0xaa, Y4, Y9, Y4
+	VPSRLD       $0x10, Y9, Y9
+	VPBLENDW     $0xaa, Y10, Y9, Y10
+	VMOVDQA      Y4, Y9
+	VPSLLD       $0x10, Y12, Y4
+	VPBLENDW     $0xaa, Y4, Y11, Y4
+	VPSRLD       $0x10, Y11, Y11
+	VPBLENDW     $0xaa, Y12, Y11, Y12
+	VMOVDQA      Y4, Y11
+	VPSLLD       $0x10, Y14, Y4
+	VPBLENDW     $0xaa, Y4, Y13, Y4
+	VPSRLD       $0x10, Y13, Y13
+	VPBLENDW     $0xaa, Y14, Y13, Y14
+	VMOVDQA      Y4, Y13
+	VPSUBW       Y7, Y8, Y4
+	VPSUBW       Y9, Y10, Y5
+	VPSUBW       Y11, Y12, Y6
+	VPADDW       Y7, Y8, Y7
+	VPADDW       Y9, Y10, Y9
+	VPADDW       Y11, Y12, Y11
+	VPMULLW      Y4, Y0, Y8
+	VPMULLW      Y5, Y0, Y10
+	VPSUBW       Y13, Y14, Y0
+	VPMULLW      Y6, Y2, Y12
+	VPADDW       Y13, Y14, Y13
+	VPMULLW      Y0, Y2, Y14
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y6, Y3, Y6
+	VPMULHW      Y0, Y3, Y0
+	VPMULHW      Y8, Y15, Y8
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y12, Y15, Y12
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y8, Y4, Y8
+	VPSUBW       Y10, Y5, Y10
+	VPSUBW       Y12, Y6, Y12
+	VPSUBW       Y14, Y0, Y14
+	VMOVDQU      1568(CX), Y0
+	VMOVDQU      1600(CX), Y1
+	VMOVDQU      1632(CX), Y2
+	VMOVDQU      1664(CX), Y3
+	VMOVSLDUP    Y9, Y4
+	VPBLENDD     $0xaa, Y4, Y7, Y4
+	VPSRLQ       $0x20, Y7, Y7
+	VPBLENDD     $0xaa, Y9, Y7, Y9
+	VMOVDQA      Y4, Y7
+	VMOVSLDUP    Y10, Y4
+	VPBLENDD     $0xaa, Y4, Y8, Y4
+	VPSRLQ       $0x20, Y8, Y8
+	VPBLENDD     $0xaa, Y10, Y8, Y10
+	VMOVDQA      Y4, Y8
+	VMOVSLDUP    Y13, Y4
+	VPBLENDD     $0xaa, Y4, Y11, Y4
+	VPSRLQ       $0x20, Y11, Y11
+	VPBLENDD     $0xaa, Y13, Y11, Y13
+	VMOVDQA      Y4, Y11
+	VMOVSLDUP    Y14, Y4
+	VPBLENDD     $0xaa, Y4, Y12, Y4
+	VPSRLQ       $0x20, Y12, Y12
+	VPBLENDD     $0xaa, Y14, Y12, Y14
+	VMOVDQA      Y4, Y12
+	VPSUBW       Y7, Y9, Y4
+	VPSUBW       Y8, Y10, Y5
+	VPSUBW       Y11, Y13, Y6
+	VPADDW       Y7, Y9, Y7
+	VPADDW       Y8, Y10, Y8
+	VPADDW       Y11, Y13, Y11
+	VPMULLW      Y4, Y0, Y9
+	VPMULLW      Y5, Y0, Y10
+	VPSUBW       Y12, Y14, Y0
+	VPMULLW      Y6, Y2, Y13
+	VPADDW       Y12, Y14, Y12
+	VPMULLW      Y0, Y2, Y14
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y6, Y3, Y6
+	VPMULHW      Y0, Y3, Y0
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y13, Y15, Y13
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y9, Y4, Y9
+	VPSUBW       Y10, Y5, Y10
+	VPSUBW       Y13, Y6, Y13
+	VPSUBW       Y14, Y0, Y14
+	MOVL         $0x00004ebf, DX
+	VMOVD        DX, X0
+	VPBROADCASTW X0, Y4
+	VPMULHW      Y4, Y7, Y5
+	VPSRAW       $0x0a, Y5, Y5
+	VPMULLW      Y15, Y5, Y5
+	VPSUBW       Y5, Y7, Y7
+	VPMULHW      Y4, Y11, Y5
+	VPSRAW       $0x0a, Y5, Y5
+	VPMULLW      Y15, Y5, Y5
+	VPSUBW       Y5, Y11, Y11
+	VMOVDQU      1824(CX), Y0
+	VMOVDQU      1856(CX), Y1
+	VMOVDQU      1888(CX), Y2
+	VMOVDQU      1920(CX), Y3
+	VPUNPCKLQDQ  Y8, Y7, Y4
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y4, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y4
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y4, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y4
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y4, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y4
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y4, Y13
+	VPSUBW       Y7, Y8, Y4
+	VPSUBW       Y9, Y10, Y5
+	VPSUBW       Y11, Y12, Y6
+	VPADDW       Y7, Y8, Y7
+	VPADDW       Y9, Y10, Y9
+	VPADDW       Y11, Y12, Y11
+	VPMULLW      Y4, Y0, Y8
+	VPMULLW      Y5, Y0, Y10
+	VPSUBW       Y13, Y14, Y0
+	VPMULLW      Y6, Y2, Y12
+	VPADDW       Y13, Y14, Y13
+	VPMULLW      Y0, Y2, Y14
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y6, Y3, Y6
+	VPMULHW      Y0, Y3, Y0
+	VPMULHW      Y8, Y15, Y8
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y12, Y15, Y12
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y8, Y4, Y8
+	VPSUBW       Y10, Y5, Y10
+	VPSUBW       Y12, Y6, Y12
+	VPSUBW       Y14, Y0, Y14
+	VPBROADCASTW 2080(CX), Y0
+	VPBROADCASTW 2082(CX), Y1
+	VPBROADCASTW 2084(CX), Y2
+	VPBROADCASTW 2086(CX), Y3
+	VPERM2I128   $0x20, Y9, Y7, Y4
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y4, Y7
+	VPERM2I128   $0x20, Y10, Y8, Y4
+	VPERM2I128   $0x31, Y10, Y8, Y10
+	VMOVDQA      Y4, Y8
+	VPERM2I128   $0x20, Y13, Y11, Y4
+	VPERM2I128   $0x31, Y13, Y11, Y13
+	VMOVDQA      Y4, Y11
+	VPERM2I128   $0x20, Y14, Y12, Y4
+	VPERM2I128   $0x31, Y14, Y12, Y14
+	VMOVDQA      Y4, Y12
+	VPSUBW       Y7, Y9, Y4
+	VPSUBW       Y8, Y10, Y5
+	VPSUBW       Y11, Y13, Y6
+	VPADDW       Y7, Y9, Y7
+	VPADDW       Y8, Y10, Y8
+	VPADDW       Y11, Y13, Y11
+	VPMULLW      Y4, Y0, Y9
+	VPMULLW      Y5, Y0, Y10
+	VPSUBW       Y12, Y14, Y0
+	VPMULLW      Y6, Y2, Y13
+	VPADDW       Y12, Y14, Y12
+	VPMULLW      Y0, Y2, Y14
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y6, Y3, Y6
+	VPMULHW      Y0, Y3, Y0
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y13, Y15, Y13
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y9, Y4, Y9
+	VPSUBW       Y10, Y5, Y10
+	VPSUBW       Y13, Y6, Y13
+	VPSUBW       Y14, Y0, Y14
+	MOVL         $0x00004ebf, DX
+	VMOVD        DX, X0
+	VPBROADCASTW X0, Y4
+	VPMULHW      Y4, Y7, Y5
+	VPSRAW       $0x0a, Y5, Y5
+	VPMULLW      Y15, Y5, Y5
+	VPSUBW       Y5, Y7, Y7
+	VPMULHW      Y4, Y11, Y5
+	VPSRAW       $0x0a, Y5, Y5
+	VPMULLW      Y15, Y5, Y5
+	VPSUBW       Y5, Y11, Y11
+	VPBROADCASTW 2096(CX), Y0
+	VPBROADCASTW 2098(CX), Y1
+	VPSUBW       Y7, Y11, Y4
+	VPSUBW       Y8, Y12, Y5
+	VPSUBW       Y9, Y13, Y6
+	VPADDW       Y7, Y11, Y7
+	VPADDW       Y8, Y12, Y8
+	VPADDW       Y9, Y13, Y9
+	VPMULLW      Y4, Y0, Y11
+	VPMULLW      Y5, Y0, Y12
+	VPSUBW       Y10, Y14, Y2
+	VPMULLW      Y6, Y0, Y13
+	VPADDW       Y10, Y14, Y10
+	VPMULLW      Y2, Y0, Y14
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y6, Y1, Y6
+	VPMULHW      Y2, Y1, Y2
+	VPMULHW      Y11, Y15, Y11
+	VPMULHW      Y12, Y15, Y12
+	VPMULHW      Y13, Y15, Y13
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y11, Y4, Y11
+	VPSUBW       Y12, Y5, Y12
+	VPSUBW       Y13, Y6, Y13
+	VPSUBW       Y14, Y2, Y14
+	VMOVDQU      Y7, (AX)
+	VMOVDQU      Y8, 32(AX)
+	VMOVDQU      Y9, 64(AX)
+	VMOVDQU      Y10, 96(AX)
+	VMOVDQU      Y11, 128(AX)
+	VMOVDQU      Y12, 160(AX)
+	VMOVDQU      Y13, 192(AX)
+	VMOVDQU      Y14, 224(AX)
+	VMOVDQU      256(AX), Y7
+	VMOVDQU      288(AX), Y8
+	VMOVDQU      320(AX), Y9
+	VMOVDQU      352(AX), Y10
+	VMOVDQU      384(AX), Y11
+	VMOVDQU      416(AX), Y12
+	VMOVDQU      448(AX), Y13
+	VMOVDQU      480(AX), Y14
+	VMOVDQU      1184(CX), Y0
+	VMOVDQU      1216(CX), Y1
+	VMOVDQU      1248(CX), Y2
+	VMOVDQU      1280(CX), Y3
+	VPSUBW       Y7, Y9, Y4
+	VPSUBW       Y8, Y10, Y5
+	VPSUBW       Y11, Y13, Y6
+	VPADDW       Y7, Y9, Y7
+	VPADDW       Y8, Y10, Y8
+	VPADDW       Y11, Y13, Y11
+	VPMULLW      Y4, Y0, Y9
+	VPMULLW      Y5, Y0, Y10
+	VPSUBW       Y12, Y14, Y0
+	VPMULLW      Y6, Y2, Y13
+	VPADDW       Y12, Y14, Y12
+	VPMULLW      Y0, Y2, Y14
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y6, Y3, Y6
+	VPMULHW      Y0, Y3, Y0
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y13, Y15, Y13
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y9, Y4, Y9
+	VPSUBW       Y10, Y5, Y10
+	VPSUBW       Y13, Y6, Y13
+	VPSUBW       Y14, Y0, Y14
+	VMOVDQU      1440(CX), Y0
+	VMOVDQU      1472(CX), Y1
+	VMOVDQU      1504(CX), Y2
+	VMOVDQU      1536(CX), Y3
+	VPSLLD       $0x10, Y8, Y4
+	VPBLENDW     $0xaa, Y4, Y7, Y4
+	VPSRLD       $0x10, Y7, Y7
+	VPBLENDW     $0xaa, Y8, Y7, Y8
+	VMOVDQA      Y4, Y7
+	VPSLLD       $0x10, Y10, Y4
+	VPBLENDW     $0xaa, Y4, Y9, Y4
+	VPSRLD       $0x10, Y9, Y9
+	VPBLENDW     $0xaa, Y10, Y9, Y10
+	VMOVDQA      Y4, Y9
+	VPSLLD       $0x10, Y12, Y4
+	VPBLENDW     $0xaa, Y4, Y11, Y4
+	VPSRLD       $0x10, Y11, Y11
+	VPBLENDW     $0xaa, Y12, Y11, Y12
+	VMOVDQA      Y4, Y11
+	VPSLLD       $0x10, Y14, Y4
+	VPBLENDW     $0xaa, Y4, Y13, Y4
+	VPSRLD       $0x10, Y13, Y13
+	VPBLENDW     $0xaa, Y14, Y13, Y14
+	VMOVDQA      Y4, Y13
+	VPSUBW       Y7, Y8, Y4
+	VPSUBW       Y9, Y10, Y5
+	VPSUBW       Y11, Y12, Y6
+	VPADDW       Y7, Y8, Y7
+	VPADDW       Y9, Y10, Y9
+	VPADDW       Y11, Y12, Y11
+	VPMULLW      Y4, Y0, Y8
+	VPMULLW      Y5, Y0, Y10
+	VPSUBW       Y13, Y14, Y0
+	VPMULLW      Y6, Y2, Y12
+	VPADDW       Y13, Y14, Y13
+	VPMULLW      Y0, Y2, Y14
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y6, Y3, Y6
+	VPMULHW      Y0, Y3, Y0
+	VPMULHW      Y8, Y15, Y8
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y12, Y15, Y12
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y8, Y4, Y8
+	VPSUBW       Y10, Y5, Y10
+	VPSUBW       Y12, Y6, Y12
+	VPSUBW       Y14, Y0, Y14
+	VMOVDQU      1696(CX), Y0
+	VMOVDQU      1728(CX), Y1
+	VMOVDQU      1760(CX), Y2
+	VMOVDQU      1792(CX), Y3
+	VMOVSLDUP    Y9, Y4
+	VPBLENDD     $0xaa, Y4, Y7, Y4
+	VPSRLQ       $0x20, Y7, Y7
+	VPBLENDD     $0xaa, Y9, Y7, Y9
+	VMOVDQA      Y4, Y7
+	VMOVSLDUP    Y10, Y4
+	VPBLENDD     $0xaa, Y4, Y8, Y4
+	VPSRLQ       $0x20, Y8, Y8
+	VPBLENDD     $0xaa, Y10, Y8, Y10
+	VMOVDQA      Y4, Y8
+	VMOVSLDUP    Y13, Y4
+	VPBLENDD     $0xaa, Y4, Y11, Y4
+	VPSRLQ       $0x20, Y11, Y11
+	VPBLENDD     $0xaa, Y13, Y11, Y13
+	VMOVDQA      Y4, Y11
+	VMOVSLDUP    Y14, Y4
+	VPBLENDD     $0xaa, Y4, Y12, Y4
+	VPSRLQ       $0x20, Y12, Y12
+	VPBLENDD     $0xaa, Y14, Y12, Y14
+	VMOVDQA      Y4, Y12
+	VPSUBW       Y7, Y9, Y4
+	VPSUBW       Y8, Y10, Y5
+	VPSUBW       Y11, Y13, Y6
+	VPADDW       Y7, Y9, Y7
+	VPADDW       Y8, Y10, Y8
+	VPADDW       Y11, Y13, Y11
+	VPMULLW      Y4, Y0, Y9
+	VPMULLW      Y5, Y0, Y10
+	VPSUBW       Y12, Y14, Y0
+	VPMULLW      Y6, Y2, Y13
+	VPADDW       Y12, Y14, Y12
+	VPMULLW      Y0, Y2, Y14
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y6, Y3, Y6
+	VPMULHW      Y0, Y3, Y0
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y13, Y15, Y13
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y9, Y4, Y9
+	VPSUBW       Y10, Y5, Y10
+	VPSUBW       Y13, Y6, Y13
+	VPSUBW       Y14, Y0, Y14
+	MOVL         $0x00004ebf, DX
+	VMOVD        DX, X0
+	VPBROADCASTW X0, Y4
+	VPMULHW      Y4, Y7, Y5
+	VPSRAW       $0x0a, Y5, Y5
+	VPMULLW      Y15, Y5, Y5
+	VPSUBW       Y5, Y7, Y7
+	VPMULHW      Y4, Y11, Y5
+	VPSRAW       $0x0a, Y5, Y5
+	VPMULLW      Y15, Y5, Y5
+	VPSUBW       Y5, Y11, Y11
+	VMOVDQU      1952(CX), Y0
+	VMOVDQU      1984(CX), Y1
+	VMOVDQU      2016(CX), Y2
+	VMOVDQU      2048(CX), Y3
+	VPUNPCKLQDQ  Y8, Y7, Y4
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y4, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y4
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y4, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y4
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y4, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y4
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y4, Y13
+	VPSUBW       Y7, Y8, Y4
+	VPSUBW       Y9, Y10, Y5
+	VPSUBW       Y11, Y12, Y6
+	VPADDW       Y7, Y8, Y7
+	VPADDW       Y9, Y10, Y9
+	VPADDW       Y11, Y12, Y11
+	VPMULLW      Y4, Y0, Y8
+	VPMULLW      Y5, Y0, Y10
+	VPSUBW       Y13, Y14, Y0
+	VPMULLW      Y6, Y2, Y12
+	VPADDW       Y13, Y14, Y13
+	VPMULLW      Y0, Y2, Y14
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y6, Y3, Y6
+	VPMULHW      Y0, Y3, Y0
+	VPMULHW      Y8, Y15, Y8
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y12, Y15, Y12
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y8, Y4, Y8
+	VPSUBW       Y10, Y5, Y10
+	VPSUBW       Y12, Y6, Y12
+	VPSUBW       Y14, Y0, Y14
+	VPBROADCASTW 2088(CX), Y0
+	VPBROADCASTW 2090(CX), Y1
+	VPBROADCASTW 2092(CX), Y2
+	VPBROADCASTW 2094(CX), Y3
+	VPERM2I128   $0x20, Y9, Y7, Y4
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y4, Y7
+	VPERM2I128   $0x20, Y10, Y8, Y4
+	VPERM2I128   $0x31, Y10, Y8, Y10
+	VMOVDQA      Y4, Y8
+	VPERM2I128   $0x20, Y13, Y11, Y4
+	VPERM2I128   $0x31, Y13, Y11, Y13
+	VMOVDQA      Y4, Y11
+	VPERM2I128   $0x20, Y14, Y12, Y4
+	VPERM2I128   $0x31, Y14, Y12, Y14
+	VMOVDQA      Y4, Y12
+	VPSUBW       Y7, Y9, Y4
+	VPSUBW       Y8, Y10, Y5
+	VPSUBW       Y11, Y13, Y6
+	VPADDW       Y7, Y9, Y7
+	VPADDW       Y8, Y10, Y8
+	VPADDW       Y11, Y13, Y11
+	VPMULLW      Y4, Y0, Y9
+	VPMULLW      Y5, Y0, Y10
+	VPSUBW       Y12, Y14, Y0
+	VPMULLW      Y6, Y2, Y13
+	VPADDW       Y12, Y14, Y12
+	VPMULLW      Y0, Y2, Y14
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y6, Y3, Y6
+	VPMULHW      Y0, Y3, Y0
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y13, Y15, Y13
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y9, Y4, Y9
+	VPSUBW       Y10, Y5, Y10
+	VPSUBW       Y13, Y6, Y13
+	VPSUBW       Y14, Y0, Y14
+	MOVL         $0x00004ebf, DX
+	VMOVD        DX, X0
+	VPBROADCASTW X0, Y4
+	VPMULHW      Y4, Y7, Y5
+	VPSRAW       $0x0a, Y5, Y5
+	VPMULLW      Y15, Y5, Y5
+	VPSUBW       Y5, Y7, Y7
+	VPMULHW      Y4, Y11, Y5
+	VPSRAW       $0x0a, Y5, Y5
+	VPMULLW      Y15, Y5, Y5
+	VPSUBW       Y5, Y11, Y11
+	VPBROADCASTW 2100(CX), Y0
+	VPBROADCASTW 2102(CX), Y1
+	VPSUBW       Y7, Y11, Y4
+	VPSUBW       Y8, Y12, Y5
+	VPSUBW       Y9, Y13, Y6
+	VPADDW       Y7, Y11, Y7
+	VPADDW       Y8, Y12, Y8
+	VPADDW       Y9, Y13, Y9
+	VPMULLW      Y4, Y0, Y11
+	VPMULLW      Y5, Y0, Y12
+	VPSUBW       Y10, Y14, Y2
+	VPMULLW      Y6, Y0, Y13
+	VPADDW       Y10, Y14, Y10
+	VPMULLW      Y2, Y0, Y14
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y6, Y1, Y6
+	VPMULHW      Y2, Y1, Y2
+	VPMULHW      Y11, Y15, Y11
+	VPMULHW      Y12, Y15, Y12
+	VPMULHW      Y13, Y15, Y13
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y11, Y4, Y11
+	VPSUBW       Y12, Y5, Y12
+	VPSUBW       Y13, Y6, Y13
+	VPSUBW       Y14, Y2, Y14
+	VMOVDQU      Y7, 256(AX)
+	VMOVDQU      Y8, 288(AX)
+	VMOVDQU      Y9, 320(AX)
+	VMOVDQU      Y10, 352(AX)
+	VMOVDQU      Y11, 384(AX)
+	VMOVDQU      Y12, 416(AX)
+	VMOVDQU      Y13, 448(AX)
+	VMOVDQU      Y14, 480(AX)
+	VPBROADCASTW 2104(CX), Y0
+	VPBROADCASTW 2106(CX), Y1
+	VMOVDQU      (AX), Y7
+	VMOVDQU      32(AX), Y8
+	VMOVDQU      64(AX), Y9
+	VMOVDQU      96(AX), Y10
+	VMOVDQU      256(AX), Y11
+	VMOVDQU      288(AX), Y12
+	VMOVDQU      320(AX), Y13
+	VMOVDQU      352(AX), Y14
+	VPSUBW       Y7, Y11, Y2
+	VPSUBW       Y8, Y12, Y3
+	VPSUBW       Y9, Y13, Y4
+	VPADDW       Y7, Y11, Y7
+	VPADDW       Y8, Y12, Y8
+	VPADDW       Y9, Y13, Y9
+	VPMULLW      Y2, Y0, Y11
+	VPMULLW      Y3, Y0, Y12
+	VPSUBW       Y10, Y14, Y5
+	VPMULLW      Y4, Y0, Y13
+	VPADDW       Y10, Y14, Y10
+	VPMULLW      Y5, Y0, Y14
+	VPMULHW      Y2, Y1, Y2
+	VPMULHW      Y3, Y1, Y3
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y11, Y15, Y11
+	VPMULHW      Y12, Y15, Y12
+	VPMULHW      Y13, Y15, Y13
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y11, Y2, Y11
+	VPSUBW       Y12, Y3, Y12
+	VPSUBW       Y13, Y4, Y13
+	VPSUBW       Y14, Y5, Y14
+	MOVL         $0xffffd8a1, DX
+	VMOVD        DX, X0
+	VPBROADCASTW X0, Y0
+	MOVL         $0x000005a1, DX
+	VMOVD        DX, X1
+	VPBROADCASTW X1, Y1
+	VPMULLW      Y7, Y0, Y2
+	VPMULLW      Y8, Y0, Y3
+	VPMULLW      Y9, Y0, Y4
+	VPMULLW      Y10, Y0, Y5
+	VPMULHW      Y7, Y1, Y7
+	VPMULHW      Y8, Y1, Y8
+	VPMULHW      Y9, Y1, Y9
+	VPMULHW      Y10, Y1, Y10
+	VPMULHW      Y2, Y15, Y2
+	VPMULHW      Y3, Y15, Y3
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPSUBW       Y2, Y7, Y7
+	VPSUBW       Y3, Y8, Y8
+	VPSUBW       Y4, Y9, Y9
+	VPSUBW       Y5, Y10, Y10
+	VPMULLW      Y11, Y0, Y2
+	VPMULLW      Y12, Y0, Y3
+	VPMULLW      Y13, Y0, Y4
+	VPMULLW      Y14, Y0, Y5
+	VPMULHW      Y11, Y1, Y11
+	VPMULHW      Y12, Y1, Y12
+	VPMULHW      Y13, Y1, Y13
+	VPMULHW      Y14, Y1, Y14
+	VPMULHW      Y2, Y15, Y2
+	VPMULHW      Y3, Y15, Y3
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPSUBW       Y2, Y11, Y11
+	VPSUBW       Y3, Y12, Y12
+	VPSUBW       Y4, Y13, Y13
+	VPSUBW       Y5, Y14, Y14
+	VMOVDQU      Y7, (AX)
+	VMOVDQU      Y8, 32(AX)
+	VMOVDQU      Y9, 64(AX)
+	VMOVDQU      Y10, 96(AX)
+	VMOVDQU      Y11, 256(AX)
+	VMOVDQU      Y12, 288(AX)
+	VMOVDQU      Y13, 320(AX)
+	VMOVDQU      Y14, 352(AX)
+	VPBROADCASTW 2104(CX), Y0
+	VPBROADCASTW 2106(CX), Y1
+	VMOVDQU      128(AX), Y7
+	VMOVDQU      160(AX), Y8
+	VMOVDQU      192(AX), Y9
+	VMOVDQU      224(AX), Y10
+	VMOVDQU      384(AX), Y11
+	VMOVDQU      416(AX), Y12
+	VMOVDQU      448(AX), Y13
+	VMOVDQU      480(AX), Y14
+	VPSUBW       Y7, Y11, Y2
+	VPSUBW       Y8, Y12, Y3
+	VPSUBW       Y9, Y13, Y4
+	VPADDW       Y7, Y11, Y7
+	VPADDW       Y8, Y12, Y8
+	VPADDW       Y9, Y13, Y9
+	VPMULLW      Y2, Y0, Y11
+	VPMULLW      Y3, Y0, Y12
+	VPSUBW       Y10, Y14, Y5
+	VPMULLW      Y4, Y0, Y13
+	VPADDW       Y10, Y14, Y10
+	VPMULLW      Y5, Y0, Y14
+	VPMULHW      Y2, Y1, Y2
+	VPMULHW      Y3, Y1, Y3
+	VPMULHW      Y4, Y1, Y4
+	VPMULHW      Y5, Y1, Y5
+	VPMULHW      Y11, Y15, Y11
+	VPMULHW      Y12, Y15, Y12
+	VPMULHW      Y13, Y15, Y13
+	VPMULHW      Y14, Y15, Y14
+	VPSUBW       Y11, Y2, Y11
+	VPSUBW       Y12, Y3, Y12
+	VPSUBW       Y13, Y4, Y13
+	VPSUBW       Y14, Y5, Y14
+	MOVL         $0xffffd8a1, CX
+	VMOVD        CX, X0
+	VPBROADCASTW X0, Y0
+	MOVL         $0x000005a1, CX
+	VMOVD        CX, X1
+	VPBROADCASTW X1, Y1
+	VPMULLW      Y7, Y0, Y2
+	VPMULLW      Y8, Y0, Y3
+	VPMULLW      Y9, Y0, Y4
+	VPMULLW      Y10, Y0, Y5
+	VPMULHW      Y7, Y1, Y7
+	VPMULHW      Y8, Y1, Y8
+	VPMULHW      Y9, Y1, Y9
+	VPMULHW      Y10, Y1, Y10
+	VPMULHW      Y2, Y15, Y2
+	VPMULHW      Y3, Y15, Y3
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPSUBW       Y2, Y7, Y7
+	VPSUBW       Y3, Y8, Y8
+	VPSUBW       Y4, Y9, Y9
+	VPSUBW       Y5, Y10, Y10
+	VPMULLW      Y11, Y0, Y2
+	VPMULLW      Y12, Y0, Y3
+	VPMULLW      Y13, Y0, Y4
+	VPMULLW      Y14, Y0, Y5
+	VPMULHW      Y11, Y1, Y11
+	VPMULHW      Y12, Y1, Y12
+	VPMULHW      Y13, Y1, Y13
+	VPMULHW      Y14, Y1, Y14
+	VPMULHW      Y2, Y15, Y2
+	VPMULHW      Y3, Y15, Y3
+	VPMULHW      Y4, Y15, Y4
+	VPMULHW      Y5, Y15, Y5
+	VPSUBW       Y2, Y11, Y11
+	VPSUBW       Y3, Y12, Y12
+	VPSUBW       Y4, Y13, Y13
+	VPSUBW       Y5, Y14, Y14
+	VMOVDQU      Y7, 128(AX)
+	VMOVDQU      Y8, 160(AX)
+	VMOVDQU      Y9, 192(AX)
+	VMOVDQU      Y10, 224(AX)
+	VMOVDQU      Y11, 384(AX)
+	VMOVDQU      Y12, 416(AX)
+	VMOVDQU      Y13, 448(AX)
+	VMOVDQU      Y14, 480(AX)
+	RET
+
+// func mulHatAVX2(p *[256]int16, a *[256]int16, b *[256]int16)
+// Requires: AVX, AVX2
+TEXT ·mulHatAVX2(SB), NOSPLIT, $8-24
+	MOVQ         p+0(FP), AX
+	MOVQ         a+8(FP), CX
+	MOVQ         b+16(FP), DX
+	LEAQ         ·ZetasAVX2+0(SB), BX
+	MOVL         $0xfffff301, SI
+	VMOVD        SI, X0
+	VPBROADCASTW X0, Y14
+	MOVL         $0x00000d01, SI
+	VMOVD        SI, X0
+	VPBROADCASTW X0, Y15
+	VMOVDQU      (CX), Y0
+	VMOVDQU      32(CX), Y1
+	VMOVDQU      64(CX), Y2
+	VMOVDQU      96(CX), Y3
+	VMOVDQU      (DX), Y4
+	VMOVDQU      32(DX), Y5
+	VMOVDQU      64(DX), Y6
+	VMOVDQU      96(DX), Y7
+	VPMULLW      Y1, Y5, Y8
+	VPMULLW      Y0, Y4, Y9
+	VPMULLW      Y0, Y5, Y10
+	VPMULLW      Y1, Y4, Y11
+	VPMULLW      Y8, Y14, Y8
+	VPMULLW      Y9, Y14, Y9
+	VPMULLW      Y10, Y14, Y10
+	VPMULLW      Y11, Y14, Y11
+	VPMULHW      Y1, Y5, Y12
+	VPMULHW      Y0, Y4, Y13
+	VPMULHW      Y0, Y5, Y0
+	VPMULHW      Y1, Y4, Y1
+	VMOVDQA      Y12, Y4
+	VMOVDQA      Y13, Y5
+	VPMULHW      Y8, Y15, Y8
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y11, Y15, Y11
+	VPSUBW       Y8, Y4, Y4
+	VPSUBW       Y9, Y5, Y5
+	VPSUBW       Y10, Y0, Y0
+	VPSUBW       Y11, Y1, Y1
+	VMOVDQU      800(BX), Y12
+	VMOVDQU      832(BX), Y13
+	VPMULLW      Y4, Y12, Y8
+	VPMULHW      Y4, Y13, Y4
+	VPMULHW      Y8, Y15, Y8
+	VPSUBW       Y8, Y4, Y4
+	VPADDW       Y4, Y5, Y4
+	VPADDW       Y0, Y1, Y5
+	VPMULLW      Y3, Y7, Y8
+	VPMULLW      Y2, Y6, Y9
+	VPMULLW      Y2, Y7, Y10
+	VPMULLW      Y3, Y6, Y11
+	VPMULLW      Y8, Y14, Y8
+	VPMULLW      Y9, Y14, Y9
+	VPMULLW      Y10, Y14, Y10
+	VPMULLW      Y11, Y14, Y11
+	VPMULHW      Y3, Y7, Y12
+	VPMULHW      Y2, Y6, Y13
+	VPMULHW      Y2, Y7, Y2
+	VPMULHW      Y3, Y6, Y3
+	VMOVDQA      Y12, Y6
+	VMOVDQA      Y13, Y7
+	VPMULHW      Y8, Y15, Y8
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y11, Y15, Y11
+	VPSUBW       Y8, Y6, Y6
+	VPSUBW       Y9, Y7, Y7
+	VPSUBW       Y10, Y2, Y2
+	VPSUBW       Y11, Y3, Y3
+	VMOVDQU      800(BX), Y12
+	VMOVDQU      832(BX), Y13
+	VPMULLW      Y6, Y12, Y8
+	VPMULHW      Y6, Y13, Y6
+	VPMULHW      Y8, Y15, Y8
+	VPSUBW       Y8, Y6, Y6
+	VPSUBW       Y6, Y7, Y6
+	VPADDW       Y2, Y3, Y7
+	VMOVDQU      Y4, (AX)
+	VMOVDQU      Y5, 32(AX)
+	VMOVDQU      Y6, 64(AX)
+	VMOVDQU      Y7, 96(AX)
+	VMOVDQU      128(CX), Y0
+	VMOVDQU      160(CX), Y1
+	VMOVDQU      192(CX), Y2
+	VMOVDQU      224(CX), Y3
+	VMOVDQU      128(DX), Y4
+	VMOVDQU      160(DX), Y5
+	VMOVDQU      192(DX), Y6
+	VMOVDQU      224(DX), Y7
+	VPMULLW      Y1, Y5, Y8
+	VPMULLW      Y0, Y4, Y9
+	VPMULLW      Y0, Y5, Y10
+	VPMULLW      Y1, Y4, Y11
+	VPMULLW      Y8, Y14, Y8
+	VPMULLW      Y9, Y14, Y9
+	VPMULLW      Y10, Y14, Y10
+	VPMULLW      Y11, Y14, Y11
+	VPMULHW      Y1, Y5, Y12
+	VPMULHW      Y0, Y4, Y13
+	VPMULHW      Y0, Y5, Y0
+	VPMULHW      Y1, Y4, Y1
+	VMOVDQA      Y12, Y4
+	VMOVDQA      Y13, Y5
+	VPMULHW      Y8, Y15, Y8
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y11, Y15, Y11
+	VPSUBW       Y8, Y4, Y4
+	VPSUBW       Y9, Y5, Y5
+	VPSUBW       Y10, Y0, Y0
+	VPSUBW       Y11, Y1, Y1
+	VMOVDQU      864(BX), Y12
+	VMOVDQU      896(BX), Y13
+	VPMULLW      Y4, Y12, Y8
+	VPMULHW      Y4, Y13, Y4
+	VPMULHW      Y8, Y15, Y8
+	VPSUBW       Y8, Y4, Y4
+	VPADDW       Y4, Y5, Y4
+	VPADDW       Y0, Y1, Y5
+	VPMULLW      Y3, Y7, Y8
+	VPMULLW      Y2, Y6, Y9
+	VPMULLW      Y2, Y7, Y10
+	VPMULLW      Y3, Y6, Y11
+	VPMULLW      Y8, Y14, Y8
+	VPMULLW      Y9, Y14, Y9
+	VPMULLW      Y10, Y14, Y10
+	VPMULLW      Y11, Y14, Y11
+	VPMULHW      Y3, Y7, Y12
+	VPMULHW      Y2, Y6, Y13
+	VPMULHW      Y2, Y7, Y2
+	VPMULHW      Y3, Y6, Y3
+	VMOVDQA      Y12, Y6
+	VMOVDQA      Y13, Y7
+	VPMULHW      Y8, Y15, Y8
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y11, Y15, Y11
+	VPSUBW       Y8, Y6, Y6
+	VPSUBW       Y9, Y7, Y7
+	VPSUBW       Y10, Y2, Y2
+	VPSUBW       Y11, Y3, Y3
+	VMOVDQU      864(BX), Y12
+	VMOVDQU      896(BX), Y13
+	VPMULLW      Y6, Y12, Y8
+	VPMULHW      Y6, Y13, Y6
+	VPMULHW      Y8, Y15, Y8
+	VPSUBW       Y8, Y6, Y6
+	VPSUBW       Y6, Y7, Y6
+	VPADDW       Y2, Y3, Y7
+	VMOVDQU      Y4, 128(AX)
+	VMOVDQU      Y5, 160(AX)
+	VMOVDQU      Y6, 192(AX)
+	VMOVDQU      Y7, 224(AX)
+	VMOVDQU      256(CX), Y0
+	VMOVDQU      288(CX), Y1
+	VMOVDQU      320(CX), Y2
+	VMOVDQU      352(CX), Y3
+	VMOVDQU      256(DX), Y4
+	VMOVDQU      288(DX), Y5
+	VMOVDQU      320(DX), Y6
+	VMOVDQU      352(DX), Y7
+	VPMULLW      Y1, Y5, Y8
+	VPMULLW      Y0, Y4, Y9
+	VPMULLW      Y0, Y5, Y10
+	VPMULLW      Y1, Y4, Y11
+	VPMULLW      Y8, Y14, Y8
+	VPMULLW      Y9, Y14, Y9
+	VPMULLW      Y10, Y14, Y10
+	VPMULLW      Y11, Y14, Y11
+	VPMULHW      Y1, Y5, Y12
+	VPMULHW      Y0, Y4, Y13
+	VPMULHW      Y0, Y5, Y0
+	VPMULHW      Y1, Y4, Y1
+	VMOVDQA      Y12, Y4
+	VMOVDQA      Y13, Y5
+	VPMULHW      Y8, Y15, Y8
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y11, Y15, Y11
+	VPSUBW       Y8, Y4, Y4
+	VPSUBW       Y9, Y5, Y5
+	VPSUBW       Y10, Y0, Y0
+	VPSUBW       Y11, Y1, Y1
+	VMOVDQU      928(BX), Y12
+	VMOVDQU      960(BX), Y13
+	VPMULLW      Y4, Y12, Y8
+	VPMULHW      Y4, Y13, Y4
+	VPMULHW      Y8, Y15, Y8
+	VPSUBW       Y8, Y4, Y4
+	VPADDW       Y4, Y5, Y4
+	VPADDW       Y0, Y1, Y5
+	VPMULLW      Y3, Y7, Y8
+	VPMULLW      Y2, Y6, Y9
+	VPMULLW      Y2, Y7, Y10
+	VPMULLW      Y3, Y6, Y11
+	VPMULLW      Y8, Y14, Y8
+	VPMULLW      Y9, Y14, Y9
+	VPMULLW      Y10, Y14, Y10
+	VPMULLW      Y11, Y14, Y11
+	VPMULHW      Y3, Y7, Y12
+	VPMULHW      Y2, Y6, Y13
+	VPMULHW      Y2, Y7, Y2
+	VPMULHW      Y3, Y6, Y3
+	VMOVDQA      Y12, Y6
+	VMOVDQA      Y13, Y7
+	VPMULHW      Y8, Y15, Y8
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y11, Y15, Y11
+	VPSUBW       Y8, Y6, Y6
+	VPSUBW       Y9, Y7, Y7
+	VPSUBW       Y10, Y2, Y2
+	VPSUBW       Y11, Y3, Y3
+	VMOVDQU      928(BX), Y12
+	VMOVDQU      960(BX), Y13
+	VPMULLW      Y6, Y12, Y8
+	VPMULHW      Y6, Y13, Y6
+	VPMULHW      Y8, Y15, Y8
+	VPSUBW       Y8, Y6, Y6
+	VPSUBW       Y6, Y7, Y6
+	VPADDW       Y2, Y3, Y7
+	VMOVDQU      Y4, 256(AX)
+	VMOVDQU      Y5, 288(AX)
+	VMOVDQU      Y6, 320(AX)
+	VMOVDQU      Y7, 352(AX)
+	VMOVDQU      384(CX), Y0
+	VMOVDQU      416(CX), Y1
+	VMOVDQU      448(CX), Y2
+	VMOVDQU      480(CX), Y3
+	VMOVDQU      384(DX), Y4
+	VMOVDQU      416(DX), Y5
+	VMOVDQU      448(DX), Y6
+	VMOVDQU      480(DX), Y7
+	VPMULLW      Y1, Y5, Y8
+	VPMULLW      Y0, Y4, Y9
+	VPMULLW      Y0, Y5, Y10
+	VPMULLW      Y1, Y4, Y11
+	VPMULLW      Y8, Y14, Y8
+	VPMULLW      Y9, Y14, Y9
+	VPMULLW      Y10, Y14, Y10
+	VPMULLW      Y11, Y14, Y11
+	VPMULHW      Y1, Y5, Y12
+	VPMULHW      Y0, Y4, Y13
+	VPMULHW      Y0, Y5, Y0
+	VPMULHW      Y1, Y4, Y1
+	VMOVDQA      Y12, Y4
+	VMOVDQA      Y13, Y5
+	VPMULHW      Y8, Y15, Y8
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y11, Y15, Y11
+	VPSUBW       Y8, Y4, Y4
+	VPSUBW       Y9, Y5, Y5
+	VPSUBW       Y10, Y0, Y0
+	VPSUBW       Y11, Y1, Y1
+	VMOVDQU      992(BX), Y12
+	VMOVDQU      1024(BX), Y13
+	VPMULLW      Y4, Y12, Y8
+	VPMULHW      Y4, Y13, Y4
+	VPMULHW      Y8, Y15, Y8
+	VPSUBW       Y8, Y4, Y4
+	VPADDW       Y4, Y5, Y4
+	VPADDW       Y0, Y1, Y5
+	VPMULLW      Y3, Y7, Y8
+	VPMULLW      Y2, Y6, Y9
+	VPMULLW      Y2, Y7, Y10
+	VPMULLW      Y3, Y6, Y11
+	VPMULLW      Y8, Y14, Y8
+	VPMULLW      Y9, Y14, Y9
+	VPMULLW      Y10, Y14, Y10
+	VPMULLW      Y11, Y14, Y11
+	VPMULHW      Y3, Y7, Y12
+	VPMULHW      Y2, Y6, Y13
+	VPMULHW      Y2, Y7, Y2
+	VPMULHW      Y3, Y6, Y3
+	VMOVDQA      Y12, Y6
+	VMOVDQA      Y13, Y7
+	VPMULHW      Y8, Y15, Y8
+	VPMULHW      Y9, Y15, Y9
+	VPMULHW      Y10, Y15, Y10
+	VPMULHW      Y11, Y15, Y11
+	VPSUBW       Y8, Y6, Y6
+	VPSUBW       Y9, Y7, Y7
+	VPSUBW       Y10, Y2, Y2
+	VPSUBW       Y11, Y3, Y3
+	VMOVDQU      992(BX), Y12
+	VMOVDQU      1024(BX), Y13
+	VPMULLW      Y6, Y12, Y8
+	VPMULHW      Y6, Y13, Y6
+	VPMULHW      Y8, Y15, Y8
+	VPSUBW       Y8, Y6, Y6
+	VPSUBW       Y6, Y7, Y6
+	VPADDW       Y2, Y3, Y7
+	VMOVDQU      Y4, 384(AX)
+	VMOVDQU      Y5, 416(AX)
+	VMOVDQU      Y6, 448(AX)
+	VMOVDQU      Y7, 480(AX)
+	RET
+
+// func detangleAVX2(p *[256]int16)
+// Requires: AVX, AVX2
+TEXT ·detangleAVX2(SB), NOSPLIT, $0-8
+	MOVQ        p+0(FP), AX
+	VMOVDQU     (AX), Y0
+	VMOVDQU     32(AX), Y1
+	VMOVDQU     64(AX), Y2
+	VMOVDQU     96(AX), Y3
+	VMOVDQU     128(AX), Y4
+	VMOVDQU     160(AX), Y5
+	VMOVDQU     192(AX), Y6
+	VMOVDQU     224(AX), Y7
+	VPSLLD      $0x10, Y1, Y8
+	VPBLENDW    $0xaa, Y8, Y0, Y8
+	VPSRLD      $0x10, Y0, Y0
+	VPBLENDW    $0xaa, Y1, Y0, Y1
+	VMOVDQA     Y8, Y0
+	VPSLLD      $0x10, Y3, Y8
+	VPBLENDW    $0xaa, Y8, Y2, Y8
+	VPSRLD      $0x10, Y2, Y2
+	VPBLENDW    $0xaa, Y3, Y2, Y3
+	VMOVDQA     Y8, Y2
+	VPSLLD      $0x10, Y5, Y8
+	VPBLENDW    $0xaa, Y8, Y4, Y8
+	VPSRLD      $0x10, Y4, Y4
+	VPBLENDW    $0xaa, Y5, Y4, Y5
+	VMOVDQA     Y8, Y4
+	VPSLLD      $0x10, Y7, Y8
+	VPBLENDW    $0xaa, Y8, Y6, Y8
+	VPSRLD      $0x10, Y6, Y6
+	VPBLENDW    $0xaa, Y7, Y6, Y7
+	VMOVDQA     Y8, Y6
+	VMOVSLDUP   Y2, Y8
+	VPBLENDD    $0xaa, Y8, Y0, Y8
+	VPSRLQ      $0x20, Y0, Y0
+	VPBLENDD    $0xaa, Y2, Y0, Y2
+	VMOVDQA     Y8, Y0
+	VMOVSLDUP   Y3, Y8
+	VPBLENDD    $0xaa, Y8, Y1, Y8
+	VPSRLQ      $0x20, Y1, Y1
+	VPBLENDD    $0xaa, Y3, Y1, Y3
+	VMOVDQA     Y8, Y1
+	VMOVSLDUP   Y6, Y8
+	VPBLENDD    $0xaa, Y8, Y4, Y8
+	VPSRLQ      $0x20, Y4, Y4
+	VPBLENDD    $0xaa, Y6, Y4, Y6
+	VMOVDQA     Y8, Y4
+	VMOVSLDUP   Y7, Y8
+	VPBLENDD    $0xaa, Y8, Y5, Y8
+	VPSRLQ      $0x20, Y5, Y5
+	VPBLENDD    $0xaa, Y7, Y5, Y7
+	VMOVDQA     Y8, Y5
+	VPUNPCKLQDQ Y1, Y0, Y8
+	VPUNPCKHQDQ Y1, Y0, Y1
+	VMOVDQA     Y8, Y0
+	VPUNPCKLQDQ Y3, Y2, Y8
+	VPUNPCKHQDQ Y3, Y2, Y3
+	VMOVDQA     Y8, Y2
+	VPUNPCKLQDQ Y5, Y4, Y8
+	VPUNPCKHQDQ Y5, Y4, Y5
+	VMOVDQA     Y8, Y4
+	VPUNPCKLQDQ Y7, Y6, Y8
+	VPUNPCKHQDQ Y7, Y6, Y7
+	VMOVDQA     Y8, Y6
+	VPERM2I128  $0x20, Y2, Y0, Y8
+	VPERM2I128  $0x31, Y2, Y0, Y2
+	VMOVDQA     Y8, Y0
+	VPERM2I128  $0x20, Y3, Y1, Y8
+	VPERM2I128  $0x31, Y3, Y1, Y3
+	VMOVDQA     Y8, Y1
+	VPERM2I128  $0x20, Y6, Y4, Y8
+	VPERM2I128  $0x31, Y6, Y4, Y6
+	VMOVDQA     Y8, Y4
+	VPERM2I128  $0x20, Y7, Y5, Y8
+	VPERM2I128  $0x31, Y7, Y5, Y7
+	VMOVDQA     Y8, Y5
+	VMOVDQU     Y0, (AX)
+	VMOVDQU     Y1, 32(AX)
+	VMOVDQU     Y2, 64(AX)
+	VMOVDQU     Y3, 96(AX)
+	VMOVDQU     Y4, 128(AX)
+	VMOVDQU     Y5, 160(AX)
+	VMOVDQU     Y6, 192(AX)
+	VMOVDQU     Y7, 224(AX)
+	VMOVDQU     256(AX), Y0
+	VMOVDQU     288(AX), Y1
+	VMOVDQU     320(AX), Y2
+	VMOVDQU     352(AX), Y3
+	VMOVDQU     384(AX), Y4
+	VMOVDQU     416(AX), Y5
+	VMOVDQU     448(AX), Y6
+	VMOVDQU     480(AX), Y7
+	VPSLLD      $0x10, Y1, Y8
+	VPBLENDW    $0xaa, Y8, Y0, Y8
+	VPSRLD      $0x10, Y0, Y0
+	VPBLENDW    $0xaa, Y1, Y0, Y1
+	VMOVDQA     Y8, Y0
+	VPSLLD      $0x10, Y3, Y8
+	VPBLENDW    $0xaa, Y8, Y2, Y8
+	VPSRLD      $0x10, Y2, Y2
+	VPBLENDW    $0xaa, Y3, Y2, Y3
+	VMOVDQA     Y8, Y2
+	VPSLLD      $0x10, Y5, Y8
+	VPBLENDW    $0xaa, Y8, Y4, Y8
+	VPSRLD      $0x10, Y4, Y4
+	VPBLENDW    $0xaa, Y5, Y4, Y5
+	VMOVDQA     Y8, Y4
+	VPSLLD      $0x10, Y7, Y8
+	VPBLENDW    $0xaa, Y8, Y6, Y8
+	VPSRLD      $0x10, Y6, Y6
+	VPBLENDW    $0xaa, Y7, Y6, Y7
+	VMOVDQA     Y8, Y6
+	VMOVSLDUP   Y2, Y8
+	VPBLENDD    $0xaa, Y8, Y0, Y8
+	VPSRLQ      $0x20, Y0, Y0
+	VPBLENDD    $0xaa, Y2, Y0, Y2
+	VMOVDQA     Y8, Y0
+	VMOVSLDUP   Y3, Y8
+	VPBLENDD    $0xaa, Y8, Y1, Y8
+	VPSRLQ      $0x20, Y1, Y1
+	VPBLENDD    $0xaa, Y3, Y1, Y3
+	VMOVDQA     Y8, Y1
+	VMOVSLDUP   Y6, Y8
+	VPBLENDD    $0xaa, Y8, Y4, Y8
+	VPSRLQ      $0x20, Y4, Y4
+	VPBLENDD    $0xaa, Y6, Y4, Y6
+	VMOVDQA     Y8, Y4
+	VMOVSLDUP   Y7, Y8
+	VPBLENDD    $0xaa, Y8, Y5, Y8
+	VPSRLQ      $0x20, Y5, Y5
+	VPBLENDD    $0xaa, Y7, Y5, Y7
+	VMOVDQA     Y8, Y5
+	VPUNPCKLQDQ Y1, Y0, Y8
+	VPUNPCKHQDQ Y1, Y0, Y1
+	VMOVDQA     Y8, Y0
+	VPUNPCKLQDQ Y3, Y2, Y8
+	VPUNPCKHQDQ Y3, Y2, Y3
+	VMOVDQA     Y8, Y2
+	VPUNPCKLQDQ Y5, Y4, Y8
+	VPUNPCKHQDQ Y5, Y4, Y5
+	VMOVDQA     Y8, Y4
+	VPUNPCKLQDQ Y7, Y6, Y8
+	VPUNPCKHQDQ Y7, Y6, Y7
+	VMOVDQA     Y8, Y6
+	VPERM2I128  $0x20, Y2, Y0, Y8
+	VPERM2I128  $0x31, Y2, Y0, Y2
+	VMOVDQA     Y8, Y0
+	VPERM2I128  $0x20, Y3, Y1, Y8
+	VPERM2I128  $0x31, Y3, Y1, Y3
+	VMOVDQA     Y8, Y1
+	VPERM2I128  $0x20, Y6, Y4, Y8
+	VPERM2I128  $0x31, Y6, Y4, Y6
+	VMOVDQA     Y8, Y4
+	VPERM2I128  $0x20, Y7, Y5, Y8
+	VPERM2I128  $0x31, Y7, Y5, Y7
+	VMOVDQA     Y8, Y5
+	VMOVDQU     Y0, 256(AX)
+	VMOVDQU     Y1, 288(AX)
+	VMOVDQU     Y2, 320(AX)
+	VMOVDQU     Y3, 352(AX)
+	VMOVDQU     Y4, 384(AX)
+	VMOVDQU     Y5, 416(AX)
+	VMOVDQU     Y6, 448(AX)
+	VMOVDQU     Y7, 480(AX)
+	RET
+
+// func tangleAVX2(p *[256]int16)
+// Requires: AVX, AVX2
+TEXT ·tangleAVX2(SB), NOSPLIT, $0-8
+	MOVQ        p+0(FP), AX
+	VMOVDQU     (AX), Y0
+	VMOVDQU     32(AX), Y1
+	VMOVDQU     64(AX), Y2
+	VMOVDQU     96(AX), Y3
+	VMOVDQU     128(AX), Y4
+	VMOVDQU     160(AX), Y5
+	VMOVDQU     192(AX), Y6
+	VMOVDQU     224(AX), Y7
+	VPERM2I128  $0x20, Y2, Y0, Y8
+	VPERM2I128  $0x31, Y2, Y0, Y2
+	VMOVDQA     Y8, Y0
+	VPERM2I128  $0x20, Y3, Y1, Y8
+	VPERM2I128  $0x31, Y3, Y1, Y3
+	VMOVDQA     Y8, Y1
+	VPERM2I128  $0x20, Y6, Y4, Y8
+	VPERM2I128  $0x31, Y6, Y4, Y6
+	VMOVDQA     Y8, Y4
+	VPERM2I128  $0x20, Y7, Y5, Y8
+	VPERM2I128  $0x31, Y7, Y5, Y7
+	VMOVDQA     Y8, Y5
+	VPUNPCKLQDQ Y1, Y0, Y8
+	VPUNPCKHQDQ Y1, Y0, Y1
+	VMOVDQA     Y8, Y0
+	VPUNPCKLQDQ Y3, Y2, Y8
+	VPUNPCKHQDQ Y3, Y2, Y3
+	VMOVDQA     Y8, Y2
+	VPUNPCKLQDQ Y5, Y4, Y8
+	VPUNPCKHQDQ Y5, Y4, Y5
+	VMOVDQA     Y8, Y4
+	VPUNPCKLQDQ Y7, Y6, Y8
+	VPUNPCKHQDQ Y7, Y6, Y7
+	VMOVDQA     Y8, Y6
+	VMOVSLDUP   Y2, Y8
+	VPBLENDD    $0xaa, Y8, Y0, Y8
+	VPSRLQ      $0x20, Y0, Y0
+	VPBLENDD    $0xaa, Y2, Y0, Y2
+	VMOVDQA     Y8, Y0
+	VMOVSLDUP   Y3, Y8
+	VPBLENDD    $0xaa, Y8, Y1, Y8
+	VPSRLQ      $0x20, Y1, Y1
+	VPBLENDD    $0xaa, Y3, Y1, Y3
+	VMOVDQA     Y8, Y1
+	VMOVSLDUP   Y6, Y8
+	VPBLENDD    $0xaa, Y8, Y4, Y8
+	VPSRLQ      $0x20, Y4, Y4
+	VPBLENDD    $0xaa, Y6, Y4, Y6
+	VMOVDQA     Y8, Y4
+	VMOVSLDUP   Y7, Y8
+	VPBLENDD    $0xaa, Y8, Y5, Y8
+	VPSRLQ      $0x20, Y5, Y5
+	VPBLENDD    $0xaa, Y7, Y5, Y7
+	VMOVDQA     Y8, Y5
+	VPSLLD      $0x10, Y1, Y8
+	VPBLENDW    $0xaa, Y8, Y0, Y8
+	VPSRLD      $0x10, Y0, Y0
+	VPBLENDW    $0xaa, Y1, Y0, Y1
+	VMOVDQA     Y8, Y0
+	VPSLLD      $0x10, Y3, Y8
+	VPBLENDW    $0xaa, Y8, Y2, Y8
+	VPSRLD      $0x10, Y2, Y2
+	VPBLENDW    $0xaa, Y3, Y2, Y3
+	VMOVDQA     Y8, Y2
+	VPSLLD      $0x10, Y5, Y8
+	VPBLENDW    $0xaa, Y8, Y4, Y8
+	VPSRLD      $0x10, Y4, Y4
+	VPBLENDW    $0xaa, Y5, Y4, Y5
+	VMOVDQA     Y8, Y4
+	VPSLLD      $0x10, Y7, Y8
+	VPBLENDW    $0xaa, Y8, Y6, Y8
+	VPSRLD      $0x10, Y6, Y6
+	VPBLENDW    $0xaa, Y7, Y6, Y7
+	VMOVDQA     Y8, Y6
+	VMOVDQU     Y0, (AX)
+	VMOVDQU     Y1, 32(AX)
+	VMOVDQU     Y2, 64(AX)
+	VMOVDQU     Y3, 96(AX)
+	VMOVDQU     Y4, 128(AX)
+	VMOVDQU     Y5, 160(AX)
+	VMOVDQU     Y6, 192(AX)
+	VMOVDQU     Y7, 224(AX)
+	VMOVDQU     256(AX), Y0
+	VMOVDQU     288(AX), Y1
+	VMOVDQU     320(AX), Y2
+	VMOVDQU     352(AX), Y3
+	VMOVDQU     384(AX), Y4
+	VMOVDQU     416(AX), Y5
+	VMOVDQU     448(AX), Y6
+	VMOVDQU     480(AX), Y7
+	VPERM2I128  $0x20, Y2, Y0, Y8
+	VPERM2I128  $0x31, Y2, Y0, Y2
+	VMOVDQA     Y8, Y0
+	VPERM2I128  $0x20, Y3, Y1, Y8
+	VPERM2I128  $0x31, Y3, Y1, Y3
+	VMOVDQA     Y8, Y1
+	VPERM2I128  $0x20, Y6, Y4, Y8
+	VPERM2I128  $0x31, Y6, Y4, Y6
+	VMOVDQA     Y8, Y4
+	VPERM2I128  $0x20, Y7, Y5, Y8
+	VPERM2I128  $0x31, Y7, Y5, Y7
+	VMOVDQA     Y8, Y5
+	VPUNPCKLQDQ Y1, Y0, Y8
+	VPUNPCKHQDQ Y1, Y0, Y1
+	VMOVDQA     Y8, Y0
+	VPUNPCKLQDQ Y3, Y2, Y8
+	VPUNPCKHQDQ Y3, Y2, Y3
+	VMOVDQA     Y8, Y2
+	VPUNPCKLQDQ Y5, Y4, Y8
+	VPUNPCKHQDQ Y5, Y4, Y5
+	VMOVDQA     Y8, Y4
+	VPUNPCKLQDQ Y7, Y6, Y8
+	VPUNPCKHQDQ Y7, Y6, Y7
+	VMOVDQA     Y8, Y6
+	VMOVSLDUP   Y2, Y8
+	VPBLENDD    $0xaa, Y8, Y0, Y8
+	VPSRLQ      $0x20, Y0, Y0
+	VPBLENDD    $0xaa, Y2, Y0, Y2
+	VMOVDQA     Y8, Y0
+	VMOVSLDUP   Y3, Y8
+	VPBLENDD    $0xaa, Y8, Y1, Y8
+	VPSRLQ      $0x20, Y1, Y1
+	VPBLENDD    $0xaa, Y3, Y1, Y3
+	VMOVDQA     Y8, Y1
+	VMOVSLDUP   Y6, Y8
+	VPBLENDD    $0xaa, Y8, Y4, Y8
+	VPSRLQ      $0x20, Y4, Y4
+	VPBLENDD    $0xaa, Y6, Y4, Y6
+	VMOVDQA     Y8, Y4
+	VMOVSLDUP   Y7, Y8
+	VPBLENDD    $0xaa, Y8, Y5, Y8
+	VPSRLQ      $0x20, Y5, Y5
+	VPBLENDD    $0xaa, Y7, Y5, Y7
+	VMOVDQA     Y8, Y5
+	VPSLLD      $0x10, Y1, Y8
+	VPBLENDW    $0xaa, Y8, Y0, Y8
+	VPSRLD      $0x10, Y0, Y0
+	VPBLENDW    $0xaa, Y1, Y0, Y1
+	VMOVDQA     Y8, Y0
+	VPSLLD      $0x10, Y3, Y8
+	VPBLENDW    $0xaa, Y8, Y2, Y8
+	VPSRLD      $0x10, Y2, Y2
+	VPBLENDW    $0xaa, Y3, Y2, Y3
+	VMOVDQA     Y8, Y2
+	VPSLLD      $0x10, Y5, Y8
+	VPBLENDW    $0xaa, Y8, Y4, Y8
+	VPSRLD      $0x10, Y4, Y4
+	VPBLENDW    $0xaa, Y5, Y4, Y5
+	VMOVDQA     Y8, Y4
+	VPSLLD      $0x10, Y7, Y8
+	VPBLENDW    $0xaa, Y8, Y6, Y8
+	VPSRLD      $0x10, Y6, Y6
+	VPBLENDW    $0xaa, Y7, Y6, Y7
+	VMOVDQA     Y8, Y6
+	VMOVDQU     Y0, 256(AX)
+	VMOVDQU     Y1, 288(AX)
+	VMOVDQU     Y2, 320(AX)
+	VMOVDQU     Y3, 352(AX)
+	VMOVDQU     Y4, 384(AX)
+	VMOVDQU     Y5, 416(AX)
+	VMOVDQU     Y6, 448(AX)
+	VMOVDQU     Y7, 480(AX)
+	RET
+
+// func barrettReduceAVX2(p *[256]int16)
+// Requires: AVX, AVX2
+TEXT ·barrettReduceAVX2(SB), NOSPLIT, $0-8
+	MOVQ         p+0(FP), AX
+	MOVL         $0x00000d01, CX
+	VMOVD        CX, X0
+	VPBROADCASTW X0, Y9
+	MOVL         $0x00004ebf, CX
+	VMOVD        CX, X0
+	VPBROADCASTW X0, Y8
+	VMOVDQU      (AX), Y0
+	VMOVDQU      32(AX), Y1
+	VMOVDQU      64(AX), Y2
+	VMOVDQU      96(AX), Y3
+	VPMULHW      Y8, Y0, Y4
+	VPMULHW      Y8, Y1, Y5
+	VPMULHW      Y8, Y2, Y6
+	VPMULHW      Y8, Y3, Y7
+	VPSRAW       $0x0a, Y4, Y4
+	VPSRAW       $0x0a, Y5, Y5
+	VPSRAW       $0x0a, Y6, Y6
+	VPSRAW       $0x0a, Y7, Y7
+	VPMULLW      Y9, Y4, Y4
+	VPMULLW      Y9, Y5, Y5
+	VPMULLW      Y9, Y6, Y6
+	VPMULLW      Y9, Y7, Y7
+	VPSUBW       Y4, Y0, Y0
+	VPSUBW       Y5, Y1, Y1
+	VPSUBW       Y6, Y2, Y2
+	VPSUBW       Y7, Y3, Y3
+	VMOVDQU      Y0, (AX)
+	VMOVDQU      Y1, 32(AX)
+	VMOVDQU      Y2, 64(AX)
+	VMOVDQU      Y3, 96(AX)
+	VMOVDQU      128(AX), Y0
+	VMOVDQU      160(AX), Y1
+	VMOVDQU      192(AX), Y2
+	VMOVDQU      224(AX), Y3
+	VPMULHW      Y8, Y0, Y4
+	VPMULHW      Y8, Y1, Y5
+	VPMULHW      Y8, Y2, Y6
+	VPMULHW      Y8, Y3, Y7
+	VPSRAW       $0x0a, Y4, Y4
+	VPSRAW       $0x0a, Y5, Y5
+	VPSRAW       $0x0a, Y6, Y6
+	VPSRAW       $0x0a, Y7, Y7
+	VPMULLW      Y9, Y4, Y4
+	VPMULLW      Y9, Y5, Y5
+	VPMULLW      Y9, Y6, Y6
+	VPMULLW      Y9, Y7, Y7
+	VPSUBW       Y4, Y0, Y0
+	VPSUBW       Y5, Y1, Y1
+	VPSUBW       Y6, Y2, Y2
+	VPSUBW       Y7, Y3, Y3
+	VMOVDQU      Y0, 128(AX)
+	VMOVDQU      Y1, 160(AX)
+	VMOVDQU      Y2, 192(AX)
+	VMOVDQU      Y3, 224(AX)
+	VMOVDQU      256(AX), Y0
+	VMOVDQU      288(AX), Y1
+	VMOVDQU      320(AX), Y2
+	VMOVDQU      352(AX), Y3
+	VPMULHW      Y8, Y0, Y4
+	VPMULHW      Y8, Y1, Y5
+	VPMULHW      Y8, Y2, Y6
+	VPMULHW      Y8, Y3, Y7
+	VPSRAW       $0x0a, Y4, Y4
+	VPSRAW       $0x0a, Y5, Y5
+	VPSRAW       $0x0a, Y6, Y6
+	VPSRAW       $0x0a, Y7, Y7
+	VPMULLW      Y9, Y4, Y4
+	VPMULLW      Y9, Y5, Y5
+	VPMULLW      Y9, Y6, Y6
+	VPMULLW      Y9, Y7, Y7
+	VPSUBW       Y4, Y0, Y0
+	VPSUBW       Y5, Y1, Y1
+	VPSUBW       Y6, Y2, Y2
+	VPSUBW       Y7, Y3, Y3
+	VMOVDQU      Y0, 256(AX)
+	VMOVDQU      Y1, 288(AX)
+	VMOVDQU      Y2, 320(AX)
+	VMOVDQU      Y3, 352(AX)
+	VMOVDQU      384(AX), Y0
+	VMOVDQU      416(AX), Y1
+	VMOVDQU      448(AX), Y2
+	VMOVDQU      480(AX), Y3
+	VPMULHW      Y8, Y0, Y4
+	VPMULHW      Y8, Y1, Y5
+	VPMULHW      Y8, Y2, Y6
+	VPMULHW      Y8, Y3, Y7
+	VPSRAW       $0x0a, Y4, Y4
+	VPSRAW       $0x0a, Y5, Y5
+	VPSRAW       $0x0a, Y6, Y6
+	VPSRAW       $0x0a, Y7, Y7
+	VPMULLW      Y9, Y4, Y4
+	VPMULLW      Y9, Y5, Y5
+	VPMULLW      Y9, Y6, Y6
+	VPMULLW      Y9, Y7, Y7
+	VPSUBW       Y4, Y0, Y0
+	VPSUBW       Y5, Y1, Y1
+	VPSUBW       Y6, Y2, Y2
+	VPSUBW       Y7, Y3, Y3
+	VMOVDQU      Y0, 384(AX)
+	VMOVDQU      Y1, 416(AX)
+	VMOVDQU      Y2, 448(AX)
+	VMOVDQU      Y3, 480(AX)
+	RET
+
+// func normalizeAVX2(p *[256]int16)
+// Requires: AVX, AVX2
+TEXT ·normalizeAVX2(SB), NOSPLIT, $0-8
+	MOVQ         p+0(FP), AX
+	MOVL         $0x00000d01, CX
+	VMOVD        CX, X0
+	VPBROADCASTW X0, Y9
+	MOVL         $0x00004ebf, CX
+	VMOVD        CX, X0
+	VPBROADCASTW X0, Y8
+	VMOVDQU      (AX), Y0
+	VMOVDQU      32(AX), Y1
+	VMOVDQU      64(AX), Y2
+	VMOVDQU      96(AX), Y3
+	VPMULHW      Y8, Y0, Y4
+	VPMULHW      Y8, Y1, Y5
+	VPMULHW      Y8, Y2, Y6
+	VPMULHW      Y8, Y3, Y7
+	VPSRAW       $0x0a, Y4, Y4
+	VPSRAW       $0x0a, Y5, Y5
+	VPSRAW       $0x0a, Y6, Y6
+	VPSRAW       $0x0a, Y7, Y7
+	VPMULLW      Y9, Y4, Y4
+	VPMULLW      Y9, Y5, Y5
+	VPMULLW      Y9, Y6, Y6
+	VPMULLW      Y9, Y7, Y7
+	VPSUBW       Y4, Y0, Y0
+	VPSUBW       Y5, Y1, Y1
+	VPSUBW       Y6, Y2, Y2
+	VPSUBW       Y7, Y3, Y3
+	VPSUBW       Y9, Y0, Y0
+	VPSUBW       Y9, Y1, Y1
+	VPSUBW       Y9, Y2, Y2
+	VPSUBW       Y9, Y3, Y3
+	VPSRAW       $0x0f, Y0, Y4
+	VPSRAW       $0x0f, Y1, Y5
+	VPSRAW       $0x0f, Y2, Y6
+	VPSRAW       $0x0f, Y3, Y7
+	VPAND        Y4, Y9, Y4
+	VPAND        Y5, Y9, Y5
+	VPAND        Y6, Y9, Y6
+	VPAND        Y7, Y9, Y7
+	VPADDW       Y0, Y4, Y0
+	VPADDW       Y1, Y5, Y1
+	VPADDW       Y2, Y6, Y2
+	VPADDW       Y3, Y7, Y3
+	VMOVDQU      Y0, (AX)
+	VMOVDQU      Y1, 32(AX)
+	VMOVDQU      Y2, 64(AX)
+	VMOVDQU      Y3, 96(AX)
+	VMOVDQU      128(AX), Y0
+	VMOVDQU      160(AX), Y1
+	VMOVDQU      192(AX), Y2
+	VMOVDQU      224(AX), Y3
+	VPMULHW      Y8, Y0, Y4
+	VPMULHW      Y8, Y1, Y5
+	VPMULHW      Y8, Y2, Y6
+	VPMULHW      Y8, Y3, Y7
+	VPSRAW       $0x0a, Y4, Y4
+	VPSRAW       $0x0a, Y5, Y5
+	VPSRAW       $0x0a, Y6, Y6
+	VPSRAW       $0x0a, Y7, Y7
+	VPMULLW      Y9, Y4, Y4
+	VPMULLW      Y9, Y5, Y5
+	VPMULLW      Y9, Y6, Y6
+	VPMULLW      Y9, Y7, Y7
+	VPSUBW       Y4, Y0, Y0
+	VPSUBW       Y5, Y1, Y1
+	VPSUBW       Y6, Y2, Y2
+	VPSUBW       Y7, Y3, Y3
+	VPSUBW       Y9, Y0, Y0
+	VPSUBW       Y9, Y1, Y1
+	VPSUBW       Y9, Y2, Y2
+	VPSUBW       Y9, Y3, Y3
+	VPSRAW       $0x0f, Y0, Y4
+	VPSRAW       $0x0f, Y1, Y5
+	VPSRAW       $0x0f, Y2, Y6
+	VPSRAW       $0x0f, Y3, Y7
+	VPAND        Y4, Y9, Y4
+	VPAND        Y5, Y9, Y5
+	VPAND        Y6, Y9, Y6
+	VPAND        Y7, Y9, Y7
+	VPADDW       Y0, Y4, Y0
+	VPADDW       Y1, Y5, Y1
+	VPADDW       Y2, Y6, Y2
+	VPADDW       Y3, Y7, Y3
+	VMOVDQU      Y0, 128(AX)
+	VMOVDQU      Y1, 160(AX)
+	VMOVDQU      Y2, 192(AX)
+	VMOVDQU      Y3, 224(AX)
+	VMOVDQU      256(AX), Y0
+	VMOVDQU      288(AX), Y1
+	VMOVDQU      320(AX), Y2
+	VMOVDQU      352(AX), Y3
+	VPMULHW      Y8, Y0, Y4
+	VPMULHW      Y8, Y1, Y5
+	VPMULHW      Y8, Y2, Y6
+	VPMULHW      Y8, Y3, Y7
+	VPSRAW       $0x0a, Y4, Y4
+	VPSRAW       $0x0a, Y5, Y5
+	VPSRAW       $0x0a, Y6, Y6
+	VPSRAW       $0x0a, Y7, Y7
+	VPMULLW      Y9, Y4, Y4
+	VPMULLW      Y9, Y5, Y5
+	VPMULLW      Y9, Y6, Y6
+	VPMULLW      Y9, Y7, Y7
+	VPSUBW       Y4, Y0, Y0
+	VPSUBW       Y5, Y1, Y1
+	VPSUBW       Y6, Y2, Y2
+	VPSUBW       Y7, Y3, Y3
+	VPSUBW       Y9, Y0, Y0
+	VPSUBW       Y9, Y1, Y1
+	VPSUBW       Y9, Y2, Y2
+	VPSUBW       Y9, Y3, Y3
+	VPSRAW       $0x0f, Y0, Y4
+	VPSRAW       $0x0f, Y1, Y5
+	VPSRAW       $0x0f, Y2, Y6
+	VPSRAW       $0x0f, Y3, Y7
+	VPAND        Y4, Y9, Y4
+	VPAND        Y5, Y9, Y5
+	VPAND        Y6, Y9, Y6
+	VPAND        Y7, Y9, Y7
+	VPADDW       Y0, Y4, Y0
+	VPADDW       Y1, Y5, Y1
+	VPADDW       Y2, Y6, Y2
+	VPADDW       Y3, Y7, Y3
+	VMOVDQU      Y0, 256(AX)
+	VMOVDQU      Y1, 288(AX)
+	VMOVDQU      Y2, 320(AX)
+	VMOVDQU      Y3, 352(AX)
+	VMOVDQU      384(AX), Y0
+	VMOVDQU      416(AX), Y1
+	VMOVDQU      448(AX), Y2
+	VMOVDQU      480(AX), Y3
+	VPMULHW      Y8, Y0, Y4
+	VPMULHW      Y8, Y1, Y5
+	VPMULHW      Y8, Y2, Y6
+	VPMULHW      Y8, Y3, Y7
+	VPSRAW       $0x0a, Y4, Y4
+	VPSRAW       $0x0a, Y5, Y5
+	VPSRAW       $0x0a, Y6, Y6
+	VPSRAW       $0x0a, Y7, Y7
+	VPMULLW      Y9, Y4, Y4
+	VPMULLW      Y9, Y5, Y5
+	VPMULLW      Y9, Y6, Y6
+	VPMULLW      Y9, Y7, Y7
+	VPSUBW       Y4, Y0, Y0
+	VPSUBW       Y5, Y1, Y1
+	VPSUBW       Y6, Y2, Y2
+	VPSUBW       Y7, Y3, Y3
+	VPSUBW       Y9, Y0, Y0
+	VPSUBW       Y9, Y1, Y1
+	VPSUBW       Y9, Y2, Y2
+	VPSUBW       Y9, Y3, Y3
+	VPSRAW       $0x0f, Y0, Y4
+	VPSRAW       $0x0f, Y1, Y5
+	VPSRAW       $0x0f, Y2, Y6
+	VPSRAW       $0x0f, Y3, Y7
+	VPAND        Y4, Y9, Y4
+	VPAND        Y5, Y9, Y5
+	VPAND        Y6, Y9, Y6
+	VPAND        Y7, Y9, Y7
+	VPADDW       Y0, Y4, Y0
+	VPADDW       Y1, Y5, Y1
+	VPADDW       Y2, Y6, Y2
+	VPADDW       Y3, Y7, Y3
+	VMOVDQU      Y0, 384(AX)
+	VMOVDQU      Y1, 416(AX)
+	VMOVDQU      Y2, 448(AX)
+	VMOVDQU      Y3, 480(AX)
+	RET
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/field.go b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/field.go
new file mode 100644
index 00000000..31e93ed5
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/field.go
@@ -0,0 +1,74 @@
+package common
+
+// Given -2¹⁵ q ≤ x < 2¹⁵ q, returns -q < y < q with x 2⁻¹⁶ = y (mod q).
+func montReduce(x int32) int16 {
+	// This is Montgomery reduction with R=2¹⁶.
+	//
+	// Note gcd(2¹⁶, q) = 1 as q is prime.  Write q' := 62209 = q⁻¹ mod R.
+	// First we compute
+	//
+	//	m := ((x mod R) q') mod R
+	//     = x q' mod R
+	//	   = int16(x q')
+	//	   = int16(int32(x) * int32(q'))
+	//
+	// Note that x q' might be as big as 2³² and could overflow the int32
+	// multiplication in the last line.  However for any int32s a and b,
+	// we have int32(int64(a)*int64(b)) = int32(a*b) and so the result is ok.
+	m := int16(x * 62209)
+
+	// Note that x - m q is divisible by R; indeed modulo R we have
+	//
+	//  x - m q ≡ x - x q' q ≡ x - x q⁻¹ q ≡ x - x = 0.
+	//
+	// We return y := (x - m q) / R.  Note that y is indeed correct as
+	// modulo q we have
+	//
+	//  y ≡ x R⁻¹ - m q R⁻¹ = x R⁻¹
+	//
+	// and as both 2¹⁵ q ≤ m q, x < 2¹⁵ q, we have
+	// 2¹⁶ q ≤ x - m q < 2¹⁶ and so q ≤ (x - m q) / R < q as desired.
+	return int16(uint32(x-int32(m)*int32(Q)) >> 16)
+}
+
+// Given any x, returns x R mod q where R=2¹⁶.
+func toMont(x int16) int16 {
+	// Note |1353 x| ≤ 1353 2¹⁵ ≤ 13318 q ≤ 2¹⁵ q and so we're within
+	// the bounds of montReduce.
+	return montReduce(int32(x) * 1353) // 1353 = R² mod q.
+}
+
+// Given any x, compute 0 ≤ y ≤ q with x = y (mod q).
+//
+// Beware: we might have barrettReduce(x) = q ≠ 0 for some x.  In fact,
+// this happens if and only if x = -nq for some positive integer n.
+func barrettReduce(x int16) int16 {
+	// This is standard Barrett reduction.
+	//
+	// For any x we have x mod q = x - ⌊x/q⌋ q.  We will use 20159/2²⁶ as
+	// an approximation of 1/q. Note that  0 ≤ 20159/2²⁶ - 1/q ≤ 0.135/2²⁶
+	// and so | x 20156/2²⁶ - x/q | ≤ 2⁻¹⁰ for |x| ≤ 2¹⁶.  For all x
+	// not a multiple of q, the number x/q is further than 1/q from any integer
+	// and so ⌊x 20156/2²⁶⌋ = ⌊x/q⌋.  If x is a multiple of q and x is positive,
+	// then x 20156/2²⁶ is larger than x/q so ⌊x 20156/2²⁶⌋ = ⌊x/q⌋ as well.
+	// Finally, if x is negative multiple of q, then ⌊x 20156/2²⁶⌋ = ⌊x/q⌋-1.
+	// Thus
+	//                        [ q        if x=-nq for pos. integer n
+	//  x - ⌊x 20156/2²⁶⌋ q = [
+	//                        [ x mod q  otherwise
+	//
+	// To compute actually compute this, note that
+	//
+	//  ⌊x 20156/2²⁶⌋ = (20159 x) >> 26.
+	return x - int16((int32(x)*20159)>>26)*Q
+}
+
+// Returns x if x < q and x - q otherwise.  Assumes x ≥ -29439.
+func csubq(x int16) int16 {
+	x -= Q // no overflow due to assumption x ≥ -29439.
+	// If x is positive, then x >> 15 = 0.  If x is negative,
+	// then uint16(x >> 15) = 2¹⁶-1.  So this will add back in q
+	// if x was smaller than q.
+	x += (x >> 15) & Q
+	return x
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go
new file mode 100644
index 00000000..66e0e86d
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/generic.go
@@ -0,0 +1,77 @@
+//go:build !amd64 || purego
+// +build !amd64 purego
+
+package common
+
+// Sets p to a + b.  Does not normalize coefficients.
+func (p *Poly) Add(a, b *Poly) {
+	p.addGeneric(a, b)
+}
+
+// Sets p to a - b.  Does not normalize coefficients.
+func (p *Poly) Sub(a, b *Poly) {
+	p.subGeneric(a, b)
+}
+
+// Executes an in-place forward "NTT" on p.
+//
+// Assumes the coefficients are in absolute value ≤q.  The resulting
+// coefficients are in absolute value ≤7q.  If the input is in Montgomery
+// form, then the result is in Montgomery form and so (by linearity of the NTT)
+// if the input is in regular form, then the result is also in regular form.
+// The order of coefficients will be "tangled". These can be put back into
+// their proper order by calling Detangle().
+func (p *Poly) NTT() {
+	p.nttGeneric()
+}
+
+// Executes an in-place inverse "NTT" on p and multiply by the Montgomery
+// factor R.
+//
+// Requires coefficients to be in "tangled" order, see Tangle().
+// Assumes the coefficients are in absolute value ≤q.  The resulting
+// coefficients are in absolute value ≤q.  If the input is in Montgomery
+// form, then the result is in Montgomery form and so (by linearity)
+// if the input is in regular form, then the result is also in regular form.
+func (p *Poly) InvNTT() {
+	p.invNTTGeneric()
+}
+
+// Sets p to the "pointwise" multiplication of a and b.
+//
+// That is: InvNTT(p) = InvNTT(a) * InvNTT(b).  Assumes a and b are in
+// Montgomery form.  Products between coefficients of a and b must be strictly
+// bounded in absolute value by 2¹⁵q.  p will be in Montgomery form and
+// bounded in absolute value by 2q.
+//
+// Requires a and b to be in "tangled" order, see Tangle().  p will be in
+// tangled order as well.
+func (p *Poly) MulHat(a, b *Poly) {
+	p.mulHatGeneric(a, b)
+}
+
+// Puts p into the right form to be used with (among others) InvNTT().
+func (p *Poly) Tangle() {
+	// In the generic implementation there is no advantage to using a
+	// different order, so we use the standard order everywhere.
+}
+
+// Puts p back into standard form.
+func (p *Poly) Detangle() {
+	// In the generic implementation there is no advantage to using a
+	// different order, so we use the standard order everywhere.
+}
+
+// Almost normalizes coefficients.
+//
+// Ensures each coefficient is in {0, …, q}.
+func (p *Poly) BarrettReduce() {
+	p.barrettReduceGeneric()
+}
+
+// Normalizes coefficients.
+//
+// Ensures each coefficient is in {0, …, q-1}.
+func (p *Poly) Normalize() {
+	p.normalizeGeneric()
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/ntt.go b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/ntt.go
new file mode 100644
index 00000000..5e565b34
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/ntt.go
@@ -0,0 +1,193 @@
+package common
+
+// Zetas lists precomputed powers of the primitive root of unity in
+// Montgomery representation used for the NTT:
+//
+//	Zetas[i] = ζᵇʳᵛ⁽ⁱ⁾ R mod q
+//
+// where ζ = 17, brv(i) is the bitreversal of a 7-bit number and R=2¹⁶ mod q.
+//
+// The following Python code generates the Zetas arrays:
+//
+//	q = 13*2**8 + 1; zeta = 17
+//	R = 2**16 % q # Montgomery const.
+//	def brv(x): return int(''.join(reversed(bin(x)[2:].zfill(7))),2)
+//	print([(pow(zeta, brv(i), q)*R)%q for i in range(128)])
+var Zetas = [128]int16{
+	2285, 2571, 2970, 1812, 1493, 1422, 287, 202, 3158, 622, 1577, 182,
+	962, 2127, 1855, 1468, 573, 2004, 264, 383, 2500, 1458, 1727, 3199,
+	2648, 1017, 732, 608, 1787, 411, 3124, 1758, 1223, 652, 2777, 1015,
+	2036, 1491, 3047, 1785, 516, 3321, 3009, 2663, 1711, 2167, 126,
+	1469, 2476, 3239, 3058, 830, 107, 1908, 3082, 2378, 2931, 961, 1821,
+	2604, 448, 2264, 677, 2054, 2226, 430, 555, 843, 2078, 871, 1550,
+	105, 422, 587, 177, 3094, 3038, 2869, 1574, 1653, 3083, 778, 1159,
+	3182, 2552, 1483, 2727, 1119, 1739, 644, 2457, 349, 418, 329, 3173,
+	3254, 817, 1097, 603, 610, 1322, 2044, 1864, 384, 2114, 3193, 1218,
+	1994, 2455, 220, 2142, 1670, 2144, 1799, 2051, 794, 1819, 2475,
+	2459, 478, 3221, 3021, 996, 991, 958, 1869, 1522, 1628,
+}
+
+// InvNTTReductions keeps track of which coefficients to apply Barrett
+// reduction to in Poly.InvNTT().
+//
+// Generated in a lazily: once a butterfly is computed which is about to
+// overflow the int16, the largest coefficient is reduced.  If that is
+// not enough, the other coefficient is reduced as well.
+//
+// This is actually optimal, as proven in https://eprint.iacr.org/2020/1377.pdf
+var InvNTTReductions = [...]int{
+	-1, // after layer 1
+	-1, // after layer 2
+	16, 17, 48, 49, 80, 81, 112, 113, 144, 145, 176, 177, 208, 209, 240,
+	241, -1, // after layer 3
+	0, 1, 32, 33, 34, 35, 64, 65, 96, 97, 98, 99, 128, 129, 160, 161, 162, 163,
+	192, 193, 224, 225, 226, 227, -1, // after layer 4
+	2, 3, 66, 67, 68, 69, 70, 71, 130, 131, 194, 195, 196, 197, 198,
+	199, -1, // after layer 5
+	4, 5, 6, 7, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
+	143, -1, // after layer 6
+	-1, //  after layer 7
+}
+
+// Executes an in-place forward "NTT" on p.
+//
+// Assumes the coefficients are in absolute value ≤q.  The resulting
+// coefficients are in absolute value ≤7q.  If the input is in Montgomery
+// form, then the result is in Montgomery form and so (by linearity of the NTT)
+// if the input is in regular form, then the result is also in regular form.
+// The order of coefficients will be "tangled". These can be put back into
+// their proper order by calling Detangle().
+func (p *Poly) nttGeneric() {
+	// Note that ℤ_q does not have a primitive 512ᵗʰ root of unity (as 512
+	// does not divide into q-1) and so we cannot do a regular NTT.  ℤ_q
+	// does have a primitive 256ᵗʰ root of unity, the smallest of which
+	// is ζ := 17.
+	//
+	// Recall that our base ring R := ℤ_q[x] / (x²⁵⁶ + 1).  The polynomial
+	// x²⁵⁶+1 will not split completely (as its roots would be 512ᵗʰ roots
+	// of unity.)  However, it does split almost (using ζ¹²⁸ = -1):
+	//
+	// x²⁵⁶ + 1 = (x²)¹²⁸ - ζ¹²⁸
+	//          = ((x²)⁶⁴ - ζ⁶⁴)((x²)⁶⁴ + ζ⁶⁴)
+	//          = ((x²)³² - ζ³²)((x²)³² + ζ³²)((x²)³² - ζ⁹⁶)((x²)³² + ζ⁹⁶)
+	//          ⋮
+	//          = (x² - ζ)(x² + ζ)(x² - ζ⁶⁵)(x² + ζ⁶⁵) … (x² + ζ¹²⁷)
+	//
+	// Note that the powers of ζ that appear (from the second line down) are
+	// in binary
+	//
+	// 0100000 1100000
+	// 0010000 1010000 0110000 1110000
+	// 0001000 1001000 0101000 1101000 0011000 1011000 0111000 1111000
+	//         …
+	//
+	// That is: brv(2), brv(3), brv(4), …, where brv(x) denotes the 7-bit
+	// bitreversal of x.  These powers of ζ are given by the Zetas array.
+	//
+	// The polynomials x² ± ζⁱ are irreducible and coprime, hence by
+	// the Chinese Remainder Theorem we know
+	//
+	//  ℤ_q[x]/(x²⁵⁶+1) → ℤ_q[x]/(x²-ζ) x … x  ℤ_q[x]/(x²+ζ¹²⁷)
+	//
+	// given by a ↦ ( a mod x²-ζ, …, a mod x²+ζ¹²⁷ )
+	// is an isomorphism, which is the "NTT".  It can be efficiently computed by
+	//
+	//
+	//  a ↦ ( a mod (x²)⁶⁴ - ζ⁶⁴, a mod (x²)⁶⁴ + ζ⁶⁴ )
+	//    ↦ ( a mod (x²)³² - ζ³², a mod (x²)³² + ζ³²,
+	//        a mod (x²)⁹⁶ - ζ⁹⁶, a mod (x²)⁹⁶ + ζ⁹⁶ )
+	//
+	//	    et cetera
+	//
+	// If N was 8 then this can be pictured in the following diagram:
+	//
+	//  https://cnx.org/resources/17ee4dfe517a6adda05377b25a00bf6e6c93c334/File0026.png
+	//
+	// Each cross is a Cooley-Tukey butterfly: it's the map
+	//
+	//  (a, b) ↦ (a + ζb, a - ζb)
+	//
+	// for the appropriate power ζ for that column and row group.
+
+	k := 0 // Index into Zetas
+
+	// l runs effectively over the columns in the diagram above; it is half the
+	// height of a row group, i.e. the number of butterflies in each row group.
+	// In the diagram above it would be 4, 2, 1.
+	for l := N / 2; l > 1; l >>= 1 {
+		// On the nᵗʰ iteration of the l-loop, the absolute value of the
+		// coefficients are bounded by nq.
+
+		// offset effectively loops over the row groups in this column; it is
+		// the first row in the row group.
+		for offset := 0; offset < N-l; offset += 2 * l {
+			k++
+			zeta := int32(Zetas[k])
+
+			// j loops over each butterfly in the row group.
+			for j := offset; j < offset+l; j++ {
+				t := montReduce(zeta * int32(p[j+l]))
+				p[j+l] = p[j] - t
+				p[j] += t
+			}
+		}
+	}
+}
+
+// Executes an in-place inverse "NTT" on p and multiply by the Montgomery
+// factor R.
+//
+// Requires coefficients to be in "tangled" order, see Tangle().
+// Assumes the coefficients are in absolute value ≤q.  The resulting
+// coefficients are in absolute value ≤q.  If the input is in Montgomery
+// form, then the result is in Montgomery form and so (by linearity)
+// if the input is in regular form, then the result is also in regular form.
+func (p *Poly) invNTTGeneric() {
+	k := 127 // Index into Zetas
+	r := -1  // Index into InvNTTReductions.
+
+	// We basically do the opposite of NTT, but postpone dividing by 2 in the
+	// inverse of the Cooley-Tukey butterfly and accumulate that into a big
+	// division by 2⁷ at the end.  See the comments in the NTT() function.
+
+	for l := 2; l < N; l <<= 1 {
+		for offset := 0; offset < N-l; offset += 2 * l {
+			// As we're inverting, we need powers of ζ⁻¹ (instead of ζ).
+			// To be precise, we need ζᵇʳᵛ⁽ᵏ⁾⁻¹²⁸. However, as ζ⁻¹²⁸ = -1,
+			// we can use the existing Zetas table instead of
+			// keeping a separate InvZetas table as in Dilithium.
+
+			minZeta := int32(Zetas[k])
+			k--
+
+			for j := offset; j < offset+l; j++ {
+				// Gentleman-Sande butterfly: (a, b) ↦ (a + b, ζ(a-b))
+				t := p[j+l] - p[j]
+				p[j] += p[j+l]
+				p[j+l] = montReduce(minZeta * int32(t))
+
+				// Note that if we had |a| < αq and |b| < βq before the
+				// butterfly, then now we have |a| < (α+β)q and |b| < q.
+			}
+		}
+
+		// We let the InvNTTReductions instruct us which coefficients to
+		// Barrett reduce.  See TestInvNTTReductions, which tests whether
+		// there is an overflow.
+		for {
+			r++
+			i := InvNTTReductions[r]
+			if i < 0 {
+				break
+			}
+			p[i] = barrettReduce(p[i])
+		}
+	}
+
+	for j := 0; j < N; j++ {
+		// Note 1441 = (128)⁻¹ R².  The coefficients are bounded by 9q, so
+		// as 1441 * 9 ≈ 2¹⁴ < 2¹⁵, we're within the required bounds
+		// for montReduce().
+		p[j] = montReduce(1441 * int32(p[j]))
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/params.go b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/params.go
new file mode 100644
index 00000000..f04d1aaa
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/params.go
@@ -0,0 +1,22 @@
+package common
+
+import (
+	"github.com/cloudflare/circl/pke/kyber/internal/common/params"
+)
+
+const (
+	// Q is the parameter q ≡ 3329 = 2¹¹ + 2¹⁰ + 2⁸ + 1.
+	Q = params.Q
+
+	// N is the parameter N: the length of the polynomials
+	N = params.N
+
+	// PolySize is the size of a packed polynomial.
+	PolySize = params.PolySize
+
+	// PlaintextSize is the size of the plaintext
+	PlaintextSize = params.PlaintextSize
+
+	// Eta2 is the parameter η₂
+	Eta2 = params.Eta2
+)
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/params/params.go b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/params/params.go
new file mode 100644
index 00000000..dee58ee9
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/params/params.go
@@ -0,0 +1,21 @@
+package params
+
+// We put these parameters in a separate package so that the Go code,
+// such as asm/src.go, that generates assembler can import it.
+
+const (
+	// Q is the parameter q ≡ 3329 = 2¹¹ + 2¹⁰ + 2⁸ + 1.
+	Q int16 = 3329
+
+	// N is the parameter N: the length of the polynomials
+	N = 256
+
+	// PolySize is the size of a packed polynomial.
+	PolySize = 384
+
+	// PlaintextSize is the size of the plaintext
+	PlaintextSize = 32
+
+	// Eta2 is the parameter η₂
+	Eta2 = 2
+)
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/poly.go b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/poly.go
new file mode 100644
index 00000000..f580e915
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/poly.go
@@ -0,0 +1,332 @@
+package common
+
+// An element of our base ring R which are polynomials over ℤ_q
+// modulo the equation Xᴺ = -1, where q=3329 and N=256.
+//
+// This type is also used to store NTT-transformed polynomials,
+// see Poly.NTT().
+//
+// Coefficients aren't always reduced.  See Normalize().
+type Poly [N]int16
+
+// Sets p to a + b.  Does not normalize coefficients.
+func (p *Poly) addGeneric(a, b *Poly) {
+	for i := 0; i < N; i++ {
+		p[i] = a[i] + b[i]
+	}
+}
+
+// Sets p to a - b.  Does not normalize coefficients.
+func (p *Poly) subGeneric(a, b *Poly) {
+	for i := 0; i < N; i++ {
+		p[i] = a[i] - b[i]
+	}
+}
+
+// Almost normalizes coefficients.
+//
+// Ensures each coefficient is in {0, …, q}.
+func (p *Poly) barrettReduceGeneric() {
+	for i := 0; i < N; i++ {
+		p[i] = barrettReduce(p[i])
+	}
+}
+
+// Normalizes coefficients.
+//
+// Ensures each coefficient is in {0, …, q-1}.
+func (p *Poly) normalizeGeneric() {
+	for i := 0; i < N; i++ {
+		p[i] = csubq(barrettReduce(p[i]))
+	}
+}
+
+// Multiplies p in-place by the Montgomery factor 2¹⁶.
+//
+// Coefficients of p can be arbitrary.  Resulting coefficients are bounded
+// in absolute value by q.
+func (p *Poly) ToMont() {
+	for i := 0; i < N; i++ {
+		p[i] = toMont(p[i])
+	}
+}
+
+// Sets p to the "pointwise" multiplication of a and b.
+//
+// That is: InvNTT(p) = InvNTT(a) * InvNTT(b).  Assumes a and b are in
+// Montgomery form.  Products between coefficients of a and b must be strictly
+// bounded in absolute value by 2¹⁵q.  p will be in Montgomery form and
+// bounded in absolute value by 2q.
+//
+// Requires a and b to be in "tangled" order, see Tangle().  p will be in
+// tangled order as well.
+func (p *Poly) mulHatGeneric(a, b *Poly) {
+	// Recall from the discussion in NTT(), that a transformed polynomial is
+	// an element of ℤ_q[x]/(x²-ζ) x … x  ℤ_q[x]/(x²+ζ¹²⁷);
+	// that is: 128 degree-one polynomials instead of simply 256 elements
+	// from ℤ_q as in the regular NTT.  So instead of pointwise multiplication,
+	// we multiply the 128 pairs of degree-one polynomials modulo the
+	// right equation:
+	//
+	//  (a₁ + a₂x)(b₁ + b₂x) = a₁b₁ + a₂b₂ζ' + (a₁b₂ + a₂b₁)x,
+	//
+	// where ζ' is the appropriate power of ζ.
+
+	k := 64
+	for i := 0; i < N; i += 4 {
+		zeta := int32(Zetas[k])
+		k++
+
+		p0 := montReduce(int32(a[i+1]) * int32(b[i+1]))
+		p0 = montReduce(int32(p0) * zeta)
+		p0 += montReduce(int32(a[i]) * int32(b[i]))
+
+		p1 := montReduce(int32(a[i]) * int32(b[i+1]))
+		p1 += montReduce(int32(a[i+1]) * int32(b[i]))
+
+		p[i] = p0
+		p[i+1] = p1
+
+		p2 := montReduce(int32(a[i+3]) * int32(b[i+3]))
+		p2 = -montReduce(int32(p2) * zeta)
+		p2 += montReduce(int32(a[i+2]) * int32(b[i+2]))
+
+		p3 := montReduce(int32(a[i+2]) * int32(b[i+3]))
+		p3 += montReduce(int32(a[i+3]) * int32(b[i+2]))
+
+		p[i+2] = p2
+		p[i+3] = p3
+	}
+}
+
+// Packs p into buf.  buf should be of length PolySize.
+//
+// Assumes p is normalized (and not just Barrett reduced) and "tangled",
+// see Tangle().
+func (p *Poly) Pack(buf []byte) {
+	q := *p
+	q.Detangle()
+	for i := 0; i < 128; i++ {
+		t0 := q[2*i]
+		t1 := q[2*i+1]
+		buf[3*i] = byte(t0)
+		buf[3*i+1] = byte(t0>>8) | byte(t1<<4)
+		buf[3*i+2] = byte(t1 >> 4)
+	}
+}
+
+// Unpacks p from buf.
+//
+// buf should be of length PolySize.  p will be "tangled", see Detangle().
+//
+// p will not be normalized; instead 0 ≤ p[i] < 4096.
+func (p *Poly) Unpack(buf []byte) {
+	for i := 0; i < 128; i++ {
+		p[2*i] = int16(buf[3*i]) | ((int16(buf[3*i+1]) << 8) & 0xfff)
+		p[2*i+1] = int16(buf[3*i+1]>>4) | (int16(buf[3*i+2]) << 4)
+	}
+	p.Tangle()
+}
+
+// Set p to Decompress_q(m, 1).
+//
+// p will be normalized.  m has to be of PlaintextSize.
+func (p *Poly) DecompressMessage(m []byte) {
+	// Decompress_q(x, 1) = ⌈xq/2⌋ = ⌊xq/2+½⌋ = (xq+1) >> 1 and so
+	// Decompress_q(0, 1) = 0 and Decompress_q(1, 1) = (q+1)/2.
+	for i := 0; i < 32; i++ {
+		for j := 0; j < 8; j++ {
+			bit := (m[i] >> uint(j)) & 1
+
+			// Set coefficient to either 0 or (q+1)/2 depending on the bit.
+			p[8*i+j] = -int16(bit) & ((Q + 1) / 2)
+		}
+	}
+}
+
+// Writes Compress_q(p, 1) to m.
+//
+// Assumes p is normalized.  m has to be of length at least PlaintextSize.
+func (p *Poly) CompressMessageTo(m []byte) {
+	// Compress_q(x, 1) is 1 on {833, …, 2496} and zero elsewhere.
+	for i := 0; i < 32; i++ {
+		m[i] = 0
+		for j := 0; j < 8; j++ {
+			x := 1664 - p[8*i+j]
+			// With the previous substitution, we want to return 1 if
+			// and only if x is in {831, …, -832}.
+			x = (x >> 15) ^ x
+			// Note (x >> 15)ˣ if x≥0 and -x-1 otherwise. Thus now we want
+			// to return 1 iff x ≤ 831, ie. x - 832 < 0.
+			x -= 832
+			m[i] |= ((byte(x >> 15)) & 1) << uint(j)
+		}
+	}
+}
+
+// Set p to Decompress_q(m, 1).
+//
+// Assumes d is in {4, 5, 10, 11}.  p will be normalized.
+func (p *Poly) Decompress(m []byte, d int) {
+	// Decompress_q(x, d) = ⌈(q/2ᵈ)x⌋
+	//                    = ⌊(q/2ᵈ)x+½⌋
+	//                    = ⌊(qx + 2ᵈ⁻¹)/2ᵈ⌋
+	//                    = (qx + (1<<(d-1))) >> d
+	switch d {
+	case 4:
+		for i := 0; i < N/2; i++ {
+			p[2*i] = int16(((1 << 3) +
+				uint32(m[i]&15)*uint32(Q)) >> 4)
+			p[2*i+1] = int16(((1 << 3) +
+				uint32(m[i]>>4)*uint32(Q)) >> 4)
+		}
+	case 5:
+		var t [8]uint16
+		idx := 0
+		for i := 0; i < N/8; i++ {
+			t[0] = uint16(m[idx])
+			t[1] = (uint16(m[idx]) >> 5) | (uint16(m[idx+1] << 3))
+			t[2] = uint16(m[idx+1]) >> 2
+			t[3] = (uint16(m[idx+1]) >> 7) | (uint16(m[idx+2] << 1))
+			t[4] = (uint16(m[idx+2]) >> 4) | (uint16(m[idx+3] << 4))
+			t[5] = uint16(m[idx+3]) >> 1
+			t[6] = (uint16(m[idx+3]) >> 6) | (uint16(m[idx+4] << 2))
+			t[7] = uint16(m[idx+4]) >> 3
+
+			for j := 0; j < 8; j++ {
+				p[8*i+j] = int16(((1 << 4) +
+					uint32(t[j]&((1<<5)-1))*uint32(Q)) >> 5)
+			}
+
+			idx += 5
+		}
+
+	case 10:
+		var t [4]uint16
+		idx := 0
+		for i := 0; i < N/4; i++ {
+			t[0] = uint16(m[idx]) | (uint16(m[idx+1]) << 8)
+			t[1] = (uint16(m[idx+1]) >> 2) | (uint16(m[idx+2]) << 6)
+			t[2] = (uint16(m[idx+2]) >> 4) | (uint16(m[idx+3]) << 4)
+			t[3] = (uint16(m[idx+3]) >> 6) | (uint16(m[idx+4]) << 2)
+
+			for j := 0; j < 4; j++ {
+				p[4*i+j] = int16(((1 << 9) +
+					uint32(t[j]&((1<<10)-1))*uint32(Q)) >> 10)
+			}
+
+			idx += 5
+		}
+	case 11:
+		var t [8]uint16
+		idx := 0
+		for i := 0; i < N/8; i++ {
+			t[0] = uint16(m[idx]) | (uint16(m[idx+1]) << 8)
+			t[1] = (uint16(m[idx+1]) >> 3) | (uint16(m[idx+2]) << 5)
+			t[2] = (uint16(m[idx+2]) >> 6) | (uint16(m[idx+3]) << 2) | (uint16(m[idx+4]) << 10)
+			t[3] = (uint16(m[idx+4]) >> 1) | (uint16(m[idx+5]) << 7)
+			t[4] = (uint16(m[idx+5]) >> 4) | (uint16(m[idx+6]) << 4)
+			t[5] = (uint16(m[idx+6]) >> 7) | (uint16(m[idx+7]) << 1) | (uint16(m[idx+8]) << 9)
+			t[6] = (uint16(m[idx+8]) >> 2) | (uint16(m[idx+9]) << 6)
+			t[7] = (uint16(m[idx+9]) >> 5) | (uint16(m[idx+10]) << 3)
+
+			for j := 0; j < 8; j++ {
+				p[8*i+j] = int16(((1 << 10) +
+					uint32(t[j]&((1<<11)-1))*uint32(Q)) >> 11)
+			}
+
+			idx += 11
+		}
+	default:
+		panic("unsupported d")
+	}
+}
+
+// Writes Compress_q(p, d) to m.
+//
+// Assumes p is normalized and d is in {4, 5, 10, 11}.
+func (p *Poly) CompressTo(m []byte, d int) {
+	// Compress_q(x, d) = ⌈(2ᵈ/q)x⌋ mod⁺ 2ᵈ
+	//                  = ⌊(2ᵈ/q)x+½⌋ mod⁺ 2ᵈ
+	//					= ⌊((x << d) + q/2) / q⌋ mod⁺ 2ᵈ
+	//					= DIV((x << d) + q/2, q) & ((1<<d) - 1)
+	//
+	// We approximate DIV(x, q) by computing (x*a)>>e, where a/(2^e) ≈ 1/q.
+	// For d in {10,11} we use 20,642,679/2^36, which computes division by x/q
+	// correctly for 0 ≤ x < 41,522,616, which fits (q << 11) + q/2 comfortably.
+	// For d in {4,5} we use 315/2^20, which doesn't compute division by x/q
+	// correctly for all inputs, but it's close enough that the end result
+	// of the compression is correct. The advantage is that we do not need
+	// to use a 64-bit intermediate value.
+	switch d {
+	case 4:
+		var t [8]uint16
+		idx := 0
+		for i := 0; i < N/8; i++ {
+			for j := 0; j < 8; j++ {
+				t[j] = uint16((((uint32(p[8*i+j])<<4)+uint32(Q)/2)*315)>>
+					20) & ((1 << 4) - 1)
+			}
+			m[idx] = byte(t[0]) | byte(t[1]<<4)
+			m[idx+1] = byte(t[2]) | byte(t[3]<<4)
+			m[idx+2] = byte(t[4]) | byte(t[5]<<4)
+			m[idx+3] = byte(t[6]) | byte(t[7]<<4)
+			idx += 4
+		}
+
+	case 5:
+		var t [8]uint16
+		idx := 0
+		for i := 0; i < N/8; i++ {
+			for j := 0; j < 8; j++ {
+				t[j] = uint16((((uint32(p[8*i+j])<<5)+uint32(Q)/2)*315)>>
+					20) & ((1 << 5) - 1)
+			}
+			m[idx] = byte(t[0]) | byte(t[1]<<5)
+			m[idx+1] = byte(t[1]>>3) | byte(t[2]<<2) | byte(t[3]<<7)
+			m[idx+2] = byte(t[3]>>1) | byte(t[4]<<4)
+			m[idx+3] = byte(t[4]>>4) | byte(t[5]<<1) | byte(t[6]<<6)
+			m[idx+4] = byte(t[6]>>2) | byte(t[7]<<3)
+			idx += 5
+		}
+
+	case 10:
+		var t [4]uint16
+		idx := 0
+		for i := 0; i < N/4; i++ {
+			for j := 0; j < 4; j++ {
+				t[j] = uint16((uint64((uint32(p[4*i+j])<<10)+uint32(Q)/2)*
+					20642679)>>36) & ((1 << 10) - 1)
+			}
+			m[idx] = byte(t[0])
+			m[idx+1] = byte(t[0]>>8) | byte(t[1]<<2)
+			m[idx+2] = byte(t[1]>>6) | byte(t[2]<<4)
+			m[idx+3] = byte(t[2]>>4) | byte(t[3]<<6)
+			m[idx+4] = byte(t[3] >> 2)
+			idx += 5
+		}
+	case 11:
+		var t [8]uint16
+		idx := 0
+		for i := 0; i < N/8; i++ {
+			for j := 0; j < 8; j++ {
+				t[j] = uint16((uint64((uint32(p[8*i+j])<<11)+uint32(Q)/2)*
+					20642679)>>36) & ((1 << 11) - 1)
+			}
+			m[idx] = byte(t[0])
+			m[idx+1] = byte(t[0]>>8) | byte(t[1]<<3)
+			m[idx+2] = byte(t[1]>>5) | byte(t[2]<<6)
+			m[idx+3] = byte(t[2] >> 2)
+			m[idx+4] = byte(t[2]>>10) | byte(t[3]<<1)
+			m[idx+5] = byte(t[3]>>7) | byte(t[4]<<4)
+			m[idx+6] = byte(t[4]>>4) | byte(t[5]<<7)
+			m[idx+7] = byte(t[5] >> 1)
+			m[idx+8] = byte(t[5]>>9) | byte(t[6]<<2)
+			m[idx+9] = byte(t[6]>>6) | byte(t[7]<<5)
+			m[idx+10] = byte(t[7] >> 3)
+			idx += 11
+		}
+	default:
+		panic("unsupported d")
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/sample.go b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/sample.go
new file mode 100644
index 00000000..ed5a33dd
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/sample.go
@@ -0,0 +1,236 @@
+package common
+
+import (
+	"encoding/binary"
+
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/simd/keccakf1600"
+)
+
+// DeriveX4Available indicates whether the system supports the quick fourway
+// sampling variants like PolyDeriveUniformX4.
+var DeriveX4Available = keccakf1600.IsEnabledX4()
+
+// Samples p from a centered binomial distribution with given η.
+//
+// Essentially CBD_η(PRF(seed, nonce)) from the specification.
+func (p *Poly) DeriveNoise(seed []byte, nonce uint8, eta int) {
+	switch eta {
+	case 2:
+		p.DeriveNoise2(seed, nonce)
+	case 3:
+		p.DeriveNoise3(seed, nonce)
+	default:
+		panic("unsupported eta")
+	}
+}
+
+// Sample p from a centered binomial distribution with n=6 and p=½ - that is:
+// coefficients are in {-3, -2, -1, 0, 1, 2, 3} with probabilities {1/64, 3/32,
+// 15/64, 5/16, 16/64, 3/32, 1/64}.
+func (p *Poly) DeriveNoise3(seed []byte, nonce uint8) {
+	keySuffix := [1]byte{nonce}
+	h := sha3.NewShake256()
+	_, _ = h.Write(seed[:])
+	_, _ = h.Write(keySuffix[:])
+
+	// The distribution at hand is exactly the same as that
+	// of (a₁ + a₂ + a₃) - (b₁ + b₂+b₃) where a_i,b_i~U(1).  Thus we need
+	// 6 bits per coefficients, thus 192 bytes of input entropy.
+
+	// We add two extra zero bytes in the buffer to be able to read 8 bytes
+	// at the same time (while using only 6.)
+	var buf [192 + 2]byte
+	_, _ = h.Read(buf[:192])
+
+	for i := 0; i < 32; i++ {
+		// t is interpreted as a₁ + 2a₂ + 4a₃ + 8b₁ + 16b₂ + ….
+		t := binary.LittleEndian.Uint64(buf[6*i:])
+
+		d := t & 0x249249249249        // a₁ + 8b₁ + …
+		d += (t >> 1) & 0x249249249249 // a₁ + a₂ + 8(b₁ + b₂) + …
+		d += (t >> 2) & 0x249249249249 // a₁ + a₂ + a₃ + 4(b₁ + b₂ + b₃) + …
+
+		for j := 0; j < 8; j++ {
+			a := int16(d) & 0x7 // a₁ + a₂ + a₃
+			d >>= 3
+			b := int16(d) & 0x7 // b₁ + b₂ + b₃
+			d >>= 3
+			p[8*i+j] = a - b
+		}
+	}
+}
+
+// Sample p from a centered binomial distribution with n=4 and p=½ - that is:
+// coefficients are in {-2, -1, 0, 1, 2} with probabilities {1/16, 1/4,
+// 3/8, 1/4, 1/16}.
+func (p *Poly) DeriveNoise2(seed []byte, nonce uint8) {
+	keySuffix := [1]byte{nonce}
+	h := sha3.NewShake256()
+	_, _ = h.Write(seed[:])
+	_, _ = h.Write(keySuffix[:])
+
+	// The distribution at hand is exactly the same as that
+	// of (a + a') - (b + b') where a,a',b,b'~U(1).  Thus we need 4 bits per
+	// coefficients, thus 128 bytes of input entropy.
+
+	var buf [128]byte
+	_, _ = h.Read(buf[:])
+
+	for i := 0; i < 16; i++ {
+		// t is interpreted as a + 2a' + 4b + 8b' + ….
+		t := binary.LittleEndian.Uint64(buf[8*i:])
+
+		d := t & 0x5555555555555555        // a + 4b + …
+		d += (t >> 1) & 0x5555555555555555 // a+a' + 4(b + b') + …
+
+		for j := 0; j < 16; j++ {
+			a := int16(d) & 0x3
+			d >>= 2
+			b := int16(d) & 0x3
+			d >>= 2
+			p[16*i+j] = a - b
+		}
+	}
+}
+
+// For each i, sample ps[i] uniformly from the given seed for coordinates
+// xs[i] and ys[i]. ps[i] may be nil and is ignored in that case.
+//
+// Can only be called when DeriveX4Available is true.
+func PolyDeriveUniformX4(ps [4]*Poly, seed *[32]byte, xs, ys [4]uint8) {
+	var perm keccakf1600.StateX4
+	state := perm.Initialize(false)
+
+	// Absorb the seed in the four states
+	for i := 0; i < 4; i++ {
+		v := binary.LittleEndian.Uint64(seed[8*i : 8*(i+1)])
+		for j := 0; j < 4; j++ {
+			state[i*4+j] = v
+		}
+	}
+
+	// Absorb the coordinates, the SHAKE128 domain separator (0b1111), the
+	// start of the padding (0b…001) and the end of the padding 0b100….
+	// Recall that the rate of SHAKE128 is 168; ie. 21 uint64s.
+	for j := 0; j < 4; j++ {
+		state[4*4+j] = uint64(xs[j]) | (uint64(ys[j]) << 8) | (0x1f << 16)
+		state[20*4+j] = 0x80 << 56
+	}
+
+	var idx [4]int // indices into ps
+	for j := 0; j < 4; j++ {
+		if ps[j] == nil {
+			idx[j] = N // mark nil polynomials as completed
+		}
+	}
+
+	done := false
+	for !done {
+		// Applies KeccaK-f[1600] to state to get the next 21 uint64s of each of
+		// the four SHAKE128 streams.
+		perm.Permute()
+
+		done = true
+
+	PolyLoop:
+		for j := 0; j < 4; j++ {
+			if idx[j] == N {
+				continue
+			}
+			for i := 0; i < 7; i++ {
+				var t [16]uint16
+
+				v1 := state[i*3*4+j]
+				v2 := state[(i*3+1)*4+j]
+				v3 := state[(i*3+2)*4+j]
+
+				t[0] = uint16(v1) & 0xfff
+				t[1] = uint16(v1>>12) & 0xfff
+				t[2] = uint16(v1>>24) & 0xfff
+				t[3] = uint16(v1>>36) & 0xfff
+				t[4] = uint16(v1>>48) & 0xfff
+				t[5] = uint16((v1>>60)|(v2<<4)) & 0xfff
+
+				t[6] = uint16(v2>>8) & 0xfff
+				t[7] = uint16(v2>>20) & 0xfff
+				t[8] = uint16(v2>>32) & 0xfff
+				t[9] = uint16(v2>>44) & 0xfff
+				t[10] = uint16((v2>>56)|(v3<<8)) & 0xfff
+
+				t[11] = uint16(v3>>4) & 0xfff
+				t[12] = uint16(v3>>16) & 0xfff
+				t[13] = uint16(v3>>28) & 0xfff
+				t[14] = uint16(v3>>40) & 0xfff
+				t[15] = uint16(v3>>52) & 0xfff
+
+				for k := 0; k < 16; k++ {
+					if t[k] < uint16(Q) {
+						ps[j][idx[j]] = int16(t[k])
+						idx[j]++
+						if idx[j] == N {
+							continue PolyLoop
+						}
+					}
+				}
+			}
+
+			done = false
+		}
+	}
+
+	for i := 0; i < 4; i++ {
+		if ps[i] != nil {
+			ps[i].Tangle()
+		}
+	}
+}
+
+// Sample p uniformly from the given seed and x and y coordinates.
+//
+// Coefficients are reduced and will be in "tangled" order.  See Tangle().
+func (p *Poly) DeriveUniform(seed *[32]byte, x, y uint8) {
+	var seedSuffix [2]byte
+	var buf [168]byte // rate of SHAKE-128
+
+	seedSuffix[0] = x
+	seedSuffix[1] = y
+
+	h := sha3.NewShake128()
+	_, _ = h.Write(seed[:])
+	_, _ = h.Write(seedSuffix[:])
+
+	i := 0
+	for {
+		_, _ = h.Read(buf[:])
+
+		for j := 0; j < 168; j += 3 {
+			t1 := (uint16(buf[j]) | (uint16(buf[j+1]) << 8)) & 0xfff
+			t2 := (uint16(buf[j+1]>>4) | (uint16(buf[j+2]) << 4)) & 0xfff
+
+			if t1 < uint16(Q) {
+				p[i] = int16(t1)
+				i++
+
+				if i == N {
+					break
+				}
+			}
+
+			if t2 < uint16(Q) {
+				p[i] = int16(t2)
+				i++
+
+				if i == N {
+					break
+				}
+			}
+		}
+
+		if i == N {
+			break
+		}
+	}
+
+	p.Tangle()
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/stubs_amd64.go b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/stubs_amd64.go
new file mode 100644
index 00000000..4b4700df
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/internal/common/stubs_amd64.go
@@ -0,0 +1,32 @@
+// Code generated by command: go run src.go -out ../amd64.s -stubs ../stubs_amd64.go -pkg common. DO NOT EDIT.
+
+//go:build amd64 && !purego
+
+package common
+
+//go:noescape
+func addAVX2(p *[256]int16, a *[256]int16, b *[256]int16)
+
+//go:noescape
+func subAVX2(p *[256]int16, a *[256]int16, b *[256]int16)
+
+//go:noescape
+func nttAVX2(p *[256]int16)
+
+//go:noescape
+func invNttAVX2(p *[256]int16)
+
+//go:noescape
+func mulHatAVX2(p *[256]int16, a *[256]int16, b *[256]int16)
+
+//go:noescape
+func detangleAVX2(p *[256]int16)
+
+//go:noescape
+func tangleAVX2(p *[256]int16)
+
+//go:noescape
+func barrettReduceAVX2(p *[256]int16)
+
+//go:noescape
+func normalizeAVX2(p *[256]int16)
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/cpapke.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/cpapke.go
new file mode 100644
index 00000000..01ef88b2
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/cpapke.go
@@ -0,0 +1,176 @@
+// Code generated from kyber512/internal/cpapke.go by gen.go
+
+package internal
+
+import (
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/pke/kyber/internal/common"
+)
+
+// A Kyber.CPAPKE private key.
+type PrivateKey struct {
+	sh Vec // NTT(s), normalized
+}
+
+// A Kyber.CPAPKE public key.
+type PublicKey struct {
+	rho [32]byte // ρ, the seed for the matrix A
+	th  Vec      // NTT(t), normalized
+
+	// cached values
+	aT Mat // the matrix Aᵀ
+}
+
+// Packs the private key to buf.
+func (sk *PrivateKey) Pack(buf []byte) {
+	sk.sh.Pack(buf)
+}
+
+// Unpacks the private key from buf.
+func (sk *PrivateKey) Unpack(buf []byte) {
+	sk.sh.Unpack(buf)
+	sk.sh.Normalize()
+}
+
+// Packs the public key to buf.
+func (pk *PublicKey) Pack(buf []byte) {
+	pk.th.Pack(buf)
+	copy(buf[K*common.PolySize:], pk.rho[:])
+}
+
+// Unpacks the public key from buf.
+func (pk *PublicKey) Unpack(buf []byte) {
+	pk.th.Unpack(buf)
+	pk.th.Normalize()
+	copy(pk.rho[:], buf[K*common.PolySize:])
+	pk.aT.Derive(&pk.rho, true)
+}
+
+// Derives a new Kyber.CPAPKE keypair from the given seed.
+func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
+	var pk PublicKey
+	var sk PrivateKey
+
+	var expandedSeed [64]byte
+
+	h := sha3.New512()
+	_, _ = h.Write(seed)
+
+	// This writes hash into expandedSeed.  Yes, this is idiomatic Go.
+	_, _ = h.Read(expandedSeed[:])
+
+	copy(pk.rho[:], expandedSeed[:32])
+	sigma := expandedSeed[32:] // σ, the noise seed
+
+	pk.aT.Derive(&pk.rho, false) // Expand ρ to matrix A; we'll transpose later
+
+	var eh Vec
+	sk.sh.DeriveNoise(sigma, 0, Eta1) // Sample secret vector s
+	sk.sh.NTT()
+	sk.sh.Normalize()
+
+	eh.DeriveNoise(sigma, K, Eta1) // Sample blind e
+	eh.NTT()
+
+	// Next, we compute t = A s + e.
+	for i := 0; i < K; i++ {
+		// Note that coefficients of s are bounded by q and those of A
+		// are bounded by 4.5q and so their product is bounded by 2¹⁵q
+		// as required for multiplication.
+		PolyDotHat(&pk.th[i], &pk.aT[i], &sk.sh)
+
+		// A and s were not in Montgomery form, so the Montgomery
+		// multiplications in the inner product added a factor R⁻¹ which
+		// we'll cancel out now.  This will also ensure the coefficients of
+		// t are bounded in absolute value by q.
+		pk.th[i].ToMont()
+	}
+
+	pk.th.Add(&pk.th, &eh) // bounded by 8q.
+	pk.th.Normalize()
+	pk.aT.Transpose()
+
+	return &pk, &sk
+}
+
+// Decrypts ciphertext ct meant for private key sk to plaintext pt.
+func (sk *PrivateKey) DecryptTo(pt, ct []byte) {
+	var u Vec
+	var v, m common.Poly
+
+	u.Decompress(ct, DU)
+	v.Decompress(ct[K*compressedPolySize(DU):], DV)
+
+	// Compute m = v - <s, u>
+	u.NTT()
+	PolyDotHat(&m, &sk.sh, &u)
+	m.BarrettReduce()
+	m.InvNTT()
+	m.Sub(&v, &m)
+	m.Normalize()
+
+	// Compress polynomial m to original message
+	m.CompressMessageTo(pt)
+}
+
+// Encrypts message pt for the public key to ciphertext ct using randomness
+// from seed.
+//
+// seed has to be of length SeedSize, pt of PlaintextSize and ct of
+// CiphertextSize.
+func (pk *PublicKey) EncryptTo(ct, pt, seed []byte) {
+	var rh, e1, u Vec
+	var e2, v, m common.Poly
+
+	// Sample r, e₁ and e₂ from B_η
+	rh.DeriveNoise(seed, 0, Eta1)
+	rh.NTT()
+	rh.BarrettReduce()
+
+	e1.DeriveNoise(seed, K, common.Eta2)
+	e2.DeriveNoise(seed, 2*K, common.Eta2)
+
+	// Next we compute u = Aᵀ r + e₁.  First Aᵀ.
+	for i := 0; i < K; i++ {
+		// Note that coefficients of r are bounded by q and those of Aᵀ
+		// are bounded by 4.5q and so their product is bounded by 2¹⁵q
+		// as required for multiplication.
+		PolyDotHat(&u[i], &pk.aT[i], &rh)
+	}
+
+	u.BarrettReduce()
+
+	// Aᵀ and r were not in Montgomery form, so the Montgomery
+	// multiplications in the inner product added a factor R⁻¹ which
+	// the InvNTT cancels out.
+	u.InvNTT()
+
+	u.Add(&u, &e1) // u = Aᵀ r + e₁
+
+	// Next compute v = <t, r> + e₂ + Decompress_q(m, 1).
+	PolyDotHat(&v, &pk.th, &rh)
+	v.BarrettReduce()
+	v.InvNTT()
+
+	m.DecompressMessage(pt)
+	v.Add(&v, &m)
+	v.Add(&v, &e2) // v = <t, r> + e₂ + Decompress_q(m, 1)
+
+	// Pack ciphertext
+	u.Normalize()
+	v.Normalize()
+
+	u.CompressTo(ct, DU)
+	v.CompressTo(ct[K*compressedPolySize(DU):], DV)
+}
+
+// Returns whether sk equals other.
+func (sk *PrivateKey) Equal(other *PrivateKey) bool {
+	ret := int16(0)
+	for i := 0; i < K; i++ {
+		for j := 0; j < common.N; j++ {
+			ret |= sk.sh[i][j] ^ other.sh[i][j]
+		}
+	}
+	return ret == 0
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/mat.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/mat.go
new file mode 100644
index 00000000..404aacfb
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/mat.go
@@ -0,0 +1,85 @@
+// Code generated from kyber512/internal/mat.go by gen.go
+
+package internal
+
+import (
+	"github.com/cloudflare/circl/pke/kyber/internal/common"
+)
+
+// A k by k matrix of polynomials.
+type Mat [K]Vec
+
+// Expands the given seed to the corresponding matrix A or its transpose Aᵀ.
+func (m *Mat) Derive(seed *[32]byte, transpose bool) {
+	if !common.DeriveX4Available {
+		if transpose {
+			for i := 0; i < K; i++ {
+				for j := 0; j < K; j++ {
+					m[i][j].DeriveUniform(seed, uint8(i), uint8(j))
+				}
+			}
+		} else {
+			for i := 0; i < K; i++ {
+				for j := 0; j < K; j++ {
+					m[i][j].DeriveUniform(seed, uint8(j), uint8(i))
+				}
+			}
+		}
+		return
+	}
+
+	var ps [4]*common.Poly
+	var xs [4]uint8
+	var ys [4]uint8
+	x := uint8(0)
+	y := uint8(0)
+
+	for x != K {
+		idx := 0
+		for ; idx < 4; idx++ {
+			ps[idx] = &m[x][y]
+
+			if transpose {
+				xs[idx] = x
+				ys[idx] = y
+			} else {
+				xs[idx] = y
+				ys[idx] = x
+			}
+
+			y++
+			if y == K {
+				x++
+				y = 0
+
+				if x == K {
+					if idx == 0 {
+						// If there is just one left, then a plain DeriveUniform
+						// is quicker than the X4 variant.
+						ps[0].DeriveUniform(seed, xs[0], ys[0])
+						return
+					}
+
+					for idx++; idx < 4; idx++ {
+						ps[idx] = nil
+					}
+
+					break
+				}
+			}
+		}
+
+		common.PolyDeriveUniformX4(ps, seed, xs, ys)
+	}
+}
+
+// Transposes A in place.
+func (m *Mat) Transpose() {
+	for i := 0; i < K-1; i++ {
+		for j := i + 1; j < K; j++ {
+			t := m[i][j]
+			m[i][j] = m[j][i]
+			m[j][i] = t
+		}
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/params.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/params.go
new file mode 100644
index 00000000..669b0eda
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/params.go
@@ -0,0 +1,21 @@
+// Code generated from params.templ.go. DO NOT EDIT.
+
+package internal
+
+import (
+	"github.com/cloudflare/circl/pke/kyber/internal/common"
+)
+
+const (
+	K             = 4
+	Eta1          = 2
+	DU            = 11
+	DV            = 5
+	PublicKeySize = 32 + K*common.PolySize
+
+	PrivateKeySize = K * common.PolySize
+
+	PlaintextSize  = common.PlaintextSize
+	SeedSize       = 32
+	CiphertextSize = 1568
+)
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/vec.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/vec.go
new file mode 100644
index 00000000..6681895a
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/internal/vec.go
@@ -0,0 +1,125 @@
+// Code generated from kyber512/internal/vec.go by gen.go
+
+package internal
+
+import (
+	"github.com/cloudflare/circl/pke/kyber/internal/common"
+)
+
+// A vector of K polynomials
+type Vec [K]common.Poly
+
+// Samples v[i] from a centered binomial distribution with given η,
+// seed and nonce+i.
+//
+// Essentially CBD_η(PRF(seed, nonce+i)) from the specification.
+func (v *Vec) DeriveNoise(seed []byte, nonce uint8, eta int) {
+	for i := 0; i < K; i++ {
+		v[i].DeriveNoise(seed, nonce+uint8(i), eta)
+	}
+}
+
+// Sets p to the inner product of a and b using "pointwise" multiplication.
+//
+// See MulHat() and NTT() for a description of the multiplication.
+// Assumes a and b are in Montgomery form.  p will be in Montgomery form,
+// and its coefficients will be bounded in absolute value by 2kq.
+// If a and b are not in Montgomery form, then the action is the same
+// as "pointwise" multiplication followed by multiplying by R⁻¹, the inverse
+// of the Montgomery factor.
+func PolyDotHat(p *common.Poly, a, b *Vec) {
+	var t common.Poly
+	*p = common.Poly{} // set p to zero
+	for i := 0; i < K; i++ {
+		t.MulHat(&a[i], &b[i])
+		p.Add(&t, p)
+	}
+}
+
+// Almost normalizes coefficients in-place.
+//
+// Ensures each coefficient is in {0, …, q}.
+func (v *Vec) BarrettReduce() {
+	for i := 0; i < K; i++ {
+		v[i].BarrettReduce()
+	}
+}
+
+// Normalizes coefficients in-place.
+//
+// Ensures each coefficient is in {0, …, q-1}.
+func (v *Vec) Normalize() {
+	for i := 0; i < K; i++ {
+		v[i].Normalize()
+	}
+}
+
+// Applies in-place inverse NTT().  See Poly.InvNTT() for assumptions.
+func (v *Vec) InvNTT() {
+	for i := 0; i < K; i++ {
+		v[i].InvNTT()
+	}
+}
+
+// Applies in-place forward NTT().  See Poly.NTT() for assumptions.
+func (v *Vec) NTT() {
+	for i := 0; i < K; i++ {
+		v[i].NTT()
+	}
+}
+
+// Sets v to a + b.
+func (v *Vec) Add(a, b *Vec) {
+	for i := 0; i < K; i++ {
+		v[i].Add(&a[i], &b[i])
+	}
+}
+
+// Packs v into buf, which must be of length K*PolySize.
+func (v *Vec) Pack(buf []byte) {
+	for i := 0; i < K; i++ {
+		v[i].Pack(buf[common.PolySize*i:])
+	}
+}
+
+// Unpacks v from buf which must be of length K*PolySize.
+func (v *Vec) Unpack(buf []byte) {
+	for i := 0; i < K; i++ {
+		v[i].Unpack(buf[common.PolySize*i:])
+	}
+}
+
+// Writes Compress_q(v, d) to m.
+//
+// Assumes v is normalized and d is in {3, 4, 5, 10, 11}.
+func (v *Vec) CompressTo(m []byte, d int) {
+	size := compressedPolySize(d)
+	for i := 0; i < K; i++ {
+		v[i].CompressTo(m[size*i:], d)
+	}
+}
+
+// Set v to Decompress_q(m, 1).
+//
+// Assumes d is in {3, 4, 5, 10, 11}.  v will be normalized.
+func (v *Vec) Decompress(m []byte, d int) {
+	size := compressedPolySize(d)
+	for i := 0; i < K; i++ {
+		v[i].Decompress(m[size*i:], d)
+	}
+}
+
+// ⌈(256 d)/8⌉
+func compressedPolySize(d int) int {
+	switch d {
+	case 4:
+		return 128
+	case 5:
+		return 160
+	case 10:
+		return 320
+	case 11:
+		return 352
+	}
+	panic("unsupported d")
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/kyber.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/kyber.go
new file mode 100644
index 00000000..fb5911fa
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber1024/kyber.go
@@ -0,0 +1,145 @@
+// Code generated from modePkg.templ.go. DO NOT EDIT.
+
+// kyber1024 implements the IND-CPA-secure Public Key Encryption
+// scheme Kyber1024.CPAPKE as submitted to round 3 of the NIST PQC competition
+// and described in
+//
+// https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
+package kyber1024
+
+import (
+	cryptoRand "crypto/rand"
+	"io"
+
+	"github.com/cloudflare/circl/pke/kyber/kyber1024/internal"
+)
+
+const (
+	// Size of seed for NewKeyFromSeed
+	KeySeedSize = internal.SeedSize
+
+	// Size of seed for EncryptTo
+	EncryptionSeedSize = internal.SeedSize
+
+	// Size of a packed PublicKey
+	PublicKeySize = internal.PublicKeySize
+
+	// Size of a packed PrivateKey
+	PrivateKeySize = internal.PrivateKeySize
+
+	// Size of a ciphertext
+	CiphertextSize = internal.CiphertextSize
+
+	// Size of a plaintext
+	PlaintextSize = internal.PlaintextSize
+)
+
+// PublicKey is the type of Kyber1024.CPAPKE public key
+type PublicKey internal.PublicKey
+
+// PrivateKey is the type of Kyber1024.CPAPKE private key
+type PrivateKey internal.PrivateKey
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
+	var seed [KeySeedSize]byte
+	if rand == nil {
+		rand = cryptoRand.Reader
+	}
+	_, err := io.ReadFull(rand, seed[:])
+	if err != nil {
+		return nil, nil, err
+	}
+	pk, sk := internal.NewKeyFromSeed(seed[:])
+	return (*PublicKey)(pk), (*PrivateKey)(sk), nil
+}
+
+// NewKeyFromSeed derives a public/private key pair using the given seed.
+//
+// Panics if seed is not of length KeySeedSize.
+func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
+	if len(seed) != KeySeedSize {
+		panic("seed must be of length KeySeedSize")
+	}
+	pk, sk := internal.NewKeyFromSeed(seed)
+	return (*PublicKey)(pk), (*PrivateKey)(sk)
+}
+
+// EncryptTo encrypts message pt for the public key and writes the ciphertext
+// to ct using randomness from seed.
+//
+// This function panics if the lengths of pt, seed, and ct are not
+// PlaintextSize, EncryptionSeedSize, and CiphertextSize respectively.
+func (pk *PublicKey) EncryptTo(ct []byte, pt []byte, seed []byte) {
+	if len(pt) != PlaintextSize {
+		panic("pt must be of length PlaintextSize")
+	}
+	if len(ct) != CiphertextSize {
+		panic("ct must be of length CiphertextSize")
+	}
+	if len(seed) != EncryptionSeedSize {
+		panic("seed must be of length EncryptionSeedSize")
+	}
+	(*internal.PublicKey)(pk).EncryptTo(ct, pt, seed)
+}
+
+// DecryptTo decrypts message ct for the private key and writes the
+// plaintext to pt.
+//
+// This function panics if the lengths of ct and pt are not
+// CiphertextSize and PlaintextSize respectively.
+func (sk *PrivateKey) DecryptTo(pt []byte, ct []byte) {
+	if len(pt) != PlaintextSize {
+		panic("pt must be of length PlaintextSize")
+	}
+	if len(ct) != CiphertextSize {
+		panic("ct must be of length CiphertextSize")
+	}
+	(*internal.PrivateKey)(sk).DecryptTo(pt, ct)
+}
+
+// Packs pk into the given buffer.
+//
+// Panics if buf is not of length PublicKeySize.
+func (pk *PublicKey) Pack(buf []byte) {
+	if len(buf) != PublicKeySize {
+		panic("buf must be of size PublicKeySize")
+	}
+	(*internal.PublicKey)(pk).Pack(buf)
+}
+
+// Packs sk into the given buffer.
+//
+// Panics if buf is not of length PrivateKeySize.
+func (sk *PrivateKey) Pack(buf []byte) {
+	if len(buf) != PrivateKeySize {
+		panic("buf must be of size PrivateKeySize")
+	}
+	(*internal.PrivateKey)(sk).Pack(buf)
+}
+
+// Unpacks pk from the given buffer.
+//
+// Panics if buf is not of length PublicKeySize.
+func (pk *PublicKey) Unpack(buf []byte) {
+	if len(buf) != PublicKeySize {
+		panic("buf must be of size PublicKeySize")
+	}
+	(*internal.PublicKey)(pk).Unpack(buf)
+}
+
+// Unpacks sk from the given buffer.
+//
+// Panics if buf is not of length PrivateKeySize.
+func (sk *PrivateKey) Unpack(buf []byte) {
+	if len(buf) != PrivateKeySize {
+		panic("buf must be of size PrivateKeySize")
+	}
+	(*internal.PrivateKey)(sk).Unpack(buf)
+}
+
+// Returns whether the two private keys are equal.
+func (sk *PrivateKey) Equal(other *PrivateKey) bool {
+	return (*internal.PrivateKey)(sk).Equal((*internal.PrivateKey)(other))
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/cpapke.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/cpapke.go
new file mode 100644
index 00000000..80ab2501
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/cpapke.go
@@ -0,0 +1,174 @@
+package internal
+
+import (
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/pke/kyber/internal/common"
+)
+
+// A Kyber.CPAPKE private key.
+type PrivateKey struct {
+	sh Vec // NTT(s), normalized
+}
+
+// A Kyber.CPAPKE public key.
+type PublicKey struct {
+	rho [32]byte // ρ, the seed for the matrix A
+	th  Vec      // NTT(t), normalized
+
+	// cached values
+	aT Mat // the matrix Aᵀ
+}
+
+// Packs the private key to buf.
+func (sk *PrivateKey) Pack(buf []byte) {
+	sk.sh.Pack(buf)
+}
+
+// Unpacks the private key from buf.
+func (sk *PrivateKey) Unpack(buf []byte) {
+	sk.sh.Unpack(buf)
+	sk.sh.Normalize()
+}
+
+// Packs the public key to buf.
+func (pk *PublicKey) Pack(buf []byte) {
+	pk.th.Pack(buf)
+	copy(buf[K*common.PolySize:], pk.rho[:])
+}
+
+// Unpacks the public key from buf.
+func (pk *PublicKey) Unpack(buf []byte) {
+	pk.th.Unpack(buf)
+	pk.th.Normalize()
+	copy(pk.rho[:], buf[K*common.PolySize:])
+	pk.aT.Derive(&pk.rho, true)
+}
+
+// Derives a new Kyber.CPAPKE keypair from the given seed.
+func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
+	var pk PublicKey
+	var sk PrivateKey
+
+	var expandedSeed [64]byte
+
+	h := sha3.New512()
+	_, _ = h.Write(seed)
+
+	// This writes hash into expandedSeed.  Yes, this is idiomatic Go.
+	_, _ = h.Read(expandedSeed[:])
+
+	copy(pk.rho[:], expandedSeed[:32])
+	sigma := expandedSeed[32:] // σ, the noise seed
+
+	pk.aT.Derive(&pk.rho, false) // Expand ρ to matrix A; we'll transpose later
+
+	var eh Vec
+	sk.sh.DeriveNoise(sigma, 0, Eta1) // Sample secret vector s
+	sk.sh.NTT()
+	sk.sh.Normalize()
+
+	eh.DeriveNoise(sigma, K, Eta1) // Sample blind e
+	eh.NTT()
+
+	// Next, we compute t = A s + e.
+	for i := 0; i < K; i++ {
+		// Note that coefficients of s are bounded by q and those of A
+		// are bounded by 4.5q and so their product is bounded by 2¹⁵q
+		// as required for multiplication.
+		PolyDotHat(&pk.th[i], &pk.aT[i], &sk.sh)
+
+		// A and s were not in Montgomery form, so the Montgomery
+		// multiplications in the inner product added a factor R⁻¹ which
+		// we'll cancel out now.  This will also ensure the coefficients of
+		// t are bounded in absolute value by q.
+		pk.th[i].ToMont()
+	}
+
+	pk.th.Add(&pk.th, &eh) // bounded by 8q.
+	pk.th.Normalize()
+	pk.aT.Transpose()
+
+	return &pk, &sk
+}
+
+// Decrypts ciphertext ct meant for private key sk to plaintext pt.
+func (sk *PrivateKey) DecryptTo(pt, ct []byte) {
+	var u Vec
+	var v, m common.Poly
+
+	u.Decompress(ct, DU)
+	v.Decompress(ct[K*compressedPolySize(DU):], DV)
+
+	// Compute m = v - <s, u>
+	u.NTT()
+	PolyDotHat(&m, &sk.sh, &u)
+	m.BarrettReduce()
+	m.InvNTT()
+	m.Sub(&v, &m)
+	m.Normalize()
+
+	// Compress polynomial m to original message
+	m.CompressMessageTo(pt)
+}
+
+// Encrypts message pt for the public key to ciphertext ct using randomness
+// from seed.
+//
+// seed has to be of length SeedSize, pt of PlaintextSize and ct of
+// CiphertextSize.
+func (pk *PublicKey) EncryptTo(ct, pt, seed []byte) {
+	var rh, e1, u Vec
+	var e2, v, m common.Poly
+
+	// Sample r, e₁ and e₂ from B_η
+	rh.DeriveNoise(seed, 0, Eta1)
+	rh.NTT()
+	rh.BarrettReduce()
+
+	e1.DeriveNoise(seed, K, common.Eta2)
+	e2.DeriveNoise(seed, 2*K, common.Eta2)
+
+	// Next we compute u = Aᵀ r + e₁.  First Aᵀ.
+	for i := 0; i < K; i++ {
+		// Note that coefficients of r are bounded by q and those of Aᵀ
+		// are bounded by 4.5q and so their product is bounded by 2¹⁵q
+		// as required for multiplication.
+		PolyDotHat(&u[i], &pk.aT[i], &rh)
+	}
+
+	u.BarrettReduce()
+
+	// Aᵀ and r were not in Montgomery form, so the Montgomery
+	// multiplications in the inner product added a factor R⁻¹ which
+	// the InvNTT cancels out.
+	u.InvNTT()
+
+	u.Add(&u, &e1) // u = Aᵀ r + e₁
+
+	// Next compute v = <t, r> + e₂ + Decompress_q(m, 1).
+	PolyDotHat(&v, &pk.th, &rh)
+	v.BarrettReduce()
+	v.InvNTT()
+
+	m.DecompressMessage(pt)
+	v.Add(&v, &m)
+	v.Add(&v, &e2) // v = <t, r> + e₂ + Decompress_q(m, 1)
+
+	// Pack ciphertext
+	u.Normalize()
+	v.Normalize()
+
+	u.CompressTo(ct, DU)
+	v.CompressTo(ct[K*compressedPolySize(DU):], DV)
+}
+
+// Returns whether sk equals other.
+func (sk *PrivateKey) Equal(other *PrivateKey) bool {
+	ret := int16(0)
+	for i := 0; i < K; i++ {
+		for j := 0; j < common.N; j++ {
+			ret |= sk.sh[i][j] ^ other.sh[i][j]
+		}
+	}
+	return ret == 0
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/mat.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/mat.go
new file mode 100644
index 00000000..735ecf55
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/mat.go
@@ -0,0 +1,83 @@
+package internal
+
+import (
+	"github.com/cloudflare/circl/pke/kyber/internal/common"
+)
+
+// A k by k matrix of polynomials.
+type Mat [K]Vec
+
+// Expands the given seed to the corresponding matrix A or its transpose Aᵀ.
+func (m *Mat) Derive(seed *[32]byte, transpose bool) {
+	if !common.DeriveX4Available {
+		if transpose {
+			for i := 0; i < K; i++ {
+				for j := 0; j < K; j++ {
+					m[i][j].DeriveUniform(seed, uint8(i), uint8(j))
+				}
+			}
+		} else {
+			for i := 0; i < K; i++ {
+				for j := 0; j < K; j++ {
+					m[i][j].DeriveUniform(seed, uint8(j), uint8(i))
+				}
+			}
+		}
+		return
+	}
+
+	var ps [4]*common.Poly
+	var xs [4]uint8
+	var ys [4]uint8
+	x := uint8(0)
+	y := uint8(0)
+
+	for x != K {
+		idx := 0
+		for ; idx < 4; idx++ {
+			ps[idx] = &m[x][y]
+
+			if transpose {
+				xs[idx] = x
+				ys[idx] = y
+			} else {
+				xs[idx] = y
+				ys[idx] = x
+			}
+
+			y++
+			if y == K {
+				x++
+				y = 0
+
+				if x == K {
+					if idx == 0 {
+						// If there is just one left, then a plain DeriveUniform
+						// is quicker than the X4 variant.
+						ps[0].DeriveUniform(seed, xs[0], ys[0])
+						return
+					}
+
+					for idx++; idx < 4; idx++ {
+						ps[idx] = nil
+					}
+
+					break
+				}
+			}
+		}
+
+		common.PolyDeriveUniformX4(ps, seed, xs, ys)
+	}
+}
+
+// Transposes A in place.
+func (m *Mat) Transpose() {
+	for i := 0; i < K-1; i++ {
+		for j := i + 1; j < K; j++ {
+			t := m[i][j]
+			m[i][j] = m[j][i]
+			m[j][i] = t
+		}
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/params.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/params.go
new file mode 100644
index 00000000..0e6df77b
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/params.go
@@ -0,0 +1,21 @@
+// Code generated from params.templ.go. DO NOT EDIT.
+
+package internal
+
+import (
+	"github.com/cloudflare/circl/pke/kyber/internal/common"
+)
+
+const (
+	K             = 2
+	Eta1          = 3
+	DU            = 10
+	DV            = 4
+	PublicKeySize = 32 + K*common.PolySize
+
+	PrivateKeySize = K * common.PolySize
+
+	PlaintextSize  = common.PlaintextSize
+	SeedSize       = 32
+	CiphertextSize = 768
+)
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/vec.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/vec.go
new file mode 100644
index 00000000..222f1ca9
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/internal/vec.go
@@ -0,0 +1,123 @@
+package internal
+
+import (
+	"github.com/cloudflare/circl/pke/kyber/internal/common"
+)
+
+// A vector of K polynomials
+type Vec [K]common.Poly
+
+// Samples v[i] from a centered binomial distribution with given η,
+// seed and nonce+i.
+//
+// Essentially CBD_η(PRF(seed, nonce+i)) from the specification.
+func (v *Vec) DeriveNoise(seed []byte, nonce uint8, eta int) {
+	for i := 0; i < K; i++ {
+		v[i].DeriveNoise(seed, nonce+uint8(i), eta)
+	}
+}
+
+// Sets p to the inner product of a and b using "pointwise" multiplication.
+//
+// See MulHat() and NTT() for a description of the multiplication.
+// Assumes a and b are in Montgomery form.  p will be in Montgomery form,
+// and its coefficients will be bounded in absolute value by 2kq.
+// If a and b are not in Montgomery form, then the action is the same
+// as "pointwise" multiplication followed by multiplying by R⁻¹, the inverse
+// of the Montgomery factor.
+func PolyDotHat(p *common.Poly, a, b *Vec) {
+	var t common.Poly
+	*p = common.Poly{} // set p to zero
+	for i := 0; i < K; i++ {
+		t.MulHat(&a[i], &b[i])
+		p.Add(&t, p)
+	}
+}
+
+// Almost normalizes coefficients in-place.
+//
+// Ensures each coefficient is in {0, …, q}.
+func (v *Vec) BarrettReduce() {
+	for i := 0; i < K; i++ {
+		v[i].BarrettReduce()
+	}
+}
+
+// Normalizes coefficients in-place.
+//
+// Ensures each coefficient is in {0, …, q-1}.
+func (v *Vec) Normalize() {
+	for i := 0; i < K; i++ {
+		v[i].Normalize()
+	}
+}
+
+// Applies in-place inverse NTT().  See Poly.InvNTT() for assumptions.
+func (v *Vec) InvNTT() {
+	for i := 0; i < K; i++ {
+		v[i].InvNTT()
+	}
+}
+
+// Applies in-place forward NTT().  See Poly.NTT() for assumptions.
+func (v *Vec) NTT() {
+	for i := 0; i < K; i++ {
+		v[i].NTT()
+	}
+}
+
+// Sets v to a + b.
+func (v *Vec) Add(a, b *Vec) {
+	for i := 0; i < K; i++ {
+		v[i].Add(&a[i], &b[i])
+	}
+}
+
+// Packs v into buf, which must be of length K*PolySize.
+func (v *Vec) Pack(buf []byte) {
+	for i := 0; i < K; i++ {
+		v[i].Pack(buf[common.PolySize*i:])
+	}
+}
+
+// Unpacks v from buf which must be of length K*PolySize.
+func (v *Vec) Unpack(buf []byte) {
+	for i := 0; i < K; i++ {
+		v[i].Unpack(buf[common.PolySize*i:])
+	}
+}
+
+// Writes Compress_q(v, d) to m.
+//
+// Assumes v is normalized and d is in {3, 4, 5, 10, 11}.
+func (v *Vec) CompressTo(m []byte, d int) {
+	size := compressedPolySize(d)
+	for i := 0; i < K; i++ {
+		v[i].CompressTo(m[size*i:], d)
+	}
+}
+
+// Set v to Decompress_q(m, 1).
+//
+// Assumes d is in {3, 4, 5, 10, 11}.  v will be normalized.
+func (v *Vec) Decompress(m []byte, d int) {
+	size := compressedPolySize(d)
+	for i := 0; i < K; i++ {
+		v[i].Decompress(m[size*i:], d)
+	}
+}
+
+// ⌈(256 d)/8⌉
+func compressedPolySize(d int) int {
+	switch d {
+	case 4:
+		return 128
+	case 5:
+		return 160
+	case 10:
+		return 320
+	case 11:
+		return 352
+	}
+	panic("unsupported d")
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/kyber.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/kyber.go
new file mode 100644
index 00000000..ea924848
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber512/kyber.go
@@ -0,0 +1,145 @@
+// Code generated from modePkg.templ.go. DO NOT EDIT.
+
+// kyber512 implements the IND-CPA-secure Public Key Encryption
+// scheme Kyber512.CPAPKE as submitted to round 3 of the NIST PQC competition
+// and described in
+//
+// https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
+package kyber512
+
+import (
+	cryptoRand "crypto/rand"
+	"io"
+
+	"github.com/cloudflare/circl/pke/kyber/kyber512/internal"
+)
+
+const (
+	// Size of seed for NewKeyFromSeed
+	KeySeedSize = internal.SeedSize
+
+	// Size of seed for EncryptTo
+	EncryptionSeedSize = internal.SeedSize
+
+	// Size of a packed PublicKey
+	PublicKeySize = internal.PublicKeySize
+
+	// Size of a packed PrivateKey
+	PrivateKeySize = internal.PrivateKeySize
+
+	// Size of a ciphertext
+	CiphertextSize = internal.CiphertextSize
+
+	// Size of a plaintext
+	PlaintextSize = internal.PlaintextSize
+)
+
+// PublicKey is the type of Kyber512.CPAPKE public key
+type PublicKey internal.PublicKey
+
+// PrivateKey is the type of Kyber512.CPAPKE private key
+type PrivateKey internal.PrivateKey
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
+	var seed [KeySeedSize]byte
+	if rand == nil {
+		rand = cryptoRand.Reader
+	}
+	_, err := io.ReadFull(rand, seed[:])
+	if err != nil {
+		return nil, nil, err
+	}
+	pk, sk := internal.NewKeyFromSeed(seed[:])
+	return (*PublicKey)(pk), (*PrivateKey)(sk), nil
+}
+
+// NewKeyFromSeed derives a public/private key pair using the given seed.
+//
+// Panics if seed is not of length KeySeedSize.
+func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
+	if len(seed) != KeySeedSize {
+		panic("seed must be of length KeySeedSize")
+	}
+	pk, sk := internal.NewKeyFromSeed(seed)
+	return (*PublicKey)(pk), (*PrivateKey)(sk)
+}
+
+// EncryptTo encrypts message pt for the public key and writes the ciphertext
+// to ct using randomness from seed.
+//
+// This function panics if the lengths of pt, seed, and ct are not
+// PlaintextSize, EncryptionSeedSize, and CiphertextSize respectively.
+func (pk *PublicKey) EncryptTo(ct []byte, pt []byte, seed []byte) {
+	if len(pt) != PlaintextSize {
+		panic("pt must be of length PlaintextSize")
+	}
+	if len(ct) != CiphertextSize {
+		panic("ct must be of length CiphertextSize")
+	}
+	if len(seed) != EncryptionSeedSize {
+		panic("seed must be of length EncryptionSeedSize")
+	}
+	(*internal.PublicKey)(pk).EncryptTo(ct, pt, seed)
+}
+
+// DecryptTo decrypts message ct for the private key and writes the
+// plaintext to pt.
+//
+// This function panics if the lengths of ct and pt are not
+// CiphertextSize and PlaintextSize respectively.
+func (sk *PrivateKey) DecryptTo(pt []byte, ct []byte) {
+	if len(pt) != PlaintextSize {
+		panic("pt must be of length PlaintextSize")
+	}
+	if len(ct) != CiphertextSize {
+		panic("ct must be of length CiphertextSize")
+	}
+	(*internal.PrivateKey)(sk).DecryptTo(pt, ct)
+}
+
+// Packs pk into the given buffer.
+//
+// Panics if buf is not of length PublicKeySize.
+func (pk *PublicKey) Pack(buf []byte) {
+	if len(buf) != PublicKeySize {
+		panic("buf must be of size PublicKeySize")
+	}
+	(*internal.PublicKey)(pk).Pack(buf)
+}
+
+// Packs sk into the given buffer.
+//
+// Panics if buf is not of length PrivateKeySize.
+func (sk *PrivateKey) Pack(buf []byte) {
+	if len(buf) != PrivateKeySize {
+		panic("buf must be of size PrivateKeySize")
+	}
+	(*internal.PrivateKey)(sk).Pack(buf)
+}
+
+// Unpacks pk from the given buffer.
+//
+// Panics if buf is not of length PublicKeySize.
+func (pk *PublicKey) Unpack(buf []byte) {
+	if len(buf) != PublicKeySize {
+		panic("buf must be of size PublicKeySize")
+	}
+	(*internal.PublicKey)(pk).Unpack(buf)
+}
+
+// Unpacks sk from the given buffer.
+//
+// Panics if buf is not of length PrivateKeySize.
+func (sk *PrivateKey) Unpack(buf []byte) {
+	if len(buf) != PrivateKeySize {
+		panic("buf must be of size PrivateKeySize")
+	}
+	(*internal.PrivateKey)(sk).Unpack(buf)
+}
+
+// Returns whether the two private keys are equal.
+func (sk *PrivateKey) Equal(other *PrivateKey) bool {
+	return (*internal.PrivateKey)(sk).Equal((*internal.PrivateKey)(other))
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/cpapke.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/cpapke.go
new file mode 100644
index 00000000..01ef88b2
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/cpapke.go
@@ -0,0 +1,176 @@
+// Code generated from kyber512/internal/cpapke.go by gen.go
+
+package internal
+
+import (
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/pke/kyber/internal/common"
+)
+
+// A Kyber.CPAPKE private key.
+type PrivateKey struct {
+	sh Vec // NTT(s), normalized
+}
+
+// A Kyber.CPAPKE public key.
+type PublicKey struct {
+	rho [32]byte // ρ, the seed for the matrix A
+	th  Vec      // NTT(t), normalized
+
+	// cached values
+	aT Mat // the matrix Aᵀ
+}
+
+// Packs the private key to buf.
+func (sk *PrivateKey) Pack(buf []byte) {
+	sk.sh.Pack(buf)
+}
+
+// Unpacks the private key from buf.
+func (sk *PrivateKey) Unpack(buf []byte) {
+	sk.sh.Unpack(buf)
+	sk.sh.Normalize()
+}
+
+// Packs the public key to buf.
+func (pk *PublicKey) Pack(buf []byte) {
+	pk.th.Pack(buf)
+	copy(buf[K*common.PolySize:], pk.rho[:])
+}
+
+// Unpacks the public key from buf.
+func (pk *PublicKey) Unpack(buf []byte) {
+	pk.th.Unpack(buf)
+	pk.th.Normalize()
+	copy(pk.rho[:], buf[K*common.PolySize:])
+	pk.aT.Derive(&pk.rho, true)
+}
+
+// Derives a new Kyber.CPAPKE keypair from the given seed.
+func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
+	var pk PublicKey
+	var sk PrivateKey
+
+	var expandedSeed [64]byte
+
+	h := sha3.New512()
+	_, _ = h.Write(seed)
+
+	// This writes hash into expandedSeed.  Yes, this is idiomatic Go.
+	_, _ = h.Read(expandedSeed[:])
+
+	copy(pk.rho[:], expandedSeed[:32])
+	sigma := expandedSeed[32:] // σ, the noise seed
+
+	pk.aT.Derive(&pk.rho, false) // Expand ρ to matrix A; we'll transpose later
+
+	var eh Vec
+	sk.sh.DeriveNoise(sigma, 0, Eta1) // Sample secret vector s
+	sk.sh.NTT()
+	sk.sh.Normalize()
+
+	eh.DeriveNoise(sigma, K, Eta1) // Sample blind e
+	eh.NTT()
+
+	// Next, we compute t = A s + e.
+	for i := 0; i < K; i++ {
+		// Note that coefficients of s are bounded by q and those of A
+		// are bounded by 4.5q and so their product is bounded by 2¹⁵q
+		// as required for multiplication.
+		PolyDotHat(&pk.th[i], &pk.aT[i], &sk.sh)
+
+		// A and s were not in Montgomery form, so the Montgomery
+		// multiplications in the inner product added a factor R⁻¹ which
+		// we'll cancel out now.  This will also ensure the coefficients of
+		// t are bounded in absolute value by q.
+		pk.th[i].ToMont()
+	}
+
+	pk.th.Add(&pk.th, &eh) // bounded by 8q.
+	pk.th.Normalize()
+	pk.aT.Transpose()
+
+	return &pk, &sk
+}
+
+// Decrypts ciphertext ct meant for private key sk to plaintext pt.
+func (sk *PrivateKey) DecryptTo(pt, ct []byte) {
+	var u Vec
+	var v, m common.Poly
+
+	u.Decompress(ct, DU)
+	v.Decompress(ct[K*compressedPolySize(DU):], DV)
+
+	// Compute m = v - <s, u>
+	u.NTT()
+	PolyDotHat(&m, &sk.sh, &u)
+	m.BarrettReduce()
+	m.InvNTT()
+	m.Sub(&v, &m)
+	m.Normalize()
+
+	// Compress polynomial m to original message
+	m.CompressMessageTo(pt)
+}
+
+// Encrypts message pt for the public key to ciphertext ct using randomness
+// from seed.
+//
+// seed has to be of length SeedSize, pt of PlaintextSize and ct of
+// CiphertextSize.
+func (pk *PublicKey) EncryptTo(ct, pt, seed []byte) {
+	var rh, e1, u Vec
+	var e2, v, m common.Poly
+
+	// Sample r, e₁ and e₂ from B_η
+	rh.DeriveNoise(seed, 0, Eta1)
+	rh.NTT()
+	rh.BarrettReduce()
+
+	e1.DeriveNoise(seed, K, common.Eta2)
+	e2.DeriveNoise(seed, 2*K, common.Eta2)
+
+	// Next we compute u = Aᵀ r + e₁.  First Aᵀ.
+	for i := 0; i < K; i++ {
+		// Note that coefficients of r are bounded by q and those of Aᵀ
+		// are bounded by 4.5q and so their product is bounded by 2¹⁵q
+		// as required for multiplication.
+		PolyDotHat(&u[i], &pk.aT[i], &rh)
+	}
+
+	u.BarrettReduce()
+
+	// Aᵀ and r were not in Montgomery form, so the Montgomery
+	// multiplications in the inner product added a factor R⁻¹ which
+	// the InvNTT cancels out.
+	u.InvNTT()
+
+	u.Add(&u, &e1) // u = Aᵀ r + e₁
+
+	// Next compute v = <t, r> + e₂ + Decompress_q(m, 1).
+	PolyDotHat(&v, &pk.th, &rh)
+	v.BarrettReduce()
+	v.InvNTT()
+
+	m.DecompressMessage(pt)
+	v.Add(&v, &m)
+	v.Add(&v, &e2) // v = <t, r> + e₂ + Decompress_q(m, 1)
+
+	// Pack ciphertext
+	u.Normalize()
+	v.Normalize()
+
+	u.CompressTo(ct, DU)
+	v.CompressTo(ct[K*compressedPolySize(DU):], DV)
+}
+
+// Returns whether sk equals other.
+func (sk *PrivateKey) Equal(other *PrivateKey) bool {
+	ret := int16(0)
+	for i := 0; i < K; i++ {
+		for j := 0; j < common.N; j++ {
+			ret |= sk.sh[i][j] ^ other.sh[i][j]
+		}
+	}
+	return ret == 0
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/mat.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/mat.go
new file mode 100644
index 00000000..404aacfb
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/mat.go
@@ -0,0 +1,85 @@
+// Code generated from kyber512/internal/mat.go by gen.go
+
+package internal
+
+import (
+	"github.com/cloudflare/circl/pke/kyber/internal/common"
+)
+
+// A k by k matrix of polynomials.
+type Mat [K]Vec
+
+// Expands the given seed to the corresponding matrix A or its transpose Aᵀ.
+func (m *Mat) Derive(seed *[32]byte, transpose bool) {
+	if !common.DeriveX4Available {
+		if transpose {
+			for i := 0; i < K; i++ {
+				for j := 0; j < K; j++ {
+					m[i][j].DeriveUniform(seed, uint8(i), uint8(j))
+				}
+			}
+		} else {
+			for i := 0; i < K; i++ {
+				for j := 0; j < K; j++ {
+					m[i][j].DeriveUniform(seed, uint8(j), uint8(i))
+				}
+			}
+		}
+		return
+	}
+
+	var ps [4]*common.Poly
+	var xs [4]uint8
+	var ys [4]uint8
+	x := uint8(0)
+	y := uint8(0)
+
+	for x != K {
+		idx := 0
+		for ; idx < 4; idx++ {
+			ps[idx] = &m[x][y]
+
+			if transpose {
+				xs[idx] = x
+				ys[idx] = y
+			} else {
+				xs[idx] = y
+				ys[idx] = x
+			}
+
+			y++
+			if y == K {
+				x++
+				y = 0
+
+				if x == K {
+					if idx == 0 {
+						// If there is just one left, then a plain DeriveUniform
+						// is quicker than the X4 variant.
+						ps[0].DeriveUniform(seed, xs[0], ys[0])
+						return
+					}
+
+					for idx++; idx < 4; idx++ {
+						ps[idx] = nil
+					}
+
+					break
+				}
+			}
+		}
+
+		common.PolyDeriveUniformX4(ps, seed, xs, ys)
+	}
+}
+
+// Transposes A in place.
+func (m *Mat) Transpose() {
+	for i := 0; i < K-1; i++ {
+		for j := i + 1; j < K; j++ {
+			t := m[i][j]
+			m[i][j] = m[j][i]
+			m[j][i] = t
+		}
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/params.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/params.go
new file mode 100644
index 00000000..27cdb1ab
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/params.go
@@ -0,0 +1,21 @@
+// Code generated from params.templ.go. DO NOT EDIT.
+
+package internal
+
+import (
+	"github.com/cloudflare/circl/pke/kyber/internal/common"
+)
+
+const (
+	K             = 3
+	Eta1          = 2
+	DU            = 10
+	DV            = 4
+	PublicKeySize = 32 + K*common.PolySize
+
+	PrivateKeySize = K * common.PolySize
+
+	PlaintextSize  = common.PlaintextSize
+	SeedSize       = 32
+	CiphertextSize = 1088
+)
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/vec.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/vec.go
new file mode 100644
index 00000000..6681895a
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/internal/vec.go
@@ -0,0 +1,125 @@
+// Code generated from kyber512/internal/vec.go by gen.go
+
+package internal
+
+import (
+	"github.com/cloudflare/circl/pke/kyber/internal/common"
+)
+
+// A vector of K polynomials
+type Vec [K]common.Poly
+
+// Samples v[i] from a centered binomial distribution with given η,
+// seed and nonce+i.
+//
+// Essentially CBD_η(PRF(seed, nonce+i)) from the specification.
+func (v *Vec) DeriveNoise(seed []byte, nonce uint8, eta int) {
+	for i := 0; i < K; i++ {
+		v[i].DeriveNoise(seed, nonce+uint8(i), eta)
+	}
+}
+
+// Sets p to the inner product of a and b using "pointwise" multiplication.
+//
+// See MulHat() and NTT() for a description of the multiplication.
+// Assumes a and b are in Montgomery form.  p will be in Montgomery form,
+// and its coefficients will be bounded in absolute value by 2kq.
+// If a and b are not in Montgomery form, then the action is the same
+// as "pointwise" multiplication followed by multiplying by R⁻¹, the inverse
+// of the Montgomery factor.
+func PolyDotHat(p *common.Poly, a, b *Vec) {
+	var t common.Poly
+	*p = common.Poly{} // set p to zero
+	for i := 0; i < K; i++ {
+		t.MulHat(&a[i], &b[i])
+		p.Add(&t, p)
+	}
+}
+
+// Almost normalizes coefficients in-place.
+//
+// Ensures each coefficient is in {0, …, q}.
+func (v *Vec) BarrettReduce() {
+	for i := 0; i < K; i++ {
+		v[i].BarrettReduce()
+	}
+}
+
+// Normalizes coefficients in-place.
+//
+// Ensures each coefficient is in {0, …, q-1}.
+func (v *Vec) Normalize() {
+	for i := 0; i < K; i++ {
+		v[i].Normalize()
+	}
+}
+
+// Applies in-place inverse NTT().  See Poly.InvNTT() for assumptions.
+func (v *Vec) InvNTT() {
+	for i := 0; i < K; i++ {
+		v[i].InvNTT()
+	}
+}
+
+// Applies in-place forward NTT().  See Poly.NTT() for assumptions.
+func (v *Vec) NTT() {
+	for i := 0; i < K; i++ {
+		v[i].NTT()
+	}
+}
+
+// Sets v to a + b.
+func (v *Vec) Add(a, b *Vec) {
+	for i := 0; i < K; i++ {
+		v[i].Add(&a[i], &b[i])
+	}
+}
+
+// Packs v into buf, which must be of length K*PolySize.
+func (v *Vec) Pack(buf []byte) {
+	for i := 0; i < K; i++ {
+		v[i].Pack(buf[common.PolySize*i:])
+	}
+}
+
+// Unpacks v from buf which must be of length K*PolySize.
+func (v *Vec) Unpack(buf []byte) {
+	for i := 0; i < K; i++ {
+		v[i].Unpack(buf[common.PolySize*i:])
+	}
+}
+
+// Writes Compress_q(v, d) to m.
+//
+// Assumes v is normalized and d is in {3, 4, 5, 10, 11}.
+func (v *Vec) CompressTo(m []byte, d int) {
+	size := compressedPolySize(d)
+	for i := 0; i < K; i++ {
+		v[i].CompressTo(m[size*i:], d)
+	}
+}
+
+// Set v to Decompress_q(m, 1).
+//
+// Assumes d is in {3, 4, 5, 10, 11}.  v will be normalized.
+func (v *Vec) Decompress(m []byte, d int) {
+	size := compressedPolySize(d)
+	for i := 0; i < K; i++ {
+		v[i].Decompress(m[size*i:], d)
+	}
+}
+
+// ⌈(256 d)/8⌉
+func compressedPolySize(d int) int {
+	switch d {
+	case 4:
+		return 128
+	case 5:
+		return 160
+	case 10:
+		return 320
+	case 11:
+		return 352
+	}
+	panic("unsupported d")
+}
diff --git a/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/kyber.go b/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/kyber.go
new file mode 100644
index 00000000..4cecbb1b
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pke/kyber/kyber768/kyber.go
@@ -0,0 +1,145 @@
+// Code generated from modePkg.templ.go. DO NOT EDIT.
+
+// kyber768 implements the IND-CPA-secure Public Key Encryption
+// scheme Kyber768.CPAPKE as submitted to round 3 of the NIST PQC competition
+// and described in
+//
+// https://pq-crystals.org/kyber/data/kyber-specification-round3.pdf
+package kyber768
+
+import (
+	cryptoRand "crypto/rand"
+	"io"
+
+	"github.com/cloudflare/circl/pke/kyber/kyber768/internal"
+)
+
+const (
+	// Size of seed for NewKeyFromSeed
+	KeySeedSize = internal.SeedSize
+
+	// Size of seed for EncryptTo
+	EncryptionSeedSize = internal.SeedSize
+
+	// Size of a packed PublicKey
+	PublicKeySize = internal.PublicKeySize
+
+	// Size of a packed PrivateKey
+	PrivateKeySize = internal.PrivateKeySize
+
+	// Size of a ciphertext
+	CiphertextSize = internal.CiphertextSize
+
+	// Size of a plaintext
+	PlaintextSize = internal.PlaintextSize
+)
+
+// PublicKey is the type of Kyber768.CPAPKE public key
+type PublicKey internal.PublicKey
+
+// PrivateKey is the type of Kyber768.CPAPKE private key
+type PrivateKey internal.PrivateKey
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
+	var seed [KeySeedSize]byte
+	if rand == nil {
+		rand = cryptoRand.Reader
+	}
+	_, err := io.ReadFull(rand, seed[:])
+	if err != nil {
+		return nil, nil, err
+	}
+	pk, sk := internal.NewKeyFromSeed(seed[:])
+	return (*PublicKey)(pk), (*PrivateKey)(sk), nil
+}
+
+// NewKeyFromSeed derives a public/private key pair using the given seed.
+//
+// Panics if seed is not of length KeySeedSize.
+func NewKeyFromSeed(seed []byte) (*PublicKey, *PrivateKey) {
+	if len(seed) != KeySeedSize {
+		panic("seed must be of length KeySeedSize")
+	}
+	pk, sk := internal.NewKeyFromSeed(seed)
+	return (*PublicKey)(pk), (*PrivateKey)(sk)
+}
+
+// EncryptTo encrypts message pt for the public key and writes the ciphertext
+// to ct using randomness from seed.
+//
+// This function panics if the lengths of pt, seed, and ct are not
+// PlaintextSize, EncryptionSeedSize, and CiphertextSize respectively.
+func (pk *PublicKey) EncryptTo(ct []byte, pt []byte, seed []byte) {
+	if len(pt) != PlaintextSize {
+		panic("pt must be of length PlaintextSize")
+	}
+	if len(ct) != CiphertextSize {
+		panic("ct must be of length CiphertextSize")
+	}
+	if len(seed) != EncryptionSeedSize {
+		panic("seed must be of length EncryptionSeedSize")
+	}
+	(*internal.PublicKey)(pk).EncryptTo(ct, pt, seed)
+}
+
+// DecryptTo decrypts message ct for the private key and writes the
+// plaintext to pt.
+//
+// This function panics if the lengths of ct and pt are not
+// CiphertextSize and PlaintextSize respectively.
+func (sk *PrivateKey) DecryptTo(pt []byte, ct []byte) {
+	if len(pt) != PlaintextSize {
+		panic("pt must be of length PlaintextSize")
+	}
+	if len(ct) != CiphertextSize {
+		panic("ct must be of length CiphertextSize")
+	}
+	(*internal.PrivateKey)(sk).DecryptTo(pt, ct)
+}
+
+// Packs pk into the given buffer.
+//
+// Panics if buf is not of length PublicKeySize.
+func (pk *PublicKey) Pack(buf []byte) {
+	if len(buf) != PublicKeySize {
+		panic("buf must be of size PublicKeySize")
+	}
+	(*internal.PublicKey)(pk).Pack(buf)
+}
+
+// Packs sk into the given buffer.
+//
+// Panics if buf is not of length PrivateKeySize.
+func (sk *PrivateKey) Pack(buf []byte) {
+	if len(buf) != PrivateKeySize {
+		panic("buf must be of size PrivateKeySize")
+	}
+	(*internal.PrivateKey)(sk).Pack(buf)
+}
+
+// Unpacks pk from the given buffer.
+//
+// Panics if buf is not of length PublicKeySize.
+func (pk *PublicKey) Unpack(buf []byte) {
+	if len(buf) != PublicKeySize {
+		panic("buf must be of size PublicKeySize")
+	}
+	(*internal.PublicKey)(pk).Unpack(buf)
+}
+
+// Unpacks sk from the given buffer.
+//
+// Panics if buf is not of length PrivateKeySize.
+func (sk *PrivateKey) Unpack(buf []byte) {
+	if len(buf) != PrivateKeySize {
+		panic("buf must be of size PrivateKeySize")
+	}
+	(*internal.PrivateKey)(sk).Unpack(buf)
+}
+
+// Returns whether the two private keys are equal.
+func (sk *PrivateKey) Equal(other *PrivateKey) bool {
+	return (*internal.PrivateKey)(sk).Equal((*internal.PrivateKey)(other))
+}
diff --git a/vendor/github.com/cloudflare/circl/pki/pki.go b/vendor/github.com/cloudflare/circl/pki/pki.go
new file mode 100644
index 00000000..a2edebdb
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/pki/pki.go
@@ -0,0 +1,182 @@
+package pki
+
+import (
+	"crypto/x509/pkix"
+	"encoding/asn1"
+	"encoding/pem"
+	"errors"
+	"strings"
+
+	"github.com/cloudflare/circl/sign"
+	"github.com/cloudflare/circl/sign/schemes"
+)
+
+var (
+	allSchemesByOID map[string]sign.Scheme
+	allSchemesByTLS map[uint]sign.Scheme
+)
+
+type pkixPrivKey struct {
+	Version    int
+	Algorithm  pkix.AlgorithmIdentifier
+	PrivateKey []byte
+}
+
+func init() {
+	allSchemesByOID = make(map[string]sign.Scheme)
+	allSchemesByTLS = make(map[uint]sign.Scheme)
+	for _, scheme := range schemes.All() {
+		if cert, ok := scheme.(CertificateScheme); ok {
+			allSchemesByOID[cert.Oid().String()] = scheme
+		}
+		if tlsScheme, ok := scheme.(TLSScheme); ok {
+			allSchemesByTLS[tlsScheme.TLSIdentifier()] = scheme
+		}
+	}
+}
+
+func SchemeByOid(oid asn1.ObjectIdentifier) sign.Scheme { return allSchemesByOID[oid.String()] }
+
+func SchemeByTLSID(id uint) sign.Scheme { return allSchemesByTLS[id] }
+
+// Additional methods when the signature scheme is supported in X509.
+type CertificateScheme interface {
+	// Return the appropriate OIDs for this instance.  It is implicitly
+	// assumed that the encoding is simple: e.g. uses the same OID for
+	// signature and public key like Ed25519.
+	Oid() asn1.ObjectIdentifier
+}
+
+// Additional methods when the signature scheme is supported in TLS.
+type TLSScheme interface {
+	TLSIdentifier() uint
+}
+
+func UnmarshalPEMPublicKey(data []byte) (sign.PublicKey, error) {
+	block, rest := pem.Decode(data)
+	if len(rest) != 0 {
+		return nil, errors.New("trailing data")
+	}
+	if !strings.HasSuffix(block.Type, "PUBLIC KEY") {
+		return nil, errors.New("pem block type is not public key")
+	}
+
+	return UnmarshalPKIXPublicKey(block.Bytes)
+}
+
+func UnmarshalPKIXPublicKey(data []byte) (sign.PublicKey, error) {
+	var pkix struct {
+		Raw       asn1.RawContent
+		Algorithm pkix.AlgorithmIdentifier
+		PublicKey asn1.BitString
+	}
+	if rest, err := asn1.Unmarshal(data, &pkix); err != nil {
+		return nil, err
+	} else if len(rest) != 0 {
+		return nil, errors.New("trailing data")
+	}
+	scheme := SchemeByOid(pkix.Algorithm.Algorithm)
+	if scheme == nil {
+		return nil, errors.New("unsupported public key algorithm")
+	}
+	return scheme.UnmarshalBinaryPublicKey(pkix.PublicKey.RightAlign())
+}
+
+func UnmarshalPEMPrivateKey(data []byte) (sign.PrivateKey, error) {
+	block, rest := pem.Decode(data)
+	if len(rest) != 0 {
+		return nil, errors.New("trailing")
+	}
+	if !strings.HasSuffix(block.Type, "PRIVATE KEY") {
+		return nil, errors.New("pem block type is not private key")
+	}
+
+	return UnmarshalPKIXPrivateKey(block.Bytes)
+}
+
+func UnmarshalPKIXPrivateKey(data []byte) (sign.PrivateKey, error) {
+	var pkix pkixPrivKey
+	if rest, err := asn1.Unmarshal(data, &pkix); err != nil {
+		return nil, err
+	} else if len(rest) != 0 {
+		return nil, errors.New("trailing data")
+	}
+	scheme := SchemeByOid(pkix.Algorithm.Algorithm)
+	if scheme == nil {
+		return nil, errors.New("unsupported public key algorithm")
+	}
+	var sk []byte
+	if rest, err := asn1.Unmarshal(pkix.PrivateKey, &sk); err != nil {
+		return nil, err
+	} else if len(rest) > 0 {
+		return nil, errors.New("trailing data")
+	}
+	return scheme.UnmarshalBinaryPrivateKey(sk)
+}
+
+func MarshalPEMPublicKey(pk sign.PublicKey) ([]byte, error) {
+	data, err := MarshalPKIXPublicKey(pk)
+	if err != nil {
+		return nil, err
+	}
+	str := pem.EncodeToMemory(&pem.Block{
+		Type:  "PUBLIC KEY",
+		Bytes: data,
+	})
+	return str, nil
+}
+
+func MarshalPKIXPublicKey(pk sign.PublicKey) ([]byte, error) {
+	data, err := pk.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+
+	scheme := pk.Scheme()
+	return asn1.Marshal(struct {
+		pkix.AlgorithmIdentifier
+		asn1.BitString
+	}{
+		pkix.AlgorithmIdentifier{
+			Algorithm: scheme.(CertificateScheme).Oid(),
+		},
+		asn1.BitString{
+			Bytes:     data,
+			BitLength: len(data) * 8,
+		},
+	})
+}
+
+func MarshalPEMPrivateKey(sk sign.PrivateKey) ([]byte, error) {
+	data, err := MarshalPKIXPrivateKey(sk)
+	if err != nil {
+		return nil, err
+	}
+	str := pem.EncodeToMemory(&pem.Block{
+		Type:  sk.Scheme().Name() + " PRIVATE KEY",
+		Bytes: data,
+	},
+	)
+	return str, nil
+}
+
+func MarshalPKIXPrivateKey(sk sign.PrivateKey) ([]byte, error) {
+	data, err := sk.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+
+	data, err = asn1.Marshal(data)
+	if err != nil {
+		return nil, err
+	}
+
+	scheme := sk.Scheme()
+	return asn1.Marshal(pkixPrivKey{
+		0,
+		pkix.AlgorithmIdentifier{
+			Algorithm: scheme.(CertificateScheme).Oid(),
+		},
+		data,
+	})
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/aes.go b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/aes.go
new file mode 100644
index 00000000..f5de2542
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/aes.go
@@ -0,0 +1,46 @@
+package common
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"encoding/binary"
+)
+
+// AES CTR stream used as a replacement for SHAKE in Dilithium[1234]-AES.
+type AesStream struct {
+	c       cipher.Block
+	counter uint64
+	nonce   uint16
+}
+
+// Create a new AesStream as a replacement of SHAKE128.  (Note that
+// not all occurrences of SHAKE are replaced by AES in the AES-variants).
+func NewAesStream128(key *[32]byte, nonce uint16) AesStream {
+	c, _ := aes.NewCipher(key[:])
+	return AesStream{c: c, nonce: nonce}
+}
+
+// Create a new AesStream as a replacement of SHAKE256.  (Note that
+// not all occurrences of SHAKE are replaced by AES in the AES-variants.)
+//
+// Yes, in an AES mode, Dilithium throws away the last 32 bytes of a seed ...
+// See the remark at the end of the caption of Figure 4 in the Round 2 spec.
+func NewAesStream256(key *[64]byte, nonce uint16) AesStream {
+	c, _ := aes.NewCipher(key[:32])
+	return AesStream{c: c, nonce: nonce}
+}
+
+// Squeeze some more blocks from the AES CTR stream into buf.
+//
+// Assumes length of buf is a multiple of 16.
+func (s *AesStream) SqueezeInto(buf []byte) {
+	var tmp [16]byte
+	binary.LittleEndian.PutUint16(tmp[:], s.nonce)
+
+	for len(buf) != 0 {
+		binary.BigEndian.PutUint64(tmp[8:], s.counter)
+		s.counter++
+		s.c.Encrypt(buf, tmp[:])
+		buf = buf[16:]
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.go b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.go
new file mode 100644
index 00000000..11f0e3dc
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.go
@@ -0,0 +1,154 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+package common
+
+import (
+	"golang.org/x/sys/cpu"
+)
+
+// Execute an in-place forward NTT on as.
+//
+// Assumes the coefficients are in Montgomery representation and bounded
+// by 2*Q.  The resulting coefficients are again in Montgomery representation,
+// but are only bounded bt 18*Q.
+func (p *Poly) NTT() {
+	if cpu.X86.HasAVX2 {
+		nttAVX2(
+			(*[N]uint32)(p),
+		)
+	} else {
+		p.nttGeneric()
+	}
+}
+
+// Execute an in-place inverse NTT and multiply by Montgomery factor R
+//
+// Assumes the coefficients are in Montgomery representation and bounded
+// by 2*Q.  The resulting coefficients are again in Montgomery representation
+// and bounded by 2*Q.
+func (p *Poly) InvNTT() {
+	if cpu.X86.HasAVX2 {
+		invNttAVX2(
+			(*[N]uint32)(p),
+		)
+	} else {
+		p.invNttGeneric()
+	}
+}
+
+// Sets p to the polynomial whose coefficients are the pointwise multiplication
+// of those of a and b.  The coefficients of p are bounded by 2q.
+//
+// Assumes a and b are in Montgomery form and that the pointwise product
+// of each coefficient is below 2³² q.
+func (p *Poly) MulHat(a, b *Poly) {
+	if cpu.X86.HasAVX2 {
+		mulHatAVX2(
+			(*[N]uint32)(p),
+			(*[N]uint32)(a),
+			(*[N]uint32)(b),
+		)
+	} else {
+		p.mulHatGeneric(a, b)
+	}
+}
+
+// Sets p to a + b.  Does not normalize polynomials.
+func (p *Poly) Add(a, b *Poly) {
+	if cpu.X86.HasAVX2 {
+		addAVX2(
+			(*[N]uint32)(p),
+			(*[N]uint32)(a),
+			(*[N]uint32)(b),
+		)
+	} else {
+		p.addGeneric(a, b)
+	}
+}
+
+// Sets p to a - b.
+//
+// Warning: assumes coefficients of b are less than 2q.
+// Sets p to a + b.  Does not normalize polynomials.
+func (p *Poly) Sub(a, b *Poly) {
+	if cpu.X86.HasAVX2 {
+		subAVX2(
+			(*[N]uint32)(p),
+			(*[N]uint32)(a),
+			(*[N]uint32)(b),
+		)
+	} else {
+		p.subGeneric(a, b)
+	}
+}
+
+// Writes p whose coefficients are in [0, 16) to buf, which must be of
+// length N/2.
+func (p *Poly) PackLe16(buf []byte) {
+	if cpu.X86.HasAVX2 {
+		if len(buf) < PolyLe16Size {
+			panic("buf too small")
+		}
+		packLe16AVX2(
+			(*[N]uint32)(p),
+			&buf[0],
+		)
+	} else {
+		p.packLe16Generic(buf)
+	}
+}
+
+// Reduces each of the coefficients to <2q.
+func (p *Poly) ReduceLe2Q() {
+	if cpu.X86.HasAVX2 {
+		reduceLe2QAVX2((*[N]uint32)(p))
+	} else {
+		p.reduceLe2QGeneric()
+	}
+}
+
+// Reduce each of the coefficients to <q.
+func (p *Poly) Normalize() {
+	if cpu.X86.HasAVX2 {
+		p.ReduceLe2Q()
+		p.NormalizeAssumingLe2Q()
+	} else {
+		p.normalizeGeneric()
+	}
+}
+
+// Normalize the coefficients in this polynomial assuming they are already
+// bounded by 2q.
+func (p *Poly) NormalizeAssumingLe2Q() {
+	if cpu.X86.HasAVX2 {
+		le2qModQAVX2((*[N]uint32)(p))
+	} else {
+		p.normalizeAssumingLe2QGeneric()
+	}
+}
+
+// Checks whether the "supnorm" (see sec 2.1 of the spec) of p is equal
+// or greater than the given bound.
+//
+// Requires the coefficients of p to be normalized.
+func (p *Poly) Exceeds(bound uint32) bool {
+	if cpu.X86.HasAVX2 {
+		return exceedsAVX2((*[N]uint32)(p), bound) == 1
+	}
+	return p.exceedsGeneric(bound)
+}
+
+// Sets p to 2ᵈ q without reducing.
+//
+// So it requires the coefficients of p  to be less than 2³²⁻ᴰ.
+func (p *Poly) MulBy2toD(q *Poly) {
+	if cpu.X86.HasAVX2 {
+		mulBy2toDAVX2(
+			(*[N]uint32)(p),
+			(*[N]uint32)(q),
+		)
+	} else {
+		p.mulBy2toDGeneric(q)
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.s b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.s
new file mode 100644
index 00000000..94180fb7
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/amd64.s
@@ -0,0 +1,8407 @@
+// Code generated by command: go run src.go -out ../amd64.s -stubs ../stubs_amd64.go -pkg common. DO NOT EDIT.
+
+//go:build amd64 && !purego
+
+#include "textflag.h"
+
+// func nttAVX2(p *[256]uint32)
+// Requires: AVX, AVX2
+TEXT ·nttAVX2(SB), $2080-8
+	MOVQ         p+0(FP), AX
+	LEAQ         ·Zetas+0(SB), CX
+	LEAQ         (SP), DX
+	MOVQ         $0xffffffffffffffe0, BX
+	ANDQ         BX, DX
+	MOVL         $0x007fe001, BX
+	VMOVD        BX, X0
+	VPBROADCASTD X0, Y0
+	MOVL         $0x00ffc002, BX
+	VMOVD        BX, X1
+	VPBROADCASTD X1, Y1
+	MOVL         $0xfc7fdfff, BX
+	VMOVD        BX, X2
+	VPBROADCASTD X2, Y2
+	VPMOVZXDQ    (AX), Y7
+	VPMOVZXDQ    128(AX), Y8
+	VPMOVZXDQ    256(AX), Y9
+	VPMOVZXDQ    384(AX), Y10
+	VPMOVZXDQ    512(AX), Y11
+	VPMOVZXDQ    640(AX), Y12
+	VPMOVZXDQ    768(AX), Y13
+	VPMOVZXDQ    896(AX), Y14
+	VPBROADCASTD 4(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 8(CX), Y3
+	VPBROADCASTD 12(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 16(CX), Y3
+	VPBROADCASTD 20(CX), Y4
+	VPBROADCASTD 24(CX), Y5
+	VPBROADCASTD 28(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VMOVDQA      Y7, (DX)
+	VMOVDQA      Y8, 256(DX)
+	VMOVDQA      Y9, 512(DX)
+	VMOVDQA      Y10, 768(DX)
+	VMOVDQA      Y11, 1024(DX)
+	VMOVDQA      Y12, 1280(DX)
+	VMOVDQA      Y13, 1536(DX)
+	VMOVDQA      Y14, 1792(DX)
+	VPMOVZXDQ    16(AX), Y7
+	VPMOVZXDQ    144(AX), Y8
+	VPMOVZXDQ    272(AX), Y9
+	VPMOVZXDQ    400(AX), Y10
+	VPMOVZXDQ    528(AX), Y11
+	VPMOVZXDQ    656(AX), Y12
+	VPMOVZXDQ    784(AX), Y13
+	VPMOVZXDQ    912(AX), Y14
+	VPBROADCASTD 4(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 8(CX), Y3
+	VPBROADCASTD 12(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 16(CX), Y3
+	VPBROADCASTD 20(CX), Y4
+	VPBROADCASTD 24(CX), Y5
+	VPBROADCASTD 28(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VMOVDQA      Y7, 32(DX)
+	VMOVDQA      Y8, 288(DX)
+	VMOVDQA      Y9, 544(DX)
+	VMOVDQA      Y10, 800(DX)
+	VMOVDQA      Y11, 1056(DX)
+	VMOVDQA      Y12, 1312(DX)
+	VMOVDQA      Y13, 1568(DX)
+	VMOVDQA      Y14, 1824(DX)
+	VPMOVZXDQ    32(AX), Y7
+	VPMOVZXDQ    160(AX), Y8
+	VPMOVZXDQ    288(AX), Y9
+	VPMOVZXDQ    416(AX), Y10
+	VPMOVZXDQ    544(AX), Y11
+	VPMOVZXDQ    672(AX), Y12
+	VPMOVZXDQ    800(AX), Y13
+	VPMOVZXDQ    928(AX), Y14
+	VPBROADCASTD 4(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 8(CX), Y3
+	VPBROADCASTD 12(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 16(CX), Y3
+	VPBROADCASTD 20(CX), Y4
+	VPBROADCASTD 24(CX), Y5
+	VPBROADCASTD 28(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VMOVDQA      Y7, 64(DX)
+	VMOVDQA      Y8, 320(DX)
+	VMOVDQA      Y9, 576(DX)
+	VMOVDQA      Y10, 832(DX)
+	VMOVDQA      Y11, 1088(DX)
+	VMOVDQA      Y12, 1344(DX)
+	VMOVDQA      Y13, 1600(DX)
+	VMOVDQA      Y14, 1856(DX)
+	VPMOVZXDQ    48(AX), Y7
+	VPMOVZXDQ    176(AX), Y8
+	VPMOVZXDQ    304(AX), Y9
+	VPMOVZXDQ    432(AX), Y10
+	VPMOVZXDQ    560(AX), Y11
+	VPMOVZXDQ    688(AX), Y12
+	VPMOVZXDQ    816(AX), Y13
+	VPMOVZXDQ    944(AX), Y14
+	VPBROADCASTD 4(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 8(CX), Y3
+	VPBROADCASTD 12(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 16(CX), Y3
+	VPBROADCASTD 20(CX), Y4
+	VPBROADCASTD 24(CX), Y5
+	VPBROADCASTD 28(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VMOVDQA      Y7, 96(DX)
+	VMOVDQA      Y8, 352(DX)
+	VMOVDQA      Y9, 608(DX)
+	VMOVDQA      Y10, 864(DX)
+	VMOVDQA      Y11, 1120(DX)
+	VMOVDQA      Y12, 1376(DX)
+	VMOVDQA      Y13, 1632(DX)
+	VMOVDQA      Y14, 1888(DX)
+	VPMOVZXDQ    64(AX), Y7
+	VPMOVZXDQ    192(AX), Y8
+	VPMOVZXDQ    320(AX), Y9
+	VPMOVZXDQ    448(AX), Y10
+	VPMOVZXDQ    576(AX), Y11
+	VPMOVZXDQ    704(AX), Y12
+	VPMOVZXDQ    832(AX), Y13
+	VPMOVZXDQ    960(AX), Y14
+	VPBROADCASTD 4(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 8(CX), Y3
+	VPBROADCASTD 12(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 16(CX), Y3
+	VPBROADCASTD 20(CX), Y4
+	VPBROADCASTD 24(CX), Y5
+	VPBROADCASTD 28(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VMOVDQA      Y7, 128(DX)
+	VMOVDQA      Y8, 384(DX)
+	VMOVDQA      Y9, 640(DX)
+	VMOVDQA      Y10, 896(DX)
+	VMOVDQA      Y11, 1152(DX)
+	VMOVDQA      Y12, 1408(DX)
+	VMOVDQA      Y13, 1664(DX)
+	VMOVDQA      Y14, 1920(DX)
+	VPMOVZXDQ    80(AX), Y7
+	VPMOVZXDQ    208(AX), Y8
+	VPMOVZXDQ    336(AX), Y9
+	VPMOVZXDQ    464(AX), Y10
+	VPMOVZXDQ    592(AX), Y11
+	VPMOVZXDQ    720(AX), Y12
+	VPMOVZXDQ    848(AX), Y13
+	VPMOVZXDQ    976(AX), Y14
+	VPBROADCASTD 4(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 8(CX), Y3
+	VPBROADCASTD 12(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 16(CX), Y3
+	VPBROADCASTD 20(CX), Y4
+	VPBROADCASTD 24(CX), Y5
+	VPBROADCASTD 28(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VMOVDQA      Y7, 160(DX)
+	VMOVDQA      Y8, 416(DX)
+	VMOVDQA      Y9, 672(DX)
+	VMOVDQA      Y10, 928(DX)
+	VMOVDQA      Y11, 1184(DX)
+	VMOVDQA      Y12, 1440(DX)
+	VMOVDQA      Y13, 1696(DX)
+	VMOVDQA      Y14, 1952(DX)
+	VPMOVZXDQ    96(AX), Y7
+	VPMOVZXDQ    224(AX), Y8
+	VPMOVZXDQ    352(AX), Y9
+	VPMOVZXDQ    480(AX), Y10
+	VPMOVZXDQ    608(AX), Y11
+	VPMOVZXDQ    736(AX), Y12
+	VPMOVZXDQ    864(AX), Y13
+	VPMOVZXDQ    992(AX), Y14
+	VPBROADCASTD 4(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 8(CX), Y3
+	VPBROADCASTD 12(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 16(CX), Y3
+	VPBROADCASTD 20(CX), Y4
+	VPBROADCASTD 24(CX), Y5
+	VPBROADCASTD 28(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VMOVDQA      Y7, 192(DX)
+	VMOVDQA      Y8, 448(DX)
+	VMOVDQA      Y9, 704(DX)
+	VMOVDQA      Y10, 960(DX)
+	VMOVDQA      Y11, 1216(DX)
+	VMOVDQA      Y12, 1472(DX)
+	VMOVDQA      Y13, 1728(DX)
+	VMOVDQA      Y14, 1984(DX)
+	VPMOVZXDQ    112(AX), Y7
+	VPMOVZXDQ    240(AX), Y8
+	VPMOVZXDQ    368(AX), Y9
+	VPMOVZXDQ    496(AX), Y10
+	VPMOVZXDQ    624(AX), Y11
+	VPMOVZXDQ    752(AX), Y12
+	VPMOVZXDQ    880(AX), Y13
+	VPMOVZXDQ    1008(AX), Y14
+	VPBROADCASTD 4(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 8(CX), Y3
+	VPBROADCASTD 12(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 16(CX), Y3
+	VPBROADCASTD 20(CX), Y4
+	VPBROADCASTD 24(CX), Y5
+	VPBROADCASTD 28(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VMOVDQA      Y7, 224(DX)
+	VMOVDQA      Y8, 480(DX)
+	VMOVDQA      Y9, 736(DX)
+	VMOVDQA      Y10, 992(DX)
+	VMOVDQA      Y11, 1248(DX)
+	VMOVDQA      Y12, 1504(DX)
+	VMOVDQA      Y13, 1760(DX)
+	VMOVDQA      Y14, 2016(DX)
+	VMOVDQA      (DX), Y7
+	VMOVDQA      32(DX), Y8
+	VMOVDQA      64(DX), Y9
+	VMOVDQA      96(DX), Y10
+	VMOVDQA      128(DX), Y11
+	VMOVDQA      160(DX), Y12
+	VMOVDQA      192(DX), Y13
+	VMOVDQA      224(DX), Y14
+	VPBROADCASTD 32(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 64(CX), Y3
+	VPBROADCASTD 68(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 128(CX), Y3
+	VPBROADCASTD 132(CX), Y4
+	VPBROADCASTD 136(CX), Y5
+	VPBROADCASTD 140(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 256(CX), Y15
+	VPBROADCASTD 260(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 264(CX), Y15
+	VPBROADCASTD 268(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 272(CX), Y15
+	VPBROADCASTD 276(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 280(CX), Y15
+	VPBROADCASTD 284(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPERM2I128   $0x20, Y8, Y7, Y15
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y15, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y15
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y15, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y15
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y15, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y15
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y15, Y13
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPMOVZXDQ    512(CX), Y3
+	VPMOVZXDQ    528(CX), Y4
+	VPMOVZXDQ    544(CX), Y5
+	VPMOVZXDQ    560(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, (AX)
+	VMOVDQU      Y9, 32(AX)
+	VMOVDQU      Y11, 64(AX)
+	VMOVDQU      Y13, 96(AX)
+	VMOVDQA      256(DX), Y7
+	VMOVDQA      288(DX), Y8
+	VMOVDQA      320(DX), Y9
+	VMOVDQA      352(DX), Y10
+	VMOVDQA      384(DX), Y11
+	VMOVDQA      416(DX), Y12
+	VMOVDQA      448(DX), Y13
+	VMOVDQA      480(DX), Y14
+	VPBROADCASTD 36(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 72(CX), Y3
+	VPBROADCASTD 76(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 144(CX), Y3
+	VPBROADCASTD 148(CX), Y4
+	VPBROADCASTD 152(CX), Y5
+	VPBROADCASTD 156(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 288(CX), Y15
+	VPBROADCASTD 292(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 296(CX), Y15
+	VPBROADCASTD 300(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 304(CX), Y15
+	VPBROADCASTD 308(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 312(CX), Y15
+	VPBROADCASTD 316(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPERM2I128   $0x20, Y8, Y7, Y15
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y15, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y15
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y15, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y15
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y15, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y15
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y15, Y13
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPMOVZXDQ    576(CX), Y3
+	VPMOVZXDQ    592(CX), Y4
+	VPMOVZXDQ    608(CX), Y5
+	VPMOVZXDQ    624(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 128(AX)
+	VMOVDQU      Y9, 160(AX)
+	VMOVDQU      Y11, 192(AX)
+	VMOVDQU      Y13, 224(AX)
+	VMOVDQA      512(DX), Y7
+	VMOVDQA      544(DX), Y8
+	VMOVDQA      576(DX), Y9
+	VMOVDQA      608(DX), Y10
+	VMOVDQA      640(DX), Y11
+	VMOVDQA      672(DX), Y12
+	VMOVDQA      704(DX), Y13
+	VMOVDQA      736(DX), Y14
+	VPBROADCASTD 40(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 80(CX), Y3
+	VPBROADCASTD 84(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 160(CX), Y3
+	VPBROADCASTD 164(CX), Y4
+	VPBROADCASTD 168(CX), Y5
+	VPBROADCASTD 172(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 320(CX), Y15
+	VPBROADCASTD 324(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 328(CX), Y15
+	VPBROADCASTD 332(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 336(CX), Y15
+	VPBROADCASTD 340(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 344(CX), Y15
+	VPBROADCASTD 348(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPERM2I128   $0x20, Y8, Y7, Y15
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y15, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y15
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y15, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y15
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y15, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y15
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y15, Y13
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPMOVZXDQ    640(CX), Y3
+	VPMOVZXDQ    656(CX), Y4
+	VPMOVZXDQ    672(CX), Y5
+	VPMOVZXDQ    688(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 256(AX)
+	VMOVDQU      Y9, 288(AX)
+	VMOVDQU      Y11, 320(AX)
+	VMOVDQU      Y13, 352(AX)
+	VMOVDQA      768(DX), Y7
+	VMOVDQA      800(DX), Y8
+	VMOVDQA      832(DX), Y9
+	VMOVDQA      864(DX), Y10
+	VMOVDQA      896(DX), Y11
+	VMOVDQA      928(DX), Y12
+	VMOVDQA      960(DX), Y13
+	VMOVDQA      992(DX), Y14
+	VPBROADCASTD 44(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 88(CX), Y3
+	VPBROADCASTD 92(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 176(CX), Y3
+	VPBROADCASTD 180(CX), Y4
+	VPBROADCASTD 184(CX), Y5
+	VPBROADCASTD 188(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 352(CX), Y15
+	VPBROADCASTD 356(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 360(CX), Y15
+	VPBROADCASTD 364(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 368(CX), Y15
+	VPBROADCASTD 372(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 376(CX), Y15
+	VPBROADCASTD 380(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPERM2I128   $0x20, Y8, Y7, Y15
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y15, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y15
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y15, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y15
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y15, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y15
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y15, Y13
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPMOVZXDQ    704(CX), Y3
+	VPMOVZXDQ    720(CX), Y4
+	VPMOVZXDQ    736(CX), Y5
+	VPMOVZXDQ    752(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 384(AX)
+	VMOVDQU      Y9, 416(AX)
+	VMOVDQU      Y11, 448(AX)
+	VMOVDQU      Y13, 480(AX)
+	VMOVDQA      1024(DX), Y7
+	VMOVDQA      1056(DX), Y8
+	VMOVDQA      1088(DX), Y9
+	VMOVDQA      1120(DX), Y10
+	VMOVDQA      1152(DX), Y11
+	VMOVDQA      1184(DX), Y12
+	VMOVDQA      1216(DX), Y13
+	VMOVDQA      1248(DX), Y14
+	VPBROADCASTD 48(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 96(CX), Y3
+	VPBROADCASTD 100(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 192(CX), Y3
+	VPBROADCASTD 196(CX), Y4
+	VPBROADCASTD 200(CX), Y5
+	VPBROADCASTD 204(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 384(CX), Y15
+	VPBROADCASTD 388(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 392(CX), Y15
+	VPBROADCASTD 396(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 400(CX), Y15
+	VPBROADCASTD 404(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 408(CX), Y15
+	VPBROADCASTD 412(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPERM2I128   $0x20, Y8, Y7, Y15
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y15, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y15
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y15, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y15
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y15, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y15
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y15, Y13
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPMOVZXDQ    768(CX), Y3
+	VPMOVZXDQ    784(CX), Y4
+	VPMOVZXDQ    800(CX), Y5
+	VPMOVZXDQ    816(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 512(AX)
+	VMOVDQU      Y9, 544(AX)
+	VMOVDQU      Y11, 576(AX)
+	VMOVDQU      Y13, 608(AX)
+	VMOVDQA      1280(DX), Y7
+	VMOVDQA      1312(DX), Y8
+	VMOVDQA      1344(DX), Y9
+	VMOVDQA      1376(DX), Y10
+	VMOVDQA      1408(DX), Y11
+	VMOVDQA      1440(DX), Y12
+	VMOVDQA      1472(DX), Y13
+	VMOVDQA      1504(DX), Y14
+	VPBROADCASTD 52(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 104(CX), Y3
+	VPBROADCASTD 108(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 208(CX), Y3
+	VPBROADCASTD 212(CX), Y4
+	VPBROADCASTD 216(CX), Y5
+	VPBROADCASTD 220(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 416(CX), Y15
+	VPBROADCASTD 420(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 424(CX), Y15
+	VPBROADCASTD 428(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 432(CX), Y15
+	VPBROADCASTD 436(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 440(CX), Y15
+	VPBROADCASTD 444(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPERM2I128   $0x20, Y8, Y7, Y15
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y15, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y15
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y15, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y15
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y15, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y15
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y15, Y13
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPMOVZXDQ    832(CX), Y3
+	VPMOVZXDQ    848(CX), Y4
+	VPMOVZXDQ    864(CX), Y5
+	VPMOVZXDQ    880(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 640(AX)
+	VMOVDQU      Y9, 672(AX)
+	VMOVDQU      Y11, 704(AX)
+	VMOVDQU      Y13, 736(AX)
+	VMOVDQA      1536(DX), Y7
+	VMOVDQA      1568(DX), Y8
+	VMOVDQA      1600(DX), Y9
+	VMOVDQA      1632(DX), Y10
+	VMOVDQA      1664(DX), Y11
+	VMOVDQA      1696(DX), Y12
+	VMOVDQA      1728(DX), Y13
+	VMOVDQA      1760(DX), Y14
+	VPBROADCASTD 56(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 112(CX), Y3
+	VPBROADCASTD 116(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 224(CX), Y3
+	VPBROADCASTD 228(CX), Y4
+	VPBROADCASTD 232(CX), Y5
+	VPBROADCASTD 236(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 448(CX), Y15
+	VPBROADCASTD 452(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 456(CX), Y15
+	VPBROADCASTD 460(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 464(CX), Y15
+	VPBROADCASTD 468(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 472(CX), Y15
+	VPBROADCASTD 476(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPERM2I128   $0x20, Y8, Y7, Y15
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y15, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y15
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y15, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y15
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y15, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y15
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y15, Y13
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPMOVZXDQ    896(CX), Y3
+	VPMOVZXDQ    912(CX), Y4
+	VPMOVZXDQ    928(CX), Y5
+	VPMOVZXDQ    944(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 768(AX)
+	VMOVDQU      Y9, 800(AX)
+	VMOVDQU      Y11, 832(AX)
+	VMOVDQU      Y13, 864(AX)
+	VMOVDQA      1792(DX), Y7
+	VMOVDQA      1824(DX), Y8
+	VMOVDQA      1856(DX), Y9
+	VMOVDQA      1888(DX), Y10
+	VMOVDQA      1920(DX), Y11
+	VMOVDQA      1952(DX), Y12
+	VMOVDQA      1984(DX), Y13
+	VMOVDQA      2016(DX), Y14
+	VPBROADCASTD 60(CX), Y3
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y11
+	VPADDD       Y8, Y1, Y12
+	VPADDD       Y9, Y1, Y13
+	VPADDD       Y10, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y9, Y9
+	VPADDD       Y6, Y10, Y10
+	VPSUBD       Y3, Y11, Y11
+	VPSUBD       Y4, Y12, Y12
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 120(CX), Y3
+	VPBROADCASTD 124(CX), Y4
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y13, Y4, Y13
+	VPMULUDQ     Y14, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y9, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y9
+	VPADDD       Y8, Y1, Y10
+	VPADDD       Y11, Y1, Y13
+	VPADDD       Y12, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y8, Y8
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y12, Y12
+	VPSUBD       Y3, Y9, Y9
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y13, Y13
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 240(CX), Y3
+	VPBROADCASTD 244(CX), Y4
+	VPBROADCASTD 248(CX), Y5
+	VPBROADCASTD 252(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPBROADCASTD 480(CX), Y15
+	VPBROADCASTD 484(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 488(CX), Y15
+	VPBROADCASTD 492(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 496(CX), Y15
+	VPBROADCASTD 500(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 504(CX), Y15
+	VPBROADCASTD 508(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPERM2I128   $0x20, Y8, Y7, Y15
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y15, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y15
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y15, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y15
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y15, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y15
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y15, Y13
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y6, Y6
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y6, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y6, Y14, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPMOVZXDQ    960(CX), Y3
+	VPMOVZXDQ    976(CX), Y4
+	VPMOVZXDQ    992(CX), Y5
+	VPMOVZXDQ    1008(CX), Y6
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y10, Y4, Y10
+	VPMULUDQ     Y12, Y5, Y12
+	VPMULUDQ     Y14, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y10, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y14, Y2
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y2, Y2
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y10, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y2, Y14, Y2
+	VPSRLQ       $0x20, Y3, Y3
+	VPSRLQ       $0x20, Y4, Y4
+	VPSRLQ       $0x20, Y5, Y5
+	VPSRLQ       $0x20, Y2, Y2
+	VPADDD       Y7, Y1, Y8
+	VPADDD       Y9, Y1, Y10
+	VPADDD       Y11, Y1, Y12
+	VPADDD       Y13, Y1, Y14
+	VPADDD       Y3, Y7, Y7
+	VPADDD       Y4, Y9, Y9
+	VPADDD       Y5, Y11, Y11
+	VPADDD       Y2, Y13, Y13
+	VPSUBD       Y3, Y8, Y8
+	VPSUBD       Y4, Y10, Y10
+	VPSUBD       Y5, Y12, Y12
+	VPSUBD       Y2, Y14, Y14
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 896(AX)
+	VMOVDQU      Y9, 928(AX)
+	VMOVDQU      Y11, 960(AX)
+	VMOVDQU      Y13, 992(AX)
+	RET
+
+// func invNttAVX2(p *[256]uint32)
+// Requires: AVX, AVX2
+TEXT ·invNttAVX2(SB), $2080-8
+	MOVQ         p+0(FP), AX
+	LEAQ         ·InvZetas+0(SB), CX
+	LEAQ         (SP), DX
+	MOVQ         $0xffffffffffffffe0, BX
+	ANDQ         BX, DX
+	MOVL         $0x007fe001, BX
+	VMOVD        BX, X0
+	VPBROADCASTD X0, Y0
+	MOVL         $0x7fe00100, BX
+	VMOVD        BX, X1
+	VPBROADCASTD X1, Y1
+	MOVL         $0xfc7fdfff, BX
+	VMOVD        BX, X2
+	VPBROADCASTD X2, Y2
+	VMOVDQU      (AX), Y7
+	VMOVDQU      32(AX), Y9
+	VMOVDQU      64(AX), Y11
+	VMOVDQU      96(AX), Y13
+	VPSRLQ       $0x20, Y7, Y8
+	VPSRLQ       $0x20, Y9, Y10
+	VPSRLQ       $0x20, Y11, Y12
+	VPSRLQ       $0x20, Y13, Y14
+	VPMOVZXDQ    (CX), Y3
+	VPMOVZXDQ    16(CX), Y4
+	VPMOVZXDQ    32(CX), Y5
+	VPMOVZXDQ    48(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 512(CX), Y15
+	VPBROADCASTD 516(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 520(CX), Y15
+	VPBROADCASTD 524(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 528(CX), Y15
+	VPBROADCASTD 532(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 536(CX), Y15
+	VPBROADCASTD 540(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPERM2I128   $0x20, Y8, Y7, Y3
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y3
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y3
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y3
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 768(CX), Y3
+	VPBROADCASTD 772(CX), Y4
+	VPBROADCASTD 776(CX), Y5
+	VPBROADCASTD 780(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 896(CX), Y3
+	VPBROADCASTD 900(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 960(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VMOVDQA      Y7, (DX)
+	VMOVDQA      Y8, 32(DX)
+	VMOVDQA      Y9, 64(DX)
+	VMOVDQA      Y10, 96(DX)
+	VMOVDQA      Y11, 128(DX)
+	VMOVDQA      Y12, 160(DX)
+	VMOVDQA      Y13, 192(DX)
+	VMOVDQA      Y14, 224(DX)
+	VMOVDQU      128(AX), Y7
+	VMOVDQU      160(AX), Y9
+	VMOVDQU      192(AX), Y11
+	VMOVDQU      224(AX), Y13
+	VPSRLQ       $0x20, Y7, Y8
+	VPSRLQ       $0x20, Y9, Y10
+	VPSRLQ       $0x20, Y11, Y12
+	VPSRLQ       $0x20, Y13, Y14
+	VPMOVZXDQ    64(CX), Y3
+	VPMOVZXDQ    80(CX), Y4
+	VPMOVZXDQ    96(CX), Y5
+	VPMOVZXDQ    112(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 544(CX), Y15
+	VPBROADCASTD 548(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 552(CX), Y15
+	VPBROADCASTD 556(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 560(CX), Y15
+	VPBROADCASTD 564(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 568(CX), Y15
+	VPBROADCASTD 572(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPERM2I128   $0x20, Y8, Y7, Y3
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y3
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y3
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y3
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 784(CX), Y3
+	VPBROADCASTD 788(CX), Y4
+	VPBROADCASTD 792(CX), Y5
+	VPBROADCASTD 796(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 904(CX), Y3
+	VPBROADCASTD 908(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 964(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VMOVDQA      Y7, 256(DX)
+	VMOVDQA      Y8, 288(DX)
+	VMOVDQA      Y9, 320(DX)
+	VMOVDQA      Y10, 352(DX)
+	VMOVDQA      Y11, 384(DX)
+	VMOVDQA      Y12, 416(DX)
+	VMOVDQA      Y13, 448(DX)
+	VMOVDQA      Y14, 480(DX)
+	VMOVDQU      256(AX), Y7
+	VMOVDQU      288(AX), Y9
+	VMOVDQU      320(AX), Y11
+	VMOVDQU      352(AX), Y13
+	VPSRLQ       $0x20, Y7, Y8
+	VPSRLQ       $0x20, Y9, Y10
+	VPSRLQ       $0x20, Y11, Y12
+	VPSRLQ       $0x20, Y13, Y14
+	VPMOVZXDQ    128(CX), Y3
+	VPMOVZXDQ    144(CX), Y4
+	VPMOVZXDQ    160(CX), Y5
+	VPMOVZXDQ    176(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 576(CX), Y15
+	VPBROADCASTD 580(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 584(CX), Y15
+	VPBROADCASTD 588(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 592(CX), Y15
+	VPBROADCASTD 596(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 600(CX), Y15
+	VPBROADCASTD 604(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPERM2I128   $0x20, Y8, Y7, Y3
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y3
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y3
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y3
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 800(CX), Y3
+	VPBROADCASTD 804(CX), Y4
+	VPBROADCASTD 808(CX), Y5
+	VPBROADCASTD 812(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 912(CX), Y3
+	VPBROADCASTD 916(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 968(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VMOVDQA      Y7, 512(DX)
+	VMOVDQA      Y8, 544(DX)
+	VMOVDQA      Y9, 576(DX)
+	VMOVDQA      Y10, 608(DX)
+	VMOVDQA      Y11, 640(DX)
+	VMOVDQA      Y12, 672(DX)
+	VMOVDQA      Y13, 704(DX)
+	VMOVDQA      Y14, 736(DX)
+	VMOVDQU      384(AX), Y7
+	VMOVDQU      416(AX), Y9
+	VMOVDQU      448(AX), Y11
+	VMOVDQU      480(AX), Y13
+	VPSRLQ       $0x20, Y7, Y8
+	VPSRLQ       $0x20, Y9, Y10
+	VPSRLQ       $0x20, Y11, Y12
+	VPSRLQ       $0x20, Y13, Y14
+	VPMOVZXDQ    192(CX), Y3
+	VPMOVZXDQ    208(CX), Y4
+	VPMOVZXDQ    224(CX), Y5
+	VPMOVZXDQ    240(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 608(CX), Y15
+	VPBROADCASTD 612(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 616(CX), Y15
+	VPBROADCASTD 620(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 624(CX), Y15
+	VPBROADCASTD 628(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 632(CX), Y15
+	VPBROADCASTD 636(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPERM2I128   $0x20, Y8, Y7, Y3
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y3
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y3
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y3
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 816(CX), Y3
+	VPBROADCASTD 820(CX), Y4
+	VPBROADCASTD 824(CX), Y5
+	VPBROADCASTD 828(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 920(CX), Y3
+	VPBROADCASTD 924(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 972(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VMOVDQA      Y7, 768(DX)
+	VMOVDQA      Y8, 800(DX)
+	VMOVDQA      Y9, 832(DX)
+	VMOVDQA      Y10, 864(DX)
+	VMOVDQA      Y11, 896(DX)
+	VMOVDQA      Y12, 928(DX)
+	VMOVDQA      Y13, 960(DX)
+	VMOVDQA      Y14, 992(DX)
+	VMOVDQU      512(AX), Y7
+	VMOVDQU      544(AX), Y9
+	VMOVDQU      576(AX), Y11
+	VMOVDQU      608(AX), Y13
+	VPSRLQ       $0x20, Y7, Y8
+	VPSRLQ       $0x20, Y9, Y10
+	VPSRLQ       $0x20, Y11, Y12
+	VPSRLQ       $0x20, Y13, Y14
+	VPMOVZXDQ    256(CX), Y3
+	VPMOVZXDQ    272(CX), Y4
+	VPMOVZXDQ    288(CX), Y5
+	VPMOVZXDQ    304(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 640(CX), Y15
+	VPBROADCASTD 644(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 648(CX), Y15
+	VPBROADCASTD 652(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 656(CX), Y15
+	VPBROADCASTD 660(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 664(CX), Y15
+	VPBROADCASTD 668(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPERM2I128   $0x20, Y8, Y7, Y3
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y3
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y3
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y3
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 832(CX), Y3
+	VPBROADCASTD 836(CX), Y4
+	VPBROADCASTD 840(CX), Y5
+	VPBROADCASTD 844(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 928(CX), Y3
+	VPBROADCASTD 932(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 976(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VMOVDQA      Y7, 1024(DX)
+	VMOVDQA      Y8, 1056(DX)
+	VMOVDQA      Y9, 1088(DX)
+	VMOVDQA      Y10, 1120(DX)
+	VMOVDQA      Y11, 1152(DX)
+	VMOVDQA      Y12, 1184(DX)
+	VMOVDQA      Y13, 1216(DX)
+	VMOVDQA      Y14, 1248(DX)
+	VMOVDQU      640(AX), Y7
+	VMOVDQU      672(AX), Y9
+	VMOVDQU      704(AX), Y11
+	VMOVDQU      736(AX), Y13
+	VPSRLQ       $0x20, Y7, Y8
+	VPSRLQ       $0x20, Y9, Y10
+	VPSRLQ       $0x20, Y11, Y12
+	VPSRLQ       $0x20, Y13, Y14
+	VPMOVZXDQ    320(CX), Y3
+	VPMOVZXDQ    336(CX), Y4
+	VPMOVZXDQ    352(CX), Y5
+	VPMOVZXDQ    368(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 672(CX), Y15
+	VPBROADCASTD 676(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 680(CX), Y15
+	VPBROADCASTD 684(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 688(CX), Y15
+	VPBROADCASTD 692(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 696(CX), Y15
+	VPBROADCASTD 700(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPERM2I128   $0x20, Y8, Y7, Y3
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y3
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y3
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y3
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 848(CX), Y3
+	VPBROADCASTD 852(CX), Y4
+	VPBROADCASTD 856(CX), Y5
+	VPBROADCASTD 860(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 936(CX), Y3
+	VPBROADCASTD 940(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 980(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VMOVDQA      Y7, 1280(DX)
+	VMOVDQA      Y8, 1312(DX)
+	VMOVDQA      Y9, 1344(DX)
+	VMOVDQA      Y10, 1376(DX)
+	VMOVDQA      Y11, 1408(DX)
+	VMOVDQA      Y12, 1440(DX)
+	VMOVDQA      Y13, 1472(DX)
+	VMOVDQA      Y14, 1504(DX)
+	VMOVDQU      768(AX), Y7
+	VMOVDQU      800(AX), Y9
+	VMOVDQU      832(AX), Y11
+	VMOVDQU      864(AX), Y13
+	VPSRLQ       $0x20, Y7, Y8
+	VPSRLQ       $0x20, Y9, Y10
+	VPSRLQ       $0x20, Y11, Y12
+	VPSRLQ       $0x20, Y13, Y14
+	VPMOVZXDQ    384(CX), Y3
+	VPMOVZXDQ    400(CX), Y4
+	VPMOVZXDQ    416(CX), Y5
+	VPMOVZXDQ    432(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 704(CX), Y15
+	VPBROADCASTD 708(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 712(CX), Y15
+	VPBROADCASTD 716(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 720(CX), Y15
+	VPBROADCASTD 724(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 728(CX), Y15
+	VPBROADCASTD 732(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPERM2I128   $0x20, Y8, Y7, Y3
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y3
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y3
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y3
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 864(CX), Y3
+	VPBROADCASTD 868(CX), Y4
+	VPBROADCASTD 872(CX), Y5
+	VPBROADCASTD 876(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 944(CX), Y3
+	VPBROADCASTD 948(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 984(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VMOVDQA      Y7, 1536(DX)
+	VMOVDQA      Y8, 1568(DX)
+	VMOVDQA      Y9, 1600(DX)
+	VMOVDQA      Y10, 1632(DX)
+	VMOVDQA      Y11, 1664(DX)
+	VMOVDQA      Y12, 1696(DX)
+	VMOVDQA      Y13, 1728(DX)
+	VMOVDQA      Y14, 1760(DX)
+	VMOVDQU      896(AX), Y7
+	VMOVDQU      928(AX), Y9
+	VMOVDQU      960(AX), Y11
+	VMOVDQU      992(AX), Y13
+	VPSRLQ       $0x20, Y7, Y8
+	VPSRLQ       $0x20, Y9, Y10
+	VPSRLQ       $0x20, Y11, Y12
+	VPSRLQ       $0x20, Y13, Y14
+	VPMOVZXDQ    448(CX), Y3
+	VPMOVZXDQ    464(CX), Y4
+	VPMOVZXDQ    480(CX), Y5
+	VPMOVZXDQ    496(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPUNPCKLQDQ  Y8, Y7, Y3
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y3
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y3
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y3
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 736(CX), Y15
+	VPBROADCASTD 740(CX), Y3
+	VPBLENDD     $0xf0, Y3, Y15, Y3
+	VPBROADCASTD 744(CX), Y15
+	VPBROADCASTD 748(CX), Y4
+	VPBLENDD     $0xf0, Y4, Y15, Y4
+	VPBROADCASTD 752(CX), Y15
+	VPBROADCASTD 756(CX), Y5
+	VPBLENDD     $0xf0, Y5, Y15, Y5
+	VPBROADCASTD 760(CX), Y15
+	VPBROADCASTD 764(CX), Y6
+	VPBLENDD     $0xf0, Y6, Y15, Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPERM2I128   $0x20, Y8, Y7, Y3
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y3, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y3
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y3, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y3
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y3, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y3
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y3, Y13
+	VPBROADCASTD 880(CX), Y3
+	VPBROADCASTD 884(CX), Y4
+	VPBROADCASTD 888(CX), Y5
+	VPBROADCASTD 892(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 952(CX), Y3
+	VPBROADCASTD 956(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 988(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VMOVDQA      Y7, 1792(DX)
+	VMOVDQA      Y8, 1824(DX)
+	VMOVDQA      Y9, 1856(DX)
+	VMOVDQA      Y10, 1888(DX)
+	VMOVDQA      Y11, 1920(DX)
+	VMOVDQA      Y12, 1952(DX)
+	VMOVDQA      Y13, 1984(DX)
+	VMOVDQA      Y14, 2016(DX)
+	VMOVDQA      (DX), Y7
+	VMOVDQA      256(DX), Y8
+	VMOVDQA      512(DX), Y9
+	VMOVDQA      768(DX), Y10
+	VMOVDQA      1024(DX), Y11
+	VMOVDQA      1280(DX), Y12
+	VMOVDQA      1536(DX), Y13
+	VMOVDQA      1792(DX), Y14
+	VPBROADCASTD 992(CX), Y3
+	VPBROADCASTD 996(CX), Y4
+	VPBROADCASTD 1000(CX), Y5
+	VPBROADCASTD 1004(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 1008(CX), Y3
+	VPBROADCASTD 1012(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 1016(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	MOVL         $0x0000a3fa, BX
+	VMOVD        BX, X3
+	VPBROADCASTD X3, Y3
+	VPMULUDQ     Y7, Y3, Y7
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y7, Y3
+	VPMULUDQ     Y2, Y8, Y4
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y7, Y3
+	VPADDQ       Y4, Y8, Y4
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPSRLQ       $0x20, Y3, Y7
+	VPSRLQ       $0x20, Y4, Y8
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y11
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y13
+	VPSRLQ       $0x20, Y6, Y14
+	VMOVDQA      Y7, (DX)
+	VMOVDQA      Y8, 256(DX)
+	VMOVDQA      Y9, 512(DX)
+	VMOVDQA      Y10, 768(DX)
+	VMOVDQA      Y11, 1024(DX)
+	VMOVDQA      Y12, 1280(DX)
+	VMOVDQA      Y13, 1536(DX)
+	VMOVDQA      Y14, 1792(DX)
+	VMOVDQA      32(DX), Y7
+	VMOVDQA      288(DX), Y8
+	VMOVDQA      544(DX), Y9
+	VMOVDQA      800(DX), Y10
+	VMOVDQA      1056(DX), Y11
+	VMOVDQA      1312(DX), Y12
+	VMOVDQA      1568(DX), Y13
+	VMOVDQA      1824(DX), Y14
+	VPBROADCASTD 992(CX), Y3
+	VPBROADCASTD 996(CX), Y4
+	VPBROADCASTD 1000(CX), Y5
+	VPBROADCASTD 1004(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 1008(CX), Y3
+	VPBROADCASTD 1012(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 1016(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	MOVL         $0x0000a3fa, BX
+	VMOVD        BX, X3
+	VPBROADCASTD X3, Y3
+	VPMULUDQ     Y7, Y3, Y7
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y7, Y3
+	VPMULUDQ     Y2, Y8, Y4
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y7, Y3
+	VPADDQ       Y4, Y8, Y4
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPSRLQ       $0x20, Y3, Y7
+	VPSRLQ       $0x20, Y4, Y8
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y11
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y13
+	VPSRLQ       $0x20, Y6, Y14
+	VMOVDQA      Y7, 32(DX)
+	VMOVDQA      Y8, 288(DX)
+	VMOVDQA      Y9, 544(DX)
+	VMOVDQA      Y10, 800(DX)
+	VMOVDQA      Y11, 1056(DX)
+	VMOVDQA      Y12, 1312(DX)
+	VMOVDQA      Y13, 1568(DX)
+	VMOVDQA      Y14, 1824(DX)
+	VMOVDQA      64(DX), Y7
+	VMOVDQA      320(DX), Y8
+	VMOVDQA      576(DX), Y9
+	VMOVDQA      832(DX), Y10
+	VMOVDQA      1088(DX), Y11
+	VMOVDQA      1344(DX), Y12
+	VMOVDQA      1600(DX), Y13
+	VMOVDQA      1856(DX), Y14
+	VPBROADCASTD 992(CX), Y3
+	VPBROADCASTD 996(CX), Y4
+	VPBROADCASTD 1000(CX), Y5
+	VPBROADCASTD 1004(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 1008(CX), Y3
+	VPBROADCASTD 1012(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 1016(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	MOVL         $0x0000a3fa, BX
+	VMOVD        BX, X3
+	VPBROADCASTD X3, Y3
+	VPMULUDQ     Y7, Y3, Y7
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y7, Y3
+	VPMULUDQ     Y2, Y8, Y4
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y7, Y3
+	VPADDQ       Y4, Y8, Y4
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPSRLQ       $0x20, Y3, Y7
+	VPSRLQ       $0x20, Y4, Y8
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y11
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y13
+	VPSRLQ       $0x20, Y6, Y14
+	VMOVDQA      Y7, 64(DX)
+	VMOVDQA      Y8, 320(DX)
+	VMOVDQA      Y9, 576(DX)
+	VMOVDQA      Y10, 832(DX)
+	VMOVDQA      Y11, 1088(DX)
+	VMOVDQA      Y12, 1344(DX)
+	VMOVDQA      Y13, 1600(DX)
+	VMOVDQA      Y14, 1856(DX)
+	VMOVDQA      96(DX), Y7
+	VMOVDQA      352(DX), Y8
+	VMOVDQA      608(DX), Y9
+	VMOVDQA      864(DX), Y10
+	VMOVDQA      1120(DX), Y11
+	VMOVDQA      1376(DX), Y12
+	VMOVDQA      1632(DX), Y13
+	VMOVDQA      1888(DX), Y14
+	VPBROADCASTD 992(CX), Y3
+	VPBROADCASTD 996(CX), Y4
+	VPBROADCASTD 1000(CX), Y5
+	VPBROADCASTD 1004(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 1008(CX), Y3
+	VPBROADCASTD 1012(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 1016(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	MOVL         $0x0000a3fa, BX
+	VMOVD        BX, X3
+	VPBROADCASTD X3, Y3
+	VPMULUDQ     Y7, Y3, Y7
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y7, Y3
+	VPMULUDQ     Y2, Y8, Y4
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y7, Y3
+	VPADDQ       Y4, Y8, Y4
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPSRLQ       $0x20, Y3, Y7
+	VPSRLQ       $0x20, Y4, Y8
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y11
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y13
+	VPSRLQ       $0x20, Y6, Y14
+	VMOVDQA      Y7, 96(DX)
+	VMOVDQA      Y8, 352(DX)
+	VMOVDQA      Y9, 608(DX)
+	VMOVDQA      Y10, 864(DX)
+	VMOVDQA      Y11, 1120(DX)
+	VMOVDQA      Y12, 1376(DX)
+	VMOVDQA      Y13, 1632(DX)
+	VMOVDQA      Y14, 1888(DX)
+	VMOVDQA      128(DX), Y7
+	VMOVDQA      384(DX), Y8
+	VMOVDQA      640(DX), Y9
+	VMOVDQA      896(DX), Y10
+	VMOVDQA      1152(DX), Y11
+	VMOVDQA      1408(DX), Y12
+	VMOVDQA      1664(DX), Y13
+	VMOVDQA      1920(DX), Y14
+	VPBROADCASTD 992(CX), Y3
+	VPBROADCASTD 996(CX), Y4
+	VPBROADCASTD 1000(CX), Y5
+	VPBROADCASTD 1004(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 1008(CX), Y3
+	VPBROADCASTD 1012(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 1016(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	MOVL         $0x0000a3fa, BX
+	VMOVD        BX, X3
+	VPBROADCASTD X3, Y3
+	VPMULUDQ     Y7, Y3, Y7
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y7, Y3
+	VPMULUDQ     Y2, Y8, Y4
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y7, Y3
+	VPADDQ       Y4, Y8, Y4
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPSRLQ       $0x20, Y3, Y7
+	VPSRLQ       $0x20, Y4, Y8
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y11
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y13
+	VPSRLQ       $0x20, Y6, Y14
+	VMOVDQA      Y7, 128(DX)
+	VMOVDQA      Y8, 384(DX)
+	VMOVDQA      Y9, 640(DX)
+	VMOVDQA      Y10, 896(DX)
+	VMOVDQA      Y11, 1152(DX)
+	VMOVDQA      Y12, 1408(DX)
+	VMOVDQA      Y13, 1664(DX)
+	VMOVDQA      Y14, 1920(DX)
+	VMOVDQA      160(DX), Y7
+	VMOVDQA      416(DX), Y8
+	VMOVDQA      672(DX), Y9
+	VMOVDQA      928(DX), Y10
+	VMOVDQA      1184(DX), Y11
+	VMOVDQA      1440(DX), Y12
+	VMOVDQA      1696(DX), Y13
+	VMOVDQA      1952(DX), Y14
+	VPBROADCASTD 992(CX), Y3
+	VPBROADCASTD 996(CX), Y4
+	VPBROADCASTD 1000(CX), Y5
+	VPBROADCASTD 1004(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 1008(CX), Y3
+	VPBROADCASTD 1012(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 1016(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	MOVL         $0x0000a3fa, BX
+	VMOVD        BX, X3
+	VPBROADCASTD X3, Y3
+	VPMULUDQ     Y7, Y3, Y7
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y7, Y3
+	VPMULUDQ     Y2, Y8, Y4
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y7, Y3
+	VPADDQ       Y4, Y8, Y4
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPSRLQ       $0x20, Y3, Y7
+	VPSRLQ       $0x20, Y4, Y8
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y11
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y13
+	VPSRLQ       $0x20, Y6, Y14
+	VMOVDQA      Y7, 160(DX)
+	VMOVDQA      Y8, 416(DX)
+	VMOVDQA      Y9, 672(DX)
+	VMOVDQA      Y10, 928(DX)
+	VMOVDQA      Y11, 1184(DX)
+	VMOVDQA      Y12, 1440(DX)
+	VMOVDQA      Y13, 1696(DX)
+	VMOVDQA      Y14, 1952(DX)
+	VMOVDQA      192(DX), Y7
+	VMOVDQA      448(DX), Y8
+	VMOVDQA      704(DX), Y9
+	VMOVDQA      960(DX), Y10
+	VMOVDQA      1216(DX), Y11
+	VMOVDQA      1472(DX), Y12
+	VMOVDQA      1728(DX), Y13
+	VMOVDQA      1984(DX), Y14
+	VPBROADCASTD 992(CX), Y3
+	VPBROADCASTD 996(CX), Y4
+	VPBROADCASTD 1000(CX), Y5
+	VPBROADCASTD 1004(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 1008(CX), Y3
+	VPBROADCASTD 1012(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 1016(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y15, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	MOVL         $0x0000a3fa, BX
+	VMOVD        BX, X3
+	VPBROADCASTD X3, Y3
+	VPMULUDQ     Y7, Y3, Y7
+	VPMULUDQ     Y8, Y3, Y8
+	VPMULUDQ     Y9, Y3, Y9
+	VPMULUDQ     Y10, Y3, Y10
+	VPMULUDQ     Y11, Y3, Y11
+	VPMULUDQ     Y12, Y3, Y12
+	VPMULUDQ     Y13, Y3, Y13
+	VPMULUDQ     Y14, Y3, Y14
+	VPMULUDQ     Y2, Y7, Y3
+	VPMULUDQ     Y2, Y8, Y4
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y7, Y3
+	VPADDQ       Y4, Y8, Y4
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPSRLQ       $0x20, Y3, Y7
+	VPSRLQ       $0x20, Y4, Y8
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPMULUDQ     Y2, Y11, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y13, Y5
+	VPMULUDQ     Y2, Y14, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPADDQ       Y3, Y11, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y13, Y5
+	VPADDQ       Y6, Y14, Y6
+	VPSRLQ       $0x20, Y3, Y11
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y13
+	VPSRLQ       $0x20, Y6, Y14
+	VMOVDQA      Y7, 192(DX)
+	VMOVDQA      Y8, 448(DX)
+	VMOVDQA      Y9, 704(DX)
+	VMOVDQA      Y10, 960(DX)
+	VMOVDQA      Y11, 1216(DX)
+	VMOVDQA      Y12, 1472(DX)
+	VMOVDQA      Y13, 1728(DX)
+	VMOVDQA      Y14, 1984(DX)
+	VMOVDQA      224(DX), Y7
+	VMOVDQA      480(DX), Y8
+	VMOVDQA      736(DX), Y9
+	VMOVDQA      992(DX), Y10
+	VMOVDQA      1248(DX), Y11
+	VMOVDQA      1504(DX), Y12
+	VMOVDQA      1760(DX), Y13
+	VMOVDQA      2016(DX), Y14
+	VPBROADCASTD 992(CX), Y3
+	VPBROADCASTD 996(CX), Y4
+	VPBROADCASTD 1000(CX), Y5
+	VPBROADCASTD 1004(CX), Y6
+	VPADDD       Y7, Y1, Y15
+	VPSUBD       Y8, Y15, Y15
+	VPADDD       Y7, Y8, Y7
+	VPMULUDQ     Y15, Y3, Y8
+	VPADDD       Y9, Y1, Y3
+	VPSUBD       Y10, Y3, Y3
+	VPADDD       Y9, Y10, Y9
+	VPMULUDQ     Y3, Y4, Y10
+	VPADDD       Y11, Y1, Y4
+	VPSUBD       Y12, Y4, Y4
+	VPADDD       Y11, Y12, Y11
+	VPMULUDQ     Y4, Y5, Y12
+	VPADDD       Y13, Y1, Y5
+	VPSUBD       Y14, Y5, Y5
+	VPADDD       Y13, Y14, Y13
+	VPMULUDQ     Y5, Y6, Y14
+	VPMULUDQ     Y2, Y8, Y15
+	VPMULUDQ     Y2, Y10, Y3
+	VPMULUDQ     Y2, Y12, Y4
+	VPMULUDQ     Y2, Y14, Y5
+	VPMULUDQ     Y0, Y15, Y15
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y15, Y8, Y15
+	VPADDQ       Y3, Y10, Y3
+	VPADDQ       Y4, Y12, Y4
+	VPADDQ       Y5, Y14, Y5
+	VPSRLQ       $0x20, Y15, Y8
+	VPSRLQ       $0x20, Y3, Y10
+	VPSRLQ       $0x20, Y4, Y12
+	VPSRLQ       $0x20, Y5, Y14
+	VPBROADCASTD 1008(CX), Y3
+	VPBROADCASTD 1012(CX), Y4
+	VPADDD       Y7, Y1, Y5
+	VPSUBD       Y9, Y5, Y5
+	VPADDD       Y7, Y9, Y7
+	VPMULUDQ     Y5, Y3, Y9
+	VPADDD       Y8, Y1, Y6
+	VPSUBD       Y10, Y6, Y6
+	VPADDD       Y8, Y10, Y8
+	VPMULUDQ     Y6, Y3, Y10
+	VPADDD       Y11, Y1, Y3
+	VPSUBD       Y13, Y3, Y3
+	VPADDD       Y11, Y13, Y11
+	VPMULUDQ     Y3, Y4, Y13
+	VPADDD       Y12, Y1, Y15
+	VPSUBD       Y14, Y15, Y15
+	VPADDD       Y12, Y14, Y12
+	VPMULUDQ     Y15, Y4, Y14
+	VPMULUDQ     Y2, Y9, Y5
+	VPMULUDQ     Y2, Y10, Y6
+	VPMULUDQ     Y2, Y13, Y3
+	VPMULUDQ     Y2, Y14, Y15
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y15, Y15
+	VPADDQ       Y5, Y9, Y5
+	VPADDQ       Y6, Y10, Y6
+	VPADDQ       Y3, Y13, Y3
+	VPADDQ       Y15, Y14, Y15
+	VPSRLQ       $0x20, Y5, Y9
+	VPSRLQ       $0x20, Y6, Y10
+	VPSRLQ       $0x20, Y3, Y13
+	VPSRLQ       $0x20, Y15, Y14
+	VPBROADCASTD 1016(CX), Y3
+	VPADDD       Y7, Y1, Y4
+	VPSUBD       Y11, Y4, Y4
+	VPADDD       Y7, Y11, Y7
+	VPMULUDQ     Y4, Y3, Y11
+	VPADDD       Y8, Y1, Y5
+	VPSUBD       Y12, Y5, Y5
+	VPADDD       Y8, Y12, Y8
+	VPMULUDQ     Y5, Y3, Y12
+	VPADDD       Y9, Y1, Y6
+	VPSUBD       Y13, Y6, Y6
+	VPADDD       Y9, Y13, Y9
+	VPMULUDQ     Y6, Y3, Y13
+	VPADDD       Y10, Y1, Y1
+	VPSUBD       Y14, Y1, Y1
+	VPADDD       Y10, Y14, Y10
+	VPMULUDQ     Y1, Y3, Y14
+	VPMULUDQ     Y2, Y11, Y4
+	VPMULUDQ     Y2, Y12, Y5
+	VPMULUDQ     Y2, Y13, Y6
+	VPMULUDQ     Y2, Y14, Y1
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y1, Y1
+	VPADDQ       Y4, Y11, Y4
+	VPADDQ       Y5, Y12, Y5
+	VPADDQ       Y6, Y13, Y6
+	VPADDQ       Y1, Y14, Y1
+	VPSRLQ       $0x20, Y4, Y11
+	VPSRLQ       $0x20, Y5, Y12
+	VPSRLQ       $0x20, Y6, Y13
+	VPSRLQ       $0x20, Y1, Y14
+	MOVL         $0x0000a3fa, CX
+	VMOVD        CX, X1
+	VPBROADCASTD X1, Y1
+	VPMULUDQ     Y7, Y1, Y7
+	VPMULUDQ     Y8, Y1, Y8
+	VPMULUDQ     Y9, Y1, Y9
+	VPMULUDQ     Y10, Y1, Y10
+	VPMULUDQ     Y11, Y1, Y11
+	VPMULUDQ     Y12, Y1, Y12
+	VPMULUDQ     Y13, Y1, Y13
+	VPMULUDQ     Y14, Y1, Y14
+	VPMULUDQ     Y2, Y7, Y1
+	VPMULUDQ     Y2, Y8, Y3
+	VPMULUDQ     Y2, Y9, Y4
+	VPMULUDQ     Y2, Y10, Y5
+	VPMULUDQ     Y0, Y1, Y1
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y5, Y5
+	VPADDQ       Y1, Y7, Y1
+	VPADDQ       Y3, Y8, Y3
+	VPADDQ       Y4, Y9, Y4
+	VPADDQ       Y5, Y10, Y5
+	VPSRLQ       $0x20, Y1, Y7
+	VPSRLQ       $0x20, Y3, Y8
+	VPSRLQ       $0x20, Y4, Y9
+	VPSRLQ       $0x20, Y5, Y10
+	VPMULUDQ     Y2, Y11, Y1
+	VPMULUDQ     Y2, Y12, Y3
+	VPMULUDQ     Y2, Y13, Y4
+	VPMULUDQ     Y2, Y14, Y2
+	VPMULUDQ     Y0, Y1, Y1
+	VPMULUDQ     Y0, Y3, Y3
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y2, Y2
+	VPADDQ       Y1, Y11, Y1
+	VPADDQ       Y3, Y12, Y3
+	VPADDQ       Y4, Y13, Y4
+	VPADDQ       Y2, Y14, Y2
+	VPSRLQ       $0x20, Y1, Y11
+	VPSRLQ       $0x20, Y3, Y12
+	VPSRLQ       $0x20, Y4, Y13
+	VPSRLQ       $0x20, Y2, Y14
+	VMOVDQA      Y7, 224(DX)
+	VMOVDQA      Y8, 480(DX)
+	VMOVDQA      Y9, 736(DX)
+	VMOVDQA      Y10, 992(DX)
+	VMOVDQA      Y11, 1248(DX)
+	VMOVDQA      Y12, 1504(DX)
+	VMOVDQA      Y13, 1760(DX)
+	VMOVDQA      Y14, 2016(DX)
+	VMOVDQA      (DX), Y7
+	VMOVDQA      32(DX), Y8
+	VMOVDQA      64(DX), Y9
+	VMOVDQA      96(DX), Y10
+	VMOVDQA      128(DX), Y11
+	VMOVDQA      160(DX), Y12
+	VMOVDQA      192(DX), Y13
+	VMOVDQA      224(DX), Y14
+	VPERM2I128   $0x20, Y8, Y7, Y0
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y0
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y0
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y0
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPUNPCKLQDQ  Y8, Y7, Y0
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y0
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y0
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y0
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, (AX)
+	VMOVDQU      Y9, 32(AX)
+	VMOVDQU      Y11, 64(AX)
+	VMOVDQU      Y13, 96(AX)
+	VMOVDQA      256(DX), Y7
+	VMOVDQA      288(DX), Y8
+	VMOVDQA      320(DX), Y9
+	VMOVDQA      352(DX), Y10
+	VMOVDQA      384(DX), Y11
+	VMOVDQA      416(DX), Y12
+	VMOVDQA      448(DX), Y13
+	VMOVDQA      480(DX), Y14
+	VPERM2I128   $0x20, Y8, Y7, Y0
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y0
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y0
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y0
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPUNPCKLQDQ  Y8, Y7, Y0
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y0
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y0
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y0
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 128(AX)
+	VMOVDQU      Y9, 160(AX)
+	VMOVDQU      Y11, 192(AX)
+	VMOVDQU      Y13, 224(AX)
+	VMOVDQA      512(DX), Y7
+	VMOVDQA      544(DX), Y8
+	VMOVDQA      576(DX), Y9
+	VMOVDQA      608(DX), Y10
+	VMOVDQA      640(DX), Y11
+	VMOVDQA      672(DX), Y12
+	VMOVDQA      704(DX), Y13
+	VMOVDQA      736(DX), Y14
+	VPERM2I128   $0x20, Y8, Y7, Y0
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y0
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y0
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y0
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPUNPCKLQDQ  Y8, Y7, Y0
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y0
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y0
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y0
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 256(AX)
+	VMOVDQU      Y9, 288(AX)
+	VMOVDQU      Y11, 320(AX)
+	VMOVDQU      Y13, 352(AX)
+	VMOVDQA      768(DX), Y7
+	VMOVDQA      800(DX), Y8
+	VMOVDQA      832(DX), Y9
+	VMOVDQA      864(DX), Y10
+	VMOVDQA      896(DX), Y11
+	VMOVDQA      928(DX), Y12
+	VMOVDQA      960(DX), Y13
+	VMOVDQA      992(DX), Y14
+	VPERM2I128   $0x20, Y8, Y7, Y0
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y0
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y0
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y0
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPUNPCKLQDQ  Y8, Y7, Y0
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y0
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y0
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y0
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 384(AX)
+	VMOVDQU      Y9, 416(AX)
+	VMOVDQU      Y11, 448(AX)
+	VMOVDQU      Y13, 480(AX)
+	VMOVDQA      1024(DX), Y7
+	VMOVDQA      1056(DX), Y8
+	VMOVDQA      1088(DX), Y9
+	VMOVDQA      1120(DX), Y10
+	VMOVDQA      1152(DX), Y11
+	VMOVDQA      1184(DX), Y12
+	VMOVDQA      1216(DX), Y13
+	VMOVDQA      1248(DX), Y14
+	VPERM2I128   $0x20, Y8, Y7, Y0
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y0
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y0
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y0
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPUNPCKLQDQ  Y8, Y7, Y0
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y0
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y0
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y0
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 512(AX)
+	VMOVDQU      Y9, 544(AX)
+	VMOVDQU      Y11, 576(AX)
+	VMOVDQU      Y13, 608(AX)
+	VMOVDQA      1280(DX), Y7
+	VMOVDQA      1312(DX), Y8
+	VMOVDQA      1344(DX), Y9
+	VMOVDQA      1376(DX), Y10
+	VMOVDQA      1408(DX), Y11
+	VMOVDQA      1440(DX), Y12
+	VMOVDQA      1472(DX), Y13
+	VMOVDQA      1504(DX), Y14
+	VPERM2I128   $0x20, Y8, Y7, Y0
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y0
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y0
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y0
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPUNPCKLQDQ  Y8, Y7, Y0
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y0
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y0
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y0
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 640(AX)
+	VMOVDQU      Y9, 672(AX)
+	VMOVDQU      Y11, 704(AX)
+	VMOVDQU      Y13, 736(AX)
+	VMOVDQA      1536(DX), Y7
+	VMOVDQA      1568(DX), Y8
+	VMOVDQA      1600(DX), Y9
+	VMOVDQA      1632(DX), Y10
+	VMOVDQA      1664(DX), Y11
+	VMOVDQA      1696(DX), Y12
+	VMOVDQA      1728(DX), Y13
+	VMOVDQA      1760(DX), Y14
+	VPERM2I128   $0x20, Y8, Y7, Y0
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y0
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y0
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y0
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPUNPCKLQDQ  Y8, Y7, Y0
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y0
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y0
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y0
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 768(AX)
+	VMOVDQU      Y9, 800(AX)
+	VMOVDQU      Y11, 832(AX)
+	VMOVDQU      Y13, 864(AX)
+	VMOVDQA      1792(DX), Y7
+	VMOVDQA      1824(DX), Y8
+	VMOVDQA      1856(DX), Y9
+	VMOVDQA      1888(DX), Y10
+	VMOVDQA      1920(DX), Y11
+	VMOVDQA      1952(DX), Y12
+	VMOVDQA      1984(DX), Y13
+	VMOVDQA      2016(DX), Y14
+	VPERM2I128   $0x20, Y8, Y7, Y0
+	VPERM2I128   $0x31, Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPERM2I128   $0x20, Y10, Y9, Y0
+	VPERM2I128   $0x31, Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPERM2I128   $0x20, Y12, Y11, Y0
+	VPERM2I128   $0x31, Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPERM2I128   $0x20, Y14, Y13, Y0
+	VPERM2I128   $0x31, Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPUNPCKLQDQ  Y8, Y7, Y0
+	VPUNPCKHQDQ  Y8, Y7, Y8
+	VMOVDQA      Y0, Y7
+	VPUNPCKLQDQ  Y10, Y9, Y0
+	VPUNPCKHQDQ  Y10, Y9, Y10
+	VMOVDQA      Y0, Y9
+	VPUNPCKLQDQ  Y12, Y11, Y0
+	VPUNPCKHQDQ  Y12, Y11, Y12
+	VMOVDQA      Y0, Y11
+	VPUNPCKLQDQ  Y14, Y13, Y0
+	VPUNPCKHQDQ  Y14, Y13, Y14
+	VMOVDQA      Y0, Y13
+	VPSLLQ       $0x20, Y8, Y8
+	VPSLLQ       $0x20, Y10, Y10
+	VPSLLQ       $0x20, Y12, Y12
+	VPSLLQ       $0x20, Y14, Y14
+	VPBLENDD     $0xaa, Y8, Y7, Y7
+	VPBLENDD     $0xaa, Y10, Y9, Y9
+	VPBLENDD     $0xaa, Y12, Y11, Y11
+	VPBLENDD     $0xaa, Y14, Y13, Y13
+	VMOVDQU      Y7, 896(AX)
+	VMOVDQU      Y9, 928(AX)
+	VMOVDQU      Y11, 960(AX)
+	VMOVDQU      Y13, 992(AX)
+	RET
+
+// func mulHatAVX2(p *[256]uint32, a *[256]uint32, b *[256]uint32)
+// Requires: AVX, AVX2
+TEXT ·mulHatAVX2(SB), NOSPLIT, $0-24
+	MOVQ         p+0(FP), AX
+	MOVQ         a+8(FP), CX
+	MOVQ         b+16(FP), DX
+	MOVL         $0x007fe001, BX
+	VMOVD        BX, X0
+	VPBROADCASTD X0, Y0
+	MOVL         $0xfc7fdfff, BX
+	VMOVD        BX, X1
+	VPBROADCASTD X1, Y1
+	VPMOVZXDQ    (CX), Y2
+	VPMOVZXDQ    16(CX), Y4
+	VPMOVZXDQ    32(CX), Y6
+	VPMOVZXDQ    48(CX), Y8
+	VPMOVZXDQ    (DX), Y3
+	VPMOVZXDQ    16(DX), Y5
+	VPMOVZXDQ    32(DX), Y7
+	VPMOVZXDQ    48(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, (AX)
+	VMOVDQU      Y7, 32(AX)
+	VPMOVZXDQ    64(CX), Y2
+	VPMOVZXDQ    80(CX), Y4
+	VPMOVZXDQ    96(CX), Y6
+	VPMOVZXDQ    112(CX), Y8
+	VPMOVZXDQ    64(DX), Y3
+	VPMOVZXDQ    80(DX), Y5
+	VPMOVZXDQ    96(DX), Y7
+	VPMOVZXDQ    112(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 64(AX)
+	VMOVDQU      Y7, 96(AX)
+	VPMOVZXDQ    128(CX), Y2
+	VPMOVZXDQ    144(CX), Y4
+	VPMOVZXDQ    160(CX), Y6
+	VPMOVZXDQ    176(CX), Y8
+	VPMOVZXDQ    128(DX), Y3
+	VPMOVZXDQ    144(DX), Y5
+	VPMOVZXDQ    160(DX), Y7
+	VPMOVZXDQ    176(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 128(AX)
+	VMOVDQU      Y7, 160(AX)
+	VPMOVZXDQ    192(CX), Y2
+	VPMOVZXDQ    208(CX), Y4
+	VPMOVZXDQ    224(CX), Y6
+	VPMOVZXDQ    240(CX), Y8
+	VPMOVZXDQ    192(DX), Y3
+	VPMOVZXDQ    208(DX), Y5
+	VPMOVZXDQ    224(DX), Y7
+	VPMOVZXDQ    240(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 192(AX)
+	VMOVDQU      Y7, 224(AX)
+	VPMOVZXDQ    256(CX), Y2
+	VPMOVZXDQ    272(CX), Y4
+	VPMOVZXDQ    288(CX), Y6
+	VPMOVZXDQ    304(CX), Y8
+	VPMOVZXDQ    256(DX), Y3
+	VPMOVZXDQ    272(DX), Y5
+	VPMOVZXDQ    288(DX), Y7
+	VPMOVZXDQ    304(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 256(AX)
+	VMOVDQU      Y7, 288(AX)
+	VPMOVZXDQ    320(CX), Y2
+	VPMOVZXDQ    336(CX), Y4
+	VPMOVZXDQ    352(CX), Y6
+	VPMOVZXDQ    368(CX), Y8
+	VPMOVZXDQ    320(DX), Y3
+	VPMOVZXDQ    336(DX), Y5
+	VPMOVZXDQ    352(DX), Y7
+	VPMOVZXDQ    368(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 320(AX)
+	VMOVDQU      Y7, 352(AX)
+	VPMOVZXDQ    384(CX), Y2
+	VPMOVZXDQ    400(CX), Y4
+	VPMOVZXDQ    416(CX), Y6
+	VPMOVZXDQ    432(CX), Y8
+	VPMOVZXDQ    384(DX), Y3
+	VPMOVZXDQ    400(DX), Y5
+	VPMOVZXDQ    416(DX), Y7
+	VPMOVZXDQ    432(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 384(AX)
+	VMOVDQU      Y7, 416(AX)
+	VPMOVZXDQ    448(CX), Y2
+	VPMOVZXDQ    464(CX), Y4
+	VPMOVZXDQ    480(CX), Y6
+	VPMOVZXDQ    496(CX), Y8
+	VPMOVZXDQ    448(DX), Y3
+	VPMOVZXDQ    464(DX), Y5
+	VPMOVZXDQ    480(DX), Y7
+	VPMOVZXDQ    496(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 448(AX)
+	VMOVDQU      Y7, 480(AX)
+	VPMOVZXDQ    512(CX), Y2
+	VPMOVZXDQ    528(CX), Y4
+	VPMOVZXDQ    544(CX), Y6
+	VPMOVZXDQ    560(CX), Y8
+	VPMOVZXDQ    512(DX), Y3
+	VPMOVZXDQ    528(DX), Y5
+	VPMOVZXDQ    544(DX), Y7
+	VPMOVZXDQ    560(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 512(AX)
+	VMOVDQU      Y7, 544(AX)
+	VPMOVZXDQ    576(CX), Y2
+	VPMOVZXDQ    592(CX), Y4
+	VPMOVZXDQ    608(CX), Y6
+	VPMOVZXDQ    624(CX), Y8
+	VPMOVZXDQ    576(DX), Y3
+	VPMOVZXDQ    592(DX), Y5
+	VPMOVZXDQ    608(DX), Y7
+	VPMOVZXDQ    624(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 576(AX)
+	VMOVDQU      Y7, 608(AX)
+	VPMOVZXDQ    640(CX), Y2
+	VPMOVZXDQ    656(CX), Y4
+	VPMOVZXDQ    672(CX), Y6
+	VPMOVZXDQ    688(CX), Y8
+	VPMOVZXDQ    640(DX), Y3
+	VPMOVZXDQ    656(DX), Y5
+	VPMOVZXDQ    672(DX), Y7
+	VPMOVZXDQ    688(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 640(AX)
+	VMOVDQU      Y7, 672(AX)
+	VPMOVZXDQ    704(CX), Y2
+	VPMOVZXDQ    720(CX), Y4
+	VPMOVZXDQ    736(CX), Y6
+	VPMOVZXDQ    752(CX), Y8
+	VPMOVZXDQ    704(DX), Y3
+	VPMOVZXDQ    720(DX), Y5
+	VPMOVZXDQ    736(DX), Y7
+	VPMOVZXDQ    752(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 704(AX)
+	VMOVDQU      Y7, 736(AX)
+	VPMOVZXDQ    768(CX), Y2
+	VPMOVZXDQ    784(CX), Y4
+	VPMOVZXDQ    800(CX), Y6
+	VPMOVZXDQ    816(CX), Y8
+	VPMOVZXDQ    768(DX), Y3
+	VPMOVZXDQ    784(DX), Y5
+	VPMOVZXDQ    800(DX), Y7
+	VPMOVZXDQ    816(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 768(AX)
+	VMOVDQU      Y7, 800(AX)
+	VPMOVZXDQ    832(CX), Y2
+	VPMOVZXDQ    848(CX), Y4
+	VPMOVZXDQ    864(CX), Y6
+	VPMOVZXDQ    880(CX), Y8
+	VPMOVZXDQ    832(DX), Y3
+	VPMOVZXDQ    848(DX), Y5
+	VPMOVZXDQ    864(DX), Y7
+	VPMOVZXDQ    880(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 832(AX)
+	VMOVDQU      Y7, 864(AX)
+	VPMOVZXDQ    896(CX), Y2
+	VPMOVZXDQ    912(CX), Y4
+	VPMOVZXDQ    928(CX), Y6
+	VPMOVZXDQ    944(CX), Y8
+	VPMOVZXDQ    896(DX), Y3
+	VPMOVZXDQ    912(DX), Y5
+	VPMOVZXDQ    928(DX), Y7
+	VPMOVZXDQ    944(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y2
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y2
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y2
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y2, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y2
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y2, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 896(AX)
+	VMOVDQU      Y7, 928(AX)
+	VPMOVZXDQ    960(CX), Y2
+	VPMOVZXDQ    976(CX), Y4
+	VPMOVZXDQ    992(CX), Y6
+	VPMOVZXDQ    1008(CX), Y8
+	VPMOVZXDQ    960(DX), Y3
+	VPMOVZXDQ    976(DX), Y5
+	VPMOVZXDQ    992(DX), Y7
+	VPMOVZXDQ    1008(DX), Y9
+	VPMULUDQ     Y2, Y3, Y3
+	VPMULUDQ     Y4, Y5, Y5
+	VPMULUDQ     Y6, Y7, Y7
+	VPMULUDQ     Y8, Y9, Y9
+	VPMULUDQ     Y1, Y3, Y2
+	VPMULUDQ     Y1, Y5, Y4
+	VPMULUDQ     Y1, Y7, Y6
+	VPMULUDQ     Y1, Y9, Y8
+	VPMULUDQ     Y0, Y2, Y2
+	VPMULUDQ     Y0, Y4, Y4
+	VPMULUDQ     Y0, Y6, Y6
+	VPMULUDQ     Y0, Y8, Y8
+	VPADDQ       Y2, Y3, Y2
+	VPADDQ       Y4, Y5, Y4
+	VPADDQ       Y6, Y7, Y6
+	VPADDQ       Y8, Y9, Y8
+	VPSRLQ       $0x20, Y2, Y3
+	VPSRLQ       $0x20, Y4, Y5
+	VPSRLQ       $0x20, Y6, Y7
+	VPSRLQ       $0x20, Y8, Y9
+	VPERM2I128   $0x20, Y5, Y3, Y0
+	VPERM2I128   $0x31, Y5, Y3, Y5
+	VMOVDQA      Y0, Y3
+	VPERM2I128   $0x20, Y9, Y7, Y0
+	VPERM2I128   $0x31, Y9, Y7, Y9
+	VMOVDQA      Y0, Y7
+	VPUNPCKLQDQ  Y5, Y3, Y0
+	VPUNPCKHQDQ  Y5, Y3, Y5
+	VMOVDQA      Y0, Y3
+	VPUNPCKLQDQ  Y9, Y7, Y0
+	VPUNPCKHQDQ  Y9, Y7, Y9
+	VMOVDQA      Y0, Y7
+	VPSLLQ       $0x20, Y5, Y5
+	VPSLLQ       $0x20, Y9, Y9
+	VPBLENDD     $0xaa, Y5, Y3, Y3
+	VPBLENDD     $0xaa, Y9, Y7, Y7
+	VMOVDQU      Y3, 960(AX)
+	VMOVDQU      Y7, 992(AX)
+	RET
+
+// func addAVX2(p *[256]uint32, a *[256]uint32, b *[256]uint32)
+// Requires: AVX, AVX2
+TEXT ·addAVX2(SB), NOSPLIT, $0-24
+	MOVQ    p+0(FP), AX
+	MOVQ    a+8(FP), CX
+	MOVQ    b+16(FP), DX
+	VMOVDQU (CX), Y0
+	VMOVDQU 32(CX), Y2
+	VMOVDQU 64(CX), Y4
+	VMOVDQU 96(CX), Y6
+	VMOVDQU 128(CX), Y8
+	VMOVDQU 160(CX), Y10
+	VMOVDQU 192(CX), Y12
+	VMOVDQU 224(CX), Y14
+	VMOVDQU (DX), Y1
+	VMOVDQU 32(DX), Y3
+	VMOVDQU 64(DX), Y5
+	VMOVDQU 96(DX), Y7
+	VMOVDQU 128(DX), Y9
+	VMOVDQU 160(DX), Y11
+	VMOVDQU 192(DX), Y13
+	VMOVDQU 224(DX), Y15
+	VPADDD  Y0, Y1, Y1
+	VPADDD  Y2, Y3, Y3
+	VPADDD  Y4, Y5, Y5
+	VPADDD  Y6, Y7, Y7
+	VPADDD  Y8, Y9, Y9
+	VPADDD  Y10, Y11, Y11
+	VPADDD  Y12, Y13, Y13
+	VPADDD  Y14, Y15, Y15
+	VMOVDQU Y1, (AX)
+	VMOVDQU Y3, 32(AX)
+	VMOVDQU Y5, 64(AX)
+	VMOVDQU Y7, 96(AX)
+	VMOVDQU Y9, 128(AX)
+	VMOVDQU Y11, 160(AX)
+	VMOVDQU Y13, 192(AX)
+	VMOVDQU Y15, 224(AX)
+	VMOVDQU 256(CX), Y0
+	VMOVDQU 288(CX), Y2
+	VMOVDQU 320(CX), Y4
+	VMOVDQU 352(CX), Y6
+	VMOVDQU 384(CX), Y8
+	VMOVDQU 416(CX), Y10
+	VMOVDQU 448(CX), Y12
+	VMOVDQU 480(CX), Y14
+	VMOVDQU 256(DX), Y1
+	VMOVDQU 288(DX), Y3
+	VMOVDQU 320(DX), Y5
+	VMOVDQU 352(DX), Y7
+	VMOVDQU 384(DX), Y9
+	VMOVDQU 416(DX), Y11
+	VMOVDQU 448(DX), Y13
+	VMOVDQU 480(DX), Y15
+	VPADDD  Y0, Y1, Y1
+	VPADDD  Y2, Y3, Y3
+	VPADDD  Y4, Y5, Y5
+	VPADDD  Y6, Y7, Y7
+	VPADDD  Y8, Y9, Y9
+	VPADDD  Y10, Y11, Y11
+	VPADDD  Y12, Y13, Y13
+	VPADDD  Y14, Y15, Y15
+	VMOVDQU Y1, 256(AX)
+	VMOVDQU Y3, 288(AX)
+	VMOVDQU Y5, 320(AX)
+	VMOVDQU Y7, 352(AX)
+	VMOVDQU Y9, 384(AX)
+	VMOVDQU Y11, 416(AX)
+	VMOVDQU Y13, 448(AX)
+	VMOVDQU Y15, 480(AX)
+	VMOVDQU 512(CX), Y0
+	VMOVDQU 544(CX), Y2
+	VMOVDQU 576(CX), Y4
+	VMOVDQU 608(CX), Y6
+	VMOVDQU 640(CX), Y8
+	VMOVDQU 672(CX), Y10
+	VMOVDQU 704(CX), Y12
+	VMOVDQU 736(CX), Y14
+	VMOVDQU 512(DX), Y1
+	VMOVDQU 544(DX), Y3
+	VMOVDQU 576(DX), Y5
+	VMOVDQU 608(DX), Y7
+	VMOVDQU 640(DX), Y9
+	VMOVDQU 672(DX), Y11
+	VMOVDQU 704(DX), Y13
+	VMOVDQU 736(DX), Y15
+	VPADDD  Y0, Y1, Y1
+	VPADDD  Y2, Y3, Y3
+	VPADDD  Y4, Y5, Y5
+	VPADDD  Y6, Y7, Y7
+	VPADDD  Y8, Y9, Y9
+	VPADDD  Y10, Y11, Y11
+	VPADDD  Y12, Y13, Y13
+	VPADDD  Y14, Y15, Y15
+	VMOVDQU Y1, 512(AX)
+	VMOVDQU Y3, 544(AX)
+	VMOVDQU Y5, 576(AX)
+	VMOVDQU Y7, 608(AX)
+	VMOVDQU Y9, 640(AX)
+	VMOVDQU Y11, 672(AX)
+	VMOVDQU Y13, 704(AX)
+	VMOVDQU Y15, 736(AX)
+	VMOVDQU 768(CX), Y0
+	VMOVDQU 800(CX), Y2
+	VMOVDQU 832(CX), Y4
+	VMOVDQU 864(CX), Y6
+	VMOVDQU 896(CX), Y8
+	VMOVDQU 928(CX), Y10
+	VMOVDQU 960(CX), Y12
+	VMOVDQU 992(CX), Y14
+	VMOVDQU 768(DX), Y1
+	VMOVDQU 800(DX), Y3
+	VMOVDQU 832(DX), Y5
+	VMOVDQU 864(DX), Y7
+	VMOVDQU 896(DX), Y9
+	VMOVDQU 928(DX), Y11
+	VMOVDQU 960(DX), Y13
+	VMOVDQU 992(DX), Y15
+	VPADDD  Y0, Y1, Y1
+	VPADDD  Y2, Y3, Y3
+	VPADDD  Y4, Y5, Y5
+	VPADDD  Y6, Y7, Y7
+	VPADDD  Y8, Y9, Y9
+	VPADDD  Y10, Y11, Y11
+	VPADDD  Y12, Y13, Y13
+	VPADDD  Y14, Y15, Y15
+	VMOVDQU Y1, 768(AX)
+	VMOVDQU Y3, 800(AX)
+	VMOVDQU Y5, 832(AX)
+	VMOVDQU Y7, 864(AX)
+	VMOVDQU Y9, 896(AX)
+	VMOVDQU Y11, 928(AX)
+	VMOVDQU Y13, 960(AX)
+	VMOVDQU Y15, 992(AX)
+	RET
+
+// func subAVX2(p *[256]uint32, a *[256]uint32, b *[256]uint32)
+// Requires: AVX, AVX2
+TEXT ·subAVX2(SB), NOSPLIT, $0-24
+	MOVQ         p+0(FP), AX
+	MOVQ         a+8(FP), CX
+	MOVQ         b+16(FP), DX
+	MOVL         $0x00ffc002, BX
+	VMOVD        BX, X0
+	VPBROADCASTD X0, Y8
+	VMOVDQU      (CX), Y0
+	VMOVDQU      32(CX), Y2
+	VMOVDQU      64(CX), Y4
+	VMOVDQU      96(CX), Y6
+	VMOVDQU      (DX), Y1
+	VMOVDQU      32(DX), Y3
+	VMOVDQU      64(DX), Y5
+	VMOVDQU      96(DX), Y7
+	VPSUBD       Y1, Y8, Y1
+	VPSUBD       Y3, Y8, Y3
+	VPSUBD       Y5, Y8, Y5
+	VPSUBD       Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y1
+	VPADDD       Y2, Y3, Y3
+	VPADDD       Y4, Y5, Y5
+	VPADDD       Y6, Y7, Y7
+	VMOVDQU      Y1, (AX)
+	VMOVDQU      Y3, 32(AX)
+	VMOVDQU      Y5, 64(AX)
+	VMOVDQU      Y7, 96(AX)
+	VMOVDQU      128(CX), Y0
+	VMOVDQU      160(CX), Y2
+	VMOVDQU      192(CX), Y4
+	VMOVDQU      224(CX), Y6
+	VMOVDQU      128(DX), Y1
+	VMOVDQU      160(DX), Y3
+	VMOVDQU      192(DX), Y5
+	VMOVDQU      224(DX), Y7
+	VPSUBD       Y1, Y8, Y1
+	VPSUBD       Y3, Y8, Y3
+	VPSUBD       Y5, Y8, Y5
+	VPSUBD       Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y1
+	VPADDD       Y2, Y3, Y3
+	VPADDD       Y4, Y5, Y5
+	VPADDD       Y6, Y7, Y7
+	VMOVDQU      Y1, 128(AX)
+	VMOVDQU      Y3, 160(AX)
+	VMOVDQU      Y5, 192(AX)
+	VMOVDQU      Y7, 224(AX)
+	VMOVDQU      256(CX), Y0
+	VMOVDQU      288(CX), Y2
+	VMOVDQU      320(CX), Y4
+	VMOVDQU      352(CX), Y6
+	VMOVDQU      256(DX), Y1
+	VMOVDQU      288(DX), Y3
+	VMOVDQU      320(DX), Y5
+	VMOVDQU      352(DX), Y7
+	VPSUBD       Y1, Y8, Y1
+	VPSUBD       Y3, Y8, Y3
+	VPSUBD       Y5, Y8, Y5
+	VPSUBD       Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y1
+	VPADDD       Y2, Y3, Y3
+	VPADDD       Y4, Y5, Y5
+	VPADDD       Y6, Y7, Y7
+	VMOVDQU      Y1, 256(AX)
+	VMOVDQU      Y3, 288(AX)
+	VMOVDQU      Y5, 320(AX)
+	VMOVDQU      Y7, 352(AX)
+	VMOVDQU      384(CX), Y0
+	VMOVDQU      416(CX), Y2
+	VMOVDQU      448(CX), Y4
+	VMOVDQU      480(CX), Y6
+	VMOVDQU      384(DX), Y1
+	VMOVDQU      416(DX), Y3
+	VMOVDQU      448(DX), Y5
+	VMOVDQU      480(DX), Y7
+	VPSUBD       Y1, Y8, Y1
+	VPSUBD       Y3, Y8, Y3
+	VPSUBD       Y5, Y8, Y5
+	VPSUBD       Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y1
+	VPADDD       Y2, Y3, Y3
+	VPADDD       Y4, Y5, Y5
+	VPADDD       Y6, Y7, Y7
+	VMOVDQU      Y1, 384(AX)
+	VMOVDQU      Y3, 416(AX)
+	VMOVDQU      Y5, 448(AX)
+	VMOVDQU      Y7, 480(AX)
+	VMOVDQU      512(CX), Y0
+	VMOVDQU      544(CX), Y2
+	VMOVDQU      576(CX), Y4
+	VMOVDQU      608(CX), Y6
+	VMOVDQU      512(DX), Y1
+	VMOVDQU      544(DX), Y3
+	VMOVDQU      576(DX), Y5
+	VMOVDQU      608(DX), Y7
+	VPSUBD       Y1, Y8, Y1
+	VPSUBD       Y3, Y8, Y3
+	VPSUBD       Y5, Y8, Y5
+	VPSUBD       Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y1
+	VPADDD       Y2, Y3, Y3
+	VPADDD       Y4, Y5, Y5
+	VPADDD       Y6, Y7, Y7
+	VMOVDQU      Y1, 512(AX)
+	VMOVDQU      Y3, 544(AX)
+	VMOVDQU      Y5, 576(AX)
+	VMOVDQU      Y7, 608(AX)
+	VMOVDQU      640(CX), Y0
+	VMOVDQU      672(CX), Y2
+	VMOVDQU      704(CX), Y4
+	VMOVDQU      736(CX), Y6
+	VMOVDQU      640(DX), Y1
+	VMOVDQU      672(DX), Y3
+	VMOVDQU      704(DX), Y5
+	VMOVDQU      736(DX), Y7
+	VPSUBD       Y1, Y8, Y1
+	VPSUBD       Y3, Y8, Y3
+	VPSUBD       Y5, Y8, Y5
+	VPSUBD       Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y1
+	VPADDD       Y2, Y3, Y3
+	VPADDD       Y4, Y5, Y5
+	VPADDD       Y6, Y7, Y7
+	VMOVDQU      Y1, 640(AX)
+	VMOVDQU      Y3, 672(AX)
+	VMOVDQU      Y5, 704(AX)
+	VMOVDQU      Y7, 736(AX)
+	VMOVDQU      768(CX), Y0
+	VMOVDQU      800(CX), Y2
+	VMOVDQU      832(CX), Y4
+	VMOVDQU      864(CX), Y6
+	VMOVDQU      768(DX), Y1
+	VMOVDQU      800(DX), Y3
+	VMOVDQU      832(DX), Y5
+	VMOVDQU      864(DX), Y7
+	VPSUBD       Y1, Y8, Y1
+	VPSUBD       Y3, Y8, Y3
+	VPSUBD       Y5, Y8, Y5
+	VPSUBD       Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y1
+	VPADDD       Y2, Y3, Y3
+	VPADDD       Y4, Y5, Y5
+	VPADDD       Y6, Y7, Y7
+	VMOVDQU      Y1, 768(AX)
+	VMOVDQU      Y3, 800(AX)
+	VMOVDQU      Y5, 832(AX)
+	VMOVDQU      Y7, 864(AX)
+	VMOVDQU      896(CX), Y0
+	VMOVDQU      928(CX), Y2
+	VMOVDQU      960(CX), Y4
+	VMOVDQU      992(CX), Y6
+	VMOVDQU      896(DX), Y1
+	VMOVDQU      928(DX), Y3
+	VMOVDQU      960(DX), Y5
+	VMOVDQU      992(DX), Y7
+	VPSUBD       Y1, Y8, Y1
+	VPSUBD       Y3, Y8, Y3
+	VPSUBD       Y5, Y8, Y5
+	VPSUBD       Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y1
+	VPADDD       Y2, Y3, Y3
+	VPADDD       Y4, Y5, Y5
+	VPADDD       Y6, Y7, Y7
+	VMOVDQU      Y1, 896(AX)
+	VMOVDQU      Y3, 928(AX)
+	VMOVDQU      Y5, 960(AX)
+	VMOVDQU      Y7, 992(AX)
+	RET
+
+// func packLe16AVX2(p *[256]uint32, buf *byte)
+// Requires: AVX, AVX2
+TEXT ·packLe16AVX2(SB), NOSPLIT, $0-16
+	MOVQ        p+0(FP), AX
+	MOVQ        buf+8(FP), CX
+	VMOVDQU     (AX), Y0
+	VPUNPCKLDQ  32(AX), Y0, Y0
+	VMOVDQU     (AX), Y2
+	VPUNPCKHDQ  32(AX), Y2, Y2
+	VMOVDQU     64(AX), Y4
+	VPUNPCKLDQ  96(AX), Y4, Y4
+	VMOVDQU     64(AX), Y6
+	VPUNPCKHDQ  96(AX), Y6, Y6
+	VMOVDQU     128(AX), Y8
+	VPUNPCKLDQ  160(AX), Y8, Y8
+	VMOVDQU     128(AX), Y10
+	VPUNPCKHDQ  160(AX), Y10, Y10
+	VMOVDQU     192(AX), Y11
+	VPUNPCKLDQ  224(AX), Y11, Y11
+	VMOVDQU     192(AX), Y13
+	VPUNPCKHDQ  224(AX), Y13, Y13
+	VPUNPCKLQDQ Y4, Y0, Y1
+	VPUNPCKHQDQ Y4, Y0, Y3
+	VPUNPCKLQDQ Y6, Y2, Y5
+	VPUNPCKHQDQ Y6, Y2, Y7
+	VPUNPCKLQDQ Y11, Y8, Y9
+	VPUNPCKHQDQ Y11, Y8, Y11
+	VPUNPCKLQDQ Y13, Y10, Y12
+	VPUNPCKHQDQ Y13, Y10, Y13
+	VPERM2I128  $0x20, Y9, Y1, Y0
+	VPERM2I128  $0x20, Y11, Y3, Y2
+	VPERM2I128  $0x20, Y12, Y5, Y4
+	VPERM2I128  $0x20, Y13, Y7, Y6
+	VPERM2I128  $0x31, Y9, Y1, Y8
+	VPERM2I128  $0x31, Y11, Y3, Y10
+	VPERM2I128  $0x31, Y12, Y5, Y11
+	VPERM2I128  $0x31, Y13, Y7, Y13
+	VPSLLD      $0x04, Y2, Y2
+	VPSLLD      $0x08, Y4, Y4
+	VPSLLD      $0x0c, Y6, Y6
+	VPSLLD      $0x10, Y8, Y8
+	VPSLLD      $0x14, Y10, Y10
+	VPSLLD      $0x18, Y11, Y11
+	VPSLLD      $0x1c, Y13, Y13
+	VPOR        Y0, Y2, Y2
+	VPOR        Y4, Y6, Y6
+	VPOR        Y8, Y10, Y10
+	VPOR        Y11, Y13, Y13
+	VPOR        Y2, Y6, Y6
+	VPOR        Y10, Y13, Y13
+	VPOR        Y6, Y13, Y13
+	VMOVDQU     Y13, (CX)
+	VMOVDQU     256(AX), Y0
+	VPUNPCKLDQ  288(AX), Y0, Y0
+	VMOVDQU     256(AX), Y2
+	VPUNPCKHDQ  288(AX), Y2, Y2
+	VMOVDQU     320(AX), Y4
+	VPUNPCKLDQ  352(AX), Y4, Y4
+	VMOVDQU     320(AX), Y6
+	VPUNPCKHDQ  352(AX), Y6, Y6
+	VMOVDQU     384(AX), Y8
+	VPUNPCKLDQ  416(AX), Y8, Y8
+	VMOVDQU     384(AX), Y10
+	VPUNPCKHDQ  416(AX), Y10, Y10
+	VMOVDQU     448(AX), Y11
+	VPUNPCKLDQ  480(AX), Y11, Y11
+	VMOVDQU     448(AX), Y13
+	VPUNPCKHDQ  480(AX), Y13, Y13
+	VPUNPCKLQDQ Y4, Y0, Y1
+	VPUNPCKHQDQ Y4, Y0, Y3
+	VPUNPCKLQDQ Y6, Y2, Y5
+	VPUNPCKHQDQ Y6, Y2, Y7
+	VPUNPCKLQDQ Y11, Y8, Y9
+	VPUNPCKHQDQ Y11, Y8, Y11
+	VPUNPCKLQDQ Y13, Y10, Y12
+	VPUNPCKHQDQ Y13, Y10, Y13
+	VPERM2I128  $0x20, Y9, Y1, Y0
+	VPERM2I128  $0x20, Y11, Y3, Y2
+	VPERM2I128  $0x20, Y12, Y5, Y4
+	VPERM2I128  $0x20, Y13, Y7, Y6
+	VPERM2I128  $0x31, Y9, Y1, Y8
+	VPERM2I128  $0x31, Y11, Y3, Y10
+	VPERM2I128  $0x31, Y12, Y5, Y11
+	VPERM2I128  $0x31, Y13, Y7, Y13
+	VPSLLD      $0x04, Y2, Y2
+	VPSLLD      $0x08, Y4, Y4
+	VPSLLD      $0x0c, Y6, Y6
+	VPSLLD      $0x10, Y8, Y8
+	VPSLLD      $0x14, Y10, Y10
+	VPSLLD      $0x18, Y11, Y11
+	VPSLLD      $0x1c, Y13, Y13
+	VPOR        Y0, Y2, Y2
+	VPOR        Y4, Y6, Y6
+	VPOR        Y8, Y10, Y10
+	VPOR        Y11, Y13, Y13
+	VPOR        Y2, Y6, Y6
+	VPOR        Y10, Y13, Y13
+	VPOR        Y6, Y13, Y13
+	VMOVDQU     Y13, 32(CX)
+	VMOVDQU     512(AX), Y0
+	VPUNPCKLDQ  544(AX), Y0, Y0
+	VMOVDQU     512(AX), Y2
+	VPUNPCKHDQ  544(AX), Y2, Y2
+	VMOVDQU     576(AX), Y4
+	VPUNPCKLDQ  608(AX), Y4, Y4
+	VMOVDQU     576(AX), Y6
+	VPUNPCKHDQ  608(AX), Y6, Y6
+	VMOVDQU     640(AX), Y8
+	VPUNPCKLDQ  672(AX), Y8, Y8
+	VMOVDQU     640(AX), Y10
+	VPUNPCKHDQ  672(AX), Y10, Y10
+	VMOVDQU     704(AX), Y11
+	VPUNPCKLDQ  736(AX), Y11, Y11
+	VMOVDQU     704(AX), Y13
+	VPUNPCKHDQ  736(AX), Y13, Y13
+	VPUNPCKLQDQ Y4, Y0, Y1
+	VPUNPCKHQDQ Y4, Y0, Y3
+	VPUNPCKLQDQ Y6, Y2, Y5
+	VPUNPCKHQDQ Y6, Y2, Y7
+	VPUNPCKLQDQ Y11, Y8, Y9
+	VPUNPCKHQDQ Y11, Y8, Y11
+	VPUNPCKLQDQ Y13, Y10, Y12
+	VPUNPCKHQDQ Y13, Y10, Y13
+	VPERM2I128  $0x20, Y9, Y1, Y0
+	VPERM2I128  $0x20, Y11, Y3, Y2
+	VPERM2I128  $0x20, Y12, Y5, Y4
+	VPERM2I128  $0x20, Y13, Y7, Y6
+	VPERM2I128  $0x31, Y9, Y1, Y8
+	VPERM2I128  $0x31, Y11, Y3, Y10
+	VPERM2I128  $0x31, Y12, Y5, Y11
+	VPERM2I128  $0x31, Y13, Y7, Y13
+	VPSLLD      $0x04, Y2, Y2
+	VPSLLD      $0x08, Y4, Y4
+	VPSLLD      $0x0c, Y6, Y6
+	VPSLLD      $0x10, Y8, Y8
+	VPSLLD      $0x14, Y10, Y10
+	VPSLLD      $0x18, Y11, Y11
+	VPSLLD      $0x1c, Y13, Y13
+	VPOR        Y0, Y2, Y2
+	VPOR        Y4, Y6, Y6
+	VPOR        Y8, Y10, Y10
+	VPOR        Y11, Y13, Y13
+	VPOR        Y2, Y6, Y6
+	VPOR        Y10, Y13, Y13
+	VPOR        Y6, Y13, Y13
+	VMOVDQU     Y13, 64(CX)
+	VMOVDQU     768(AX), Y0
+	VPUNPCKLDQ  800(AX), Y0, Y0
+	VMOVDQU     768(AX), Y2
+	VPUNPCKHDQ  800(AX), Y2, Y2
+	VMOVDQU     832(AX), Y4
+	VPUNPCKLDQ  864(AX), Y4, Y4
+	VMOVDQU     832(AX), Y6
+	VPUNPCKHDQ  864(AX), Y6, Y6
+	VMOVDQU     896(AX), Y8
+	VPUNPCKLDQ  928(AX), Y8, Y8
+	VMOVDQU     896(AX), Y10
+	VPUNPCKHDQ  928(AX), Y10, Y10
+	VMOVDQU     960(AX), Y11
+	VPUNPCKLDQ  992(AX), Y11, Y11
+	VMOVDQU     960(AX), Y13
+	VPUNPCKHDQ  992(AX), Y13, Y13
+	VPUNPCKLQDQ Y4, Y0, Y1
+	VPUNPCKHQDQ Y4, Y0, Y3
+	VPUNPCKLQDQ Y6, Y2, Y5
+	VPUNPCKHQDQ Y6, Y2, Y7
+	VPUNPCKLQDQ Y11, Y8, Y9
+	VPUNPCKHQDQ Y11, Y8, Y11
+	VPUNPCKLQDQ Y13, Y10, Y12
+	VPUNPCKHQDQ Y13, Y10, Y13
+	VPERM2I128  $0x20, Y9, Y1, Y0
+	VPERM2I128  $0x20, Y11, Y3, Y2
+	VPERM2I128  $0x20, Y12, Y5, Y4
+	VPERM2I128  $0x20, Y13, Y7, Y6
+	VPERM2I128  $0x31, Y9, Y1, Y8
+	VPERM2I128  $0x31, Y11, Y3, Y10
+	VPERM2I128  $0x31, Y12, Y5, Y11
+	VPERM2I128  $0x31, Y13, Y7, Y13
+	VPSLLD      $0x04, Y2, Y2
+	VPSLLD      $0x08, Y4, Y4
+	VPSLLD      $0x0c, Y6, Y6
+	VPSLLD      $0x10, Y8, Y8
+	VPSLLD      $0x14, Y10, Y10
+	VPSLLD      $0x18, Y11, Y11
+	VPSLLD      $0x1c, Y13, Y13
+	VPOR        Y0, Y2, Y2
+	VPOR        Y4, Y6, Y6
+	VPOR        Y8, Y10, Y10
+	VPOR        Y11, Y13, Y13
+	VPOR        Y2, Y6, Y6
+	VPOR        Y10, Y13, Y13
+	VPOR        Y6, Y13, Y13
+	VMOVDQU     Y13, 96(CX)
+	RET
+
+// func reduceLe2QAVX2(p *[256]uint32)
+// Requires: AVX, AVX2
+TEXT ·reduceLe2QAVX2(SB), NOSPLIT, $0-8
+	MOVQ         p+0(FP), AX
+	MOVL         $0x007fffff, CX
+	VMOVD        CX, X0
+	VPBROADCASTD X0, Y12
+	VMOVDQU      (AX), Y0
+	VMOVDQU      32(AX), Y3
+	VMOVDQU      64(AX), Y6
+	VMOVDQU      96(AX), Y9
+	VPSRLD       $0x17, Y0, Y1
+	VPSRLD       $0x17, Y3, Y4
+	VPSRLD       $0x17, Y6, Y7
+	VPSRLD       $0x17, Y9, Y10
+	VPAND        Y0, Y12, Y0
+	VPAND        Y3, Y12, Y3
+	VPAND        Y6, Y12, Y6
+	VPAND        Y9, Y12, Y9
+	VPSLLD       $0x0d, Y1, Y2
+	VPSLLD       $0x0d, Y4, Y5
+	VPSLLD       $0x0d, Y7, Y8
+	VPSLLD       $0x0d, Y10, Y11
+	VPSUBD       Y1, Y2, Y2
+	VPSUBD       Y4, Y5, Y5
+	VPSUBD       Y7, Y8, Y8
+	VPSUBD       Y10, Y11, Y11
+	VPADDD       Y0, Y2, Y0
+	VPADDD       Y3, Y5, Y3
+	VPADDD       Y6, Y8, Y6
+	VPADDD       Y9, Y11, Y9
+	VMOVDQU      Y0, (AX)
+	VMOVDQU      Y3, 32(AX)
+	VMOVDQU      Y6, 64(AX)
+	VMOVDQU      Y9, 96(AX)
+	VMOVDQU      128(AX), Y0
+	VMOVDQU      160(AX), Y3
+	VMOVDQU      192(AX), Y6
+	VMOVDQU      224(AX), Y9
+	VPSRLD       $0x17, Y0, Y1
+	VPSRLD       $0x17, Y3, Y4
+	VPSRLD       $0x17, Y6, Y7
+	VPSRLD       $0x17, Y9, Y10
+	VPAND        Y0, Y12, Y0
+	VPAND        Y3, Y12, Y3
+	VPAND        Y6, Y12, Y6
+	VPAND        Y9, Y12, Y9
+	VPSLLD       $0x0d, Y1, Y2
+	VPSLLD       $0x0d, Y4, Y5
+	VPSLLD       $0x0d, Y7, Y8
+	VPSLLD       $0x0d, Y10, Y11
+	VPSUBD       Y1, Y2, Y2
+	VPSUBD       Y4, Y5, Y5
+	VPSUBD       Y7, Y8, Y8
+	VPSUBD       Y10, Y11, Y11
+	VPADDD       Y0, Y2, Y0
+	VPADDD       Y3, Y5, Y3
+	VPADDD       Y6, Y8, Y6
+	VPADDD       Y9, Y11, Y9
+	VMOVDQU      Y0, 128(AX)
+	VMOVDQU      Y3, 160(AX)
+	VMOVDQU      Y6, 192(AX)
+	VMOVDQU      Y9, 224(AX)
+	VMOVDQU      256(AX), Y0
+	VMOVDQU      288(AX), Y3
+	VMOVDQU      320(AX), Y6
+	VMOVDQU      352(AX), Y9
+	VPSRLD       $0x17, Y0, Y1
+	VPSRLD       $0x17, Y3, Y4
+	VPSRLD       $0x17, Y6, Y7
+	VPSRLD       $0x17, Y9, Y10
+	VPAND        Y0, Y12, Y0
+	VPAND        Y3, Y12, Y3
+	VPAND        Y6, Y12, Y6
+	VPAND        Y9, Y12, Y9
+	VPSLLD       $0x0d, Y1, Y2
+	VPSLLD       $0x0d, Y4, Y5
+	VPSLLD       $0x0d, Y7, Y8
+	VPSLLD       $0x0d, Y10, Y11
+	VPSUBD       Y1, Y2, Y2
+	VPSUBD       Y4, Y5, Y5
+	VPSUBD       Y7, Y8, Y8
+	VPSUBD       Y10, Y11, Y11
+	VPADDD       Y0, Y2, Y0
+	VPADDD       Y3, Y5, Y3
+	VPADDD       Y6, Y8, Y6
+	VPADDD       Y9, Y11, Y9
+	VMOVDQU      Y0, 256(AX)
+	VMOVDQU      Y3, 288(AX)
+	VMOVDQU      Y6, 320(AX)
+	VMOVDQU      Y9, 352(AX)
+	VMOVDQU      384(AX), Y0
+	VMOVDQU      416(AX), Y3
+	VMOVDQU      448(AX), Y6
+	VMOVDQU      480(AX), Y9
+	VPSRLD       $0x17, Y0, Y1
+	VPSRLD       $0x17, Y3, Y4
+	VPSRLD       $0x17, Y6, Y7
+	VPSRLD       $0x17, Y9, Y10
+	VPAND        Y0, Y12, Y0
+	VPAND        Y3, Y12, Y3
+	VPAND        Y6, Y12, Y6
+	VPAND        Y9, Y12, Y9
+	VPSLLD       $0x0d, Y1, Y2
+	VPSLLD       $0x0d, Y4, Y5
+	VPSLLD       $0x0d, Y7, Y8
+	VPSLLD       $0x0d, Y10, Y11
+	VPSUBD       Y1, Y2, Y2
+	VPSUBD       Y4, Y5, Y5
+	VPSUBD       Y7, Y8, Y8
+	VPSUBD       Y10, Y11, Y11
+	VPADDD       Y0, Y2, Y0
+	VPADDD       Y3, Y5, Y3
+	VPADDD       Y6, Y8, Y6
+	VPADDD       Y9, Y11, Y9
+	VMOVDQU      Y0, 384(AX)
+	VMOVDQU      Y3, 416(AX)
+	VMOVDQU      Y6, 448(AX)
+	VMOVDQU      Y9, 480(AX)
+	VMOVDQU      512(AX), Y0
+	VMOVDQU      544(AX), Y3
+	VMOVDQU      576(AX), Y6
+	VMOVDQU      608(AX), Y9
+	VPSRLD       $0x17, Y0, Y1
+	VPSRLD       $0x17, Y3, Y4
+	VPSRLD       $0x17, Y6, Y7
+	VPSRLD       $0x17, Y9, Y10
+	VPAND        Y0, Y12, Y0
+	VPAND        Y3, Y12, Y3
+	VPAND        Y6, Y12, Y6
+	VPAND        Y9, Y12, Y9
+	VPSLLD       $0x0d, Y1, Y2
+	VPSLLD       $0x0d, Y4, Y5
+	VPSLLD       $0x0d, Y7, Y8
+	VPSLLD       $0x0d, Y10, Y11
+	VPSUBD       Y1, Y2, Y2
+	VPSUBD       Y4, Y5, Y5
+	VPSUBD       Y7, Y8, Y8
+	VPSUBD       Y10, Y11, Y11
+	VPADDD       Y0, Y2, Y0
+	VPADDD       Y3, Y5, Y3
+	VPADDD       Y6, Y8, Y6
+	VPADDD       Y9, Y11, Y9
+	VMOVDQU      Y0, 512(AX)
+	VMOVDQU      Y3, 544(AX)
+	VMOVDQU      Y6, 576(AX)
+	VMOVDQU      Y9, 608(AX)
+	VMOVDQU      640(AX), Y0
+	VMOVDQU      672(AX), Y3
+	VMOVDQU      704(AX), Y6
+	VMOVDQU      736(AX), Y9
+	VPSRLD       $0x17, Y0, Y1
+	VPSRLD       $0x17, Y3, Y4
+	VPSRLD       $0x17, Y6, Y7
+	VPSRLD       $0x17, Y9, Y10
+	VPAND        Y0, Y12, Y0
+	VPAND        Y3, Y12, Y3
+	VPAND        Y6, Y12, Y6
+	VPAND        Y9, Y12, Y9
+	VPSLLD       $0x0d, Y1, Y2
+	VPSLLD       $0x0d, Y4, Y5
+	VPSLLD       $0x0d, Y7, Y8
+	VPSLLD       $0x0d, Y10, Y11
+	VPSUBD       Y1, Y2, Y2
+	VPSUBD       Y4, Y5, Y5
+	VPSUBD       Y7, Y8, Y8
+	VPSUBD       Y10, Y11, Y11
+	VPADDD       Y0, Y2, Y0
+	VPADDD       Y3, Y5, Y3
+	VPADDD       Y6, Y8, Y6
+	VPADDD       Y9, Y11, Y9
+	VMOVDQU      Y0, 640(AX)
+	VMOVDQU      Y3, 672(AX)
+	VMOVDQU      Y6, 704(AX)
+	VMOVDQU      Y9, 736(AX)
+	VMOVDQU      768(AX), Y0
+	VMOVDQU      800(AX), Y3
+	VMOVDQU      832(AX), Y6
+	VMOVDQU      864(AX), Y9
+	VPSRLD       $0x17, Y0, Y1
+	VPSRLD       $0x17, Y3, Y4
+	VPSRLD       $0x17, Y6, Y7
+	VPSRLD       $0x17, Y9, Y10
+	VPAND        Y0, Y12, Y0
+	VPAND        Y3, Y12, Y3
+	VPAND        Y6, Y12, Y6
+	VPAND        Y9, Y12, Y9
+	VPSLLD       $0x0d, Y1, Y2
+	VPSLLD       $0x0d, Y4, Y5
+	VPSLLD       $0x0d, Y7, Y8
+	VPSLLD       $0x0d, Y10, Y11
+	VPSUBD       Y1, Y2, Y2
+	VPSUBD       Y4, Y5, Y5
+	VPSUBD       Y7, Y8, Y8
+	VPSUBD       Y10, Y11, Y11
+	VPADDD       Y0, Y2, Y0
+	VPADDD       Y3, Y5, Y3
+	VPADDD       Y6, Y8, Y6
+	VPADDD       Y9, Y11, Y9
+	VMOVDQU      Y0, 768(AX)
+	VMOVDQU      Y3, 800(AX)
+	VMOVDQU      Y6, 832(AX)
+	VMOVDQU      Y9, 864(AX)
+	VMOVDQU      896(AX), Y0
+	VMOVDQU      928(AX), Y3
+	VMOVDQU      960(AX), Y6
+	VMOVDQU      992(AX), Y9
+	VPSRLD       $0x17, Y0, Y1
+	VPSRLD       $0x17, Y3, Y4
+	VPSRLD       $0x17, Y6, Y7
+	VPSRLD       $0x17, Y9, Y10
+	VPAND        Y0, Y12, Y0
+	VPAND        Y3, Y12, Y3
+	VPAND        Y6, Y12, Y6
+	VPAND        Y9, Y12, Y9
+	VPSLLD       $0x0d, Y1, Y2
+	VPSLLD       $0x0d, Y4, Y5
+	VPSLLD       $0x0d, Y7, Y8
+	VPSLLD       $0x0d, Y10, Y11
+	VPSUBD       Y1, Y2, Y2
+	VPSUBD       Y4, Y5, Y5
+	VPSUBD       Y7, Y8, Y8
+	VPSUBD       Y10, Y11, Y11
+	VPADDD       Y0, Y2, Y0
+	VPADDD       Y3, Y5, Y3
+	VPADDD       Y6, Y8, Y6
+	VPADDD       Y9, Y11, Y9
+	VMOVDQU      Y0, 896(AX)
+	VMOVDQU      Y3, 928(AX)
+	VMOVDQU      Y6, 960(AX)
+	VMOVDQU      Y9, 992(AX)
+	RET
+
+// func le2qModQAVX2(p *[256]uint32)
+// Requires: AVX, AVX2
+TEXT ·le2qModQAVX2(SB), NOSPLIT, $0-8
+	MOVQ         p+0(FP), AX
+	MOVL         $0x007fe001, CX
+	VMOVD        CX, X0
+	VPBROADCASTD X0, Y8
+	VMOVDQU      (AX), Y0
+	VMOVDQU      32(AX), Y2
+	VMOVDQU      64(AX), Y4
+	VMOVDQU      96(AX), Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPAND        Y1, Y8, Y1
+	VPAND        Y3, Y8, Y3
+	VPAND        Y5, Y8, Y5
+	VPAND        Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y0
+	VPADDD       Y2, Y3, Y2
+	VPADDD       Y4, Y5, Y4
+	VPADDD       Y6, Y7, Y6
+	VMOVDQU      Y0, (AX)
+	VMOVDQU      Y2, 32(AX)
+	VMOVDQU      Y4, 64(AX)
+	VMOVDQU      Y6, 96(AX)
+	VMOVDQU      128(AX), Y0
+	VMOVDQU      160(AX), Y2
+	VMOVDQU      192(AX), Y4
+	VMOVDQU      224(AX), Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPAND        Y1, Y8, Y1
+	VPAND        Y3, Y8, Y3
+	VPAND        Y5, Y8, Y5
+	VPAND        Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y0
+	VPADDD       Y2, Y3, Y2
+	VPADDD       Y4, Y5, Y4
+	VPADDD       Y6, Y7, Y6
+	VMOVDQU      Y0, 128(AX)
+	VMOVDQU      Y2, 160(AX)
+	VMOVDQU      Y4, 192(AX)
+	VMOVDQU      Y6, 224(AX)
+	VMOVDQU      256(AX), Y0
+	VMOVDQU      288(AX), Y2
+	VMOVDQU      320(AX), Y4
+	VMOVDQU      352(AX), Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPAND        Y1, Y8, Y1
+	VPAND        Y3, Y8, Y3
+	VPAND        Y5, Y8, Y5
+	VPAND        Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y0
+	VPADDD       Y2, Y3, Y2
+	VPADDD       Y4, Y5, Y4
+	VPADDD       Y6, Y7, Y6
+	VMOVDQU      Y0, 256(AX)
+	VMOVDQU      Y2, 288(AX)
+	VMOVDQU      Y4, 320(AX)
+	VMOVDQU      Y6, 352(AX)
+	VMOVDQU      384(AX), Y0
+	VMOVDQU      416(AX), Y2
+	VMOVDQU      448(AX), Y4
+	VMOVDQU      480(AX), Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPAND        Y1, Y8, Y1
+	VPAND        Y3, Y8, Y3
+	VPAND        Y5, Y8, Y5
+	VPAND        Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y0
+	VPADDD       Y2, Y3, Y2
+	VPADDD       Y4, Y5, Y4
+	VPADDD       Y6, Y7, Y6
+	VMOVDQU      Y0, 384(AX)
+	VMOVDQU      Y2, 416(AX)
+	VMOVDQU      Y4, 448(AX)
+	VMOVDQU      Y6, 480(AX)
+	VMOVDQU      512(AX), Y0
+	VMOVDQU      544(AX), Y2
+	VMOVDQU      576(AX), Y4
+	VMOVDQU      608(AX), Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPAND        Y1, Y8, Y1
+	VPAND        Y3, Y8, Y3
+	VPAND        Y5, Y8, Y5
+	VPAND        Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y0
+	VPADDD       Y2, Y3, Y2
+	VPADDD       Y4, Y5, Y4
+	VPADDD       Y6, Y7, Y6
+	VMOVDQU      Y0, 512(AX)
+	VMOVDQU      Y2, 544(AX)
+	VMOVDQU      Y4, 576(AX)
+	VMOVDQU      Y6, 608(AX)
+	VMOVDQU      640(AX), Y0
+	VMOVDQU      672(AX), Y2
+	VMOVDQU      704(AX), Y4
+	VMOVDQU      736(AX), Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPAND        Y1, Y8, Y1
+	VPAND        Y3, Y8, Y3
+	VPAND        Y5, Y8, Y5
+	VPAND        Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y0
+	VPADDD       Y2, Y3, Y2
+	VPADDD       Y4, Y5, Y4
+	VPADDD       Y6, Y7, Y6
+	VMOVDQU      Y0, 640(AX)
+	VMOVDQU      Y2, 672(AX)
+	VMOVDQU      Y4, 704(AX)
+	VMOVDQU      Y6, 736(AX)
+	VMOVDQU      768(AX), Y0
+	VMOVDQU      800(AX), Y2
+	VMOVDQU      832(AX), Y4
+	VMOVDQU      864(AX), Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPAND        Y1, Y8, Y1
+	VPAND        Y3, Y8, Y3
+	VPAND        Y5, Y8, Y5
+	VPAND        Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y0
+	VPADDD       Y2, Y3, Y2
+	VPADDD       Y4, Y5, Y4
+	VPADDD       Y6, Y7, Y6
+	VMOVDQU      Y0, 768(AX)
+	VMOVDQU      Y2, 800(AX)
+	VMOVDQU      Y4, 832(AX)
+	VMOVDQU      Y6, 864(AX)
+	VMOVDQU      896(AX), Y0
+	VMOVDQU      928(AX), Y2
+	VMOVDQU      960(AX), Y4
+	VMOVDQU      992(AX), Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPAND        Y1, Y8, Y1
+	VPAND        Y3, Y8, Y3
+	VPAND        Y5, Y8, Y5
+	VPAND        Y7, Y8, Y7
+	VPADDD       Y0, Y1, Y0
+	VPADDD       Y2, Y3, Y2
+	VPADDD       Y4, Y5, Y4
+	VPADDD       Y6, Y7, Y6
+	VMOVDQU      Y0, 896(AX)
+	VMOVDQU      Y2, 928(AX)
+	VMOVDQU      Y4, 960(AX)
+	VMOVDQU      Y6, 992(AX)
+	RET
+
+// func exceedsAVX2(p *[256]uint32, bound uint32) uint8
+// Requires: AVX, AVX2
+TEXT ·exceedsAVX2(SB), NOSPLIT, $0-17
+	MOVQ         p+0(FP), AX
+	MOVL         bound+8(FP), CX
+	VMOVD        CX, X0
+	VPBROADCASTD X0, Y8
+	MOVL         $0x003ff000, CX
+	VMOVD        CX, X0
+	VPBROADCASTD X0, Y9
+	MOVL         $0x80000000, CX
+	VMOVD        CX, X0
+	VPBROADCASTD X0, Y10
+	MOVL         $0x88888888, CX
+	VMOVDQU      (AX), Y0
+	VMOVDQU      32(AX), Y2
+	VMOVDQU      64(AX), Y4
+	VMOVDQU      96(AX), Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPXOR        Y0, Y1, Y0
+	VPXOR        Y2, Y3, Y2
+	VPXOR        Y4, Y5, Y4
+	VPXOR        Y6, Y7, Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPAND        Y0, Y10, Y0
+	VPAND        Y2, Y10, Y2
+	VPAND        Y4, Y10, Y4
+	VPAND        Y6, Y10, Y6
+	VPMOVMSKB    Y0, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y2, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y4, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y6, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VMOVDQU      128(AX), Y0
+	VMOVDQU      160(AX), Y2
+	VMOVDQU      192(AX), Y4
+	VMOVDQU      224(AX), Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPXOR        Y0, Y1, Y0
+	VPXOR        Y2, Y3, Y2
+	VPXOR        Y4, Y5, Y4
+	VPXOR        Y6, Y7, Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPAND        Y0, Y10, Y0
+	VPAND        Y2, Y10, Y2
+	VPAND        Y4, Y10, Y4
+	VPAND        Y6, Y10, Y6
+	VPMOVMSKB    Y0, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y2, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y4, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y6, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VMOVDQU      256(AX), Y0
+	VMOVDQU      288(AX), Y2
+	VMOVDQU      320(AX), Y4
+	VMOVDQU      352(AX), Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPXOR        Y0, Y1, Y0
+	VPXOR        Y2, Y3, Y2
+	VPXOR        Y4, Y5, Y4
+	VPXOR        Y6, Y7, Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPAND        Y0, Y10, Y0
+	VPAND        Y2, Y10, Y2
+	VPAND        Y4, Y10, Y4
+	VPAND        Y6, Y10, Y6
+	VPMOVMSKB    Y0, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y2, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y4, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y6, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VMOVDQU      384(AX), Y0
+	VMOVDQU      416(AX), Y2
+	VMOVDQU      448(AX), Y4
+	VMOVDQU      480(AX), Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPXOR        Y0, Y1, Y0
+	VPXOR        Y2, Y3, Y2
+	VPXOR        Y4, Y5, Y4
+	VPXOR        Y6, Y7, Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPAND        Y0, Y10, Y0
+	VPAND        Y2, Y10, Y2
+	VPAND        Y4, Y10, Y4
+	VPAND        Y6, Y10, Y6
+	VPMOVMSKB    Y0, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y2, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y4, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y6, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VMOVDQU      512(AX), Y0
+	VMOVDQU      544(AX), Y2
+	VMOVDQU      576(AX), Y4
+	VMOVDQU      608(AX), Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPXOR        Y0, Y1, Y0
+	VPXOR        Y2, Y3, Y2
+	VPXOR        Y4, Y5, Y4
+	VPXOR        Y6, Y7, Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPAND        Y0, Y10, Y0
+	VPAND        Y2, Y10, Y2
+	VPAND        Y4, Y10, Y4
+	VPAND        Y6, Y10, Y6
+	VPMOVMSKB    Y0, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y2, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y4, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y6, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VMOVDQU      640(AX), Y0
+	VMOVDQU      672(AX), Y2
+	VMOVDQU      704(AX), Y4
+	VMOVDQU      736(AX), Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPXOR        Y0, Y1, Y0
+	VPXOR        Y2, Y3, Y2
+	VPXOR        Y4, Y5, Y4
+	VPXOR        Y6, Y7, Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPAND        Y0, Y10, Y0
+	VPAND        Y2, Y10, Y2
+	VPAND        Y4, Y10, Y4
+	VPAND        Y6, Y10, Y6
+	VPMOVMSKB    Y0, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y2, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y4, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y6, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VMOVDQU      768(AX), Y0
+	VMOVDQU      800(AX), Y2
+	VMOVDQU      832(AX), Y4
+	VMOVDQU      864(AX), Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPXOR        Y0, Y1, Y0
+	VPXOR        Y2, Y3, Y2
+	VPXOR        Y4, Y5, Y4
+	VPXOR        Y6, Y7, Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPAND        Y0, Y10, Y0
+	VPAND        Y2, Y10, Y2
+	VPAND        Y4, Y10, Y4
+	VPAND        Y6, Y10, Y6
+	VPMOVMSKB    Y0, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y2, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y4, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VPMOVMSKB    Y6, DX
+	XORL         CX, DX
+	TESTL        DX, DX
+	JNZ          exceeded
+	VMOVDQU      896(AX), Y0
+	VMOVDQU      928(AX), Y2
+	VMOVDQU      960(AX), Y4
+	VMOVDQU      992(AX), Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSRAD       $0x1f, Y0, Y1
+	VPSRAD       $0x1f, Y2, Y3
+	VPSRAD       $0x1f, Y4, Y5
+	VPSRAD       $0x1f, Y6, Y7
+	VPXOR        Y0, Y1, Y0
+	VPXOR        Y2, Y3, Y2
+	VPXOR        Y4, Y5, Y4
+	VPXOR        Y6, Y7, Y6
+	VPSUBD       Y0, Y9, Y0
+	VPSUBD       Y2, Y9, Y2
+	VPSUBD       Y4, Y9, Y4
+	VPSUBD       Y6, Y9, Y6
+	VPSUBD       Y8, Y0, Y0
+	VPSUBD       Y8, Y2, Y2
+	VPSUBD       Y8, Y4, Y4
+	VPSUBD       Y8, Y6, Y6
+	VPAND        Y0, Y10, Y0
+	VPAND        Y2, Y10, Y2
+	VPAND        Y4, Y10, Y4
+	VPAND        Y6, Y10, Y6
+	VPMOVMSKB    Y0, AX
+	XORL         CX, AX
+	TESTL        AX, AX
+	JNZ          exceeded
+	VPMOVMSKB    Y2, AX
+	XORL         CX, AX
+	TESTL        AX, AX
+	JNZ          exceeded
+	VPMOVMSKB    Y4, AX
+	XORL         CX, AX
+	TESTL        AX, AX
+	JNZ          exceeded
+	VPMOVMSKB    Y6, AX
+	XORL         CX, AX
+	TESTL        AX, AX
+	JNZ          exceeded
+	XORB         AL, AL
+	MOVB         AL, ret+16(FP)
+	RET
+
+exceeded:
+	MOVB $0x01, AL
+	MOVB AL, ret+16(FP)
+	RET
+
+// func mulBy2toDAVX2(p *[256]uint32, q *[256]uint32)
+// Requires: AVX, AVX2
+TEXT ·mulBy2toDAVX2(SB), NOSPLIT, $0-16
+	MOVQ    p+0(FP), AX
+	MOVQ    q+8(FP), CX
+	VMOVDQU (CX), Y0
+	VMOVDQU 32(CX), Y1
+	VMOVDQU 64(CX), Y2
+	VMOVDQU 96(CX), Y3
+	VMOVDQU 128(CX), Y4
+	VMOVDQU 160(CX), Y5
+	VMOVDQU 192(CX), Y6
+	VMOVDQU 224(CX), Y7
+	VPSLLD  $0x0d, Y0, Y0
+	VPSLLD  $0x0d, Y1, Y1
+	VPSLLD  $0x0d, Y2, Y2
+	VPSLLD  $0x0d, Y3, Y3
+	VPSLLD  $0x0d, Y4, Y4
+	VPSLLD  $0x0d, Y5, Y5
+	VPSLLD  $0x0d, Y6, Y6
+	VPSLLD  $0x0d, Y7, Y7
+	VMOVDQU Y0, (AX)
+	VMOVDQU Y1, 32(AX)
+	VMOVDQU Y2, 64(AX)
+	VMOVDQU Y3, 96(AX)
+	VMOVDQU Y4, 128(AX)
+	VMOVDQU Y5, 160(AX)
+	VMOVDQU Y6, 192(AX)
+	VMOVDQU Y7, 224(AX)
+	VMOVDQU 256(CX), Y0
+	VMOVDQU 288(CX), Y1
+	VMOVDQU 320(CX), Y2
+	VMOVDQU 352(CX), Y3
+	VMOVDQU 384(CX), Y4
+	VMOVDQU 416(CX), Y5
+	VMOVDQU 448(CX), Y6
+	VMOVDQU 480(CX), Y7
+	VPSLLD  $0x0d, Y0, Y0
+	VPSLLD  $0x0d, Y1, Y1
+	VPSLLD  $0x0d, Y2, Y2
+	VPSLLD  $0x0d, Y3, Y3
+	VPSLLD  $0x0d, Y4, Y4
+	VPSLLD  $0x0d, Y5, Y5
+	VPSLLD  $0x0d, Y6, Y6
+	VPSLLD  $0x0d, Y7, Y7
+	VMOVDQU Y0, 256(AX)
+	VMOVDQU Y1, 288(AX)
+	VMOVDQU Y2, 320(AX)
+	VMOVDQU Y3, 352(AX)
+	VMOVDQU Y4, 384(AX)
+	VMOVDQU Y5, 416(AX)
+	VMOVDQU Y6, 448(AX)
+	VMOVDQU Y7, 480(AX)
+	VMOVDQU 512(CX), Y0
+	VMOVDQU 544(CX), Y1
+	VMOVDQU 576(CX), Y2
+	VMOVDQU 608(CX), Y3
+	VMOVDQU 640(CX), Y4
+	VMOVDQU 672(CX), Y5
+	VMOVDQU 704(CX), Y6
+	VMOVDQU 736(CX), Y7
+	VPSLLD  $0x0d, Y0, Y0
+	VPSLLD  $0x0d, Y1, Y1
+	VPSLLD  $0x0d, Y2, Y2
+	VPSLLD  $0x0d, Y3, Y3
+	VPSLLD  $0x0d, Y4, Y4
+	VPSLLD  $0x0d, Y5, Y5
+	VPSLLD  $0x0d, Y6, Y6
+	VPSLLD  $0x0d, Y7, Y7
+	VMOVDQU Y0, 512(AX)
+	VMOVDQU Y1, 544(AX)
+	VMOVDQU Y2, 576(AX)
+	VMOVDQU Y3, 608(AX)
+	VMOVDQU Y4, 640(AX)
+	VMOVDQU Y5, 672(AX)
+	VMOVDQU Y6, 704(AX)
+	VMOVDQU Y7, 736(AX)
+	VMOVDQU 768(CX), Y0
+	VMOVDQU 800(CX), Y1
+	VMOVDQU 832(CX), Y2
+	VMOVDQU 864(CX), Y3
+	VMOVDQU 896(CX), Y4
+	VMOVDQU 928(CX), Y5
+	VMOVDQU 960(CX), Y6
+	VMOVDQU 992(CX), Y7
+	VPSLLD  $0x0d, Y0, Y0
+	VPSLLD  $0x0d, Y1, Y1
+	VPSLLD  $0x0d, Y2, Y2
+	VPSLLD  $0x0d, Y3, Y3
+	VPSLLD  $0x0d, Y4, Y4
+	VPSLLD  $0x0d, Y5, Y5
+	VPSLLD  $0x0d, Y6, Y6
+	VPSLLD  $0x0d, Y7, Y7
+	VMOVDQU Y0, 768(AX)
+	VMOVDQU Y1, 800(AX)
+	VMOVDQU Y2, 832(AX)
+	VMOVDQU Y3, 864(AX)
+	VMOVDQU Y4, 896(AX)
+	VMOVDQU Y5, 928(AX)
+	VMOVDQU Y6, 960(AX)
+	VMOVDQU Y7, 992(AX)
+	RET
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/field.go b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/field.go
new file mode 100644
index 00000000..2aab16ec
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/field.go
@@ -0,0 +1,52 @@
+package common
+
+// Returns a y with y < 2q and y = x mod q.
+// Note that in general *not*: ReduceLe2Q(ReduceLe2Q(x)) == x.
+func ReduceLe2Q(x uint32) uint32 {
+	// Note 2²³ = 2¹³ - 1 mod q. So, writing  x = x₁ 2²³ + x₂ with x₂ < 2²³
+	// and x₁ < 2⁹, we have x = y (mod q) where
+	// y = x₂ + x₁ 2¹³ - x₁ ≤ 2²³ + 2¹³ < 2q.
+	x1 := x >> 23
+	x2 := x & 0x7FFFFF // 2²³-1
+	return x2 + (x1 << 13) - x1
+}
+
+// Returns x mod q.
+func modQ(x uint32) uint32 {
+	return le2qModQ(ReduceLe2Q(x))
+}
+
+// For x R ≤ q 2³², find y ≤ 2q with y = x mod q.
+func montReduceLe2Q(x uint64) uint32 {
+	// Qinv = 4236238847 = -(q⁻¹) mod 2³²
+	m := (x * Qinv) & 0xffffffff
+	return uint32((x + m*uint64(Q)) >> 32)
+}
+
+// Returns x mod q for 0 ≤ x < 2q.
+func le2qModQ(x uint32) uint32 {
+	x -= Q
+	mask := uint32(int32(x) >> 31) // mask is 2³²-1 if x was neg.; 0 otherwise
+	return x + (mask & Q)
+}
+
+// Splits 0 ≤ a < Q into a0 and a1 with a = a1*2ᴰ + a0
+// and -2ᴰ⁻¹ < a0 < 2ᴰ⁻¹.  Returns a0 + Q and a1.
+func power2round(a uint32) (a0plusQ, a1 uint32) {
+	// We effectively compute a0 = a mod± 2ᵈ
+	//                    and a1 = (a - a0) / 2ᵈ.
+	a0 := a & ((1 << D) - 1) // a mod 2ᵈ
+
+	// a0 is one of  0, 1, ..., 2ᵈ⁻¹-1, 2ᵈ⁻¹, 2ᵈ⁻¹+1, ..., 2ᵈ-1
+	a0 -= (1 << (D - 1)) + 1
+	// now a0 is     -2ᵈ⁻¹-1, -2ᵈ⁻¹, ..., -2, -1, 0, ..., 2ᵈ⁻¹-2
+	// Next, we add 2ᴰ to those a0 that are negative (seen as int32).
+	a0 += uint32(int32(a0)>>31) & (1 << D)
+	// now a0 is     2ᵈ⁻¹-1, 2ᵈ⁻¹, ..., 2ᵈ-2, 2ᵈ-1, 0, ..., 2ᵈ⁻¹-2
+	a0 -= (1 << (D - 1)) - 1
+	// now a0 id     0, 1, 2, ..., 2ᵈ⁻¹-1, 2ᵈ⁻¹-1, -2ᵈ⁻¹-1, ...
+	// which is what we want.
+	a0plusQ = Q + a0
+	a1 = (a - a0) >> D
+	return
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/generic.go b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/generic.go
new file mode 100644
index 00000000..2736e161
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/generic.go
@@ -0,0 +1,81 @@
+//go:build !amd64 || purego
+// +build !amd64 purego
+
+package common
+
+// Execute an in-place forward NTT on as.
+//
+// Assumes the coefficients are in Montgomery representation and bounded
+// by 2*Q.  The resulting coefficients are again in Montgomery representation,
+// but are only bounded bt 18*Q.
+func (p *Poly) NTT() {
+	p.nttGeneric()
+}
+
+// Execute an in-place inverse NTT and multiply by Montgomery factor R
+//
+// Assumes the coefficients are in Montgomery representation and bounded
+// by 2*Q.  The resulting coefficients are again in Montgomery representation
+// and bounded by 2*Q.
+func (p *Poly) InvNTT() {
+	p.invNttGeneric()
+}
+
+// Sets p to the polynomial whose coefficients are the pointwise multiplication
+// of those of a and b.  The coefficients of p are bounded by 2q.
+//
+// Assumes a and b are in Montgomery form and that the pointwise product
+// of each coefficient is below 2³² q.
+func (p *Poly) MulHat(a, b *Poly) {
+	p.mulHatGeneric(a, b)
+}
+
+// Sets p to a + b.  Does not normalize polynomials.
+func (p *Poly) Add(a, b *Poly) {
+	p.addGeneric(a, b)
+}
+
+// Sets p to a - b.
+//
+// Warning: assumes coefficients of b are less than 2q.
+// Sets p to a + b.  Does not normalize polynomials.
+func (p *Poly) Sub(a, b *Poly) {
+	p.subGeneric(a, b)
+}
+
+// Writes p whose coefficients are in [0, 16) to buf, which must be of
+// length N/2.
+func (p *Poly) PackLe16(buf []byte) {
+	p.packLe16Generic(buf)
+}
+
+// Reduces each of the coefficients to <2q.
+func (p *Poly) ReduceLe2Q() {
+	p.reduceLe2QGeneric()
+}
+
+// Reduce each of the coefficients to <q.
+func (p *Poly) Normalize() {
+	p.normalizeGeneric()
+}
+
+// Normalize the coefficients in this polynomial assuming they are already
+// bounded by 2q.
+func (p *Poly) NormalizeAssumingLe2Q() {
+	p.normalizeAssumingLe2QGeneric()
+}
+
+// Checks whether the "supnorm" (see sec 2.1 of the spec) of p is equal
+// or greater than the given bound.
+//
+// Requires the coefficients of p to be normalized.
+func (p *Poly) Exceeds(bound uint32) bool {
+	return p.exceedsGeneric(bound)
+}
+
+// Sets p to 2ᵈ q without reducing.
+//
+// So it requires the coefficients of p  to be less than 2³²⁻ᴰ.
+func (p *Poly) MulBy2toD(q *Poly) {
+	p.mulBy2toDGeneric(q)
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/ntt.go b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/ntt.go
new file mode 100644
index 00000000..6f5370ae
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/ntt.go
@@ -0,0 +1,217 @@
+package common
+
+// Zetas lists precomputed powers of the root of unity in Montgomery
+// representation used for the NTT:
+//
+//	Zetas[i] = zetaᵇʳᵛ⁽ⁱ⁾ R mod q,
+//
+// where zeta = 1753, brv(i) is the bitreversal of a 8-bit number
+// and R=2³² mod q.
+//
+// The following Python code generates the Zetas (and InvZetas) lists:
+//
+//	q = 2**23 - 2**13 + 1; zeta = 1753
+//	R = 2**32 % q # Montgomery const.
+//	def brv(x): return int(''.join(reversed(bin(x)[2:].zfill(8))),2)
+//	def inv(x): return pow(x, q-2, q) # inverse in F(q)
+//	print([(pow(zeta, brv(i), q)*R)%q for i in range(256)])
+//	print([(pow(inv(zeta), -(brv(255-i)-256), q)*R)%q for i in range(256)])
+var Zetas = [N]uint32{
+	4193792, 25847, 5771523, 7861508, 237124, 7602457, 7504169,
+	466468, 1826347, 2353451, 8021166, 6288512, 3119733, 5495562,
+	3111497, 2680103, 2725464, 1024112, 7300517, 3585928, 7830929,
+	7260833, 2619752, 6271868, 6262231, 4520680, 6980856, 5102745,
+	1757237, 8360995, 4010497, 280005, 2706023, 95776, 3077325,
+	3530437, 6718724, 4788269, 5842901, 3915439, 4519302, 5336701,
+	3574422, 5512770, 3539968, 8079950, 2348700, 7841118, 6681150,
+	6736599, 3505694, 4558682, 3507263, 6239768, 6779997, 3699596,
+	811944, 531354, 954230, 3881043, 3900724, 5823537, 2071892,
+	5582638, 4450022, 6851714, 4702672, 5339162, 6927966, 3475950,
+	2176455, 6795196, 7122806, 1939314, 4296819, 7380215, 5190273,
+	5223087, 4747489, 126922, 3412210, 7396998, 2147896, 2715295,
+	5412772, 4686924, 7969390, 5903370, 7709315, 7151892, 8357436,
+	7072248, 7998430, 1349076, 1852771, 6949987, 5037034, 264944,
+	508951, 3097992, 44288, 7280319, 904516, 3958618, 4656075,
+	8371839, 1653064, 5130689, 2389356, 8169440, 759969, 7063561,
+	189548, 4827145, 3159746, 6529015, 5971092, 8202977, 1315589,
+	1341330, 1285669, 6795489, 7567685, 6940675, 5361315, 4499357,
+	4751448, 3839961, 2091667, 3407706, 2316500, 3817976, 5037939,
+	2244091, 5933984, 4817955, 266997, 2434439, 7144689, 3513181,
+	4860065, 4621053, 7183191, 5187039, 900702, 1859098, 909542,
+	819034, 495491, 6767243, 8337157, 7857917, 7725090, 5257975,
+	2031748, 3207046, 4823422, 7855319, 7611795, 4784579, 342297,
+	286988, 5942594, 4108315, 3437287, 5038140, 1735879, 203044,
+	2842341, 2691481, 5790267, 1265009, 4055324, 1247620, 2486353,
+	1595974, 4613401, 1250494, 2635921, 4832145, 5386378, 1869119,
+	1903435, 7329447, 7047359, 1237275, 5062207, 6950192, 7929317,
+	1312455, 3306115, 6417775, 7100756, 1917081, 5834105, 7005614,
+	1500165, 777191, 2235880, 3406031, 7838005, 5548557, 6709241,
+	6533464, 5796124, 4656147, 594136, 4603424, 6366809, 2432395,
+	2454455, 8215696, 1957272, 3369112, 185531, 7173032, 5196991,
+	162844, 1616392, 3014001, 810149, 1652634, 4686184, 6581310,
+	5341501, 3523897, 3866901, 269760, 2213111, 7404533, 1717735,
+	472078, 7953734, 1723600, 6577327, 1910376, 6712985, 7276084,
+	8119771, 4546524, 5441381, 6144432, 7959518, 6094090, 183443,
+	7403526, 1612842, 4834730, 7826001, 3919660, 8332111, 7018208,
+	3937738, 1400424, 7534263, 1976782,
+}
+
+// InvZetas lists precomputed powers of the inverse root of unity in Montgomery
+// representation used for the inverse NTT:
+//
+//	InvZetas[i] = zetaᵇʳᵛ⁽²⁵⁵⁻ⁱ⁾⁻²⁵⁶ R mod q,
+//
+// where zeta = 1753, brv(i) is the bitreversal of a 8-bit number
+// and R=2³² mod q.
+var InvZetas = [N]uint32{
+	6403635, 846154, 6979993, 4442679, 1362209, 48306, 4460757,
+	554416, 3545687, 6767575, 976891, 8196974, 2286327, 420899,
+	2235985, 2939036, 3833893, 260646, 1104333, 1667432, 6470041,
+	1803090, 6656817, 426683, 7908339, 6662682, 975884, 6167306,
+	8110657, 4513516, 4856520, 3038916, 1799107, 3694233, 6727783,
+	7570268, 5366416, 6764025, 8217573, 3183426, 1207385, 8194886,
+	5011305, 6423145, 164721, 5925962, 5948022, 2013608, 3776993,
+	7786281, 3724270, 2584293, 1846953, 1671176, 2831860, 542412,
+	4974386, 6144537, 7603226, 6880252, 1374803, 2546312, 6463336,
+	1279661, 1962642, 5074302, 7067962, 451100, 1430225, 3318210,
+	7143142, 1333058, 1050970, 6476982, 6511298, 2994039, 3548272,
+	5744496, 7129923, 3767016, 6784443, 5894064, 7132797, 4325093,
+	7115408, 2590150, 5688936, 5538076, 8177373, 6644538, 3342277,
+	4943130, 4272102, 2437823, 8093429, 8038120, 3595838, 768622,
+	525098, 3556995, 5173371, 6348669, 3122442, 655327, 522500,
+	43260, 1613174, 7884926, 7561383, 7470875, 6521319, 7479715,
+	3193378, 1197226, 3759364, 3520352, 4867236, 1235728, 5945978,
+	8113420, 3562462, 2446433, 6136326, 3342478, 4562441, 6063917,
+	4972711, 6288750, 4540456, 3628969, 3881060, 3019102, 1439742,
+	812732, 1584928, 7094748, 7039087, 7064828, 177440, 2409325,
+	1851402, 5220671, 3553272, 8190869, 1316856, 7620448, 210977,
+	5991061, 3249728, 6727353, 8578, 3724342, 4421799, 7475901,
+	1100098, 8336129, 5282425, 7871466, 8115473, 3343383, 1430430,
+	6527646, 7031341, 381987, 1308169, 22981, 1228525, 671102,
+	2477047, 411027, 3693493, 2967645, 5665122, 6232521, 983419,
+	4968207, 8253495, 3632928, 3157330, 3190144, 1000202, 4083598,
+	6441103, 1257611, 1585221, 6203962, 4904467, 1452451, 3041255,
+	3677745, 1528703, 3930395, 2797779, 6308525, 2556880, 4479693,
+	4499374, 7426187, 7849063, 7568473, 4680821, 1600420, 2140649,
+	4873154, 3821735, 4874723, 1643818, 1699267, 539299, 6031717,
+	300467, 4840449, 2867647, 4805995, 3043716, 3861115, 4464978,
+	2537516, 3592148, 1661693, 4849980, 5303092, 8284641, 5674394,
+	8100412, 4369920, 19422, 6623180, 3277672, 1399561, 3859737,
+	2118186, 2108549, 5760665, 1119584, 549488, 4794489, 1079900,
+	7356305, 5654953, 5700314, 5268920, 2884855, 5260684, 2091905,
+	359251, 6026966, 6554070, 7913949, 876248, 777960, 8143293,
+	518909, 2608894, 8354570, 4186625,
+}
+
+// Execute an in-place forward NTT on as.
+//
+// Assumes the coefficients are in Montgomery representation and bounded
+// by 2*Q.  The resulting coefficients are again in Montgomery representation,
+// but are only bounded bt 18*Q.
+func (p *Poly) nttGeneric() {
+	// Writing z := zeta for our root of unity zeta := 1753, note z²⁵⁶=-1
+	// (otherwise the order of z wouldn't be 512) and so
+	//
+	//  x²⁵⁶ + 1 = x²⁵⁶ - z²⁵⁶
+	//           = (x¹²⁸ - z¹²⁸)(x¹²⁸ + z¹²⁸)
+	//           = (x⁶⁴ - z⁶⁴)(x⁶⁴ + z⁶⁴)(x⁶⁴ + z¹⁹²)(x⁶⁴ - z¹⁹²)
+	//          ...
+	//           = (x-z)(x+z)(x - z¹²⁹)(x + z¹²⁹) ... (x - z²⁵⁵)(x + z²⁵⁵)
+	//
+	// Note that the powers of z that appear (from the second line) are
+	//  in binary
+	//
+	//  01000000 11000000
+	//  00100000 10100000 01100000 11100000
+	//  00010000 10010000 01010000 11010000 00110000 10110000 01110000 11110000
+	//     ...
+	//
+	// i.e. brv(2), brv(3), brv(4), ... and these powers of z are given by
+	// the Zetas array.
+	//
+	// The polynomials x ± zⁱ are irreducible and coprime, hence by the
+	// Chinese Remainder Theorem we know
+	//
+	//  R[x]/(x²⁵⁶+1) → R[x] / (x-z) x ... x R[x] / (x+z²⁵⁵)
+	//                      ~= ∏_i R
+	//
+	// given by
+	//
+	//  a ↦ ( a mod x-z, ..., a mod x+z²⁵⁵ )
+	//    ~ ( a(z), a(-z), a(z¹²⁹), a(-z¹²⁹), ..., a(z²⁵⁵), a(-z²⁵⁵) )
+	//
+	// is an isomorphism, which is the forward NTT.  It can be computed
+	// efficiently by computing
+	//
+	//  a ↦ ( a mod x¹²⁸ - z¹²⁸, a mod x¹²⁸ + z¹²⁸ )
+	//    ↦ ( a mod x⁶⁴ - z⁶⁴,  a mod x⁶⁴ + z⁶⁴,
+	//        a mod x⁶⁴ - z¹⁹², a mod x⁶⁴ + z¹⁹² )
+	//       et cetera
+	//
+	// If N was 8 then this can be pictured in the following diagram:
+	//
+	//  https://cnx.org/resources/17ee4dfe517a6adda05377b25a00bf6e6c93c334/File0026.png
+	//
+	// Each cross is a Cooley--Tukey butterfly: it's the map
+	//
+	//      (a, b) ↦ (a + ζ, a - ζ)
+	//
+	// for the appropriate ζ for that column and row group.
+
+	k := 0 // Index into Zetas
+
+	// l runs effectively over the columns in the diagram above; it is
+	// half the height of a row group, i.e. the number of butterflies in
+	// each row group.  In the diagram above it would be 4, 2, 1.
+	for l := uint(N / 2); l > 0; l >>= 1 {
+		// On the n-th iteration of the l-loop, the coefficients start off
+		// bounded by n*2*Q.
+		//
+		// offset effectively loops over the row groups in this column; it
+		// is the first row in the row group.
+		for offset := uint(0); offset < N-l; offset += 2 * l {
+			k++
+			zeta := uint64(Zetas[k])
+
+			// j loops over each butterfly in the row group.
+			for j := offset; j < offset+l; j++ {
+				t := montReduceLe2Q(zeta * uint64(p[j+l]))
+				p[j+l] = p[j] + (2*Q - t) // Cooley--Tukey butterfly
+				p[j] += t
+			}
+		}
+	}
+}
+
+// Execute an in-place inverse NTT and multiply by Montgomery factor R
+//
+// Assumes the coefficients are in Montgomery representation and bounded
+// by 2*Q.  The resulting coefficients are again in Montgomery representation
+// and bounded by 2*Q.
+func (p *Poly) invNttGeneric() {
+	k := 0 // Index into InvZetas
+
+	// We basically do the opposite of NTT, but postpone dividing by 2 in the
+	// inverse of the Cooley--Tukey butterfly and accumulate that to a big
+	// division by 2⁸ at the end.  See comments in the NTT() function.
+
+	for l := uint(1); l < N; l <<= 1 {
+		// On the n-th iteration of the l-loop, the coefficients start off
+		// bounded by 2ⁿ⁻¹*2*Q, so by 256*Q on the last.
+		for offset := uint(0); offset < N-l; offset += 2 * l {
+			zeta := uint64(InvZetas[k])
+			k++
+			for j := offset; j < offset+l; j++ {
+				t := p[j] // Gentleman--Sande butterfly
+				p[j] = t + p[j+l]
+				t += 256*Q - p[j+l]
+				p[j+l] = montReduceLe2Q(zeta * uint64(t))
+			}
+		}
+	}
+
+	for j := uint(0); j < N; j++ {
+		// ROver256 = 41978 = (256)⁻¹ R²
+		p[j] = montReduceLe2Q(ROver256 * uint64(p[j]))
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/pack.go b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/pack.go
new file mode 100644
index 00000000..6c366089
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/pack.go
@@ -0,0 +1,160 @@
+package common
+
+// Sets p to the polynomial whose coefficients are less than 1024 encoded
+// into buf (which must be of size PolyT1Size).
+//
+// p will be normalized.
+func (p *Poly) UnpackT1(buf []byte) {
+	j := 0
+	for i := 0; i < PolyT1Size; i += 5 {
+		p[j] = (uint32(buf[i]) | (uint32(buf[i+1]) << 8)) & 0x3ff
+		p[j+1] = (uint32(buf[i+1]>>2) | (uint32(buf[i+2]) << 6)) & 0x3ff
+		p[j+2] = (uint32(buf[i+2]>>4) | (uint32(buf[i+3]) << 4)) & 0x3ff
+		p[j+3] = (uint32(buf[i+3]>>6) | (uint32(buf[i+4]) << 2)) & 0x3ff
+		j += 4
+	}
+}
+
+// Writes p whose coefficients are in (-2ᵈ⁻¹, 2ᵈ⁻¹] into buf which
+// has to be of length at least PolyT0Size.
+//
+// Assumes that the coefficients are not normalized, but lie in the
+// range (q-2ᵈ⁻¹, q+2ᵈ⁻¹].
+func (p *Poly) PackT0(buf []byte) {
+	j := 0
+	for i := 0; i < PolyT0Size; i += 13 {
+		p0 := Q + (1 << (D - 1)) - p[j]
+		p1 := Q + (1 << (D - 1)) - p[j+1]
+		p2 := Q + (1 << (D - 1)) - p[j+2]
+		p3 := Q + (1 << (D - 1)) - p[j+3]
+		p4 := Q + (1 << (D - 1)) - p[j+4]
+		p5 := Q + (1 << (D - 1)) - p[j+5]
+		p6 := Q + (1 << (D - 1)) - p[j+6]
+		p7 := Q + (1 << (D - 1)) - p[j+7]
+
+		buf[i] = byte(p0 >> 0)
+		buf[i+1] = byte(p0>>8) | byte(p1<<5)
+		buf[i+2] = byte(p1 >> 3)
+		buf[i+3] = byte(p1>>11) | byte(p2<<2)
+		buf[i+4] = byte(p2>>6) | byte(p3<<7)
+		buf[i+5] = byte(p3 >> 1)
+		buf[i+6] = byte(p3>>9) | byte(p4<<4)
+		buf[i+7] = byte(p4 >> 4)
+		buf[i+8] = byte(p4>>12) | byte(p5<<1)
+		buf[i+9] = byte(p5>>7) | byte(p6<<6)
+		buf[i+10] = byte(p6 >> 2)
+		buf[i+11] = byte(p6>>10) | byte(p7<<3)
+		buf[i+12] = byte(p7 >> 5)
+		j += 8
+	}
+}
+
+// Sets p to the polynomial packed into buf by PackT0.
+//
+// The coefficients of p will not be normalized, but will lie
+// in (-2ᵈ⁻¹, 2ᵈ⁻¹].
+func (p *Poly) UnpackT0(buf []byte) {
+	j := 0
+	for i := 0; i < PolyT0Size; i += 13 {
+		p[j] = Q + (1 << (D - 1)) - ((uint32(buf[i]) |
+			(uint32(buf[i+1]) << 8)) & 0x1fff)
+		p[j+1] = Q + (1 << (D - 1)) - (((uint32(buf[i+1]) >> 5) |
+			(uint32(buf[i+2]) << 3) |
+			(uint32(buf[i+3]) << 11)) & 0x1fff)
+		p[j+2] = Q + (1 << (D - 1)) - (((uint32(buf[i+3]) >> 2) |
+			(uint32(buf[i+4]) << 6)) & 0x1fff)
+		p[j+3] = Q + (1 << (D - 1)) - (((uint32(buf[i+4]) >> 7) |
+			(uint32(buf[i+5]) << 1) |
+			(uint32(buf[i+6]) << 9)) & 0x1fff)
+		p[j+4] = Q + (1 << (D - 1)) - (((uint32(buf[i+6]) >> 4) |
+			(uint32(buf[i+7]) << 4) |
+			(uint32(buf[i+8]) << 12)) & 0x1fff)
+		p[j+5] = Q + (1 << (D - 1)) - (((uint32(buf[i+8]) >> 1) |
+			(uint32(buf[i+9]) << 7)) & 0x1fff)
+		p[j+6] = Q + (1 << (D - 1)) - (((uint32(buf[i+9]) >> 6) |
+			(uint32(buf[i+10]) << 2) |
+			(uint32(buf[i+11]) << 10)) & 0x1fff)
+		p[j+7] = Q + (1 << (D - 1)) - ((uint32(buf[i+11]) >> 3) |
+			(uint32(buf[i+12]) << 5))
+
+		j += 8
+	}
+}
+
+// Writes p whose coefficients are less than 1024 into buf, which must be
+// of size at least PolyT1Size .
+//
+// Assumes coefficients of p are normalized.
+func (p *Poly) PackT1(buf []byte) {
+	j := 0
+	for i := 0; i < PolyT1Size; i += 5 {
+		buf[i] = byte(p[j])
+		buf[i+1] = byte(p[j]>>8) | byte(p[j+1]<<2)
+		buf[i+2] = byte(p[j+1]>>6) | byte(p[j+2]<<4)
+		buf[i+3] = byte(p[j+2]>>4) | byte(p[j+3]<<6)
+		buf[i+4] = byte(p[j+3] >> 2)
+		j += 4
+	}
+}
+
+// Writes p whose coefficients are in [0, 16) to buf, which must be of
+// length N/2.
+func (p *Poly) packLe16Generic(buf []byte) {
+	j := 0
+	for i := 0; i < PolyLe16Size; i++ {
+		buf[i] = byte(p[j]) | byte(p[j+1]<<4)
+		j += 2
+	}
+}
+
+// Writes p with 60 non-zero coefficients {-1,1} to buf, which must have
+// length 40.
+func (p *Poly) PackB60(buf []byte) {
+	// We start with a mask of the non-zero positions of p (which is 32 bytes)
+	// and then append 60 packed bits, where a one indicates a negative
+	// coefficients.
+	var signs uint64
+	mask := uint64(1)
+	for i := 0; i < 32; i++ {
+		buf[i] = 0
+		for j := 0; j < 8; j++ {
+			if p[8*i+j] != 0 {
+				buf[i] |= 1 << uint(j)
+				if p[8*i+j] == Q-1 {
+					signs |= mask
+				}
+				mask <<= 1
+			}
+		}
+	}
+	for i := uint64(0); i < 8; i++ {
+		buf[i+32] = uint8(signs >> (8 * i))
+	}
+}
+
+// UnpackB60 sets p to the polynomial packed into buf with Poly.PackB60().
+//
+// Returns whether unpacking was successful.
+func (p *Poly) UnpackB60(buf []byte) bool {
+	*p = Poly{} // zero p
+	signs := (uint64(buf[32]) | (uint64(buf[33]) << 8) |
+		(uint64(buf[34]) << 16) | (uint64(buf[35]) << 24) |
+		(uint64(buf[36]) << 32) | (uint64(buf[37]) << 40) |
+		(uint64(buf[38]) << 48) | (uint64(buf[39]) << 56))
+	if signs>>60 != 0 {
+		return false // ensure unused bits are zero for strong unforgeability
+	}
+
+	for i := 0; i < 32; i++ {
+		for j := 0; j < 8; j++ {
+			if (buf[i]>>uint(j))&1 == 1 {
+				p[8*i+j] = 1
+				// Note 1 ^ (1 | (Q-1)) = Q-1 and (-1)&x = x
+				p[8*i+j] ^= uint32(-(signs & 1)) & (1 | (Q - 1))
+				signs >>= 1
+			}
+		}
+	}
+
+	return true
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/params.go b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/params.go
new file mode 100644
index 00000000..7713c6da
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/params.go
@@ -0,0 +1,18 @@
+package common
+
+import (
+	"github.com/cloudflare/circl/sign/dilithium/internal/common/params"
+)
+
+const (
+	SeedSize     = params.SeedSize
+	N            = params.N
+	Q            = params.Q
+	QBits        = params.QBits
+	Qinv         = params.Qinv
+	ROver256     = params.ROver256
+	D            = params.D
+	PolyT1Size   = params.PolyT1Size
+	PolyT0Size   = params.PolyT0Size
+	PolyLe16Size = params.PolyLe16Size
+)
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/params/params.go b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/params/params.go
new file mode 100644
index 00000000..2df20e3a
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/params/params.go
@@ -0,0 +1,25 @@
+package params
+
+// We put these parameters in a separate package so that the Go code,
+// such as ntt_amd64_src.go, that generates assembler can import it.
+
+const (
+	SeedSize = 32
+	N        = 256
+	Q        = 8380417 // 2²³ - 2¹³ + 1
+	QBits    = 23
+	Qinv     = 4236238847 // = -(q^-1) mod 2³²
+	ROver256 = 41978      // = (256)⁻¹ R² mod q, where R=2³²
+	D        = 13
+
+	// Size of T1 packed.  (Note that the formula is not valid in general,
+	// but it is for the parameters used in the modes of Dilithium.)
+	PolyT1Size = (N * (QBits - D)) / 8
+
+	// Size of T0 packed.  (Note that the formula is not valid in general,
+	// but it is for the parameters used in the modes of Dilithium.)
+	PolyT0Size = (N * D) / 8
+
+	// Size of a packed polynomial whose coefficients are in [0,16).
+	PolyLe16Size = N / 2
+)
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/poly.go b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/poly.go
new file mode 100644
index 00000000..7ac8e57d
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/poly.go
@@ -0,0 +1,101 @@
+package common
+
+// An element of our base ring R which are polynomials over Z_q modulo
+// the equation Xᴺ = -1, where q=2²³ - 2¹³ + 1 and N=256.
+//
+// Coefficients aren't always reduced.  See Normalize().
+type Poly [N]uint32
+
+// Reduces each of the coefficients to <2q.
+func (p *Poly) reduceLe2QGeneric() {
+	for i := uint(0); i < N; i++ {
+		p[i] = ReduceLe2Q(p[i])
+	}
+}
+
+// Reduce each of the coefficients to <q.
+func (p *Poly) normalizeGeneric() {
+	for i := uint(0); i < N; i++ {
+		p[i] = modQ(p[i])
+	}
+}
+
+// Normalize the coefficients in this polynomial assuming they are already
+// bounded by 2q.
+func (p *Poly) normalizeAssumingLe2QGeneric() {
+	for i := 0; i < N; i++ {
+		p[i] = le2qModQ(p[i])
+	}
+}
+
+// Sets p to a + b.  Does not normalize polynomials.
+func (p *Poly) addGeneric(a, b *Poly) {
+	for i := uint(0); i < N; i++ {
+		p[i] = a[i] + b[i]
+	}
+}
+
+// Sets p to a - b.
+//
+// Warning: assumes coefficients of b are less than 2q.
+func (p *Poly) subGeneric(a, b *Poly) {
+	for i := uint(0); i < N; i++ {
+		p[i] = a[i] + (2*Q - b[i])
+	}
+}
+
+// Checks whether the "supnorm" (see sec 2.1 of the spec) of p is equal
+// or greater than the given bound.
+//
+// Requires the coefficients of p to be normalized.
+func (p *Poly) exceedsGeneric(bound uint32) bool {
+	// Note that we are allowed to leak which coefficients break the bound,
+	// but not their sign.
+	for i := 0; i < N; i++ {
+		// The central. reps. of {0,       1, ..., (Q-1)/2,  (Q+1)/2, ..., Q-1}
+		// are given by          {0,       1, ..., (Q-1)/2, -(Q-1)/2, ...,  -1}
+		// so their norms are    {0,       1, ..., (Q-1)/2,  (Q-1)/2, ...,   1}.
+		// We'll compute them in a different way though.
+
+		// Sets x to             {(Q-1)/2, (Q-3)/2, ..., 0, -1, ..., -(Q-1)/2}
+		x := int32((Q-1)/2) - int32(p[i])
+		// Sets x to             {(Q-1)/2, (Q-3)/2, ..., 0, 0, ...,  (Q-3)/2}
+		x ^= (x >> 31)
+		// Sets x to             {0,       1, ...,  (Q-1)/2, (Q-1)/2, ..., 1}
+		x = int32((Q-1)/2) - x
+		if uint32(x) >= bound {
+			return true
+		}
+	}
+	return false
+}
+
+// Splits p into p1 and p0 such that [i]p1 * 2ᴰ + [i]p0 = [i]p
+// with -2ᴰ⁻¹ < [i]p0 ≤ 2ᴰ⁻¹.  Returns p0 + Q and p1.
+//
+// Requires the coefficients of p to be normalized.
+func (p *Poly) Power2Round(p0PlusQ, p1 *Poly) {
+	for i := 0; i < N; i++ {
+		p0PlusQ[i], p1[i] = power2round(p[i])
+	}
+}
+
+// Sets p to the polynomial whose coefficients are the pointwise multiplication
+// of those of a and b.  The coefficients of p are bounded by 2q.
+//
+// Assumes a and b are in Montgomery form and that the pointwise product
+// of each coefficient is below 2³² q.
+func (p *Poly) mulHatGeneric(a, b *Poly) {
+	for i := 0; i < N; i++ {
+		p[i] = montReduceLe2Q(uint64(a[i]) * uint64(b[i]))
+	}
+}
+
+// Sets p to 2ᵈ q without reducing.
+//
+// So it requires the coefficients of p  to be less than 2³²⁻ᴰ.
+func (p *Poly) mulBy2toDGeneric(q *Poly) {
+	for i := 0; i < N; i++ {
+		p[i] = q[i] << D
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/stubs_amd64.go b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/stubs_amd64.go
new file mode 100644
index 00000000..3afeda4d
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/internal/common/stubs_amd64.go
@@ -0,0 +1,35 @@
+// Code generated by command: go run src.go -out ../amd64.s -stubs ../stubs_amd64.go -pkg common. DO NOT EDIT.
+
+//go:build amd64 && !purego
+
+package common
+
+//go:noescape
+func nttAVX2(p *[256]uint32)
+
+//go:noescape
+func invNttAVX2(p *[256]uint32)
+
+//go:noescape
+func mulHatAVX2(p *[256]uint32, a *[256]uint32, b *[256]uint32)
+
+//go:noescape
+func addAVX2(p *[256]uint32, a *[256]uint32, b *[256]uint32)
+
+//go:noescape
+func subAVX2(p *[256]uint32, a *[256]uint32, b *[256]uint32)
+
+//go:noescape
+func packLe16AVX2(p *[256]uint32, buf *byte)
+
+//go:noescape
+func reduceLe2QAVX2(p *[256]uint32)
+
+//go:noescape
+func le2qModQAVX2(p *[256]uint32)
+
+//go:noescape
+func exceedsAVX2(p *[256]uint32, bound uint32) uint8
+
+//go:noescape
+func mulBy2toDAVX2(p *[256]uint32, q *[256]uint32)
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/dilithium.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/dilithium.go
new file mode 100644
index 00000000..13ac869a
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/dilithium.go
@@ -0,0 +1,181 @@
+// Code generated from modePkg.templ.go. DO NOT EDIT.
+
+// mode2 implements the CRYSTALS-Dilithium signature scheme Dilithium2
+// as submitted to round3 of the NIST PQC competition and described in
+//
+// https://pq-crystals.org/dilithium/data/dilithium-specification-round3-20210208.pdf
+package mode2
+
+import (
+	"crypto"
+	"errors"
+	"io"
+
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+	"github.com/cloudflare/circl/sign/dilithium/mode2/internal"
+)
+
+const (
+	// Size of seed for NewKeyFromSeed
+	SeedSize = common.SeedSize
+
+	// Size of a packed PublicKey
+	PublicKeySize = internal.PublicKeySize
+
+	// Size of a packed PrivateKey
+	PrivateKeySize = internal.PrivateKeySize
+
+	// Size of a signature
+	SignatureSize = internal.SignatureSize
+)
+
+// PublicKey is the type of Dilithium2 public key
+type PublicKey internal.PublicKey
+
+// PrivateKey is the type of Dilithium2 private key
+type PrivateKey internal.PrivateKey
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
+	pk, sk, err := internal.GenerateKey(rand)
+	return (*PublicKey)(pk), (*PrivateKey)(sk), err
+}
+
+// NewKeyFromSeed derives a public/private key pair using the given seed.
+func NewKeyFromSeed(seed *[SeedSize]byte) (*PublicKey, *PrivateKey) {
+	pk, sk := internal.NewKeyFromSeed(seed)
+	return (*PublicKey)(pk), (*PrivateKey)(sk)
+}
+
+// SignTo signs the given message and writes the signature into signature.
+// It will panic if signature is not of length at least SignatureSize.
+func SignTo(sk *PrivateKey, msg []byte, signature []byte) {
+	internal.SignTo(
+		(*internal.PrivateKey)(sk),
+		msg,
+		signature,
+	)
+}
+
+// Verify checks whether the given signature by pk on msg is valid.
+func Verify(pk *PublicKey, msg []byte, signature []byte) bool {
+	return internal.Verify(
+		(*internal.PublicKey)(pk),
+		msg,
+		signature,
+	)
+}
+
+// Sets pk to the public key encoded in buf.
+func (pk *PublicKey) Unpack(buf *[PublicKeySize]byte) {
+	(*internal.PublicKey)(pk).Unpack(buf)
+}
+
+// Sets sk to the private key encoded in buf.
+func (sk *PrivateKey) Unpack(buf *[PrivateKeySize]byte) {
+	(*internal.PrivateKey)(sk).Unpack(buf)
+}
+
+// Packs the public key into buf.
+func (pk *PublicKey) Pack(buf *[PublicKeySize]byte) {
+	(*internal.PublicKey)(pk).Pack(buf)
+}
+
+// Packs the private key into buf.
+func (sk *PrivateKey) Pack(buf *[PrivateKeySize]byte) {
+	(*internal.PrivateKey)(sk).Pack(buf)
+}
+
+// Packs the public key.
+func (pk *PublicKey) Bytes() []byte {
+	var buf [PublicKeySize]byte
+	pk.Pack(&buf)
+	return buf[:]
+}
+
+// Packs the private key.
+func (sk *PrivateKey) Bytes() []byte {
+	var buf [PrivateKeySize]byte
+	sk.Pack(&buf)
+	return buf[:]
+}
+
+// Packs the public key.
+func (pk *PublicKey) MarshalBinary() ([]byte, error) {
+	return pk.Bytes(), nil
+}
+
+// Packs the private key.
+func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
+	return sk.Bytes(), nil
+}
+
+// Unpacks the public key from data.
+func (pk *PublicKey) UnmarshalBinary(data []byte) error {
+	if len(data) != PublicKeySize {
+		return errors.New("packed public key must be of mode2.PublicKeySize bytes")
+	}
+	var buf [PublicKeySize]byte
+	copy(buf[:], data)
+	pk.Unpack(&buf)
+	return nil
+}
+
+// Unpacks the private key from data.
+func (sk *PrivateKey) UnmarshalBinary(data []byte) error {
+	if len(data) != PrivateKeySize {
+		return errors.New("packed private key must be of mode2.PrivateKeySize bytes")
+	}
+	var buf [PrivateKeySize]byte
+	copy(buf[:], data)
+	sk.Unpack(&buf)
+	return nil
+}
+
+// Sign signs the given message.
+//
+// opts.HashFunc() must return zero, which can be achieved by passing
+// crypto.Hash(0) for opts.  rand is ignored.  Will only return an error
+// if opts.HashFunc() is non-zero.
+//
+// This function is used to make PrivateKey implement the crypto.Signer
+// interface.  The package-level SignTo function might be more convenient
+// to use.
+func (sk *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) (
+	signature []byte, err error) {
+	var sig [SignatureSize]byte
+
+	if opts.HashFunc() != crypto.Hash(0) {
+		return nil, errors.New("dilithium: cannot sign hashed message")
+	}
+
+	SignTo(sk, msg, sig[:])
+	return sig[:], nil
+}
+
+// Computes the public key corresponding to this private key.
+//
+// Returns a *PublicKey.  The type crypto.PublicKey is used to make
+// PrivateKey implement the crypto.Signer interface.
+func (sk *PrivateKey) Public() crypto.PublicKey {
+	return (*PublicKey)((*internal.PrivateKey)(sk).Public())
+}
+
+// Equal returns whether the two private keys equal.
+func (sk *PrivateKey) Equal(other crypto.PrivateKey) bool {
+	castOther, ok := other.(*PrivateKey)
+	if !ok {
+		return false
+	}
+	return (*internal.PrivateKey)(sk).Equal((*internal.PrivateKey)(castOther))
+}
+
+// Equal returns whether the two public keys equal.
+func (pk *PublicKey) Equal(other crypto.PublicKey) bool {
+	castOther, ok := other.(*PublicKey)
+	if !ok {
+		return false
+	}
+	return (*internal.PublicKey)(pk).Equal((*internal.PublicKey)(castOther))
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/dilithium.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/dilithium.go
new file mode 100644
index 00000000..79a17d50
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/dilithium.go
@@ -0,0 +1,477 @@
+// Code generated from mode3/internal/dilithium.go by gen.go
+
+package internal
+
+import (
+	cryptoRand "crypto/rand"
+	"crypto/subtle"
+	"io"
+
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+)
+
+const (
+	// Size of a packed polynomial of norm ≤η.
+	// (Note that the  formula is not valid in general.)
+	PolyLeqEtaSize = (common.N * DoubleEtaBits) / 8
+
+	// β = τη, the maximum size of c s₂.
+	Beta = Tau * Eta
+
+	// γ₁ range of y
+	Gamma1 = 1 << Gamma1Bits
+
+	// Size of packed polynomial of norm <γ₁ such as z
+	PolyLeGamma1Size = (Gamma1Bits + 1) * common.N / 8
+
+	// α = 2γ₂ parameter for decompose
+	Alpha = 2 * Gamma2
+
+	// Size of a packed private key
+	PrivateKeySize = 32 + 32 + 32 + PolyLeqEtaSize*(L+K) + common.PolyT0Size*K
+
+	// Size of a packed public key
+	PublicKeySize = 32 + common.PolyT1Size*K
+
+	// Size of a packed signature
+	SignatureSize = L*PolyLeGamma1Size + Omega + K + 32
+
+	// Size of packed w₁
+	PolyW1Size = (common.N * (common.QBits - Gamma1Bits)) / 8
+)
+
+// PublicKey is the type of Dilithium public keys.
+type PublicKey struct {
+	rho [32]byte
+	t1  VecK
+
+	// Cached values
+	t1p [common.PolyT1Size * K]byte
+	A   *Mat
+	tr  *[32]byte
+}
+
+// PrivateKey is the type of Dilithium private keys.
+type PrivateKey struct {
+	rho [32]byte
+	key [32]byte
+	s1  VecL
+	s2  VecK
+	t0  VecK
+	tr  [32]byte
+
+	// Cached values
+	A   Mat  // ExpandA(ρ)
+	s1h VecL // NTT(s₁)
+	s2h VecK // NTT(s₂)
+	t0h VecK // NTT(t₀)
+}
+
+type unpackedSignature struct {
+	z    VecL
+	hint VecK
+	c    [32]byte
+}
+
+// Packs the signature into buf.
+func (sig *unpackedSignature) Pack(buf []byte) {
+	copy(buf[:], sig.c[:])
+	sig.z.PackLeGamma1(buf[32:])
+	sig.hint.PackHint(buf[32+L*PolyLeGamma1Size:])
+}
+
+// Sets sig to the signature encoded in the buffer.
+//
+// Returns whether buf contains a properly packed signature.
+func (sig *unpackedSignature) Unpack(buf []byte) bool {
+	if len(buf) < SignatureSize {
+		return false
+	}
+	copy(sig.c[:], buf[:])
+	sig.z.UnpackLeGamma1(buf[32:])
+	if sig.z.Exceeds(Gamma1 - Beta) {
+		return false
+	}
+	if !sig.hint.UnpackHint(buf[32+L*PolyLeGamma1Size:]) {
+		return false
+	}
+	return true
+}
+
+// Packs the public key into buf.
+func (pk *PublicKey) Pack(buf *[PublicKeySize]byte) {
+	copy(buf[:32], pk.rho[:])
+	copy(buf[32:], pk.t1p[:])
+}
+
+// Sets pk to the public key encoded in buf.
+func (pk *PublicKey) Unpack(buf *[PublicKeySize]byte) {
+	copy(pk.rho[:], buf[:32])
+	copy(pk.t1p[:], buf[32:])
+
+	pk.t1.UnpackT1(pk.t1p[:])
+	pk.A = new(Mat)
+	pk.A.Derive(&pk.rho)
+
+	// tr = CRH(ρ ‖ t1) = CRH(pk)
+	pk.tr = new([32]byte)
+	h := sha3.NewShake256()
+	_, _ = h.Write(buf[:])
+	_, _ = h.Read(pk.tr[:])
+}
+
+// Packs the private key into buf.
+func (sk *PrivateKey) Pack(buf *[PrivateKeySize]byte) {
+	copy(buf[:32], sk.rho[:])
+	copy(buf[32:64], sk.key[:])
+	copy(buf[64:96], sk.tr[:])
+	offset := 96
+	sk.s1.PackLeqEta(buf[offset:])
+	offset += PolyLeqEtaSize * L
+	sk.s2.PackLeqEta(buf[offset:])
+	offset += PolyLeqEtaSize * K
+	sk.t0.PackT0(buf[offset:])
+}
+
+// Sets sk to the private key encoded in buf.
+func (sk *PrivateKey) Unpack(buf *[PrivateKeySize]byte) {
+	copy(sk.rho[:], buf[:32])
+	copy(sk.key[:], buf[32:64])
+	copy(sk.tr[:], buf[64:96])
+	offset := 96
+	sk.s1.UnpackLeqEta(buf[offset:])
+	offset += PolyLeqEtaSize * L
+	sk.s2.UnpackLeqEta(buf[offset:])
+	offset += PolyLeqEtaSize * K
+	sk.t0.UnpackT0(buf[offset:])
+
+	// Cached values
+	sk.A.Derive(&sk.rho)
+	sk.t0h = sk.t0
+	sk.t0h.NTT()
+	sk.s1h = sk.s1
+	sk.s1h.NTT()
+	sk.s2h = sk.s2
+	sk.s2h.NTT()
+}
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
+	var seed [32]byte
+	if rand == nil {
+		rand = cryptoRand.Reader
+	}
+	_, err := io.ReadFull(rand, seed[:])
+	if err != nil {
+		return nil, nil, err
+	}
+	pk, sk := NewKeyFromSeed(&seed)
+	return pk, sk, nil
+}
+
+// NewKeyFromSeed derives a public/private key pair using the given seed.
+func NewKeyFromSeed(seed *[common.SeedSize]byte) (*PublicKey, *PrivateKey) {
+	var eSeed [128]byte // expanded seed
+	var pk PublicKey
+	var sk PrivateKey
+	var sSeed [64]byte
+
+	h := sha3.NewShake256()
+	_, _ = h.Write(seed[:])
+	_, _ = h.Read(eSeed[:])
+
+	copy(pk.rho[:], eSeed[:32])
+	copy(sSeed[:], eSeed[32:96])
+	copy(sk.key[:], eSeed[96:])
+	copy(sk.rho[:], pk.rho[:])
+
+	sk.A.Derive(&pk.rho)
+
+	for i := uint16(0); i < L; i++ {
+		PolyDeriveUniformLeqEta(&sk.s1[i], &sSeed, i)
+	}
+
+	for i := uint16(0); i < K; i++ {
+		PolyDeriveUniformLeqEta(&sk.s2[i], &sSeed, i+L)
+	}
+
+	sk.s1h = sk.s1
+	sk.s1h.NTT()
+	sk.s2h = sk.s2
+	sk.s2h.NTT()
+
+	sk.computeT0andT1(&sk.t0, &pk.t1)
+
+	sk.t0h = sk.t0
+	sk.t0h.NTT()
+
+	// Complete public key far enough to be packed
+	pk.t1.PackT1(pk.t1p[:])
+	pk.A = &sk.A
+
+	// Finish private key
+	var packedPk [PublicKeySize]byte
+	pk.Pack(&packedPk)
+
+	// tr = CRH(ρ ‖ t1) = CRH(pk)
+	h.Reset()
+	_, _ = h.Write(packedPk[:])
+	_, _ = h.Read(sk.tr[:])
+
+	// Finish cache of public key
+	pk.tr = &sk.tr
+
+	return &pk, &sk
+}
+
+// Computes t0 and t1 from sk.s1h, sk.s2 and sk.A.
+func (sk *PrivateKey) computeT0andT1(t0, t1 *VecK) {
+	var t VecK
+
+	// Set t to A s₁ + s₂
+	for i := 0; i < K; i++ {
+		PolyDotHat(&t[i], &sk.A[i], &sk.s1h)
+		t[i].ReduceLe2Q()
+		t[i].InvNTT()
+	}
+	t.Add(&t, &sk.s2)
+	t.Normalize()
+
+	// Compute t₀, t₁ = Power2Round(t)
+	t.Power2Round(t0, t1)
+}
+
+// Verify checks whether the given signature by pk on msg is valid.
+func Verify(pk *PublicKey, msg []byte, signature []byte) bool {
+	var sig unpackedSignature
+	var mu [64]byte
+	var zh VecL
+	var Az, Az2dct1, w1 VecK
+	var ch common.Poly
+	var cp [32]byte
+	var w1Packed [PolyW1Size * K]byte
+
+	// Note that Unpack() checked whether ‖z‖_∞ < γ₁ - β
+	// and ensured that there at most ω ones in pk.hint.
+	if !sig.Unpack(signature) {
+		return false
+	}
+
+	// μ = CRH(tr ‖ msg)
+	h := sha3.NewShake256()
+	_, _ = h.Write(pk.tr[:])
+	_, _ = h.Write(msg)
+	_, _ = h.Read(mu[:])
+
+	// Compute Az
+	zh = sig.z
+	zh.NTT()
+
+	for i := 0; i < K; i++ {
+		PolyDotHat(&Az[i], &pk.A[i], &zh)
+	}
+
+	// Next, we compute Az - 2ᵈ·c·t₁.
+	// Note that the coefficients of t₁ are bounded by 256 = 2⁹,
+	// so the coefficients of Az2dct1 will bounded by 2⁹⁺ᵈ = 2²³ < 2q,
+	// which is small enough for NTT().
+	Az2dct1.MulBy2toD(&pk.t1)
+	Az2dct1.NTT()
+	PolyDeriveUniformBall(&ch, &sig.c)
+	ch.NTT()
+	for i := 0; i < K; i++ {
+		Az2dct1[i].MulHat(&Az2dct1[i], &ch)
+	}
+	Az2dct1.Sub(&Az, &Az2dct1)
+	Az2dct1.ReduceLe2Q()
+	Az2dct1.InvNTT()
+	Az2dct1.NormalizeAssumingLe2Q()
+
+	// UseHint(pk.hint, Az - 2ᵈ·c·t₁)
+	//    = UseHint(pk.hint, w - c·s₂ + c·t₀)
+	//    = UseHint(pk.hint, r + c·t₀)
+	//    = r₁ = w₁.
+	w1.UseHint(&Az2dct1, &sig.hint)
+	w1.PackW1(w1Packed[:])
+
+	// c' = H(μ, w₁)
+	h.Reset()
+	_, _ = h.Write(mu[:])
+	_, _ = h.Write(w1Packed[:])
+	_, _ = h.Read(cp[:])
+
+	return sig.c == cp
+}
+
+// SignTo signs the given message and writes the signature into signature.
+//
+//nolint:funlen
+func SignTo(sk *PrivateKey, msg []byte, signature []byte) {
+	var mu, rhop [64]byte
+	var w1Packed [PolyW1Size * K]byte
+	var y, yh VecL
+	var w, w0, w1, w0mcs2, ct0, w0mcs2pct0 VecK
+	var ch common.Poly
+	var yNonce uint16
+	var sig unpackedSignature
+
+	if len(signature) < SignatureSize {
+		panic("Signature does not fit in that byteslice")
+	}
+
+	//  μ = CRH(tr ‖ msg)
+	h := sha3.NewShake256()
+	_, _ = h.Write(sk.tr[:])
+	_, _ = h.Write(msg)
+	_, _ = h.Read(mu[:])
+
+	// ρ' = CRH(key ‖ μ)
+	h.Reset()
+	_, _ = h.Write(sk.key[:])
+	_, _ = h.Write(mu[:])
+	_, _ = h.Read(rhop[:])
+
+	// Main rejection loop
+	attempt := 0
+	for {
+		attempt++
+		if attempt >= 576 {
+			// Depending on the mode, one try has a chance between 1/7 and 1/4
+			// of succeeding.  Thus it is safe to say that 576 iterations
+			// are enough as (6/7)⁵⁷⁶ < 2⁻¹²⁸.
+			panic("This should only happen 1 in  2^{128}: something is wrong.")
+		}
+
+		// y = ExpandMask(ρ', key)
+		VecLDeriveUniformLeGamma1(&y, &rhop, yNonce)
+		yNonce += uint16(L)
+
+		// Set w to A y
+		yh = y
+		yh.NTT()
+		for i := 0; i < K; i++ {
+			PolyDotHat(&w[i], &sk.A[i], &yh)
+			w[i].ReduceLe2Q()
+			w[i].InvNTT()
+		}
+
+		// Decompose w into w₀ and w₁
+		w.NormalizeAssumingLe2Q()
+		w.Decompose(&w0, &w1)
+
+		// c~ = H(μ ‖ w₁)
+		w1.PackW1(w1Packed[:])
+		h.Reset()
+		_, _ = h.Write(mu[:])
+		_, _ = h.Write(w1Packed[:])
+		_, _ = h.Read(sig.c[:])
+
+		PolyDeriveUniformBall(&ch, &sig.c)
+		ch.NTT()
+
+		// Ensure ‖ w₀ - c·s2 ‖_∞ < γ₂ - β.
+		//
+		// By Lemma 3 of the specification this is equivalent to checking that
+		// both ‖ r₀ ‖_∞ < γ₂ - β and r₁ = w₁, for the decomposition
+		// w - c·s₂	 = r₁ α + r₀ as computed by decompose().
+		// See also §4.1 of the specification.
+		for i := 0; i < K; i++ {
+			w0mcs2[i].MulHat(&ch, &sk.s2h[i])
+			w0mcs2[i].InvNTT()
+		}
+		w0mcs2.Sub(&w0, &w0mcs2)
+		w0mcs2.Normalize()
+
+		if w0mcs2.Exceeds(Gamma2 - Beta) {
+			continue
+		}
+
+		// z = y + c·s₁
+		for i := 0; i < L; i++ {
+			sig.z[i].MulHat(&ch, &sk.s1h[i])
+			sig.z[i].InvNTT()
+		}
+		sig.z.Add(&sig.z, &y)
+		sig.z.Normalize()
+
+		// Ensure  ‖z‖_∞ < γ₁ - β
+		if sig.z.Exceeds(Gamma1 - Beta) {
+			continue
+		}
+
+		// Compute c·t₀
+		for i := 0; i < K; i++ {
+			ct0[i].MulHat(&ch, &sk.t0h[i])
+			ct0[i].InvNTT()
+		}
+		ct0.NormalizeAssumingLe2Q()
+
+		// Ensure ‖c·t₀‖_∞ < γ₂.
+		if ct0.Exceeds(Gamma2) {
+			continue
+		}
+
+		// Create the hint to be able to reconstruct w₁ from w - c·s₂ + c·t0.
+		// Note that we're not using makeHint() in the obvious way as we
+		// do not know whether ‖ sc·s₂ - c·t₀ ‖_∞ < γ₂.  Instead we note
+		// that our makeHint() is actually the same as a makeHint for a
+		// different decomposition:
+		//
+		// Earlier we ensured indirectly with a check that r₁ = w₁ where
+		// r = w - c·s₂.  Hence r₀ = r - r₁ α = w - c·s₂ - w₁ α = w₀ - c·s₂.
+		// Thus  MakeHint(w₀ - c·s₂ + c·t₀, w₁) = MakeHint(r0 + c·t₀, r₁)
+		// and UseHint(w - c·s₂ + c·t₀, w₁) = UseHint(r + c·t₀, r₁).
+		// As we just ensured that ‖ c·t₀ ‖_∞ < γ₂ our usage is correct.
+		w0mcs2pct0.Add(&w0mcs2, &ct0)
+		w0mcs2pct0.NormalizeAssumingLe2Q()
+		hintPop := sig.hint.MakeHint(&w0mcs2pct0, &w1)
+		if hintPop > Omega {
+			continue
+		}
+
+		break
+	}
+
+	sig.Pack(signature[:])
+}
+
+// Computes the public key corresponding to this private key.
+func (sk *PrivateKey) Public() *PublicKey {
+	var t0 VecK
+	pk := &PublicKey{
+		rho: sk.rho,
+		A:   &sk.A,
+		tr:  &sk.tr,
+	}
+	sk.computeT0andT1(&t0, &pk.t1)
+	pk.t1.PackT1(pk.t1p[:])
+	return pk
+}
+
+// Equal returns whether the two public keys are equal
+func (pk *PublicKey) Equal(other *PublicKey) bool {
+	return pk.rho == other.rho && pk.t1 == other.t1
+}
+
+// Equal returns whether the two private keys are equal
+func (sk *PrivateKey) Equal(other *PrivateKey) bool {
+	ret := (subtle.ConstantTimeCompare(sk.rho[:], other.rho[:]) &
+		subtle.ConstantTimeCompare(sk.key[:], other.key[:]) &
+		subtle.ConstantTimeCompare(sk.tr[:], other.tr[:]))
+
+	acc := uint32(0)
+	for i := 0; i < L; i++ {
+		for j := 0; j < common.N; j++ {
+			acc |= sk.s1[i][j] ^ other.s1[i][j]
+		}
+	}
+	for i := 0; i < K; i++ {
+		for j := 0; j < common.N; j++ {
+			acc |= sk.s2[i][j] ^ other.s2[i][j]
+			acc |= sk.t0[i][j] ^ other.t0[i][j]
+		}
+	}
+	return (ret & subtle.ConstantTimeEq(int32(acc), 0)) == 1
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/mat.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/mat.go
new file mode 100644
index 00000000..cb473c14
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/mat.go
@@ -0,0 +1,59 @@
+// Code generated from mode3/internal/mat.go by gen.go
+
+package internal
+
+import (
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+)
+
+// A k by l matrix of polynomials.
+type Mat [K]VecL
+
+// Expands the given seed to a complete matrix.
+//
+// This function is called ExpandA in the specification.
+func (m *Mat) Derive(seed *[32]byte) {
+	if !DeriveX4Available {
+		for i := uint16(0); i < K; i++ {
+			for j := uint16(0); j < L; j++ {
+				PolyDeriveUniform(&m[i][j], seed, (i<<8)+j)
+			}
+		}
+		return
+	}
+
+	idx := 0
+	var nonces [4]uint16
+	var ps [4]*common.Poly
+	for i := uint16(0); i < K; i++ {
+		for j := uint16(0); j < L; j++ {
+			nonces[idx] = (i << 8) + j
+			ps[idx] = &m[i][j]
+			idx++
+			if idx == 4 {
+				idx = 0
+				PolyDeriveUniformX4(ps, seed, nonces)
+			}
+		}
+	}
+	if idx != 0 {
+		for i := idx; i < 4; i++ {
+			ps[i] = nil
+		}
+		PolyDeriveUniformX4(ps, seed, nonces)
+	}
+}
+
+// Set p to the inner product of a and b using pointwise multiplication.
+//
+// Assumes a and b are in Montgomery form and their coefficients are
+// pairwise sufficiently small to multiply, see Poly.MulHat().  Resulting
+// coefficients are bounded by 2Lq.
+func PolyDotHat(p *common.Poly, a, b *VecL) {
+	var t common.Poly
+	*p = common.Poly{} // zero p
+	for i := 0; i < L; i++ {
+		t.MulHat(&a[i], &b[i])
+		p.Add(&t, p)
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/pack.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/pack.go
new file mode 100644
index 00000000..0285dfd8
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/pack.go
@@ -0,0 +1,270 @@
+// Code generated from mode3/internal/pack.go by gen.go
+
+package internal
+
+import (
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+)
+
+// Writes p with norm less than or equal η into buf, which must be of
+// size PolyLeqEtaSize.
+//
+// Assumes coefficients of p are not normalized, but in [q-η,q+η].
+func PolyPackLeqEta(p *common.Poly, buf []byte) {
+	if DoubleEtaBits == 4 { // compiler eliminates branch
+		j := 0
+		for i := 0; i < PolyLeqEtaSize; i++ {
+			buf[i] = (byte(common.Q+Eta-p[j]) |
+				byte(common.Q+Eta-p[j+1])<<4)
+			j += 2
+		}
+	} else if DoubleEtaBits == 3 {
+		j := 0
+		for i := 0; i < PolyLeqEtaSize; i += 3 {
+			buf[i] = (byte(common.Q+Eta-p[j]) |
+				(byte(common.Q+Eta-p[j+1]) << 3) |
+				(byte(common.Q+Eta-p[j+2]) << 6))
+			buf[i+1] = ((byte(common.Q+Eta-p[j+2]) >> 2) |
+				(byte(common.Q+Eta-p[j+3]) << 1) |
+				(byte(common.Q+Eta-p[j+4]) << 4) |
+				(byte(common.Q+Eta-p[j+5]) << 7))
+			buf[i+2] = ((byte(common.Q+Eta-p[j+5]) >> 1) |
+				(byte(common.Q+Eta-p[j+6]) << 2) |
+				(byte(common.Q+Eta-p[j+7]) << 5))
+			j += 8
+		}
+	} else {
+		panic("eta not supported")
+	}
+}
+
+// Sets p to the polynomial of norm less than or equal η encoded in the
+// given buffer of size PolyLeqEtaSize.
+//
+// Output coefficients of p are not normalized, but in [q-η,q+η] provided
+// buf was created using PackLeqEta.
+//
+// Beware, for arbitrary buf the coefficients of p might end up in
+// the interval [q-2^b,q+2^b] where b is the least b with η≤2^b.
+func PolyUnpackLeqEta(p *common.Poly, buf []byte) {
+	if DoubleEtaBits == 4 { // compiler eliminates branch
+		j := 0
+		for i := 0; i < PolyLeqEtaSize; i++ {
+			p[j] = common.Q + Eta - uint32(buf[i]&15)
+			p[j+1] = common.Q + Eta - uint32(buf[i]>>4)
+			j += 2
+		}
+	} else if DoubleEtaBits == 3 {
+		j := 0
+		for i := 0; i < PolyLeqEtaSize; i += 3 {
+			p[j] = common.Q + Eta - uint32(buf[i]&7)
+			p[j+1] = common.Q + Eta - uint32((buf[i]>>3)&7)
+			p[j+2] = common.Q + Eta - uint32((buf[i]>>6)|((buf[i+1]<<2)&7))
+			p[j+3] = common.Q + Eta - uint32((buf[i+1]>>1)&7)
+			p[j+4] = common.Q + Eta - uint32((buf[i+1]>>4)&7)
+			p[j+5] = common.Q + Eta - uint32((buf[i+1]>>7)|((buf[i+2]<<1)&7))
+			p[j+6] = common.Q + Eta - uint32((buf[i+2]>>2)&7)
+			p[j+7] = common.Q + Eta - uint32((buf[i+2]>>5)&7)
+			j += 8
+		}
+	} else {
+		panic("eta not supported")
+	}
+}
+
+// Writes v with coefficients in {0, 1} of which at most ω non-zero
+// to buf, which must have length ω+k.
+func (v *VecK) PackHint(buf []byte) {
+	// The packed hint starts with the indices of the non-zero coefficients
+	// For instance:
+	//
+	//    (x⁵⁶ + x¹⁰⁰, x²⁵⁵, 0, x² + x²³, x¹)
+	//
+	// Yields
+	//
+	//  56, 100, 255, 2, 23, 1
+	//
+	// Then we pad with zeroes until we have a list of ω items:
+	// //  56, 100, 255, 2, 23, 1, 0, 0, ..., 0
+	//
+	// Then we finish with a list of the switch-over-indices in this
+	// list between polynomials, so:
+	//
+	//  56, 100, 255, 2, 23, 1, 0, 0, ..., 0, 2, 3, 3, 5, 6
+
+	off := uint8(0)
+	for i := 0; i < K; i++ {
+		for j := uint16(0); j < common.N; j++ {
+			if v[i][j] != 0 {
+				buf[off] = uint8(j)
+				off++
+			}
+		}
+		buf[Omega+i] = off
+	}
+	for ; off < Omega; off++ {
+		buf[off] = 0
+	}
+}
+
+// Sets v to the vector encoded using VecK.PackHint()
+//
+// Returns whether unpacking was successful.
+func (v *VecK) UnpackHint(buf []byte) bool {
+	// A priori, there would be several reasonable ways to encode the same
+	// hint vector.  We take care to only allow only one encoding, to ensure
+	// "strong unforgeability".
+	//
+	// See PackHint() source for description of the encoding.
+	*v = VecK{}         // zero v
+	prevSOP := uint8(0) // previous switch-over-point
+	for i := 0; i < K; i++ {
+		SOP := buf[Omega+i]
+		if SOP < prevSOP || SOP > Omega {
+			return false // ensures switch-over-points are increasing
+		}
+		for j := prevSOP; j < SOP; j++ {
+			if j > prevSOP && buf[j] <= buf[j-1] {
+				return false // ensures indices are increasing (within a poly)
+			}
+			v[i][buf[j]] = 1
+		}
+		prevSOP = SOP
+	}
+	for j := prevSOP; j < Omega; j++ {
+		if buf[j] != 0 {
+			return false // ensures padding indices are zero
+		}
+	}
+
+	return true
+}
+
+// Sets p to the polynomial packed into buf by PolyPackLeGamma1.
+//
+// p will be normalized.
+func PolyUnpackLeGamma1(p *common.Poly, buf []byte) {
+	if Gamma1Bits == 17 {
+		j := 0
+		for i := 0; i < PolyLeGamma1Size; i += 9 {
+			p0 := uint32(buf[i]) | (uint32(buf[i+1]) << 8) |
+				(uint32(buf[i+2]&0x3) << 16)
+			p1 := uint32(buf[i+2]>>2) | (uint32(buf[i+3]) << 6) |
+				(uint32(buf[i+4]&0xf) << 14)
+			p2 := uint32(buf[i+4]>>4) | (uint32(buf[i+5]) << 4) |
+				(uint32(buf[i+6]&0x3f) << 12)
+			p3 := uint32(buf[i+6]>>6) | (uint32(buf[i+7]) << 2) |
+				(uint32(buf[i+8]) << 10)
+
+			// coefficients in [0,…,2γ₁)
+			p0 = Gamma1 - p0 // (-γ₁,…,γ₁]
+			p1 = Gamma1 - p1
+			p2 = Gamma1 - p2
+			p3 = Gamma1 - p3
+
+			p0 += uint32(int32(p0)>>31) & common.Q // normalize
+			p1 += uint32(int32(p1)>>31) & common.Q
+			p2 += uint32(int32(p2)>>31) & common.Q
+			p3 += uint32(int32(p3)>>31) & common.Q
+
+			p[j] = p0
+			p[j+1] = p1
+			p[j+2] = p2
+			p[j+3] = p3
+
+			j += 4
+		}
+	} else if Gamma1Bits == 19 {
+		j := 0
+		for i := 0; i < PolyLeGamma1Size; i += 5 {
+			p0 := uint32(buf[i]) | (uint32(buf[i+1]) << 8) |
+				(uint32(buf[i+2]&0xf) << 16)
+			p1 := uint32(buf[i+2]>>4) | (uint32(buf[i+3]) << 4) |
+				(uint32(buf[i+4]) << 12)
+
+			p0 = Gamma1 - p0
+			p1 = Gamma1 - p1
+
+			p0 += uint32(int32(p0)>>31) & common.Q
+			p1 += uint32(int32(p1)>>31) & common.Q
+
+			p[j] = p0
+			p[j+1] = p1
+
+			j += 2
+		}
+	} else {
+		panic("γ₁ not supported")
+	}
+}
+
+// Writes p whose coefficients are in (-γ₁,γ₁] into buf
+// which has to be of length PolyLeGamma1Size.
+//
+// Assumes p is normalized.
+func PolyPackLeGamma1(p *common.Poly, buf []byte) {
+	if Gamma1Bits == 17 {
+		j := 0
+		// coefficients in [0,…,γ₁] ∪ (q-γ₁,…,q)
+		for i := 0; i < PolyLeGamma1Size; i += 9 {
+			p0 := Gamma1 - p[j]                    // [0,…,γ₁] ∪ (γ₁-q,…,2γ₁-q)
+			p0 += uint32(int32(p0)>>31) & common.Q // [0,…,2γ₁)
+			p1 := Gamma1 - p[j+1]
+			p1 += uint32(int32(p1)>>31) & common.Q
+			p2 := Gamma1 - p[j+2]
+			p2 += uint32(int32(p2)>>31) & common.Q
+			p3 := Gamma1 - p[j+3]
+			p3 += uint32(int32(p3)>>31) & common.Q
+
+			buf[i+0] = byte(p0)
+			buf[i+1] = byte(p0 >> 8)
+			buf[i+2] = byte(p0>>16) | byte(p1<<2)
+			buf[i+3] = byte(p1 >> 6)
+			buf[i+4] = byte(p1>>14) | byte(p2<<4)
+			buf[i+5] = byte(p2 >> 4)
+			buf[i+6] = byte(p2>>12) | byte(p3<<6)
+			buf[i+7] = byte(p3 >> 2)
+			buf[i+8] = byte(p3 >> 10)
+
+			j += 4
+		}
+	} else if Gamma1Bits == 19 {
+		j := 0
+		for i := 0; i < PolyLeGamma1Size; i += 5 {
+			// Coefficients are in [0, γ₁] ∪ (Q-γ₁, Q)
+			p0 := Gamma1 - p[j]
+			p0 += uint32(int32(p0)>>31) & common.Q
+			p1 := Gamma1 - p[j+1]
+			p1 += uint32(int32(p1)>>31) & common.Q
+
+			buf[i+0] = byte(p0)
+			buf[i+1] = byte(p0 >> 8)
+			buf[i+2] = byte(p0>>16) | byte(p1<<4)
+			buf[i+3] = byte(p1 >> 4)
+			buf[i+4] = byte(p1 >> 12)
+
+			j += 2
+		}
+	} else {
+		panic("γ₁ not supported")
+	}
+}
+
+// Pack w₁ into buf, which must be of length PolyW1Size.
+//
+// Assumes w₁ is normalized.
+func PolyPackW1(p *common.Poly, buf []byte) {
+	if Gamma1Bits == 19 {
+		p.PackLe16(buf)
+	} else if Gamma1Bits == 17 {
+		j := 0
+		for i := 0; i < PolyW1Size; i += 3 {
+			buf[i] = byte(p[j]) | byte(p[j+1]<<6)
+			buf[i+1] = byte(p[j+1]>>2) | byte(p[j+2]<<4)
+			buf[i+2] = byte(p[j+2]>>4) | byte(p[j+3]<<2)
+			j += 4
+		}
+	} else {
+		panic("unsupported γ₁")
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/params.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/params.go
new file mode 100644
index 00000000..b49db55b
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/params.go
@@ -0,0 +1,16 @@
+// Code generated from params.templ.go. DO NOT EDIT.
+
+package internal
+
+const (
+	Name          = "Dilithium2"
+	UseAES        = false
+	K             = 4
+	L             = 4
+	Eta           = 2
+	DoubleEtaBits = 3
+	Omega         = 80
+	Tau           = 39
+	Gamma1Bits    = 17
+	Gamma2        = 95232
+)
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/rounding.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/rounding.go
new file mode 100644
index 00000000..71360cb2
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/rounding.go
@@ -0,0 +1,142 @@
+// Code generated from mode3/internal/rounding.go by gen.go
+
+package internal
+
+import (
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+)
+
+// Splits 0 ≤ a < q into a₀ and a₁ with a = a₁*α + a₀ with -α/2 < a₀ ≤ α/2,
+// except for when we would have a₁ = (q-1)/α in which case a₁=0 is taken
+// and -α/2 ≤ a₀ < 0.  Returns a₀ + q.  Note 0 ≤ a₁ < (q-1)/α.
+// Recall α = 2γ₂.
+func decompose(a uint32) (a0plusQ, a1 uint32) {
+	// a₁ = ⌈a / 128⌉
+	a1 = (a + 127) >> 7
+
+	if Alpha == 523776 {
+		// 1025/2²² is close enough to 1/4092 so that a₁
+		// becomes a/α rounded down.
+		a1 = ((a1*1025 + (1 << 21)) >> 22)
+
+		// For the corner-case a₁ = (q-1)/α = 16, we have to set a₁=0.
+		a1 &= 15
+	} else if Alpha == 190464 {
+		// 1488/2²⁴ is close enough to 1/1488 so that a₁
+		// becomes a/α rounded down.
+		a1 = ((a1 * 11275) + (1 << 23)) >> 24
+
+		// For the corner-case a₁ = (q-1)/α = 44, we have to set a₁=0.
+		a1 ^= uint32(int32(43-a1)>>31) & a1
+	} else {
+		panic("unsupported α")
+	}
+
+	a0plusQ = a - a1*Alpha
+
+	// In the corner-case, when we set a₁=0, we will incorrectly
+	// have a₀ > (q-1)/2 and we'll need to subtract q.  As we
+	// return a₀ + q, that comes down to adding q if a₀ < (q-1)/2.
+	a0plusQ += uint32(int32(a0plusQ-(common.Q-1)/2)>>31) & common.Q
+
+	return
+}
+
+// Assume 0 ≤ r, f < Q with ‖f‖_∞ ≤ α/2.  Decompose r as r = r1*α + r0 as
+// computed by decompose().  Write r' := r - f (mod Q).  Now, decompose
+// r'=r-f again as  r' = r'1*α + r'0 using decompose().  As f is small, we
+// have r'1 = r1 + h, where h ∈ {-1, 0, 1}.  makeHint() computes |h|
+// given z0 := r0 - f (mod Q) and r1.  With |h|, which is called the hint,
+// we can reconstruct r1 using only r' = r - f, which is done by useHint().
+// To wit:
+//
+//	useHint( r - f, makeHint( r0 - f, r1 ) ) = r1.
+//
+// Assumes 0 ≤ z0 < Q.
+func makeHint(z0, r1 uint32) uint32 {
+	// If -α/2 < r0 - f ≤ α/2, then r1*α + r0 - f is a valid decomposition of r'
+	// with the restrictions of decompose() and so r'1 = r1.  So the hint
+	// should be 0. This is covered by the first two inequalities.
+	// There is one other case: if r0 - f = -α/2, then r1*α + r0 - f is also
+	// a valid decomposition if r1 = 0.  In the other cases a one is carried
+	// and the hint should be 1.
+	if z0 <= Gamma2 || z0 > common.Q-Gamma2 || (z0 == common.Q-Gamma2 && r1 == 0) {
+		return 0
+	}
+	return 1
+}
+
+// Uses the hint created by makeHint() to reconstruct r1 from r'=r-f; see
+// documentation of makeHint() for context.
+// Assumes 0 ≤ r' < Q.
+func useHint(rp uint32, hint uint32) uint32 {
+	rp0plusQ, rp1 := decompose(rp)
+	if hint == 0 {
+		return rp1
+	}
+	if rp0plusQ > common.Q {
+		return (rp1 + 1) & 15
+	}
+	return (rp1 - 1) & 15
+}
+
+// Sets p to the hint polynomial for p0 the modified low bits and p1
+// the unmodified high bits --- see makeHint().
+//
+// Returns the number of ones in the hint polynomial.
+func PolyMakeHint(p, p0, p1 *common.Poly) (pop uint32) {
+	for i := 0; i < common.N; i++ {
+		h := makeHint(p0[i], p1[i])
+		pop += h
+		p[i] = h
+	}
+	return
+}
+
+// Computes corrections to the high bits of the polynomial q according
+// to the hints in h and sets p to the corrected high bits.  Returns p.
+func PolyUseHint(p, q, hint *common.Poly) {
+	var q0PlusQ common.Poly
+
+	// See useHint() and makeHint() for an explanation.  We reimplement it
+	// here so that we can call Poly.Decompose(), which might be way faster
+	// than calling decompose() in a loop (for instance when having AVX2.)
+
+	PolyDecompose(q, &q0PlusQ, p)
+
+	for i := 0; i < common.N; i++ {
+		if hint[i] == 0 {
+			continue
+		}
+		if Gamma2 == 261888 {
+			if q0PlusQ[i] > common.Q {
+				p[i] = (p[i] + 1) & 15
+			} else {
+				p[i] = (p[i] - 1) & 15
+			}
+		} else if Gamma2 == 95232 {
+			if q0PlusQ[i] > common.Q {
+				if p[i] == 43 {
+					p[i] = 0
+				} else {
+					p[i]++
+				}
+			} else {
+				if p[i] == 0 {
+					p[i] = 43
+				} else {
+					p[i]--
+				}
+			}
+		} else {
+			panic("unsupported γ₂")
+		}
+	}
+}
+
+// Splits each of the coefficients of p using decompose.
+func PolyDecompose(p, p0PlusQ, p1 *common.Poly) {
+	for i := 0; i < common.N; i++ {
+		p0PlusQ[i], p1[i] = decompose(p[i])
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/sample.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/sample.go
new file mode 100644
index 00000000..c47185ad
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/sample.go
@@ -0,0 +1,370 @@
+// Code generated from mode3/internal/sample.go by gen.go
+
+package internal
+
+import (
+	"encoding/binary"
+
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+	"github.com/cloudflare/circl/simd/keccakf1600"
+)
+
+// DeriveX4Available indicates whether the system supports the quick fourway
+// sampling variants like PolyDeriveUniformX4.
+var DeriveX4Available = keccakf1600.IsEnabledX4() && !UseAES
+
+// For each i, sample ps[i] uniformly from the given seed and nonces[i].
+// ps[i] may be nil and is ignored in that case.
+//
+// Can only be called when DeriveX4Available is true.
+func PolyDeriveUniformX4(ps [4]*common.Poly, seed *[32]byte, nonces [4]uint16) {
+	var perm keccakf1600.StateX4
+	state := perm.Initialize(false)
+
+	// Absorb the seed in the four states
+	for i := 0; i < 4; i++ {
+		v := binary.LittleEndian.Uint64(seed[8*i : 8*(i+1)])
+		for j := 0; j < 4; j++ {
+			state[i*4+j] = v
+		}
+	}
+
+	// Absorb the nonces, the SHAKE128 domain separator (0b1111), the
+	// start of the padding (0b...001) and the end of the padding 0b100...
+	// Recall that the rate of SHAKE128 is 168 --- i.e. 21 uint64s.
+	for j := 0; j < 4; j++ {
+		state[4*4+j] = uint64(nonces[j]) | (0x1f << 16)
+		state[20*4+j] = 0x80 << 56
+	}
+
+	var idx [4]int // indices into ps
+	for j := 0; j < 4; j++ {
+		if ps[j] == nil {
+			idx[j] = common.N // mark nil polynomial as completed
+		}
+	}
+
+	done := false
+	for !done {
+		// Applies KeccaK-f[1600] to state to get the next 21 uint64s of each
+		// of the four SHAKE128 streams.
+		perm.Permute()
+
+		done = true
+
+	PolyLoop:
+		for j := 0; j < 4; j++ {
+			if idx[j] == common.N {
+				continue
+			}
+			for i := 0; i < 7; i++ {
+				var t [8]uint32
+				t[0] = uint32(state[i*3*4+j] & 0x7fffff)
+				t[1] = uint32((state[i*3*4+j] >> 24) & 0x7fffff)
+				t[2] = uint32((state[i*3*4+j] >> 48) |
+					((state[(i*3+1)*4+j] & 0x7f) << 16))
+				t[3] = uint32((state[(i*3+1)*4+j] >> 8) & 0x7fffff)
+				t[4] = uint32((state[(i*3+1)*4+j] >> 32) & 0x7fffff)
+				t[5] = uint32((state[(i*3+1)*4+j] >> 56) |
+					((state[(i*3+2)*4+j] & 0x7fff) << 8))
+				t[6] = uint32((state[(i*3+2)*4+j] >> 16) & 0x7fffff)
+				t[7] = uint32((state[(i*3+2)*4+j] >> 40) & 0x7fffff)
+
+				for k := 0; k < 8; k++ {
+					if t[k] < common.Q {
+						ps[j][idx[j]] = t[k]
+						idx[j]++
+						if idx[j] == common.N {
+							continue PolyLoop
+						}
+					}
+				}
+			}
+			done = false
+		}
+	}
+}
+
+// Sample p uniformly from the given seed and nonce.
+//
+// p will be normalized.
+func PolyDeriveUniform(p *common.Poly, seed *[32]byte, nonce uint16) {
+	var i, length int
+	var buf [12 * 16]byte // fits 168B SHAKE-128 rate and 12 16B AES blocks
+
+	if UseAES {
+		length = 12 * 16
+	} else {
+		length = 168
+	}
+
+	sample := func() {
+		// Note that 3 divides into 168 and 12*16, so we use up buf completely.
+		for j := 0; j < length && i < common.N; j += 3 {
+			t := (uint32(buf[j]) | (uint32(buf[j+1]) << 8) |
+				(uint32(buf[j+2]) << 16)) & 0x7fffff
+
+			// We use rejection sampling
+			if t < common.Q {
+				p[i] = t
+				i++
+			}
+		}
+	}
+
+	if UseAES {
+		h := common.NewAesStream128(seed, nonce)
+
+		for i < common.N {
+			h.SqueezeInto(buf[:length])
+			sample()
+		}
+	} else {
+		var iv [32 + 2]byte // 32 byte seed + uint16 nonce
+		h := sha3.NewShake128()
+		copy(iv[:32], seed[:])
+		iv[32] = uint8(nonce)
+		iv[33] = uint8(nonce >> 8)
+		_, _ = h.Write(iv[:])
+
+		for i < common.N {
+			_, _ = h.Read(buf[:168])
+			sample()
+		}
+	}
+}
+
+// Sample p uniformly with coefficients of norm less than or equal η,
+// using the given seed and nonce.
+//
+// p will not be normalized, but will have coefficients in [q-η,q+η].
+func PolyDeriveUniformLeqEta(p *common.Poly, seed *[64]byte, nonce uint16) {
+	// Assumes 2 < η < 8.
+	var i, length int
+	var buf [9 * 16]byte // fits 136B SHAKE-256 rate and 9 16B AES blocks
+
+	if UseAES {
+		length = 9 * 16
+	} else {
+		length = 136
+	}
+
+	sample := func() {
+		// We use rejection sampling
+		for j := 0; j < length && i < common.N; j++ {
+			t1 := uint32(buf[j]) & 15
+			t2 := uint32(buf[j]) >> 4
+			if Eta == 2 { // branch is eliminated by compiler
+				if t1 <= 14 {
+					t1 -= ((205 * t1) >> 10) * 5 // reduce mod  5
+					p[i] = common.Q + Eta - t1
+					i++
+				}
+				if t2 <= 14 && i < common.N {
+					t2 -= ((205 * t2) >> 10) * 5 // reduce mod 5
+					p[i] = common.Q + Eta - t2
+					i++
+				}
+			} else if Eta == 4 {
+				if t1 <= 2*Eta {
+					p[i] = common.Q + Eta - t1
+					i++
+				}
+				if t2 <= 2*Eta && i < common.N {
+					p[i] = common.Q + Eta - t2
+					i++
+				}
+			} else {
+				panic("unsupported η")
+			}
+		}
+	}
+
+	if UseAES {
+		h := common.NewAesStream256(seed, nonce)
+
+		for i < common.N {
+			h.SqueezeInto(buf[:length])
+			sample()
+		}
+	} else {
+		var iv [64 + 2]byte // 64 byte seed + uint16 nonce
+
+		h := sha3.NewShake256()
+		copy(iv[:64], seed[:])
+		iv[64] = uint8(nonce)
+		iv[65] = uint8(nonce >> 8)
+
+		// 136 is SHAKE-256 rate
+		_, _ = h.Write(iv[:])
+
+		for i < common.N {
+			_, _ = h.Read(buf[:136])
+			sample()
+		}
+	}
+}
+
+// Sample v[i] uniformly with coefficients in (-γ₁,…,γ₁]  using the
+// given seed and nonce+i
+//
+// p will be normalized.
+func VecLDeriveUniformLeGamma1(v *VecL, seed *[64]byte, nonce uint16) {
+	for i := 0; i < L; i++ {
+		PolyDeriveUniformLeGamma1(&v[i], seed, nonce+uint16(i))
+	}
+}
+
+// Sample p uniformly with coefficients in (-γ₁,…,γK1s] using the
+// given seed and nonce.
+//
+// p will be normalized.
+func PolyDeriveUniformLeGamma1(p *common.Poly, seed *[64]byte, nonce uint16) {
+	var buf [PolyLeGamma1Size]byte
+
+	if UseAES {
+		h := common.NewAesStream256(seed, nonce)
+		h.SqueezeInto(buf[:])
+	} else {
+		var iv [66]byte
+		h := sha3.NewShake256()
+		copy(iv[:64], seed[:])
+		iv[64] = uint8(nonce)
+		iv[65] = uint8(nonce >> 8)
+		_, _ = h.Write(iv[:])
+		_, _ = h.Read(buf[:])
+	}
+
+	PolyUnpackLeGamma1(p, buf[:])
+}
+
+// For each i, sample ps[i] uniformly with τ non-zero coefficients in {q-1,1}
+// using the given seed and w1[i].  ps[i] may be nil and is ignored
+// in that case.  ps[i] will be normalized.
+//
+// Can only be called when DeriveX4Available is true.
+//
+// This function is currently not used (yet).
+func PolyDeriveUniformBallX4(ps [4]*common.Poly, seed *[32]byte) {
+	var perm keccakf1600.StateX4
+	state := perm.Initialize(false)
+
+	// Absorb the seed in the four states
+	for i := 0; i < 4; i++ {
+		v := binary.LittleEndian.Uint64(seed[8*i : 8*(i+1)])
+		for j := 0; j < 4; j++ {
+			state[i*4+j] = v
+		}
+	}
+
+	// SHAKE256 domain separator and padding
+	for j := 0; j < 4; j++ {
+		state[4*4+j] ^= 0x1f
+		state[16*4+j] ^= 0x80 << 56
+	}
+	perm.Permute()
+
+	var signs [4]uint64
+	var idx [4]uint16 // indices into ps
+
+	for j := 0; j < 4; j++ {
+		if ps[j] != nil {
+			signs[j] = state[j]
+			*ps[j] = common.Poly{} // zero ps[j]
+			idx[j] = common.N - Tau
+		} else {
+			idx[j] = common.N // mark as completed
+		}
+	}
+
+	stateOffset := 1
+	for {
+		done := true
+
+	PolyLoop:
+		for j := 0; j < 4; j++ {
+			if idx[j] == common.N {
+				continue
+			}
+
+			for i := stateOffset; i < 17; i++ {
+				var bs [8]byte
+				binary.LittleEndian.PutUint64(bs[:], state[4*i+j])
+				for k := 0; k < 8; k++ {
+					b := uint16(bs[k])
+
+					if b > idx[j] {
+						continue
+					}
+
+					ps[j][idx[j]] = ps[j][b]
+					ps[j][b] = 1
+					// Takes least significant bit of signs and uses it for the sign.
+					// Note 1 ^ (1 | (Q-1)) = Q-1.
+					ps[j][b] ^= uint32((-(signs[j] & 1)) & (1 | (common.Q - 1)))
+					signs[j] >>= 1
+
+					idx[j]++
+					if idx[j] == common.N {
+						continue PolyLoop
+					}
+				}
+			}
+
+			done = false
+		}
+
+		if done {
+			break
+		}
+
+		perm.Permute()
+		stateOffset = 0
+	}
+}
+
+// Samples p uniformly with τ non-zero coefficients in {q-1,1}.
+//
+// The polynomial p will be normalized.
+func PolyDeriveUniformBall(p *common.Poly, seed *[32]byte) {
+	var buf [136]byte // SHAKE-256 rate is 136
+
+	h := sha3.NewShake256()
+	_, _ = h.Write(seed[:])
+	_, _ = h.Read(buf[:])
+
+	// Essentially we generate a sequence of τ ones or minus ones,
+	// prepend 196 zeroes and shuffle the concatenation using the
+	// usual algorithm (Fisher--Yates.)
+	signs := binary.LittleEndian.Uint64(buf[:])
+	bufOff := 8 // offset into buf
+
+	*p = common.Poly{} // zero p
+	for i := uint16(common.N - Tau); i < common.N; i++ {
+		var b uint16
+
+		// Find location of where to move the new coefficient to using
+		// rejection sampling.
+		for {
+			if bufOff >= 136 {
+				_, _ = h.Read(buf[:])
+				bufOff = 0
+			}
+
+			b = uint16(buf[bufOff])
+			bufOff++
+
+			if b <= i {
+				break
+			}
+		}
+
+		p[i] = p[b]
+		p[b] = 1
+		// Takes least significant bit of signs and uses it for the sign.
+		// Note 1 ^ (1 | (Q-1)) = Q-1.
+		p[b] ^= uint32((-(signs & 1)) & (1 | (common.Q - 1)))
+		signs >>= 1
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/vec.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/vec.go
new file mode 100644
index 00000000..f52973e4
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode2/internal/vec.go
@@ -0,0 +1,281 @@
+// Code generated from mode3/internal/vec.go by gen.go
+
+package internal
+
+import (
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+)
+
+// A vector of L polynomials.
+type VecL [L]common.Poly
+
+// A vector of K polynomials.
+type VecK [K]common.Poly
+
+// Normalize the polynomials in this vector.
+func (v *VecL) Normalize() {
+	for i := 0; i < L; i++ {
+		v[i].Normalize()
+	}
+}
+
+// Normalize the polynomials in this vector assuming their coefficients
+// are already bounded by 2q.
+func (v *VecL) NormalizeAssumingLe2Q() {
+	for i := 0; i < L; i++ {
+		v[i].NormalizeAssumingLe2Q()
+	}
+}
+
+// Sets v to w + u.  Does not normalize.
+func (v *VecL) Add(w, u *VecL) {
+	for i := 0; i < L; i++ {
+		v[i].Add(&w[i], &u[i])
+	}
+}
+
+// Applies NTT componentwise. See Poly.NTT() for details.
+func (v *VecL) NTT() {
+	for i := 0; i < L; i++ {
+		v[i].NTT()
+	}
+}
+
+// Checks whether any of the coefficients exceeds the given bound in supnorm
+//
+// Requires the vector to be normalized.
+func (v *VecL) Exceeds(bound uint32) bool {
+	for i := 0; i < L; i++ {
+		if v[i].Exceeds(bound) {
+			return true
+		}
+	}
+	return false
+}
+
+// Applies Poly.Power2Round componentwise.
+//
+// Requires the vector to be normalized.
+func (v *VecL) Power2Round(v0PlusQ, v1 *VecL) {
+	for i := 0; i < L; i++ {
+		v[i].Power2Round(&v0PlusQ[i], &v1[i])
+	}
+}
+
+// Applies Poly.Decompose componentwise.
+//
+// Requires the vector to be normalized.
+func (v *VecL) Decompose(v0PlusQ, v1 *VecL) {
+	for i := 0; i < L; i++ {
+		PolyDecompose(&v[i], &v0PlusQ[i], &v1[i])
+	}
+}
+
+// Sequentially packs each polynomial using Poly.PackLeqEta().
+func (v *VecL) PackLeqEta(buf []byte) {
+	offset := 0
+	for i := 0; i < L; i++ {
+		PolyPackLeqEta(&v[i], buf[offset:])
+		offset += PolyLeqEtaSize
+	}
+}
+
+// Sets v to the polynomials packed in buf using VecL.PackLeqEta().
+func (v *VecL) UnpackLeqEta(buf []byte) {
+	offset := 0
+	for i := 0; i < L; i++ {
+		PolyUnpackLeqEta(&v[i], buf[offset:])
+		offset += PolyLeqEtaSize
+	}
+}
+
+// Sequentially packs each polynomial using PolyPackLeGamma1().
+func (v *VecL) PackLeGamma1(buf []byte) {
+	offset := 0
+	for i := 0; i < L; i++ {
+		PolyPackLeGamma1(&v[i], buf[offset:])
+		offset += PolyLeGamma1Size
+	}
+}
+
+// Sets v to the polynomials packed in buf using VecL.PackLeGamma1().
+func (v *VecL) UnpackLeGamma1(buf []byte) {
+	offset := 0
+	for i := 0; i < L; i++ {
+		PolyUnpackLeGamma1(&v[i], buf[offset:])
+		offset += PolyLeGamma1Size
+	}
+}
+
+// Normalize the polynomials in this vector.
+func (v *VecK) Normalize() {
+	for i := 0; i < K; i++ {
+		v[i].Normalize()
+	}
+}
+
+// Normalize the polynomials in this vector assuming their coefficients
+// are already bounded by 2q.
+func (v *VecK) NormalizeAssumingLe2Q() {
+	for i := 0; i < K; i++ {
+		v[i].NormalizeAssumingLe2Q()
+	}
+}
+
+// Sets v to w + u.  Does not normalize.
+func (v *VecK) Add(w, u *VecK) {
+	for i := 0; i < K; i++ {
+		v[i].Add(&w[i], &u[i])
+	}
+}
+
+// Checks whether any of the coefficients exceeds the given bound in supnorm
+//
+// Requires the vector to be normalized.
+func (v *VecK) Exceeds(bound uint32) bool {
+	for i := 0; i < K; i++ {
+		if v[i].Exceeds(bound) {
+			return true
+		}
+	}
+	return false
+}
+
+// Applies Poly.Power2Round componentwise.
+//
+// Requires the vector to be normalized.
+func (v *VecK) Power2Round(v0PlusQ, v1 *VecK) {
+	for i := 0; i < K; i++ {
+		v[i].Power2Round(&v0PlusQ[i], &v1[i])
+	}
+}
+
+// Applies Poly.Decompose componentwise.
+//
+// Requires the vector to be normalized.
+func (v *VecK) Decompose(v0PlusQ, v1 *VecK) {
+	for i := 0; i < K; i++ {
+		PolyDecompose(&v[i], &v0PlusQ[i], &v1[i])
+	}
+}
+
+// Sets v to the hint vector for v0 the modified low bits and v1
+// the unmodified high bits --- see makeHint().
+//
+// Returns the number of ones in the hint vector.
+func (v *VecK) MakeHint(v0, v1 *VecK) (pop uint32) {
+	for i := 0; i < K; i++ {
+		pop += PolyMakeHint(&v[i], &v0[i], &v1[i])
+	}
+	return
+}
+
+// Computes corrections to the high bits of the polynomials in the vector
+// w using the hints in h and sets v to the corrected high bits.  Returns v.
+// See useHint().
+func (v *VecK) UseHint(q, hint *VecK) *VecK {
+	for i := 0; i < K; i++ {
+		PolyUseHint(&v[i], &q[i], &hint[i])
+	}
+	return v
+}
+
+// Sequentially packs each polynomial using Poly.PackT1().
+func (v *VecK) PackT1(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		v[i].PackT1(buf[offset:])
+		offset += common.PolyT1Size
+	}
+}
+
+// Sets v to the vector packed into buf by PackT1().
+func (v *VecK) UnpackT1(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		v[i].UnpackT1(buf[offset:])
+		offset += common.PolyT1Size
+	}
+}
+
+// Sequentially packs each polynomial using Poly.PackT0().
+func (v *VecK) PackT0(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		v[i].PackT0(buf[offset:])
+		offset += common.PolyT0Size
+	}
+}
+
+// Sets v to the vector packed into buf by PackT0().
+func (v *VecK) UnpackT0(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		v[i].UnpackT0(buf[offset:])
+		offset += common.PolyT0Size
+	}
+}
+
+// Sequentially packs each polynomial using Poly.PackLeqEta().
+func (v *VecK) PackLeqEta(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		PolyPackLeqEta(&v[i], buf[offset:])
+		offset += PolyLeqEtaSize
+	}
+}
+
+// Sets v to the polynomials packed in buf using VecK.PackLeqEta().
+func (v *VecK) UnpackLeqEta(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		PolyUnpackLeqEta(&v[i], buf[offset:])
+		offset += PolyLeqEtaSize
+	}
+}
+
+// Applies NTT componentwise. See Poly.NTT() for details.
+func (v *VecK) NTT() {
+	for i := 0; i < K; i++ {
+		v[i].NTT()
+	}
+}
+
+// Sequentially packs each polynomial using PolyPackW1().
+func (v *VecK) PackW1(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		PolyPackW1(&v[i], buf[offset:])
+		offset += PolyW1Size
+	}
+}
+
+// Sets v to a - b.
+//
+// Warning: assumes coefficients of the polynomials of  b are less than 2q.
+func (v *VecK) Sub(a, b *VecK) {
+	for i := 0; i < K; i++ {
+		v[i].Sub(&a[i], &b[i])
+	}
+}
+
+// Sets v to 2ᵈ w without reducing.
+func (v *VecK) MulBy2toD(w *VecK) {
+	for i := 0; i < K; i++ {
+		v[i].MulBy2toD(&w[i])
+	}
+}
+
+// Applies InvNTT componentwise. See Poly.InvNTT() for details.
+func (v *VecK) InvNTT() {
+	for i := 0; i < K; i++ {
+		v[i].InvNTT()
+	}
+}
+
+// Applies Poly.ReduceLe2Q() componentwise.
+func (v *VecK) ReduceLe2Q() {
+	for i := 0; i < K; i++ {
+		v[i].ReduceLe2Q()
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/dilithium.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/dilithium.go
new file mode 100644
index 00000000..3ab9d6b5
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/dilithium.go
@@ -0,0 +1,181 @@
+// Code generated from modePkg.templ.go. DO NOT EDIT.
+
+// mode3 implements the CRYSTALS-Dilithium signature scheme Dilithium3
+// as submitted to round3 of the NIST PQC competition and described in
+//
+// https://pq-crystals.org/dilithium/data/dilithium-specification-round3-20210208.pdf
+package mode3
+
+import (
+	"crypto"
+	"errors"
+	"io"
+
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+	"github.com/cloudflare/circl/sign/dilithium/mode3/internal"
+)
+
+const (
+	// Size of seed for NewKeyFromSeed
+	SeedSize = common.SeedSize
+
+	// Size of a packed PublicKey
+	PublicKeySize = internal.PublicKeySize
+
+	// Size of a packed PrivateKey
+	PrivateKeySize = internal.PrivateKeySize
+
+	// Size of a signature
+	SignatureSize = internal.SignatureSize
+)
+
+// PublicKey is the type of Dilithium3 public key
+type PublicKey internal.PublicKey
+
+// PrivateKey is the type of Dilithium3 private key
+type PrivateKey internal.PrivateKey
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
+	pk, sk, err := internal.GenerateKey(rand)
+	return (*PublicKey)(pk), (*PrivateKey)(sk), err
+}
+
+// NewKeyFromSeed derives a public/private key pair using the given seed.
+func NewKeyFromSeed(seed *[SeedSize]byte) (*PublicKey, *PrivateKey) {
+	pk, sk := internal.NewKeyFromSeed(seed)
+	return (*PublicKey)(pk), (*PrivateKey)(sk)
+}
+
+// SignTo signs the given message and writes the signature into signature.
+// It will panic if signature is not of length at least SignatureSize.
+func SignTo(sk *PrivateKey, msg []byte, signature []byte) {
+	internal.SignTo(
+		(*internal.PrivateKey)(sk),
+		msg,
+		signature,
+	)
+}
+
+// Verify checks whether the given signature by pk on msg is valid.
+func Verify(pk *PublicKey, msg []byte, signature []byte) bool {
+	return internal.Verify(
+		(*internal.PublicKey)(pk),
+		msg,
+		signature,
+	)
+}
+
+// Sets pk to the public key encoded in buf.
+func (pk *PublicKey) Unpack(buf *[PublicKeySize]byte) {
+	(*internal.PublicKey)(pk).Unpack(buf)
+}
+
+// Sets sk to the private key encoded in buf.
+func (sk *PrivateKey) Unpack(buf *[PrivateKeySize]byte) {
+	(*internal.PrivateKey)(sk).Unpack(buf)
+}
+
+// Packs the public key into buf.
+func (pk *PublicKey) Pack(buf *[PublicKeySize]byte) {
+	(*internal.PublicKey)(pk).Pack(buf)
+}
+
+// Packs the private key into buf.
+func (sk *PrivateKey) Pack(buf *[PrivateKeySize]byte) {
+	(*internal.PrivateKey)(sk).Pack(buf)
+}
+
+// Packs the public key.
+func (pk *PublicKey) Bytes() []byte {
+	var buf [PublicKeySize]byte
+	pk.Pack(&buf)
+	return buf[:]
+}
+
+// Packs the private key.
+func (sk *PrivateKey) Bytes() []byte {
+	var buf [PrivateKeySize]byte
+	sk.Pack(&buf)
+	return buf[:]
+}
+
+// Packs the public key.
+func (pk *PublicKey) MarshalBinary() ([]byte, error) {
+	return pk.Bytes(), nil
+}
+
+// Packs the private key.
+func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
+	return sk.Bytes(), nil
+}
+
+// Unpacks the public key from data.
+func (pk *PublicKey) UnmarshalBinary(data []byte) error {
+	if len(data) != PublicKeySize {
+		return errors.New("packed public key must be of mode3.PublicKeySize bytes")
+	}
+	var buf [PublicKeySize]byte
+	copy(buf[:], data)
+	pk.Unpack(&buf)
+	return nil
+}
+
+// Unpacks the private key from data.
+func (sk *PrivateKey) UnmarshalBinary(data []byte) error {
+	if len(data) != PrivateKeySize {
+		return errors.New("packed private key must be of mode3.PrivateKeySize bytes")
+	}
+	var buf [PrivateKeySize]byte
+	copy(buf[:], data)
+	sk.Unpack(&buf)
+	return nil
+}
+
+// Sign signs the given message.
+//
+// opts.HashFunc() must return zero, which can be achieved by passing
+// crypto.Hash(0) for opts.  rand is ignored.  Will only return an error
+// if opts.HashFunc() is non-zero.
+//
+// This function is used to make PrivateKey implement the crypto.Signer
+// interface.  The package-level SignTo function might be more convenient
+// to use.
+func (sk *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) (
+	signature []byte, err error) {
+	var sig [SignatureSize]byte
+
+	if opts.HashFunc() != crypto.Hash(0) {
+		return nil, errors.New("dilithium: cannot sign hashed message")
+	}
+
+	SignTo(sk, msg, sig[:])
+	return sig[:], nil
+}
+
+// Computes the public key corresponding to this private key.
+//
+// Returns a *PublicKey.  The type crypto.PublicKey is used to make
+// PrivateKey implement the crypto.Signer interface.
+func (sk *PrivateKey) Public() crypto.PublicKey {
+	return (*PublicKey)((*internal.PrivateKey)(sk).Public())
+}
+
+// Equal returns whether the two private keys equal.
+func (sk *PrivateKey) Equal(other crypto.PrivateKey) bool {
+	castOther, ok := other.(*PrivateKey)
+	if !ok {
+		return false
+	}
+	return (*internal.PrivateKey)(sk).Equal((*internal.PrivateKey)(castOther))
+}
+
+// Equal returns whether the two public keys equal.
+func (pk *PublicKey) Equal(other crypto.PublicKey) bool {
+	castOther, ok := other.(*PublicKey)
+	if !ok {
+		return false
+	}
+	return (*internal.PublicKey)(pk).Equal((*internal.PublicKey)(castOther))
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/dilithium.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/dilithium.go
new file mode 100644
index 00000000..59e43cc1
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/dilithium.go
@@ -0,0 +1,475 @@
+package internal
+
+import (
+	cryptoRand "crypto/rand"
+	"crypto/subtle"
+	"io"
+
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+)
+
+const (
+	// Size of a packed polynomial of norm ≤η.
+	// (Note that the  formula is not valid in general.)
+	PolyLeqEtaSize = (common.N * DoubleEtaBits) / 8
+
+	// β = τη, the maximum size of c s₂.
+	Beta = Tau * Eta
+
+	// γ₁ range of y
+	Gamma1 = 1 << Gamma1Bits
+
+	// Size of packed polynomial of norm <γ₁ such as z
+	PolyLeGamma1Size = (Gamma1Bits + 1) * common.N / 8
+
+	// α = 2γ₂ parameter for decompose
+	Alpha = 2 * Gamma2
+
+	// Size of a packed private key
+	PrivateKeySize = 32 + 32 + 32 + PolyLeqEtaSize*(L+K) + common.PolyT0Size*K
+
+	// Size of a packed public key
+	PublicKeySize = 32 + common.PolyT1Size*K
+
+	// Size of a packed signature
+	SignatureSize = L*PolyLeGamma1Size + Omega + K + 32
+
+	// Size of packed w₁
+	PolyW1Size = (common.N * (common.QBits - Gamma1Bits)) / 8
+)
+
+// PublicKey is the type of Dilithium public keys.
+type PublicKey struct {
+	rho [32]byte
+	t1  VecK
+
+	// Cached values
+	t1p [common.PolyT1Size * K]byte
+	A   *Mat
+	tr  *[32]byte
+}
+
+// PrivateKey is the type of Dilithium private keys.
+type PrivateKey struct {
+	rho [32]byte
+	key [32]byte
+	s1  VecL
+	s2  VecK
+	t0  VecK
+	tr  [32]byte
+
+	// Cached values
+	A   Mat  // ExpandA(ρ)
+	s1h VecL // NTT(s₁)
+	s2h VecK // NTT(s₂)
+	t0h VecK // NTT(t₀)
+}
+
+type unpackedSignature struct {
+	z    VecL
+	hint VecK
+	c    [32]byte
+}
+
+// Packs the signature into buf.
+func (sig *unpackedSignature) Pack(buf []byte) {
+	copy(buf[:], sig.c[:])
+	sig.z.PackLeGamma1(buf[32:])
+	sig.hint.PackHint(buf[32+L*PolyLeGamma1Size:])
+}
+
+// Sets sig to the signature encoded in the buffer.
+//
+// Returns whether buf contains a properly packed signature.
+func (sig *unpackedSignature) Unpack(buf []byte) bool {
+	if len(buf) < SignatureSize {
+		return false
+	}
+	copy(sig.c[:], buf[:])
+	sig.z.UnpackLeGamma1(buf[32:])
+	if sig.z.Exceeds(Gamma1 - Beta) {
+		return false
+	}
+	if !sig.hint.UnpackHint(buf[32+L*PolyLeGamma1Size:]) {
+		return false
+	}
+	return true
+}
+
+// Packs the public key into buf.
+func (pk *PublicKey) Pack(buf *[PublicKeySize]byte) {
+	copy(buf[:32], pk.rho[:])
+	copy(buf[32:], pk.t1p[:])
+}
+
+// Sets pk to the public key encoded in buf.
+func (pk *PublicKey) Unpack(buf *[PublicKeySize]byte) {
+	copy(pk.rho[:], buf[:32])
+	copy(pk.t1p[:], buf[32:])
+
+	pk.t1.UnpackT1(pk.t1p[:])
+	pk.A = new(Mat)
+	pk.A.Derive(&pk.rho)
+
+	// tr = CRH(ρ ‖ t1) = CRH(pk)
+	pk.tr = new([32]byte)
+	h := sha3.NewShake256()
+	_, _ = h.Write(buf[:])
+	_, _ = h.Read(pk.tr[:])
+}
+
+// Packs the private key into buf.
+func (sk *PrivateKey) Pack(buf *[PrivateKeySize]byte) {
+	copy(buf[:32], sk.rho[:])
+	copy(buf[32:64], sk.key[:])
+	copy(buf[64:96], sk.tr[:])
+	offset := 96
+	sk.s1.PackLeqEta(buf[offset:])
+	offset += PolyLeqEtaSize * L
+	sk.s2.PackLeqEta(buf[offset:])
+	offset += PolyLeqEtaSize * K
+	sk.t0.PackT0(buf[offset:])
+}
+
+// Sets sk to the private key encoded in buf.
+func (sk *PrivateKey) Unpack(buf *[PrivateKeySize]byte) {
+	copy(sk.rho[:], buf[:32])
+	copy(sk.key[:], buf[32:64])
+	copy(sk.tr[:], buf[64:96])
+	offset := 96
+	sk.s1.UnpackLeqEta(buf[offset:])
+	offset += PolyLeqEtaSize * L
+	sk.s2.UnpackLeqEta(buf[offset:])
+	offset += PolyLeqEtaSize * K
+	sk.t0.UnpackT0(buf[offset:])
+
+	// Cached values
+	sk.A.Derive(&sk.rho)
+	sk.t0h = sk.t0
+	sk.t0h.NTT()
+	sk.s1h = sk.s1
+	sk.s1h.NTT()
+	sk.s2h = sk.s2
+	sk.s2h.NTT()
+}
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
+	var seed [32]byte
+	if rand == nil {
+		rand = cryptoRand.Reader
+	}
+	_, err := io.ReadFull(rand, seed[:])
+	if err != nil {
+		return nil, nil, err
+	}
+	pk, sk := NewKeyFromSeed(&seed)
+	return pk, sk, nil
+}
+
+// NewKeyFromSeed derives a public/private key pair using the given seed.
+func NewKeyFromSeed(seed *[common.SeedSize]byte) (*PublicKey, *PrivateKey) {
+	var eSeed [128]byte // expanded seed
+	var pk PublicKey
+	var sk PrivateKey
+	var sSeed [64]byte
+
+	h := sha3.NewShake256()
+	_, _ = h.Write(seed[:])
+	_, _ = h.Read(eSeed[:])
+
+	copy(pk.rho[:], eSeed[:32])
+	copy(sSeed[:], eSeed[32:96])
+	copy(sk.key[:], eSeed[96:])
+	copy(sk.rho[:], pk.rho[:])
+
+	sk.A.Derive(&pk.rho)
+
+	for i := uint16(0); i < L; i++ {
+		PolyDeriveUniformLeqEta(&sk.s1[i], &sSeed, i)
+	}
+
+	for i := uint16(0); i < K; i++ {
+		PolyDeriveUniformLeqEta(&sk.s2[i], &sSeed, i+L)
+	}
+
+	sk.s1h = sk.s1
+	sk.s1h.NTT()
+	sk.s2h = sk.s2
+	sk.s2h.NTT()
+
+	sk.computeT0andT1(&sk.t0, &pk.t1)
+
+	sk.t0h = sk.t0
+	sk.t0h.NTT()
+
+	// Complete public key far enough to be packed
+	pk.t1.PackT1(pk.t1p[:])
+	pk.A = &sk.A
+
+	// Finish private key
+	var packedPk [PublicKeySize]byte
+	pk.Pack(&packedPk)
+
+	// tr = CRH(ρ ‖ t1) = CRH(pk)
+	h.Reset()
+	_, _ = h.Write(packedPk[:])
+	_, _ = h.Read(sk.tr[:])
+
+	// Finish cache of public key
+	pk.tr = &sk.tr
+
+	return &pk, &sk
+}
+
+// Computes t0 and t1 from sk.s1h, sk.s2 and sk.A.
+func (sk *PrivateKey) computeT0andT1(t0, t1 *VecK) {
+	var t VecK
+
+	// Set t to A s₁ + s₂
+	for i := 0; i < K; i++ {
+		PolyDotHat(&t[i], &sk.A[i], &sk.s1h)
+		t[i].ReduceLe2Q()
+		t[i].InvNTT()
+	}
+	t.Add(&t, &sk.s2)
+	t.Normalize()
+
+	// Compute t₀, t₁ = Power2Round(t)
+	t.Power2Round(t0, t1)
+}
+
+// Verify checks whether the given signature by pk on msg is valid.
+func Verify(pk *PublicKey, msg []byte, signature []byte) bool {
+	var sig unpackedSignature
+	var mu [64]byte
+	var zh VecL
+	var Az, Az2dct1, w1 VecK
+	var ch common.Poly
+	var cp [32]byte
+	var w1Packed [PolyW1Size * K]byte
+
+	// Note that Unpack() checked whether ‖z‖_∞ < γ₁ - β
+	// and ensured that there at most ω ones in pk.hint.
+	if !sig.Unpack(signature) {
+		return false
+	}
+
+	// μ = CRH(tr ‖ msg)
+	h := sha3.NewShake256()
+	_, _ = h.Write(pk.tr[:])
+	_, _ = h.Write(msg)
+	_, _ = h.Read(mu[:])
+
+	// Compute Az
+	zh = sig.z
+	zh.NTT()
+
+	for i := 0; i < K; i++ {
+		PolyDotHat(&Az[i], &pk.A[i], &zh)
+	}
+
+	// Next, we compute Az - 2ᵈ·c·t₁.
+	// Note that the coefficients of t₁ are bounded by 256 = 2⁹,
+	// so the coefficients of Az2dct1 will bounded by 2⁹⁺ᵈ = 2²³ < 2q,
+	// which is small enough for NTT().
+	Az2dct1.MulBy2toD(&pk.t1)
+	Az2dct1.NTT()
+	PolyDeriveUniformBall(&ch, &sig.c)
+	ch.NTT()
+	for i := 0; i < K; i++ {
+		Az2dct1[i].MulHat(&Az2dct1[i], &ch)
+	}
+	Az2dct1.Sub(&Az, &Az2dct1)
+	Az2dct1.ReduceLe2Q()
+	Az2dct1.InvNTT()
+	Az2dct1.NormalizeAssumingLe2Q()
+
+	// UseHint(pk.hint, Az - 2ᵈ·c·t₁)
+	//    = UseHint(pk.hint, w - c·s₂ + c·t₀)
+	//    = UseHint(pk.hint, r + c·t₀)
+	//    = r₁ = w₁.
+	w1.UseHint(&Az2dct1, &sig.hint)
+	w1.PackW1(w1Packed[:])
+
+	// c' = H(μ, w₁)
+	h.Reset()
+	_, _ = h.Write(mu[:])
+	_, _ = h.Write(w1Packed[:])
+	_, _ = h.Read(cp[:])
+
+	return sig.c == cp
+}
+
+// SignTo signs the given message and writes the signature into signature.
+//
+//nolint:funlen
+func SignTo(sk *PrivateKey, msg []byte, signature []byte) {
+	var mu, rhop [64]byte
+	var w1Packed [PolyW1Size * K]byte
+	var y, yh VecL
+	var w, w0, w1, w0mcs2, ct0, w0mcs2pct0 VecK
+	var ch common.Poly
+	var yNonce uint16
+	var sig unpackedSignature
+
+	if len(signature) < SignatureSize {
+		panic("Signature does not fit in that byteslice")
+	}
+
+	//  μ = CRH(tr ‖ msg)
+	h := sha3.NewShake256()
+	_, _ = h.Write(sk.tr[:])
+	_, _ = h.Write(msg)
+	_, _ = h.Read(mu[:])
+
+	// ρ' = CRH(key ‖ μ)
+	h.Reset()
+	_, _ = h.Write(sk.key[:])
+	_, _ = h.Write(mu[:])
+	_, _ = h.Read(rhop[:])
+
+	// Main rejection loop
+	attempt := 0
+	for {
+		attempt++
+		if attempt >= 576 {
+			// Depending on the mode, one try has a chance between 1/7 and 1/4
+			// of succeeding.  Thus it is safe to say that 576 iterations
+			// are enough as (6/7)⁵⁷⁶ < 2⁻¹²⁸.
+			panic("This should only happen 1 in  2^{128}: something is wrong.")
+		}
+
+		// y = ExpandMask(ρ', key)
+		VecLDeriveUniformLeGamma1(&y, &rhop, yNonce)
+		yNonce += uint16(L)
+
+		// Set w to A y
+		yh = y
+		yh.NTT()
+		for i := 0; i < K; i++ {
+			PolyDotHat(&w[i], &sk.A[i], &yh)
+			w[i].ReduceLe2Q()
+			w[i].InvNTT()
+		}
+
+		// Decompose w into w₀ and w₁
+		w.NormalizeAssumingLe2Q()
+		w.Decompose(&w0, &w1)
+
+		// c~ = H(μ ‖ w₁)
+		w1.PackW1(w1Packed[:])
+		h.Reset()
+		_, _ = h.Write(mu[:])
+		_, _ = h.Write(w1Packed[:])
+		_, _ = h.Read(sig.c[:])
+
+		PolyDeriveUniformBall(&ch, &sig.c)
+		ch.NTT()
+
+		// Ensure ‖ w₀ - c·s2 ‖_∞ < γ₂ - β.
+		//
+		// By Lemma 3 of the specification this is equivalent to checking that
+		// both ‖ r₀ ‖_∞ < γ₂ - β and r₁ = w₁, for the decomposition
+		// w - c·s₂	 = r₁ α + r₀ as computed by decompose().
+		// See also §4.1 of the specification.
+		for i := 0; i < K; i++ {
+			w0mcs2[i].MulHat(&ch, &sk.s2h[i])
+			w0mcs2[i].InvNTT()
+		}
+		w0mcs2.Sub(&w0, &w0mcs2)
+		w0mcs2.Normalize()
+
+		if w0mcs2.Exceeds(Gamma2 - Beta) {
+			continue
+		}
+
+		// z = y + c·s₁
+		for i := 0; i < L; i++ {
+			sig.z[i].MulHat(&ch, &sk.s1h[i])
+			sig.z[i].InvNTT()
+		}
+		sig.z.Add(&sig.z, &y)
+		sig.z.Normalize()
+
+		// Ensure  ‖z‖_∞ < γ₁ - β
+		if sig.z.Exceeds(Gamma1 - Beta) {
+			continue
+		}
+
+		// Compute c·t₀
+		for i := 0; i < K; i++ {
+			ct0[i].MulHat(&ch, &sk.t0h[i])
+			ct0[i].InvNTT()
+		}
+		ct0.NormalizeAssumingLe2Q()
+
+		// Ensure ‖c·t₀‖_∞ < γ₂.
+		if ct0.Exceeds(Gamma2) {
+			continue
+		}
+
+		// Create the hint to be able to reconstruct w₁ from w - c·s₂ + c·t0.
+		// Note that we're not using makeHint() in the obvious way as we
+		// do not know whether ‖ sc·s₂ - c·t₀ ‖_∞ < γ₂.  Instead we note
+		// that our makeHint() is actually the same as a makeHint for a
+		// different decomposition:
+		//
+		// Earlier we ensured indirectly with a check that r₁ = w₁ where
+		// r = w - c·s₂.  Hence r₀ = r - r₁ α = w - c·s₂ - w₁ α = w₀ - c·s₂.
+		// Thus  MakeHint(w₀ - c·s₂ + c·t₀, w₁) = MakeHint(r0 + c·t₀, r₁)
+		// and UseHint(w - c·s₂ + c·t₀, w₁) = UseHint(r + c·t₀, r₁).
+		// As we just ensured that ‖ c·t₀ ‖_∞ < γ₂ our usage is correct.
+		w0mcs2pct0.Add(&w0mcs2, &ct0)
+		w0mcs2pct0.NormalizeAssumingLe2Q()
+		hintPop := sig.hint.MakeHint(&w0mcs2pct0, &w1)
+		if hintPop > Omega {
+			continue
+		}
+
+		break
+	}
+
+	sig.Pack(signature[:])
+}
+
+// Computes the public key corresponding to this private key.
+func (sk *PrivateKey) Public() *PublicKey {
+	var t0 VecK
+	pk := &PublicKey{
+		rho: sk.rho,
+		A:   &sk.A,
+		tr:  &sk.tr,
+	}
+	sk.computeT0andT1(&t0, &pk.t1)
+	pk.t1.PackT1(pk.t1p[:])
+	return pk
+}
+
+// Equal returns whether the two public keys are equal
+func (pk *PublicKey) Equal(other *PublicKey) bool {
+	return pk.rho == other.rho && pk.t1 == other.t1
+}
+
+// Equal returns whether the two private keys are equal
+func (sk *PrivateKey) Equal(other *PrivateKey) bool {
+	ret := (subtle.ConstantTimeCompare(sk.rho[:], other.rho[:]) &
+		subtle.ConstantTimeCompare(sk.key[:], other.key[:]) &
+		subtle.ConstantTimeCompare(sk.tr[:], other.tr[:]))
+
+	acc := uint32(0)
+	for i := 0; i < L; i++ {
+		for j := 0; j < common.N; j++ {
+			acc |= sk.s1[i][j] ^ other.s1[i][j]
+		}
+	}
+	for i := 0; i < K; i++ {
+		for j := 0; j < common.N; j++ {
+			acc |= sk.s2[i][j] ^ other.s2[i][j]
+			acc |= sk.t0[i][j] ^ other.t0[i][j]
+		}
+	}
+	return (ret & subtle.ConstantTimeEq(int32(acc), 0)) == 1
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/mat.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/mat.go
new file mode 100644
index 00000000..ce39b7f9
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/mat.go
@@ -0,0 +1,57 @@
+package internal
+
+import (
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+)
+
+// A k by l matrix of polynomials.
+type Mat [K]VecL
+
+// Expands the given seed to a complete matrix.
+//
+// This function is called ExpandA in the specification.
+func (m *Mat) Derive(seed *[32]byte) {
+	if !DeriveX4Available {
+		for i := uint16(0); i < K; i++ {
+			for j := uint16(0); j < L; j++ {
+				PolyDeriveUniform(&m[i][j], seed, (i<<8)+j)
+			}
+		}
+		return
+	}
+
+	idx := 0
+	var nonces [4]uint16
+	var ps [4]*common.Poly
+	for i := uint16(0); i < K; i++ {
+		for j := uint16(0); j < L; j++ {
+			nonces[idx] = (i << 8) + j
+			ps[idx] = &m[i][j]
+			idx++
+			if idx == 4 {
+				idx = 0
+				PolyDeriveUniformX4(ps, seed, nonces)
+			}
+		}
+	}
+	if idx != 0 {
+		for i := idx; i < 4; i++ {
+			ps[i] = nil
+		}
+		PolyDeriveUniformX4(ps, seed, nonces)
+	}
+}
+
+// Set p to the inner product of a and b using pointwise multiplication.
+//
+// Assumes a and b are in Montgomery form and their coefficients are
+// pairwise sufficiently small to multiply, see Poly.MulHat().  Resulting
+// coefficients are bounded by 2Lq.
+func PolyDotHat(p *common.Poly, a, b *VecL) {
+	var t common.Poly
+	*p = common.Poly{} // zero p
+	for i := 0; i < L; i++ {
+		t.MulHat(&a[i], &b[i])
+		p.Add(&t, p)
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/pack.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/pack.go
new file mode 100644
index 00000000..6a152d73
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/pack.go
@@ -0,0 +1,268 @@
+package internal
+
+import (
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+)
+
+// Writes p with norm less than or equal η into buf, which must be of
+// size PolyLeqEtaSize.
+//
+// Assumes coefficients of p are not normalized, but in [q-η,q+η].
+func PolyPackLeqEta(p *common.Poly, buf []byte) {
+	if DoubleEtaBits == 4 { // compiler eliminates branch
+		j := 0
+		for i := 0; i < PolyLeqEtaSize; i++ {
+			buf[i] = (byte(common.Q+Eta-p[j]) |
+				byte(common.Q+Eta-p[j+1])<<4)
+			j += 2
+		}
+	} else if DoubleEtaBits == 3 {
+		j := 0
+		for i := 0; i < PolyLeqEtaSize; i += 3 {
+			buf[i] = (byte(common.Q+Eta-p[j]) |
+				(byte(common.Q+Eta-p[j+1]) << 3) |
+				(byte(common.Q+Eta-p[j+2]) << 6))
+			buf[i+1] = ((byte(common.Q+Eta-p[j+2]) >> 2) |
+				(byte(common.Q+Eta-p[j+3]) << 1) |
+				(byte(common.Q+Eta-p[j+4]) << 4) |
+				(byte(common.Q+Eta-p[j+5]) << 7))
+			buf[i+2] = ((byte(common.Q+Eta-p[j+5]) >> 1) |
+				(byte(common.Q+Eta-p[j+6]) << 2) |
+				(byte(common.Q+Eta-p[j+7]) << 5))
+			j += 8
+		}
+	} else {
+		panic("eta not supported")
+	}
+}
+
+// Sets p to the polynomial of norm less than or equal η encoded in the
+// given buffer of size PolyLeqEtaSize.
+//
+// Output coefficients of p are not normalized, but in [q-η,q+η] provided
+// buf was created using PackLeqEta.
+//
+// Beware, for arbitrary buf the coefficients of p might end up in
+// the interval [q-2^b,q+2^b] where b is the least b with η≤2^b.
+func PolyUnpackLeqEta(p *common.Poly, buf []byte) {
+	if DoubleEtaBits == 4 { // compiler eliminates branch
+		j := 0
+		for i := 0; i < PolyLeqEtaSize; i++ {
+			p[j] = common.Q + Eta - uint32(buf[i]&15)
+			p[j+1] = common.Q + Eta - uint32(buf[i]>>4)
+			j += 2
+		}
+	} else if DoubleEtaBits == 3 {
+		j := 0
+		for i := 0; i < PolyLeqEtaSize; i += 3 {
+			p[j] = common.Q + Eta - uint32(buf[i]&7)
+			p[j+1] = common.Q + Eta - uint32((buf[i]>>3)&7)
+			p[j+2] = common.Q + Eta - uint32((buf[i]>>6)|((buf[i+1]<<2)&7))
+			p[j+3] = common.Q + Eta - uint32((buf[i+1]>>1)&7)
+			p[j+4] = common.Q + Eta - uint32((buf[i+1]>>4)&7)
+			p[j+5] = common.Q + Eta - uint32((buf[i+1]>>7)|((buf[i+2]<<1)&7))
+			p[j+6] = common.Q + Eta - uint32((buf[i+2]>>2)&7)
+			p[j+7] = common.Q + Eta - uint32((buf[i+2]>>5)&7)
+			j += 8
+		}
+	} else {
+		panic("eta not supported")
+	}
+}
+
+// Writes v with coefficients in {0, 1} of which at most ω non-zero
+// to buf, which must have length ω+k.
+func (v *VecK) PackHint(buf []byte) {
+	// The packed hint starts with the indices of the non-zero coefficients
+	// For instance:
+	//
+	//    (x⁵⁶ + x¹⁰⁰, x²⁵⁵, 0, x² + x²³, x¹)
+	//
+	// Yields
+	//
+	//  56, 100, 255, 2, 23, 1
+	//
+	// Then we pad with zeroes until we have a list of ω items:
+	// //  56, 100, 255, 2, 23, 1, 0, 0, ..., 0
+	//
+	// Then we finish with a list of the switch-over-indices in this
+	// list between polynomials, so:
+	//
+	//  56, 100, 255, 2, 23, 1, 0, 0, ..., 0, 2, 3, 3, 5, 6
+
+	off := uint8(0)
+	for i := 0; i < K; i++ {
+		for j := uint16(0); j < common.N; j++ {
+			if v[i][j] != 0 {
+				buf[off] = uint8(j)
+				off++
+			}
+		}
+		buf[Omega+i] = off
+	}
+	for ; off < Omega; off++ {
+		buf[off] = 0
+	}
+}
+
+// Sets v to the vector encoded using VecK.PackHint()
+//
+// Returns whether unpacking was successful.
+func (v *VecK) UnpackHint(buf []byte) bool {
+	// A priori, there would be several reasonable ways to encode the same
+	// hint vector.  We take care to only allow only one encoding, to ensure
+	// "strong unforgeability".
+	//
+	// See PackHint() source for description of the encoding.
+	*v = VecK{}         // zero v
+	prevSOP := uint8(0) // previous switch-over-point
+	for i := 0; i < K; i++ {
+		SOP := buf[Omega+i]
+		if SOP < prevSOP || SOP > Omega {
+			return false // ensures switch-over-points are increasing
+		}
+		for j := prevSOP; j < SOP; j++ {
+			if j > prevSOP && buf[j] <= buf[j-1] {
+				return false // ensures indices are increasing (within a poly)
+			}
+			v[i][buf[j]] = 1
+		}
+		prevSOP = SOP
+	}
+	for j := prevSOP; j < Omega; j++ {
+		if buf[j] != 0 {
+			return false // ensures padding indices are zero
+		}
+	}
+
+	return true
+}
+
+// Sets p to the polynomial packed into buf by PolyPackLeGamma1.
+//
+// p will be normalized.
+func PolyUnpackLeGamma1(p *common.Poly, buf []byte) {
+	if Gamma1Bits == 17 {
+		j := 0
+		for i := 0; i < PolyLeGamma1Size; i += 9 {
+			p0 := uint32(buf[i]) | (uint32(buf[i+1]) << 8) |
+				(uint32(buf[i+2]&0x3) << 16)
+			p1 := uint32(buf[i+2]>>2) | (uint32(buf[i+3]) << 6) |
+				(uint32(buf[i+4]&0xf) << 14)
+			p2 := uint32(buf[i+4]>>4) | (uint32(buf[i+5]) << 4) |
+				(uint32(buf[i+6]&0x3f) << 12)
+			p3 := uint32(buf[i+6]>>6) | (uint32(buf[i+7]) << 2) |
+				(uint32(buf[i+8]) << 10)
+
+			// coefficients in [0,…,2γ₁)
+			p0 = Gamma1 - p0 // (-γ₁,…,γ₁]
+			p1 = Gamma1 - p1
+			p2 = Gamma1 - p2
+			p3 = Gamma1 - p3
+
+			p0 += uint32(int32(p0)>>31) & common.Q // normalize
+			p1 += uint32(int32(p1)>>31) & common.Q
+			p2 += uint32(int32(p2)>>31) & common.Q
+			p3 += uint32(int32(p3)>>31) & common.Q
+
+			p[j] = p0
+			p[j+1] = p1
+			p[j+2] = p2
+			p[j+3] = p3
+
+			j += 4
+		}
+	} else if Gamma1Bits == 19 {
+		j := 0
+		for i := 0; i < PolyLeGamma1Size; i += 5 {
+			p0 := uint32(buf[i]) | (uint32(buf[i+1]) << 8) |
+				(uint32(buf[i+2]&0xf) << 16)
+			p1 := uint32(buf[i+2]>>4) | (uint32(buf[i+3]) << 4) |
+				(uint32(buf[i+4]) << 12)
+
+			p0 = Gamma1 - p0
+			p1 = Gamma1 - p1
+
+			p0 += uint32(int32(p0)>>31) & common.Q
+			p1 += uint32(int32(p1)>>31) & common.Q
+
+			p[j] = p0
+			p[j+1] = p1
+
+			j += 2
+		}
+	} else {
+		panic("γ₁ not supported")
+	}
+}
+
+// Writes p whose coefficients are in (-γ₁,γ₁] into buf
+// which has to be of length PolyLeGamma1Size.
+//
+// Assumes p is normalized.
+func PolyPackLeGamma1(p *common.Poly, buf []byte) {
+	if Gamma1Bits == 17 {
+		j := 0
+		// coefficients in [0,…,γ₁] ∪ (q-γ₁,…,q)
+		for i := 0; i < PolyLeGamma1Size; i += 9 {
+			p0 := Gamma1 - p[j]                    // [0,…,γ₁] ∪ (γ₁-q,…,2γ₁-q)
+			p0 += uint32(int32(p0)>>31) & common.Q // [0,…,2γ₁)
+			p1 := Gamma1 - p[j+1]
+			p1 += uint32(int32(p1)>>31) & common.Q
+			p2 := Gamma1 - p[j+2]
+			p2 += uint32(int32(p2)>>31) & common.Q
+			p3 := Gamma1 - p[j+3]
+			p3 += uint32(int32(p3)>>31) & common.Q
+
+			buf[i+0] = byte(p0)
+			buf[i+1] = byte(p0 >> 8)
+			buf[i+2] = byte(p0>>16) | byte(p1<<2)
+			buf[i+3] = byte(p1 >> 6)
+			buf[i+4] = byte(p1>>14) | byte(p2<<4)
+			buf[i+5] = byte(p2 >> 4)
+			buf[i+6] = byte(p2>>12) | byte(p3<<6)
+			buf[i+7] = byte(p3 >> 2)
+			buf[i+8] = byte(p3 >> 10)
+
+			j += 4
+		}
+	} else if Gamma1Bits == 19 {
+		j := 0
+		for i := 0; i < PolyLeGamma1Size; i += 5 {
+			// Coefficients are in [0, γ₁] ∪ (Q-γ₁, Q)
+			p0 := Gamma1 - p[j]
+			p0 += uint32(int32(p0)>>31) & common.Q
+			p1 := Gamma1 - p[j+1]
+			p1 += uint32(int32(p1)>>31) & common.Q
+
+			buf[i+0] = byte(p0)
+			buf[i+1] = byte(p0 >> 8)
+			buf[i+2] = byte(p0>>16) | byte(p1<<4)
+			buf[i+3] = byte(p1 >> 4)
+			buf[i+4] = byte(p1 >> 12)
+
+			j += 2
+		}
+	} else {
+		panic("γ₁ not supported")
+	}
+}
+
+// Pack w₁ into buf, which must be of length PolyW1Size.
+//
+// Assumes w₁ is normalized.
+func PolyPackW1(p *common.Poly, buf []byte) {
+	if Gamma1Bits == 19 {
+		p.PackLe16(buf)
+	} else if Gamma1Bits == 17 {
+		j := 0
+		for i := 0; i < PolyW1Size; i += 3 {
+			buf[i] = byte(p[j]) | byte(p[j+1]<<6)
+			buf[i+1] = byte(p[j+1]>>2) | byte(p[j+2]<<4)
+			buf[i+2] = byte(p[j+2]>>4) | byte(p[j+3]<<2)
+			j += 4
+		}
+	} else {
+		panic("unsupported γ₁")
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/params.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/params.go
new file mode 100644
index 00000000..c2292523
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/params.go
@@ -0,0 +1,16 @@
+// Code generated from params.templ.go. DO NOT EDIT.
+
+package internal
+
+const (
+	Name          = "Dilithium3"
+	UseAES        = false
+	K             = 6
+	L             = 5
+	Eta           = 4
+	DoubleEtaBits = 4
+	Omega         = 55
+	Tau           = 49
+	Gamma1Bits    = 19
+	Gamma2        = 261888
+)
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/rounding.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/rounding.go
new file mode 100644
index 00000000..f44c951d
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/rounding.go
@@ -0,0 +1,140 @@
+package internal
+
+import (
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+)
+
+// Splits 0 ≤ a < q into a₀ and a₁ with a = a₁*α + a₀ with -α/2 < a₀ ≤ α/2,
+// except for when we would have a₁ = (q-1)/α in which case a₁=0 is taken
+// and -α/2 ≤ a₀ < 0.  Returns a₀ + q.  Note 0 ≤ a₁ < (q-1)/α.
+// Recall α = 2γ₂.
+func decompose(a uint32) (a0plusQ, a1 uint32) {
+	// a₁ = ⌈a / 128⌉
+	a1 = (a + 127) >> 7
+
+	if Alpha == 523776 {
+		// 1025/2²² is close enough to 1/4092 so that a₁
+		// becomes a/α rounded down.
+		a1 = ((a1*1025 + (1 << 21)) >> 22)
+
+		// For the corner-case a₁ = (q-1)/α = 16, we have to set a₁=0.
+		a1 &= 15
+	} else if Alpha == 190464 {
+		// 1488/2²⁴ is close enough to 1/1488 so that a₁
+		// becomes a/α rounded down.
+		a1 = ((a1 * 11275) + (1 << 23)) >> 24
+
+		// For the corner-case a₁ = (q-1)/α = 44, we have to set a₁=0.
+		a1 ^= uint32(int32(43-a1)>>31) & a1
+	} else {
+		panic("unsupported α")
+	}
+
+	a0plusQ = a - a1*Alpha
+
+	// In the corner-case, when we set a₁=0, we will incorrectly
+	// have a₀ > (q-1)/2 and we'll need to subtract q.  As we
+	// return a₀ + q, that comes down to adding q if a₀ < (q-1)/2.
+	a0plusQ += uint32(int32(a0plusQ-(common.Q-1)/2)>>31) & common.Q
+
+	return
+}
+
+// Assume 0 ≤ r, f < Q with ‖f‖_∞ ≤ α/2.  Decompose r as r = r1*α + r0 as
+// computed by decompose().  Write r' := r - f (mod Q).  Now, decompose
+// r'=r-f again as  r' = r'1*α + r'0 using decompose().  As f is small, we
+// have r'1 = r1 + h, where h ∈ {-1, 0, 1}.  makeHint() computes |h|
+// given z0 := r0 - f (mod Q) and r1.  With |h|, which is called the hint,
+// we can reconstruct r1 using only r' = r - f, which is done by useHint().
+// To wit:
+//
+//	useHint( r - f, makeHint( r0 - f, r1 ) ) = r1.
+//
+// Assumes 0 ≤ z0 < Q.
+func makeHint(z0, r1 uint32) uint32 {
+	// If -α/2 < r0 - f ≤ α/2, then r1*α + r0 - f is a valid decomposition of r'
+	// with the restrictions of decompose() and so r'1 = r1.  So the hint
+	// should be 0. This is covered by the first two inequalities.
+	// There is one other case: if r0 - f = -α/2, then r1*α + r0 - f is also
+	// a valid decomposition if r1 = 0.  In the other cases a one is carried
+	// and the hint should be 1.
+	if z0 <= Gamma2 || z0 > common.Q-Gamma2 || (z0 == common.Q-Gamma2 && r1 == 0) {
+		return 0
+	}
+	return 1
+}
+
+// Uses the hint created by makeHint() to reconstruct r1 from r'=r-f; see
+// documentation of makeHint() for context.
+// Assumes 0 ≤ r' < Q.
+func useHint(rp uint32, hint uint32) uint32 {
+	rp0plusQ, rp1 := decompose(rp)
+	if hint == 0 {
+		return rp1
+	}
+	if rp0plusQ > common.Q {
+		return (rp1 + 1) & 15
+	}
+	return (rp1 - 1) & 15
+}
+
+// Sets p to the hint polynomial for p0 the modified low bits and p1
+// the unmodified high bits --- see makeHint().
+//
+// Returns the number of ones in the hint polynomial.
+func PolyMakeHint(p, p0, p1 *common.Poly) (pop uint32) {
+	for i := 0; i < common.N; i++ {
+		h := makeHint(p0[i], p1[i])
+		pop += h
+		p[i] = h
+	}
+	return
+}
+
+// Computes corrections to the high bits of the polynomial q according
+// to the hints in h and sets p to the corrected high bits.  Returns p.
+func PolyUseHint(p, q, hint *common.Poly) {
+	var q0PlusQ common.Poly
+
+	// See useHint() and makeHint() for an explanation.  We reimplement it
+	// here so that we can call Poly.Decompose(), which might be way faster
+	// than calling decompose() in a loop (for instance when having AVX2.)
+
+	PolyDecompose(q, &q0PlusQ, p)
+
+	for i := 0; i < common.N; i++ {
+		if hint[i] == 0 {
+			continue
+		}
+		if Gamma2 == 261888 {
+			if q0PlusQ[i] > common.Q {
+				p[i] = (p[i] + 1) & 15
+			} else {
+				p[i] = (p[i] - 1) & 15
+			}
+		} else if Gamma2 == 95232 {
+			if q0PlusQ[i] > common.Q {
+				if p[i] == 43 {
+					p[i] = 0
+				} else {
+					p[i]++
+				}
+			} else {
+				if p[i] == 0 {
+					p[i] = 43
+				} else {
+					p[i]--
+				}
+			}
+		} else {
+			panic("unsupported γ₂")
+		}
+	}
+}
+
+// Splits each of the coefficients of p using decompose.
+func PolyDecompose(p, p0PlusQ, p1 *common.Poly) {
+	for i := 0; i < common.N; i++ {
+		p0PlusQ[i], p1[i] = decompose(p[i])
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/sample.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/sample.go
new file mode 100644
index 00000000..256ec731
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/sample.go
@@ -0,0 +1,368 @@
+package internal
+
+import (
+	"encoding/binary"
+
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+	"github.com/cloudflare/circl/simd/keccakf1600"
+)
+
+// DeriveX4Available indicates whether the system supports the quick fourway
+// sampling variants like PolyDeriveUniformX4.
+var DeriveX4Available = keccakf1600.IsEnabledX4() && !UseAES
+
+// For each i, sample ps[i] uniformly from the given seed and nonces[i].
+// ps[i] may be nil and is ignored in that case.
+//
+// Can only be called when DeriveX4Available is true.
+func PolyDeriveUniformX4(ps [4]*common.Poly, seed *[32]byte, nonces [4]uint16) {
+	var perm keccakf1600.StateX4
+	state := perm.Initialize(false)
+
+	// Absorb the seed in the four states
+	for i := 0; i < 4; i++ {
+		v := binary.LittleEndian.Uint64(seed[8*i : 8*(i+1)])
+		for j := 0; j < 4; j++ {
+			state[i*4+j] = v
+		}
+	}
+
+	// Absorb the nonces, the SHAKE128 domain separator (0b1111), the
+	// start of the padding (0b...001) and the end of the padding 0b100...
+	// Recall that the rate of SHAKE128 is 168 --- i.e. 21 uint64s.
+	for j := 0; j < 4; j++ {
+		state[4*4+j] = uint64(nonces[j]) | (0x1f << 16)
+		state[20*4+j] = 0x80 << 56
+	}
+
+	var idx [4]int // indices into ps
+	for j := 0; j < 4; j++ {
+		if ps[j] == nil {
+			idx[j] = common.N // mark nil polynomial as completed
+		}
+	}
+
+	done := false
+	for !done {
+		// Applies KeccaK-f[1600] to state to get the next 21 uint64s of each
+		// of the four SHAKE128 streams.
+		perm.Permute()
+
+		done = true
+
+	PolyLoop:
+		for j := 0; j < 4; j++ {
+			if idx[j] == common.N {
+				continue
+			}
+			for i := 0; i < 7; i++ {
+				var t [8]uint32
+				t[0] = uint32(state[i*3*4+j] & 0x7fffff)
+				t[1] = uint32((state[i*3*4+j] >> 24) & 0x7fffff)
+				t[2] = uint32((state[i*3*4+j] >> 48) |
+					((state[(i*3+1)*4+j] & 0x7f) << 16))
+				t[3] = uint32((state[(i*3+1)*4+j] >> 8) & 0x7fffff)
+				t[4] = uint32((state[(i*3+1)*4+j] >> 32) & 0x7fffff)
+				t[5] = uint32((state[(i*3+1)*4+j] >> 56) |
+					((state[(i*3+2)*4+j] & 0x7fff) << 8))
+				t[6] = uint32((state[(i*3+2)*4+j] >> 16) & 0x7fffff)
+				t[7] = uint32((state[(i*3+2)*4+j] >> 40) & 0x7fffff)
+
+				for k := 0; k < 8; k++ {
+					if t[k] < common.Q {
+						ps[j][idx[j]] = t[k]
+						idx[j]++
+						if idx[j] == common.N {
+							continue PolyLoop
+						}
+					}
+				}
+			}
+			done = false
+		}
+	}
+}
+
+// Sample p uniformly from the given seed and nonce.
+//
+// p will be normalized.
+func PolyDeriveUniform(p *common.Poly, seed *[32]byte, nonce uint16) {
+	var i, length int
+	var buf [12 * 16]byte // fits 168B SHAKE-128 rate and 12 16B AES blocks
+
+	if UseAES {
+		length = 12 * 16
+	} else {
+		length = 168
+	}
+
+	sample := func() {
+		// Note that 3 divides into 168 and 12*16, so we use up buf completely.
+		for j := 0; j < length && i < common.N; j += 3 {
+			t := (uint32(buf[j]) | (uint32(buf[j+1]) << 8) |
+				(uint32(buf[j+2]) << 16)) & 0x7fffff
+
+			// We use rejection sampling
+			if t < common.Q {
+				p[i] = t
+				i++
+			}
+		}
+	}
+
+	if UseAES {
+		h := common.NewAesStream128(seed, nonce)
+
+		for i < common.N {
+			h.SqueezeInto(buf[:length])
+			sample()
+		}
+	} else {
+		var iv [32 + 2]byte // 32 byte seed + uint16 nonce
+		h := sha3.NewShake128()
+		copy(iv[:32], seed[:])
+		iv[32] = uint8(nonce)
+		iv[33] = uint8(nonce >> 8)
+		_, _ = h.Write(iv[:])
+
+		for i < common.N {
+			_, _ = h.Read(buf[:168])
+			sample()
+		}
+	}
+}
+
+// Sample p uniformly with coefficients of norm less than or equal η,
+// using the given seed and nonce.
+//
+// p will not be normalized, but will have coefficients in [q-η,q+η].
+func PolyDeriveUniformLeqEta(p *common.Poly, seed *[64]byte, nonce uint16) {
+	// Assumes 2 < η < 8.
+	var i, length int
+	var buf [9 * 16]byte // fits 136B SHAKE-256 rate and 9 16B AES blocks
+
+	if UseAES {
+		length = 9 * 16
+	} else {
+		length = 136
+	}
+
+	sample := func() {
+		// We use rejection sampling
+		for j := 0; j < length && i < common.N; j++ {
+			t1 := uint32(buf[j]) & 15
+			t2 := uint32(buf[j]) >> 4
+			if Eta == 2 { // branch is eliminated by compiler
+				if t1 <= 14 {
+					t1 -= ((205 * t1) >> 10) * 5 // reduce mod  5
+					p[i] = common.Q + Eta - t1
+					i++
+				}
+				if t2 <= 14 && i < common.N {
+					t2 -= ((205 * t2) >> 10) * 5 // reduce mod 5
+					p[i] = common.Q + Eta - t2
+					i++
+				}
+			} else if Eta == 4 {
+				if t1 <= 2*Eta {
+					p[i] = common.Q + Eta - t1
+					i++
+				}
+				if t2 <= 2*Eta && i < common.N {
+					p[i] = common.Q + Eta - t2
+					i++
+				}
+			} else {
+				panic("unsupported η")
+			}
+		}
+	}
+
+	if UseAES {
+		h := common.NewAesStream256(seed, nonce)
+
+		for i < common.N {
+			h.SqueezeInto(buf[:length])
+			sample()
+		}
+	} else {
+		var iv [64 + 2]byte // 64 byte seed + uint16 nonce
+
+		h := sha3.NewShake256()
+		copy(iv[:64], seed[:])
+		iv[64] = uint8(nonce)
+		iv[65] = uint8(nonce >> 8)
+
+		// 136 is SHAKE-256 rate
+		_, _ = h.Write(iv[:])
+
+		for i < common.N {
+			_, _ = h.Read(buf[:136])
+			sample()
+		}
+	}
+}
+
+// Sample v[i] uniformly with coefficients in (-γ₁,…,γ₁]  using the
+// given seed and nonce+i
+//
+// p will be normalized.
+func VecLDeriveUniformLeGamma1(v *VecL, seed *[64]byte, nonce uint16) {
+	for i := 0; i < L; i++ {
+		PolyDeriveUniformLeGamma1(&v[i], seed, nonce+uint16(i))
+	}
+}
+
+// Sample p uniformly with coefficients in (-γ₁,…,γK1s] using the
+// given seed and nonce.
+//
+// p will be normalized.
+func PolyDeriveUniformLeGamma1(p *common.Poly, seed *[64]byte, nonce uint16) {
+	var buf [PolyLeGamma1Size]byte
+
+	if UseAES {
+		h := common.NewAesStream256(seed, nonce)
+		h.SqueezeInto(buf[:])
+	} else {
+		var iv [66]byte
+		h := sha3.NewShake256()
+		copy(iv[:64], seed[:])
+		iv[64] = uint8(nonce)
+		iv[65] = uint8(nonce >> 8)
+		_, _ = h.Write(iv[:])
+		_, _ = h.Read(buf[:])
+	}
+
+	PolyUnpackLeGamma1(p, buf[:])
+}
+
+// For each i, sample ps[i] uniformly with τ non-zero coefficients in {q-1,1}
+// using the given seed and w1[i].  ps[i] may be nil and is ignored
+// in that case.  ps[i] will be normalized.
+//
+// Can only be called when DeriveX4Available is true.
+//
+// This function is currently not used (yet).
+func PolyDeriveUniformBallX4(ps [4]*common.Poly, seed *[32]byte) {
+	var perm keccakf1600.StateX4
+	state := perm.Initialize(false)
+
+	// Absorb the seed in the four states
+	for i := 0; i < 4; i++ {
+		v := binary.LittleEndian.Uint64(seed[8*i : 8*(i+1)])
+		for j := 0; j < 4; j++ {
+			state[i*4+j] = v
+		}
+	}
+
+	// SHAKE256 domain separator and padding
+	for j := 0; j < 4; j++ {
+		state[4*4+j] ^= 0x1f
+		state[16*4+j] ^= 0x80 << 56
+	}
+	perm.Permute()
+
+	var signs [4]uint64
+	var idx [4]uint16 // indices into ps
+
+	for j := 0; j < 4; j++ {
+		if ps[j] != nil {
+			signs[j] = state[j]
+			*ps[j] = common.Poly{} // zero ps[j]
+			idx[j] = common.N - Tau
+		} else {
+			idx[j] = common.N // mark as completed
+		}
+	}
+
+	stateOffset := 1
+	for {
+		done := true
+
+	PolyLoop:
+		for j := 0; j < 4; j++ {
+			if idx[j] == common.N {
+				continue
+			}
+
+			for i := stateOffset; i < 17; i++ {
+				var bs [8]byte
+				binary.LittleEndian.PutUint64(bs[:], state[4*i+j])
+				for k := 0; k < 8; k++ {
+					b := uint16(bs[k])
+
+					if b > idx[j] {
+						continue
+					}
+
+					ps[j][idx[j]] = ps[j][b]
+					ps[j][b] = 1
+					// Takes least significant bit of signs and uses it for the sign.
+					// Note 1 ^ (1 | (Q-1)) = Q-1.
+					ps[j][b] ^= uint32((-(signs[j] & 1)) & (1 | (common.Q - 1)))
+					signs[j] >>= 1
+
+					idx[j]++
+					if idx[j] == common.N {
+						continue PolyLoop
+					}
+				}
+			}
+
+			done = false
+		}
+
+		if done {
+			break
+		}
+
+		perm.Permute()
+		stateOffset = 0
+	}
+}
+
+// Samples p uniformly with τ non-zero coefficients in {q-1,1}.
+//
+// The polynomial p will be normalized.
+func PolyDeriveUniformBall(p *common.Poly, seed *[32]byte) {
+	var buf [136]byte // SHAKE-256 rate is 136
+
+	h := sha3.NewShake256()
+	_, _ = h.Write(seed[:])
+	_, _ = h.Read(buf[:])
+
+	// Essentially we generate a sequence of τ ones or minus ones,
+	// prepend 196 zeroes and shuffle the concatenation using the
+	// usual algorithm (Fisher--Yates.)
+	signs := binary.LittleEndian.Uint64(buf[:])
+	bufOff := 8 // offset into buf
+
+	*p = common.Poly{} // zero p
+	for i := uint16(common.N - Tau); i < common.N; i++ {
+		var b uint16
+
+		// Find location of where to move the new coefficient to using
+		// rejection sampling.
+		for {
+			if bufOff >= 136 {
+				_, _ = h.Read(buf[:])
+				bufOff = 0
+			}
+
+			b = uint16(buf[bufOff])
+			bufOff++
+
+			if b <= i {
+				break
+			}
+		}
+
+		p[i] = p[b]
+		p[b] = 1
+		// Takes least significant bit of signs and uses it for the sign.
+		// Note 1 ^ (1 | (Q-1)) = Q-1.
+		p[b] ^= uint32((-(signs & 1)) & (1 | (common.Q - 1)))
+		signs >>= 1
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/vec.go b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/vec.go
new file mode 100644
index 00000000..1a5fe4ca
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/dilithium/mode3/internal/vec.go
@@ -0,0 +1,279 @@
+package internal
+
+import (
+	"github.com/cloudflare/circl/sign/dilithium/internal/common"
+)
+
+// A vector of L polynomials.
+type VecL [L]common.Poly
+
+// A vector of K polynomials.
+type VecK [K]common.Poly
+
+// Normalize the polynomials in this vector.
+func (v *VecL) Normalize() {
+	for i := 0; i < L; i++ {
+		v[i].Normalize()
+	}
+}
+
+// Normalize the polynomials in this vector assuming their coefficients
+// are already bounded by 2q.
+func (v *VecL) NormalizeAssumingLe2Q() {
+	for i := 0; i < L; i++ {
+		v[i].NormalizeAssumingLe2Q()
+	}
+}
+
+// Sets v to w + u.  Does not normalize.
+func (v *VecL) Add(w, u *VecL) {
+	for i := 0; i < L; i++ {
+		v[i].Add(&w[i], &u[i])
+	}
+}
+
+// Applies NTT componentwise. See Poly.NTT() for details.
+func (v *VecL) NTT() {
+	for i := 0; i < L; i++ {
+		v[i].NTT()
+	}
+}
+
+// Checks whether any of the coefficients exceeds the given bound in supnorm
+//
+// Requires the vector to be normalized.
+func (v *VecL) Exceeds(bound uint32) bool {
+	for i := 0; i < L; i++ {
+		if v[i].Exceeds(bound) {
+			return true
+		}
+	}
+	return false
+}
+
+// Applies Poly.Power2Round componentwise.
+//
+// Requires the vector to be normalized.
+func (v *VecL) Power2Round(v0PlusQ, v1 *VecL) {
+	for i := 0; i < L; i++ {
+		v[i].Power2Round(&v0PlusQ[i], &v1[i])
+	}
+}
+
+// Applies Poly.Decompose componentwise.
+//
+// Requires the vector to be normalized.
+func (v *VecL) Decompose(v0PlusQ, v1 *VecL) {
+	for i := 0; i < L; i++ {
+		PolyDecompose(&v[i], &v0PlusQ[i], &v1[i])
+	}
+}
+
+// Sequentially packs each polynomial using Poly.PackLeqEta().
+func (v *VecL) PackLeqEta(buf []byte) {
+	offset := 0
+	for i := 0; i < L; i++ {
+		PolyPackLeqEta(&v[i], buf[offset:])
+		offset += PolyLeqEtaSize
+	}
+}
+
+// Sets v to the polynomials packed in buf using VecL.PackLeqEta().
+func (v *VecL) UnpackLeqEta(buf []byte) {
+	offset := 0
+	for i := 0; i < L; i++ {
+		PolyUnpackLeqEta(&v[i], buf[offset:])
+		offset += PolyLeqEtaSize
+	}
+}
+
+// Sequentially packs each polynomial using PolyPackLeGamma1().
+func (v *VecL) PackLeGamma1(buf []byte) {
+	offset := 0
+	for i := 0; i < L; i++ {
+		PolyPackLeGamma1(&v[i], buf[offset:])
+		offset += PolyLeGamma1Size
+	}
+}
+
+// Sets v to the polynomials packed in buf using VecL.PackLeGamma1().
+func (v *VecL) UnpackLeGamma1(buf []byte) {
+	offset := 0
+	for i := 0; i < L; i++ {
+		PolyUnpackLeGamma1(&v[i], buf[offset:])
+		offset += PolyLeGamma1Size
+	}
+}
+
+// Normalize the polynomials in this vector.
+func (v *VecK) Normalize() {
+	for i := 0; i < K; i++ {
+		v[i].Normalize()
+	}
+}
+
+// Normalize the polynomials in this vector assuming their coefficients
+// are already bounded by 2q.
+func (v *VecK) NormalizeAssumingLe2Q() {
+	for i := 0; i < K; i++ {
+		v[i].NormalizeAssumingLe2Q()
+	}
+}
+
+// Sets v to w + u.  Does not normalize.
+func (v *VecK) Add(w, u *VecK) {
+	for i := 0; i < K; i++ {
+		v[i].Add(&w[i], &u[i])
+	}
+}
+
+// Checks whether any of the coefficients exceeds the given bound in supnorm
+//
+// Requires the vector to be normalized.
+func (v *VecK) Exceeds(bound uint32) bool {
+	for i := 0; i < K; i++ {
+		if v[i].Exceeds(bound) {
+			return true
+		}
+	}
+	return false
+}
+
+// Applies Poly.Power2Round componentwise.
+//
+// Requires the vector to be normalized.
+func (v *VecK) Power2Round(v0PlusQ, v1 *VecK) {
+	for i := 0; i < K; i++ {
+		v[i].Power2Round(&v0PlusQ[i], &v1[i])
+	}
+}
+
+// Applies Poly.Decompose componentwise.
+//
+// Requires the vector to be normalized.
+func (v *VecK) Decompose(v0PlusQ, v1 *VecK) {
+	for i := 0; i < K; i++ {
+		PolyDecompose(&v[i], &v0PlusQ[i], &v1[i])
+	}
+}
+
+// Sets v to the hint vector for v0 the modified low bits and v1
+// the unmodified high bits --- see makeHint().
+//
+// Returns the number of ones in the hint vector.
+func (v *VecK) MakeHint(v0, v1 *VecK) (pop uint32) {
+	for i := 0; i < K; i++ {
+		pop += PolyMakeHint(&v[i], &v0[i], &v1[i])
+	}
+	return
+}
+
+// Computes corrections to the high bits of the polynomials in the vector
+// w using the hints in h and sets v to the corrected high bits.  Returns v.
+// See useHint().
+func (v *VecK) UseHint(q, hint *VecK) *VecK {
+	for i := 0; i < K; i++ {
+		PolyUseHint(&v[i], &q[i], &hint[i])
+	}
+	return v
+}
+
+// Sequentially packs each polynomial using Poly.PackT1().
+func (v *VecK) PackT1(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		v[i].PackT1(buf[offset:])
+		offset += common.PolyT1Size
+	}
+}
+
+// Sets v to the vector packed into buf by PackT1().
+func (v *VecK) UnpackT1(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		v[i].UnpackT1(buf[offset:])
+		offset += common.PolyT1Size
+	}
+}
+
+// Sequentially packs each polynomial using Poly.PackT0().
+func (v *VecK) PackT0(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		v[i].PackT0(buf[offset:])
+		offset += common.PolyT0Size
+	}
+}
+
+// Sets v to the vector packed into buf by PackT0().
+func (v *VecK) UnpackT0(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		v[i].UnpackT0(buf[offset:])
+		offset += common.PolyT0Size
+	}
+}
+
+// Sequentially packs each polynomial using Poly.PackLeqEta().
+func (v *VecK) PackLeqEta(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		PolyPackLeqEta(&v[i], buf[offset:])
+		offset += PolyLeqEtaSize
+	}
+}
+
+// Sets v to the polynomials packed in buf using VecK.PackLeqEta().
+func (v *VecK) UnpackLeqEta(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		PolyUnpackLeqEta(&v[i], buf[offset:])
+		offset += PolyLeqEtaSize
+	}
+}
+
+// Applies NTT componentwise. See Poly.NTT() for details.
+func (v *VecK) NTT() {
+	for i := 0; i < K; i++ {
+		v[i].NTT()
+	}
+}
+
+// Sequentially packs each polynomial using PolyPackW1().
+func (v *VecK) PackW1(buf []byte) {
+	offset := 0
+	for i := 0; i < K; i++ {
+		PolyPackW1(&v[i], buf[offset:])
+		offset += PolyW1Size
+	}
+}
+
+// Sets v to a - b.
+//
+// Warning: assumes coefficients of the polynomials of  b are less than 2q.
+func (v *VecK) Sub(a, b *VecK) {
+	for i := 0; i < K; i++ {
+		v[i].Sub(&a[i], &b[i])
+	}
+}
+
+// Sets v to 2ᵈ w without reducing.
+func (v *VecK) MulBy2toD(w *VecK) {
+	for i := 0; i < K; i++ {
+		v[i].MulBy2toD(&w[i])
+	}
+}
+
+// Applies InvNTT componentwise. See Poly.InvNTT() for details.
+func (v *VecK) InvNTT() {
+	for i := 0; i < K; i++ {
+		v[i].InvNTT()
+	}
+}
+
+// Applies Poly.ReduceLe2Q() componentwise.
+func (v *VecK) ReduceLe2Q() {
+	for i := 0; i < K; i++ {
+		v[i].ReduceLe2Q()
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/ed25519.go b/vendor/github.com/cloudflare/circl/sign/ed25519/ed25519.go
new file mode 100644
index 00000000..2c73c26f
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/ed25519.go
@@ -0,0 +1,453 @@
+// Package ed25519 implements Ed25519 signature scheme as described in RFC-8032.
+//
+// This package provides optimized implementations of the three signature
+// variants and maintaining closer compatibility with crypto/ed25519.
+//
+//	| Scheme Name | Sign Function     | Verification  | Context           |
+//	|-------------|-------------------|---------------|-------------------|
+//	| Ed25519     | Sign              | Verify        | None              |
+//	| Ed25519Ph   | SignPh            | VerifyPh      | Yes, can be empty |
+//	| Ed25519Ctx  | SignWithCtx       | VerifyWithCtx | Yes, non-empty    |
+//	| All above   | (PrivateKey).Sign | VerifyAny     | As above          |
+//
+// Specific functions for sign and verify are defined. A generic signing
+// function for all schemes is available through the crypto.Signer interface,
+// which is implemented by the PrivateKey type. A correspond all-in-one
+// verification method is provided by the VerifyAny function.
+//
+// Signing with Ed25519Ph or Ed25519Ctx requires a context string for domain
+// separation. This parameter is passed using a SignerOptions struct defined
+// in this package. While Ed25519Ph accepts an empty context, Ed25519Ctx
+// enforces non-empty context strings.
+//
+// # Compatibility with crypto.ed25519
+//
+// These functions are compatible with the “Ed25519” function defined in
+// RFC-8032. However, unlike RFC 8032's formulation, this package's private
+// key representation includes a public key suffix to make multiple signing
+// operations with the same key more efficient. This package refers to the
+// RFC-8032 private key as the “seed”.
+//
+// References
+//
+//   - RFC-8032: https://rfc-editor.org/rfc/rfc8032.txt
+//   - Ed25519: https://ed25519.cr.yp.to/
+//   - EdDSA: High-speed high-security signatures. https://doi.org/10.1007/s13389-012-0027-1
+package ed25519
+
+import (
+	"bytes"
+	"crypto"
+	cryptoRand "crypto/rand"
+	"crypto/sha512"
+	"crypto/subtle"
+	"errors"
+	"fmt"
+	"io"
+	"strconv"
+
+	"github.com/cloudflare/circl/sign"
+)
+
+const (
+	// ContextMaxSize is the maximum length (in bytes) allowed for context.
+	ContextMaxSize = 255
+	// PublicKeySize is the size, in bytes, of public keys as used in this package.
+	PublicKeySize = 32
+	// PrivateKeySize is the size, in bytes, of private keys as used in this package.
+	PrivateKeySize = 64
+	// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
+	SignatureSize = 64
+	// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
+	SeedSize = 32
+)
+
+const (
+	paramB = 256 / 8 // Size of keys in bytes.
+)
+
+// SignerOptions implements crypto.SignerOpts and augments with parameters
+// that are specific to the Ed25519 signature schemes.
+type SignerOptions struct {
+	// Hash must be crypto.Hash(0) for Ed25519/Ed25519ctx, or crypto.SHA512
+	// for Ed25519ph.
+	crypto.Hash
+
+	// Context is an optional domain separation string for Ed25519ph and a
+	// must for Ed25519ctx. Its length must be less or equal than 255 bytes.
+	Context string
+
+	// Scheme is an identifier for choosing a signature scheme. The zero value
+	// is ED25519.
+	Scheme SchemeID
+}
+
+// SchemeID is an identifier for each signature scheme.
+type SchemeID uint
+
+const (
+	ED25519 SchemeID = iota
+	ED25519Ph
+	ED25519Ctx
+)
+
+// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
+type PrivateKey []byte
+
+// Equal reports whether priv and x have the same value.
+func (priv PrivateKey) Equal(x crypto.PrivateKey) bool {
+	xx, ok := x.(PrivateKey)
+	return ok && subtle.ConstantTimeCompare(priv, xx) == 1
+}
+
+// Public returns the PublicKey corresponding to priv.
+func (priv PrivateKey) Public() crypto.PublicKey {
+	publicKey := make(PublicKey, PublicKeySize)
+	copy(publicKey, priv[SeedSize:])
+	return publicKey
+}
+
+// Seed returns the private key seed corresponding to priv. It is provided for
+// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
+// in this package.
+func (priv PrivateKey) Seed() []byte {
+	seed := make([]byte, SeedSize)
+	copy(seed, priv[:SeedSize])
+	return seed
+}
+
+func (priv PrivateKey) Scheme() sign.Scheme { return sch }
+
+func (pub PublicKey) Scheme() sign.Scheme { return sch }
+
+func (priv PrivateKey) MarshalBinary() (data []byte, err error) {
+	privateKey := make(PrivateKey, PrivateKeySize)
+	copy(privateKey, priv)
+	return privateKey, nil
+}
+
+func (pub PublicKey) MarshalBinary() (data []byte, err error) {
+	publicKey := make(PublicKey, PublicKeySize)
+	copy(publicKey, pub)
+	return publicKey, nil
+}
+
+// Equal reports whether pub and x have the same value.
+func (pub PublicKey) Equal(x crypto.PublicKey) bool {
+	xx, ok := x.(PublicKey)
+	return ok && bytes.Equal(pub, xx)
+}
+
+// Sign creates a signature of a message with priv key.
+// This function is compatible with crypto.ed25519 and also supports the
+// three signature variants defined in RFC-8032, namely Ed25519 (or pure
+// EdDSA), Ed25519Ph, and Ed25519Ctx.
+// The opts.HashFunc() must return zero to specify either Ed25519 or Ed25519Ctx
+// variant. This can be achieved by passing crypto.Hash(0) as the value for
+// opts.
+// The opts.HashFunc() must return SHA512 to specify the Ed25519Ph variant.
+// This can be achieved by passing crypto.SHA512 as the value for opts.
+// Use a SignerOptions struct (defined in this package) to pass a context
+// string for signing.
+func (priv PrivateKey) Sign(
+	rand io.Reader,
+	message []byte,
+	opts crypto.SignerOpts,
+) (signature []byte, err error) {
+	var ctx string
+	var scheme SchemeID
+	if o, ok := opts.(SignerOptions); ok {
+		ctx = o.Context
+		scheme = o.Scheme
+	}
+
+	switch true {
+	case scheme == ED25519 && opts.HashFunc() == crypto.Hash(0):
+		return Sign(priv, message), nil
+	case scheme == ED25519Ph && opts.HashFunc() == crypto.SHA512:
+		return SignPh(priv, message, ctx), nil
+	case scheme == ED25519Ctx && opts.HashFunc() == crypto.Hash(0) && len(ctx) > 0:
+		return SignWithCtx(priv, message, ctx), nil
+	default:
+		return nil, errors.New("ed25519: bad hash algorithm")
+	}
+}
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
+	if rand == nil {
+		rand = cryptoRand.Reader
+	}
+
+	seed := make([]byte, SeedSize)
+	if _, err := io.ReadFull(rand, seed); err != nil {
+		return nil, nil, err
+	}
+
+	privateKey := NewKeyFromSeed(seed)
+	publicKey := make(PublicKey, PublicKeySize)
+	copy(publicKey, privateKey[SeedSize:])
+
+	return publicKey, privateKey, nil
+}
+
+// NewKeyFromSeed calculates a private key from a seed. It will panic if
+// len(seed) is not SeedSize. This function is provided for interoperability
+// with RFC 8032. RFC 8032's private keys correspond to seeds in this
+// package.
+func NewKeyFromSeed(seed []byte) PrivateKey {
+	privateKey := make(PrivateKey, PrivateKeySize)
+	newKeyFromSeed(privateKey, seed)
+	return privateKey
+}
+
+func newKeyFromSeed(privateKey, seed []byte) {
+	if l := len(seed); l != SeedSize {
+		panic("ed25519: bad seed length: " + strconv.Itoa(l))
+	}
+	var P pointR1
+	k := sha512.Sum512(seed)
+	clamp(k[:])
+	reduceModOrder(k[:paramB], false)
+	P.fixedMult(k[:paramB])
+	copy(privateKey[:SeedSize], seed)
+	_ = P.ToBytes(privateKey[SeedSize:])
+}
+
+func signAll(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash bool) {
+	if l := len(privateKey); l != PrivateKeySize {
+		panic("ed25519: bad private key length: " + strconv.Itoa(l))
+	}
+
+	H := sha512.New()
+	var PHM []byte
+
+	if preHash {
+		_, _ = H.Write(message)
+		PHM = H.Sum(nil)
+		H.Reset()
+	} else {
+		PHM = message
+	}
+
+	// 1.  Hash the 32-byte private key using SHA-512.
+	_, _ = H.Write(privateKey[:SeedSize])
+	h := H.Sum(nil)
+	clamp(h[:])
+	prefix, s := h[paramB:], h[:paramB]
+
+	// 2.  Compute SHA-512(dom2(F, C) || prefix || PH(M))
+	H.Reset()
+
+	writeDom(H, ctx, preHash)
+
+	_, _ = H.Write(prefix)
+	_, _ = H.Write(PHM)
+	r := H.Sum(nil)
+	reduceModOrder(r[:], true)
+
+	// 3.  Compute the point [r]B.
+	var P pointR1
+	P.fixedMult(r[:paramB])
+	R := (&[paramB]byte{})[:]
+	if err := P.ToBytes(R); err != nil {
+		panic(err)
+	}
+
+	// 4.  Compute SHA512(dom2(F, C) || R || A || PH(M)).
+	H.Reset()
+
+	writeDom(H, ctx, preHash)
+
+	_, _ = H.Write(R)
+	_, _ = H.Write(privateKey[SeedSize:])
+	_, _ = H.Write(PHM)
+	hRAM := H.Sum(nil)
+
+	reduceModOrder(hRAM[:], true)
+
+	// 5.  Compute S = (r + k * s) mod order.
+	S := (&[paramB]byte{})[:]
+	calculateS(S, r[:paramB], hRAM[:paramB], s)
+
+	// 6.  The signature is the concatenation of R and S.
+	copy(signature[:paramB], R[:])
+	copy(signature[paramB:], S[:])
+}
+
+// Sign signs the message with privateKey and returns a signature.
+// This function supports the signature variant defined in RFC-8032: Ed25519,
+// also known as the pure version of EdDSA.
+// It will panic if len(privateKey) is not PrivateKeySize.
+func Sign(privateKey PrivateKey, message []byte) []byte {
+	signature := make([]byte, SignatureSize)
+	signAll(signature, privateKey, message, []byte(""), false)
+	return signature
+}
+
+// SignPh creates a signature of a message with private key and context.
+// This function supports the signature variant defined in RFC-8032: Ed25519ph,
+// meaning it internally hashes the message using SHA-512, and optionally
+// accepts a context string.
+// It will panic if len(privateKey) is not PrivateKeySize.
+// Context could be passed to this function, which length should be no more than
+// ContextMaxSize=255. It can be empty.
+func SignPh(privateKey PrivateKey, message []byte, ctx string) []byte {
+	if len(ctx) > ContextMaxSize {
+		panic(fmt.Errorf("ed25519: bad context length: %v", len(ctx)))
+	}
+
+	signature := make([]byte, SignatureSize)
+	signAll(signature, privateKey, message, []byte(ctx), true)
+	return signature
+}
+
+// SignWithCtx creates a signature of a message with private key and context.
+// This function supports the signature variant defined in RFC-8032: Ed25519ctx,
+// meaning it accepts a non-empty context string.
+// It will panic if len(privateKey) is not PrivateKeySize.
+// Context must be passed to this function, which length should be no more than
+// ContextMaxSize=255 and cannot be empty.
+func SignWithCtx(privateKey PrivateKey, message []byte, ctx string) []byte {
+	if len(ctx) == 0 || len(ctx) > ContextMaxSize {
+		panic(fmt.Errorf("ed25519: bad context length: %v > %v", len(ctx), ContextMaxSize))
+	}
+
+	signature := make([]byte, SignatureSize)
+	signAll(signature, privateKey, message, []byte(ctx), false)
+	return signature
+}
+
+func verify(public PublicKey, message, signature, ctx []byte, preHash bool) bool {
+	if len(public) != PublicKeySize ||
+		len(signature) != SignatureSize ||
+		!isLessThanOrder(signature[paramB:]) {
+		return false
+	}
+
+	var P pointR1
+	if ok := P.FromBytes(public); !ok {
+		return false
+	}
+
+	H := sha512.New()
+	var PHM []byte
+
+	if preHash {
+		_, _ = H.Write(message)
+		PHM = H.Sum(nil)
+		H.Reset()
+	} else {
+		PHM = message
+	}
+
+	R := signature[:paramB]
+
+	writeDom(H, ctx, preHash)
+
+	_, _ = H.Write(R)
+	_, _ = H.Write(public)
+	_, _ = H.Write(PHM)
+	hRAM := H.Sum(nil)
+	reduceModOrder(hRAM[:], true)
+
+	var Q pointR1
+	encR := (&[paramB]byte{})[:]
+	P.neg()
+	Q.doubleMult(&P, signature[paramB:], hRAM[:paramB])
+	_ = Q.ToBytes(encR)
+	return bytes.Equal(R, encR)
+}
+
+// VerifyAny returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded.
+// This function supports all the three signature variants defined in RFC-8032,
+// namely Ed25519 (or pure EdDSA), Ed25519Ph, and Ed25519Ctx.
+// The opts.HashFunc() must return zero to specify either Ed25519 or Ed25519Ctx
+// variant. This can be achieved by passing crypto.Hash(0) as the value for opts.
+// The opts.HashFunc() must return SHA512 to specify the Ed25519Ph variant.
+// This can be achieved by passing crypto.SHA512 as the value for opts.
+// Use a SignerOptions struct to pass a context string for signing.
+func VerifyAny(public PublicKey, message, signature []byte, opts crypto.SignerOpts) bool {
+	var ctx string
+	var scheme SchemeID
+	if o, ok := opts.(SignerOptions); ok {
+		ctx = o.Context
+		scheme = o.Scheme
+	}
+
+	switch true {
+	case scheme == ED25519 && opts.HashFunc() == crypto.Hash(0):
+		return Verify(public, message, signature)
+	case scheme == ED25519Ph && opts.HashFunc() == crypto.SHA512:
+		return VerifyPh(public, message, signature, ctx)
+	case scheme == ED25519Ctx && opts.HashFunc() == crypto.Hash(0) && len(ctx) > 0:
+		return VerifyWithCtx(public, message, signature, ctx)
+	default:
+		return false
+	}
+}
+
+// Verify returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded.
+// This function supports the signature variant defined in RFC-8032: Ed25519,
+// also known as the pure version of EdDSA.
+func Verify(public PublicKey, message, signature []byte) bool {
+	return verify(public, message, signature, []byte(""), false)
+}
+
+// VerifyPh returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded.
+// This function supports the signature variant defined in RFC-8032: Ed25519ph,
+// meaning it internally hashes the message using SHA-512.
+// Context could be passed to this function, which length should be no more than
+// 255. It can be empty.
+func VerifyPh(public PublicKey, message, signature []byte, ctx string) bool {
+	return verify(public, message, signature, []byte(ctx), true)
+}
+
+// VerifyWithCtx returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded, or when context is
+// not provided.
+// This function supports the signature variant defined in RFC-8032: Ed25519ctx,
+// meaning it does not handle prehashed messages. Non-empty context string must be
+// provided, and must not be more than 255 of length.
+func VerifyWithCtx(public PublicKey, message, signature []byte, ctx string) bool {
+	if len(ctx) == 0 || len(ctx) > ContextMaxSize {
+		return false
+	}
+
+	return verify(public, message, signature, []byte(ctx), false)
+}
+
+func clamp(k []byte) {
+	k[0] &= 248
+	k[paramB-1] = (k[paramB-1] & 127) | 64
+}
+
+// isLessThanOrder returns true if 0 <= x < order.
+func isLessThanOrder(x []byte) bool {
+	i := len(order) - 1
+	for i > 0 && x[i] == order[i] {
+		i--
+	}
+	return x[i] < order[i]
+}
+
+func writeDom(h io.Writer, ctx []byte, preHash bool) {
+	dom2 := "SigEd25519 no Ed25519 collisions"
+
+	if len(ctx) > 0 {
+		_, _ = h.Write([]byte(dom2))
+		if preHash {
+			_, _ = h.Write([]byte{byte(0x01), byte(len(ctx))})
+		} else {
+			_, _ = h.Write([]byte{byte(0x00), byte(len(ctx))})
+		}
+		_, _ = h.Write(ctx)
+	} else if preHash {
+		_, _ = h.Write([]byte(dom2))
+		_, _ = h.Write([]byte{0x01, 0x00})
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/modular.go b/vendor/github.com/cloudflare/circl/sign/ed25519/modular.go
new file mode 100644
index 00000000..10efafdc
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/modular.go
@@ -0,0 +1,175 @@
+package ed25519
+
+import (
+	"encoding/binary"
+	"math/bits"
+)
+
+var order = [paramB]byte{
+	0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
+	0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+}
+
+// isLessThan returns true if 0 <= x < y, and assumes that slices have the same length.
+func isLessThan(x, y []byte) bool {
+	i := len(x) - 1
+	for i > 0 && x[i] == y[i] {
+		i--
+	}
+	return x[i] < y[i]
+}
+
+// reduceModOrder calculates k = k mod order of the curve.
+func reduceModOrder(k []byte, is512Bit bool) {
+	var X [((2 * paramB) * 8) / 64]uint64
+	numWords := len(k) >> 3
+	for i := 0; i < numWords; i++ {
+		X[i] = binary.LittleEndian.Uint64(k[i*8 : (i+1)*8])
+	}
+	red512(&X, is512Bit)
+	for i := 0; i < numWords; i++ {
+		binary.LittleEndian.PutUint64(k[i*8:(i+1)*8], X[i])
+	}
+}
+
+// red512 calculates x = x mod Order of the curve.
+func red512(x *[8]uint64, full bool) {
+	// Implementation of Algs.(14.47)+(14.52) of Handbook of Applied
+	// Cryptography, by A. Menezes, P. van Oorschot, and S. Vanstone.
+	const (
+		ell0   = uint64(0x5812631a5cf5d3ed)
+		ell1   = uint64(0x14def9dea2f79cd6)
+		ell160 = uint64(0x812631a5cf5d3ed0)
+		ell161 = uint64(0x4def9dea2f79cd65)
+		ell162 = uint64(0x0000000000000001)
+	)
+
+	var c0, c1, c2, c3 uint64
+	r0, r1, r2, r3, r4 := x[0], x[1], x[2], x[3], uint64(0)
+
+	if full {
+		q0, q1, q2, q3 := x[4], x[5], x[6], x[7]
+
+		for i := 0; i < 3; i++ {
+			h0, s0 := bits.Mul64(q0, ell160)
+			h1, s1 := bits.Mul64(q1, ell160)
+			h2, s2 := bits.Mul64(q2, ell160)
+			h3, s3 := bits.Mul64(q3, ell160)
+
+			s1, c0 = bits.Add64(h0, s1, 0)
+			s2, c1 = bits.Add64(h1, s2, c0)
+			s3, c2 = bits.Add64(h2, s3, c1)
+			s4, _ := bits.Add64(h3, 0, c2)
+
+			h0, l0 := bits.Mul64(q0, ell161)
+			h1, l1 := bits.Mul64(q1, ell161)
+			h2, l2 := bits.Mul64(q2, ell161)
+			h3, l3 := bits.Mul64(q3, ell161)
+
+			l1, c0 = bits.Add64(h0, l1, 0)
+			l2, c1 = bits.Add64(h1, l2, c0)
+			l3, c2 = bits.Add64(h2, l3, c1)
+			l4, _ := bits.Add64(h3, 0, c2)
+
+			s1, c0 = bits.Add64(s1, l0, 0)
+			s2, c1 = bits.Add64(s2, l1, c0)
+			s3, c2 = bits.Add64(s3, l2, c1)
+			s4, c3 = bits.Add64(s4, l3, c2)
+			s5, s6 := bits.Add64(l4, 0, c3)
+
+			s2, c0 = bits.Add64(s2, q0, 0)
+			s3, c1 = bits.Add64(s3, q1, c0)
+			s4, c2 = bits.Add64(s4, q2, c1)
+			s5, c3 = bits.Add64(s5, q3, c2)
+			s6, s7 := bits.Add64(s6, 0, c3)
+
+			q := q0 | q1 | q2 | q3
+			m := -((q | -q) >> 63) // if q=0 then m=0...0 else m=1..1
+			s0 &= m
+			s1 &= m
+			s2 &= m
+			s3 &= m
+			q0, q1, q2, q3 = s4, s5, s6, s7
+
+			if (i+1)%2 == 0 {
+				r0, c0 = bits.Add64(r0, s0, 0)
+				r1, c1 = bits.Add64(r1, s1, c0)
+				r2, c2 = bits.Add64(r2, s2, c1)
+				r3, c3 = bits.Add64(r3, s3, c2)
+				r4, _ = bits.Add64(r4, 0, c3)
+			} else {
+				r0, c0 = bits.Sub64(r0, s0, 0)
+				r1, c1 = bits.Sub64(r1, s1, c0)
+				r2, c2 = bits.Sub64(r2, s2, c1)
+				r3, c3 = bits.Sub64(r3, s3, c2)
+				r4, _ = bits.Sub64(r4, 0, c3)
+			}
+		}
+
+		m := -(r4 >> 63)
+		r0, c0 = bits.Add64(r0, m&ell160, 0)
+		r1, c1 = bits.Add64(r1, m&ell161, c0)
+		r2, c2 = bits.Add64(r2, m&ell162, c1)
+		r3, c3 = bits.Add64(r3, 0, c2)
+		r4, _ = bits.Add64(r4, m&1, c3)
+		x[4], x[5], x[6], x[7] = 0, 0, 0, 0
+	}
+
+	q0 := (r4 << 4) | (r3 >> 60)
+	r3 &= (uint64(1) << 60) - 1
+
+	h0, s0 := bits.Mul64(ell0, q0)
+	h1, s1 := bits.Mul64(ell1, q0)
+	s1, c0 = bits.Add64(h0, s1, 0)
+	s2, _ := bits.Add64(h1, 0, c0)
+
+	r0, c0 = bits.Sub64(r0, s0, 0)
+	r1, c1 = bits.Sub64(r1, s1, c0)
+	r2, c2 = bits.Sub64(r2, s2, c1)
+	r3, _ = bits.Sub64(r3, 0, c2)
+
+	x[0], x[1], x[2], x[3] = r0, r1, r2, r3
+}
+
+// calculateS performs s = r+k*a mod Order of the curve.
+func calculateS(s, r, k, a []byte) {
+	K := [4]uint64{
+		binary.LittleEndian.Uint64(k[0*8 : 1*8]),
+		binary.LittleEndian.Uint64(k[1*8 : 2*8]),
+		binary.LittleEndian.Uint64(k[2*8 : 3*8]),
+		binary.LittleEndian.Uint64(k[3*8 : 4*8]),
+	}
+	S := [8]uint64{
+		binary.LittleEndian.Uint64(r[0*8 : 1*8]),
+		binary.LittleEndian.Uint64(r[1*8 : 2*8]),
+		binary.LittleEndian.Uint64(r[2*8 : 3*8]),
+		binary.LittleEndian.Uint64(r[3*8 : 4*8]),
+	}
+	var c3 uint64
+	for i := range K {
+		ai := binary.LittleEndian.Uint64(a[i*8 : (i+1)*8])
+
+		h0, l0 := bits.Mul64(K[0], ai)
+		h1, l1 := bits.Mul64(K[1], ai)
+		h2, l2 := bits.Mul64(K[2], ai)
+		h3, l3 := bits.Mul64(K[3], ai)
+
+		l1, c0 := bits.Add64(h0, l1, 0)
+		l2, c1 := bits.Add64(h1, l2, c0)
+		l3, c2 := bits.Add64(h2, l3, c1)
+		l4, _ := bits.Add64(h3, 0, c2)
+
+		S[i+0], c0 = bits.Add64(S[i+0], l0, 0)
+		S[i+1], c1 = bits.Add64(S[i+1], l1, c0)
+		S[i+2], c2 = bits.Add64(S[i+2], l2, c1)
+		S[i+3], c3 = bits.Add64(S[i+3], l3, c2)
+		S[i+4], _ = bits.Add64(S[i+4], l4, c3)
+	}
+	red512(&S, true)
+	binary.LittleEndian.PutUint64(s[0*8:1*8], S[0])
+	binary.LittleEndian.PutUint64(s[1*8:2*8], S[1])
+	binary.LittleEndian.PutUint64(s[2*8:3*8], S[2])
+	binary.LittleEndian.PutUint64(s[3*8:4*8], S[3])
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/mult.go b/vendor/github.com/cloudflare/circl/sign/ed25519/mult.go
new file mode 100644
index 00000000..3216aae3
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/mult.go
@@ -0,0 +1,180 @@
+package ed25519
+
+import (
+	"crypto/subtle"
+	"encoding/binary"
+	"math/bits"
+
+	"github.com/cloudflare/circl/internal/conv"
+	"github.com/cloudflare/circl/math"
+	fp "github.com/cloudflare/circl/math/fp25519"
+)
+
+var paramD = fp.Elt{
+	0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
+	0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
+	0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
+	0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52,
+}
+
+// mLSBRecoding parameters.
+const (
+	fxT        = 257
+	fxV        = 2
+	fxW        = 3
+	fx2w1      = 1 << (uint(fxW) - 1)
+	numWords64 = (paramB * 8 / 64)
+)
+
+// mLSBRecoding is the odd-only modified LSB-set.
+//
+// Reference:
+//
+//	"Efficient and secure algorithms for GLV-based scalar multiplication and
+//	 their implementation on GLV–GLS curves" by (Faz-Hernandez et al.)
+//	 http://doi.org/10.1007/s13389-014-0085-7.
+func mLSBRecoding(L []int8, k []byte) {
+	const ee = (fxT + fxW*fxV - 1) / (fxW * fxV)
+	const dd = ee * fxV
+	const ll = dd * fxW
+	if len(L) == (ll + 1) {
+		var m [numWords64 + 1]uint64
+		for i := 0; i < numWords64; i++ {
+			m[i] = binary.LittleEndian.Uint64(k[8*i : 8*i+8])
+		}
+		condAddOrderN(&m)
+		L[dd-1] = 1
+		for i := 0; i < dd-1; i++ {
+			kip1 := (m[(i+1)/64] >> (uint(i+1) % 64)) & 0x1
+			L[i] = int8(kip1<<1) - 1
+		}
+		{ // right-shift by d
+			right := uint(dd % 64)
+			left := uint(64) - right
+			lim := ((numWords64+1)*64 - dd) / 64
+			j := dd / 64
+			for i := 0; i < lim; i++ {
+				m[i] = (m[i+j] >> right) | (m[i+j+1] << left)
+			}
+			m[lim] = m[lim+j] >> right
+		}
+		for i := dd; i < ll; i++ {
+			L[i] = L[i%dd] * int8(m[0]&0x1)
+			div2subY(m[:], int64(L[i]>>1), numWords64)
+		}
+		L[ll] = int8(m[0])
+	}
+}
+
+// absolute returns always a positive value.
+func absolute(x int32) int32 {
+	mask := x >> 31
+	return (x + mask) ^ mask
+}
+
+// condAddOrderN updates x = x+order if x is even, otherwise x remains unchanged.
+func condAddOrderN(x *[numWords64 + 1]uint64) {
+	isOdd := (x[0] & 0x1) - 1
+	c := uint64(0)
+	for i := 0; i < numWords64; i++ {
+		orderWord := binary.LittleEndian.Uint64(order[8*i : 8*i+8])
+		o := isOdd & orderWord
+		x0, c0 := bits.Add64(x[i], o, c)
+		x[i] = x0
+		c = c0
+	}
+	x[numWords64], _ = bits.Add64(x[numWords64], 0, c)
+}
+
+// div2subY update x = (x/2) - y.
+func div2subY(x []uint64, y int64, l int) {
+	s := uint64(y >> 63)
+	for i := 0; i < l-1; i++ {
+		x[i] = (x[i] >> 1) | (x[i+1] << 63)
+	}
+	x[l-1] = (x[l-1] >> 1)
+
+	b := uint64(0)
+	x0, b0 := bits.Sub64(x[0], uint64(y), b)
+	x[0] = x0
+	b = b0
+	for i := 1; i < l-1; i++ {
+		x0, b0 := bits.Sub64(x[i], s, b)
+		x[i] = x0
+		b = b0
+	}
+	x[l-1], _ = bits.Sub64(x[l-1], s, b)
+}
+
+func (P *pointR1) fixedMult(scalar []byte) {
+	if len(scalar) != paramB {
+		panic("wrong scalar size")
+	}
+	const ee = (fxT + fxW*fxV - 1) / (fxW * fxV)
+	const dd = ee * fxV
+	const ll = dd * fxW
+
+	L := make([]int8, ll+1)
+	mLSBRecoding(L[:], scalar)
+	S := &pointR3{}
+	P.SetIdentity()
+	for ii := ee - 1; ii >= 0; ii-- {
+		P.double()
+		for j := 0; j < fxV; j++ {
+			dig := L[fxW*dd-j*ee+ii-ee]
+			for i := (fxW-1)*dd - j*ee + ii - ee; i >= (2*dd - j*ee + ii - ee); i = i - dd {
+				dig = 2*dig + L[i]
+			}
+			idx := absolute(int32(dig))
+			sig := L[dd-j*ee+ii-ee]
+			Tabj := &tabSign[fxV-j-1]
+			for k := 0; k < fx2w1; k++ {
+				S.cmov(&Tabj[k], subtle.ConstantTimeEq(int32(k), idx))
+			}
+			S.cneg(subtle.ConstantTimeEq(int32(sig), -1))
+			P.mixAdd(S)
+		}
+	}
+}
+
+const (
+	omegaFix = 7
+	omegaVar = 5
+)
+
+// doubleMult returns P=mG+nQ.
+func (P *pointR1) doubleMult(Q *pointR1, m, n []byte) {
+	nafFix := math.OmegaNAF(conv.BytesLe2BigInt(m), omegaFix)
+	nafVar := math.OmegaNAF(conv.BytesLe2BigInt(n), omegaVar)
+
+	if len(nafFix) > len(nafVar) {
+		nafVar = append(nafVar, make([]int32, len(nafFix)-len(nafVar))...)
+	} else if len(nafFix) < len(nafVar) {
+		nafFix = append(nafFix, make([]int32, len(nafVar)-len(nafFix))...)
+	}
+
+	var TabQ [1 << (omegaVar - 2)]pointR2
+	Q.oddMultiples(TabQ[:])
+	P.SetIdentity()
+	for i := len(nafFix) - 1; i >= 0; i-- {
+		P.double()
+		// Generator point
+		if nafFix[i] != 0 {
+			idxM := absolute(nafFix[i]) >> 1
+			R := tabVerif[idxM]
+			if nafFix[i] < 0 {
+				R.neg()
+			}
+			P.mixAdd(&R)
+		}
+		// Variable input point
+		if nafVar[i] != 0 {
+			idxN := absolute(nafVar[i]) >> 1
+			S := TabQ[idxN]
+			if nafVar[i] < 0 {
+				S.neg()
+			}
+			P.add(&S)
+		}
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/point.go b/vendor/github.com/cloudflare/circl/sign/ed25519/point.go
new file mode 100644
index 00000000..374a6950
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/point.go
@@ -0,0 +1,195 @@
+package ed25519
+
+import fp "github.com/cloudflare/circl/math/fp25519"
+
+type (
+	pointR1 struct{ x, y, z, ta, tb fp.Elt }
+	pointR2 struct {
+		pointR3
+		z2 fp.Elt
+	}
+)
+type pointR3 struct{ addYX, subYX, dt2 fp.Elt }
+
+func (P *pointR1) neg() {
+	fp.Neg(&P.x, &P.x)
+	fp.Neg(&P.ta, &P.ta)
+}
+
+func (P *pointR1) SetIdentity() {
+	P.x = fp.Elt{}
+	fp.SetOne(&P.y)
+	fp.SetOne(&P.z)
+	P.ta = fp.Elt{}
+	P.tb = fp.Elt{}
+}
+
+func (P *pointR1) toAffine() {
+	fp.Inv(&P.z, &P.z)
+	fp.Mul(&P.x, &P.x, &P.z)
+	fp.Mul(&P.y, &P.y, &P.z)
+	fp.Modp(&P.x)
+	fp.Modp(&P.y)
+	fp.SetOne(&P.z)
+	P.ta = P.x
+	P.tb = P.y
+}
+
+func (P *pointR1) ToBytes(k []byte) error {
+	P.toAffine()
+	var x [fp.Size]byte
+	err := fp.ToBytes(k[:fp.Size], &P.y)
+	if err != nil {
+		return err
+	}
+	err = fp.ToBytes(x[:], &P.x)
+	if err != nil {
+		return err
+	}
+	b := x[0] & 1
+	k[paramB-1] = k[paramB-1] | (b << 7)
+	return nil
+}
+
+func (P *pointR1) FromBytes(k []byte) bool {
+	if len(k) != paramB {
+		panic("wrong size")
+	}
+	signX := k[paramB-1] >> 7
+	copy(P.y[:], k[:fp.Size])
+	P.y[fp.Size-1] &= 0x7F
+	p := fp.P()
+	if !isLessThan(P.y[:], p[:]) {
+		return false
+	}
+
+	one, u, v := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}
+	fp.SetOne(one)
+	fp.Sqr(u, &P.y)                // u = y^2
+	fp.Mul(v, u, &paramD)          // v = dy^2
+	fp.Sub(u, u, one)              // u = y^2-1
+	fp.Add(v, v, one)              // v = dy^2+1
+	isQR := fp.InvSqrt(&P.x, u, v) // x = sqrt(u/v)
+	if !isQR {
+		return false
+	}
+	fp.Modp(&P.x) // x = x mod p
+	if fp.IsZero(&P.x) && signX == 1 {
+		return false
+	}
+	if signX != (P.x[0] & 1) {
+		fp.Neg(&P.x, &P.x)
+	}
+	P.ta = P.x
+	P.tb = P.y
+	fp.SetOne(&P.z)
+	return true
+}
+
+// double calculates 2P for curves with A=-1.
+func (P *pointR1) double() {
+	Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb
+	a, b, c, e, f, g, h := Px, Py, Pz, Pta, Px, Py, Ptb
+	fp.Add(e, Px, Py) // x+y
+	fp.Sqr(a, Px)     // A = x^2
+	fp.Sqr(b, Py)     // B = y^2
+	fp.Sqr(c, Pz)     // z^2
+	fp.Add(c, c, c)   // C = 2*z^2
+	fp.Add(h, a, b)   // H = A+B
+	fp.Sqr(e, e)      // (x+y)^2
+	fp.Sub(e, e, h)   // E = (x+y)^2-A-B
+	fp.Sub(g, b, a)   // G = B-A
+	fp.Sub(f, c, g)   // F = C-G
+	fp.Mul(Pz, f, g)  // Z = F * G
+	fp.Mul(Px, e, f)  // X = E * F
+	fp.Mul(Py, g, h)  // Y = G * H, T = E * H
+}
+
+func (P *pointR1) mixAdd(Q *pointR3) {
+	fp.Add(&P.z, &P.z, &P.z) // D = 2*z1
+	P.coreAddition(Q)
+}
+
+func (P *pointR1) add(Q *pointR2) {
+	fp.Mul(&P.z, &P.z, &Q.z2) // D = 2*z1*z2
+	P.coreAddition(&Q.pointR3)
+}
+
+// coreAddition calculates P=P+Q for curves with A=-1.
+func (P *pointR1) coreAddition(Q *pointR3) {
+	Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb
+	addYX2, subYX2, dt2 := &Q.addYX, &Q.subYX, &Q.dt2
+	a, b, c, d, e, f, g, h := Px, Py, &fp.Elt{}, Pz, Pta, Px, Py, Ptb
+	fp.Mul(c, Pta, Ptb)  // t1 = ta*tb
+	fp.Sub(h, Py, Px)    // y1-x1
+	fp.Add(b, Py, Px)    // y1+x1
+	fp.Mul(a, h, subYX2) // A = (y1-x1)*(y2-x2)
+	fp.Mul(b, b, addYX2) // B = (y1+x1)*(y2+x2)
+	fp.Mul(c, c, dt2)    // C = 2*D*t1*t2
+	fp.Sub(e, b, a)      // E = B-A
+	fp.Add(h, b, a)      // H = B+A
+	fp.Sub(f, d, c)      // F = D-C
+	fp.Add(g, d, c)      // G = D+C
+	fp.Mul(Pz, f, g)     // Z = F * G
+	fp.Mul(Px, e, f)     // X = E * F
+	fp.Mul(Py, g, h)     // Y = G * H, T = E * H
+}
+
+func (P *pointR1) oddMultiples(T []pointR2) {
+	var R pointR2
+	n := len(T)
+	T[0].fromR1(P)
+	_2P := *P
+	_2P.double()
+	R.fromR1(&_2P)
+	for i := 1; i < n; i++ {
+		P.add(&R)
+		T[i].fromR1(P)
+	}
+}
+
+func (P *pointR1) isEqual(Q *pointR1) bool {
+	l, r := &fp.Elt{}, &fp.Elt{}
+	fp.Mul(l, &P.x, &Q.z)
+	fp.Mul(r, &Q.x, &P.z)
+	fp.Sub(l, l, r)
+	b := fp.IsZero(l)
+	fp.Mul(l, &P.y, &Q.z)
+	fp.Mul(r, &Q.y, &P.z)
+	fp.Sub(l, l, r)
+	b = b && fp.IsZero(l)
+	fp.Mul(l, &P.ta, &P.tb)
+	fp.Mul(l, l, &Q.z)
+	fp.Mul(r, &Q.ta, &Q.tb)
+	fp.Mul(r, r, &P.z)
+	fp.Sub(l, l, r)
+	b = b && fp.IsZero(l)
+	return b
+}
+
+func (P *pointR3) neg() {
+	P.addYX, P.subYX = P.subYX, P.addYX
+	fp.Neg(&P.dt2, &P.dt2)
+}
+
+func (P *pointR2) fromR1(Q *pointR1) {
+	fp.Add(&P.addYX, &Q.y, &Q.x)
+	fp.Sub(&P.subYX, &Q.y, &Q.x)
+	fp.Mul(&P.dt2, &Q.ta, &Q.tb)
+	fp.Mul(&P.dt2, &P.dt2, &paramD)
+	fp.Add(&P.dt2, &P.dt2, &P.dt2)
+	fp.Add(&P.z2, &Q.z, &Q.z)
+}
+
+func (P *pointR3) cneg(b int) {
+	t := &fp.Elt{}
+	fp.Cswap(&P.addYX, &P.subYX, uint(b))
+	fp.Neg(t, &P.dt2)
+	fp.Cmov(&P.dt2, t, uint(b))
+}
+
+func (P *pointR3) cmov(Q *pointR3, b int) {
+	fp.Cmov(&P.addYX, &Q.addYX, uint(b))
+	fp.Cmov(&P.subYX, &Q.subYX, uint(b))
+	fp.Cmov(&P.dt2, &Q.dt2, uint(b))
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/pubkey.go b/vendor/github.com/cloudflare/circl/sign/ed25519/pubkey.go
new file mode 100644
index 00000000..c3505b67
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/pubkey.go
@@ -0,0 +1,9 @@
+//go:build go1.13
+// +build go1.13
+
+package ed25519
+
+import cryptoEd25519 "crypto/ed25519"
+
+// PublicKey is the type of Ed25519 public keys.
+type PublicKey cryptoEd25519.PublicKey
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/pubkey112.go b/vendor/github.com/cloudflare/circl/sign/ed25519/pubkey112.go
new file mode 100644
index 00000000..d57d86ef
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/pubkey112.go
@@ -0,0 +1,7 @@
+//go:build !go1.13
+// +build !go1.13
+
+package ed25519
+
+// PublicKey is the type of Ed25519 public keys.
+type PublicKey []byte
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/signapi.go b/vendor/github.com/cloudflare/circl/sign/ed25519/signapi.go
new file mode 100644
index 00000000..e4520f52
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/signapi.go
@@ -0,0 +1,87 @@
+package ed25519
+
+import (
+	"crypto/rand"
+	"encoding/asn1"
+
+	"github.com/cloudflare/circl/sign"
+)
+
+var sch sign.Scheme = &scheme{}
+
+// Scheme returns a signature interface.
+func Scheme() sign.Scheme { return sch }
+
+type scheme struct{}
+
+func (*scheme) Name() string          { return "Ed25519" }
+func (*scheme) PublicKeySize() int    { return PublicKeySize }
+func (*scheme) PrivateKeySize() int   { return PrivateKeySize }
+func (*scheme) SignatureSize() int    { return SignatureSize }
+func (*scheme) SeedSize() int         { return SeedSize }
+func (*scheme) TLSIdentifier() uint   { return 0x0807 }
+func (*scheme) SupportsContext() bool { return false }
+func (*scheme) Oid() asn1.ObjectIdentifier {
+	return asn1.ObjectIdentifier{1, 3, 101, 112}
+}
+
+func (*scheme) GenerateKey() (sign.PublicKey, sign.PrivateKey, error) {
+	return GenerateKey(rand.Reader)
+}
+
+func (*scheme) Sign(
+	sk sign.PrivateKey,
+	message []byte,
+	opts *sign.SignatureOpts,
+) []byte {
+	priv, ok := sk.(PrivateKey)
+	if !ok {
+		panic(sign.ErrTypeMismatch)
+	}
+	if opts != nil && opts.Context != "" {
+		panic(sign.ErrContextNotSupported)
+	}
+	return Sign(priv, message)
+}
+
+func (*scheme) Verify(
+	pk sign.PublicKey,
+	message, signature []byte,
+	opts *sign.SignatureOpts,
+) bool {
+	pub, ok := pk.(PublicKey)
+	if !ok {
+		panic(sign.ErrTypeMismatch)
+	}
+	if opts != nil {
+		if opts.Context != "" {
+			panic(sign.ErrContextNotSupported)
+		}
+	}
+	return Verify(pub, message, signature)
+}
+
+func (*scheme) DeriveKey(seed []byte) (sign.PublicKey, sign.PrivateKey) {
+	privateKey := NewKeyFromSeed(seed)
+	publicKey := make(PublicKey, PublicKeySize)
+	copy(publicKey, privateKey[SeedSize:])
+	return publicKey, privateKey
+}
+
+func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (sign.PublicKey, error) {
+	if len(buf) < PublicKeySize {
+		return nil, sign.ErrPubKeySize
+	}
+	pub := make(PublicKey, PublicKeySize)
+	copy(pub, buf[:PublicKeySize])
+	return pub, nil
+}
+
+func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (sign.PrivateKey, error) {
+	if len(buf) < PrivateKeySize {
+		return nil, sign.ErrPrivKeySize
+	}
+	priv := make(PrivateKey, PrivateKeySize)
+	copy(priv, buf[:PrivateKeySize])
+	return priv, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed25519/tables.go b/vendor/github.com/cloudflare/circl/sign/ed25519/tables.go
new file mode 100644
index 00000000..8763b426
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed25519/tables.go
@@ -0,0 +1,213 @@
+package ed25519
+
+import fp "github.com/cloudflare/circl/math/fp25519"
+
+var tabSign = [fxV][fx2w1]pointR3{
+	{
+		pointR3{
+			addYX: fp.Elt{0x85, 0x3b, 0x8c, 0xf5, 0xc6, 0x93, 0xbc, 0x2f, 0x19, 0x0e, 0x8c, 0xfb, 0xc6, 0x2d, 0x93, 0xcf, 0xc2, 0x42, 0x3d, 0x64, 0x98, 0x48, 0x0b, 0x27, 0x65, 0xba, 0xd4, 0x33, 0x3a, 0x9d, 0xcf, 0x07},
+			subYX: fp.Elt{0x3e, 0x91, 0x40, 0xd7, 0x05, 0x39, 0x10, 0x9d, 0xb3, 0xbe, 0x40, 0xd1, 0x05, 0x9f, 0x39, 0xfd, 0x09, 0x8a, 0x8f, 0x68, 0x34, 0x84, 0xc1, 0xa5, 0x67, 0x12, 0xf8, 0x98, 0x92, 0x2f, 0xfd, 0x44},
+			dt2:   fp.Elt{0x68, 0xaa, 0x7a, 0x87, 0x05, 0x12, 0xc9, 0xab, 0x9e, 0xc4, 0xaa, 0xcc, 0x23, 0xe8, 0xd9, 0x26, 0x8c, 0x59, 0x43, 0xdd, 0xcb, 0x7d, 0x1b, 0x5a, 0xa8, 0x65, 0x0c, 0x9f, 0x68, 0x7b, 0x11, 0x6f},
+		},
+		{
+			addYX: fp.Elt{0x7c, 0xb0, 0x9e, 0xe6, 0xc5, 0xbf, 0xfa, 0x13, 0x8e, 0x0d, 0x22, 0xde, 0xc8, 0xd1, 0xce, 0x52, 0x02, 0xd5, 0x62, 0x31, 0x71, 0x0e, 0x8e, 0x9d, 0xb0, 0xd6, 0x00, 0xa5, 0x5a, 0x0e, 0xce, 0x72},
+			subYX: fp.Elt{0x1a, 0x8e, 0x5c, 0xdc, 0xa4, 0xb3, 0x6c, 0x51, 0x18, 0xa0, 0x09, 0x80, 0x9a, 0x46, 0x33, 0xd5, 0xe0, 0x3c, 0x4d, 0x3b, 0xfc, 0x49, 0xa2, 0x43, 0x29, 0xe1, 0x29, 0xa9, 0x93, 0xea, 0x7c, 0x35},
+			dt2:   fp.Elt{0x08, 0x46, 0x6f, 0x68, 0x7f, 0x0b, 0x7c, 0x9e, 0xad, 0xba, 0x07, 0x61, 0x74, 0x83, 0x2f, 0xfc, 0x26, 0xd6, 0x09, 0xb9, 0x00, 0x34, 0x36, 0x4f, 0x01, 0xf3, 0x48, 0xdb, 0x43, 0xba, 0x04, 0x44},
+		},
+		{
+			addYX: fp.Elt{0x4c, 0xda, 0x0d, 0x13, 0x66, 0xfd, 0x82, 0x84, 0x9f, 0x75, 0x5b, 0xa2, 0x17, 0xfe, 0x34, 0xbf, 0x1f, 0xcb, 0xba, 0x90, 0x55, 0x80, 0x83, 0xfd, 0x63, 0xb9, 0x18, 0xf8, 0x5b, 0x5d, 0x94, 0x1e},
+			subYX: fp.Elt{0xb9, 0xdb, 0x6c, 0x04, 0x88, 0x22, 0xd8, 0x79, 0x83, 0x2f, 0x8d, 0x65, 0x6b, 0xd2, 0xab, 0x1b, 0xdd, 0x65, 0xe5, 0x93, 0x63, 0xf8, 0xa2, 0xd8, 0x3c, 0xf1, 0x4b, 0xc5, 0x99, 0xd1, 0xf2, 0x12},
+			dt2:   fp.Elt{0x05, 0x4c, 0xb8, 0x3b, 0xfe, 0xf5, 0x9f, 0x2e, 0xd1, 0xb2, 0xb8, 0xff, 0xfe, 0x6d, 0xd9, 0x37, 0xe0, 0xae, 0xb4, 0x5a, 0x51, 0x80, 0x7e, 0x9b, 0x1d, 0xd1, 0x8d, 0x8c, 0x56, 0xb1, 0x84, 0x35},
+		},
+		{
+			addYX: fp.Elt{0x39, 0x71, 0x43, 0x34, 0xe3, 0x42, 0x45, 0xa1, 0xf2, 0x68, 0x71, 0xa7, 0xe8, 0x23, 0xfd, 0x9f, 0x86, 0x48, 0xff, 0xe5, 0x96, 0x74, 0xcf, 0x05, 0x49, 0xe2, 0xb3, 0x6c, 0x17, 0x77, 0x2f, 0x6d},
+			subYX: fp.Elt{0x73, 0x3f, 0xc1, 0xc7, 0x6a, 0x66, 0xa1, 0x20, 0xdd, 0x11, 0xfb, 0x7a, 0x6e, 0xa8, 0x51, 0xb8, 0x3f, 0x9d, 0xa2, 0x97, 0x84, 0xb5, 0xc7, 0x90, 0x7c, 0xab, 0x48, 0xd6, 0x84, 0xa3, 0xd5, 0x1a},
+			dt2:   fp.Elt{0x63, 0x27, 0x3c, 0x49, 0x4b, 0xfc, 0x22, 0xf2, 0x0b, 0x50, 0xc2, 0x0f, 0xb4, 0x1f, 0x31, 0x0c, 0x2f, 0x53, 0xab, 0xaa, 0x75, 0x6f, 0xe0, 0x69, 0x39, 0x56, 0xe0, 0x3b, 0xb7, 0xa8, 0xbf, 0x45},
+		},
+	},
+	{
+		{
+			addYX: fp.Elt{0x00, 0x45, 0xd9, 0x0d, 0x58, 0x03, 0xfc, 0x29, 0x93, 0xec, 0xbb, 0x6f, 0xa4, 0x7a, 0xd2, 0xec, 0xf8, 0xa7, 0xe2, 0xc2, 0x5f, 0x15, 0x0a, 0x13, 0xd5, 0xa1, 0x06, 0xb7, 0x1a, 0x15, 0x6b, 0x41},
+			subYX: fp.Elt{0x85, 0x8c, 0xb2, 0x17, 0xd6, 0x3b, 0x0a, 0xd3, 0xea, 0x3b, 0x77, 0x39, 0xb7, 0x77, 0xd3, 0xc5, 0xbf, 0x5c, 0x6a, 0x1e, 0x8c, 0xe7, 0xc6, 0xc6, 0xc4, 0xb7, 0x2a, 0x8b, 0xf7, 0xb8, 0x61, 0x0d},
+			dt2:   fp.Elt{0xb0, 0x36, 0xc1, 0xe9, 0xef, 0xd7, 0xa8, 0x56, 0x20, 0x4b, 0xe4, 0x58, 0xcd, 0xe5, 0x07, 0xbd, 0xab, 0xe0, 0x57, 0x1b, 0xda, 0x2f, 0xe6, 0xaf, 0xd2, 0xe8, 0x77, 0x42, 0xf7, 0x2a, 0x1a, 0x19},
+		},
+		{
+			addYX: fp.Elt{0x6a, 0x6d, 0x6d, 0xd1, 0xfa, 0xf5, 0x03, 0x30, 0xbd, 0x6d, 0xc2, 0xc8, 0xf5, 0x38, 0x80, 0x4f, 0xb2, 0xbe, 0xa1, 0x76, 0x50, 0x1a, 0x73, 0xf2, 0x78, 0x2b, 0x8e, 0x3a, 0x1e, 0x34, 0x47, 0x7b},
+			subYX: fp.Elt{0xc3, 0x2c, 0x36, 0xdc, 0xc5, 0x45, 0xbc, 0xef, 0x1b, 0x64, 0xd6, 0x65, 0x28, 0xe9, 0xda, 0x84, 0x13, 0xbe, 0x27, 0x8e, 0x3f, 0x98, 0x2a, 0x37, 0xee, 0x78, 0x97, 0xd6, 0xc0, 0x6f, 0xb4, 0x53},
+			dt2:   fp.Elt{0x58, 0x5d, 0xa7, 0xa3, 0x68, 0xbb, 0x20, 0x30, 0x2e, 0x03, 0xe9, 0xb1, 0xd4, 0x90, 0x72, 0xe3, 0x71, 0xb2, 0x36, 0x3e, 0x73, 0xa0, 0x2e, 0x3d, 0xd1, 0x85, 0x33, 0x62, 0x4e, 0xa7, 0x7b, 0x31},
+		},
+		{
+			addYX: fp.Elt{0xbf, 0xc4, 0x38, 0x53, 0xfb, 0x68, 0xa9, 0x77, 0xce, 0x55, 0xf9, 0x05, 0xcb, 0xeb, 0xfb, 0x8c, 0x46, 0xc2, 0x32, 0x7c, 0xf0, 0xdb, 0xd7, 0x2c, 0x62, 0x8e, 0xdd, 0x54, 0x75, 0xcf, 0x3f, 0x33},
+			subYX: fp.Elt{0x49, 0x50, 0x1f, 0x4e, 0x6e, 0x55, 0x55, 0xde, 0x8c, 0x4e, 0x77, 0x96, 0x38, 0x3b, 0xfe, 0xb6, 0x43, 0x3c, 0x86, 0x69, 0xc2, 0x72, 0x66, 0x1f, 0x6b, 0xf9, 0x87, 0xbc, 0x4f, 0x37, 0x3e, 0x3c},
+			dt2:   fp.Elt{0xd2, 0x2f, 0x06, 0x6b, 0x08, 0x07, 0x69, 0x77, 0xc0, 0x94, 0xcc, 0xae, 0x43, 0x00, 0x59, 0x6e, 0xa3, 0x63, 0xa8, 0xdd, 0xfa, 0x24, 0x18, 0xd0, 0x35, 0xc7, 0x78, 0xf7, 0x0d, 0xd4, 0x5a, 0x1e},
+		},
+		{
+			addYX: fp.Elt{0x45, 0xc1, 0x17, 0x51, 0xf8, 0xed, 0x7e, 0xc7, 0xa9, 0x1a, 0x11, 0x6e, 0x2d, 0xef, 0x0b, 0xd5, 0x3f, 0x98, 0xb0, 0xa3, 0x9d, 0x65, 0xf1, 0xcd, 0x53, 0x4a, 0x8a, 0x18, 0x70, 0x0a, 0x7f, 0x23},
+			subYX: fp.Elt{0xdd, 0xef, 0xbe, 0x3a, 0x31, 0xe0, 0xbc, 0xbe, 0x6d, 0x5d, 0x79, 0x87, 0xd6, 0xbe, 0x68, 0xe3, 0x59, 0x76, 0x8c, 0x86, 0x0e, 0x7a, 0x92, 0x13, 0x14, 0x8f, 0x67, 0xb3, 0xcb, 0x1a, 0x76, 0x76},
+			dt2:   fp.Elt{0x56, 0x7a, 0x1c, 0x9d, 0xca, 0x96, 0xf9, 0xf9, 0x03, 0x21, 0xd4, 0xe8, 0xb3, 0xd5, 0xe9, 0x52, 0xc8, 0x54, 0x1e, 0x1b, 0x13, 0xb6, 0xfd, 0x47, 0x7d, 0x02, 0x32, 0x33, 0x27, 0xe2, 0x1f, 0x19},
+		},
+	},
+}
+
+var tabVerif = [1 << (omegaFix - 2)]pointR3{
+	{ /* 1P */
+		addYX: fp.Elt{0x85, 0x3b, 0x8c, 0xf5, 0xc6, 0x93, 0xbc, 0x2f, 0x19, 0x0e, 0x8c, 0xfb, 0xc6, 0x2d, 0x93, 0xcf, 0xc2, 0x42, 0x3d, 0x64, 0x98, 0x48, 0x0b, 0x27, 0x65, 0xba, 0xd4, 0x33, 0x3a, 0x9d, 0xcf, 0x07},
+		subYX: fp.Elt{0x3e, 0x91, 0x40, 0xd7, 0x05, 0x39, 0x10, 0x9d, 0xb3, 0xbe, 0x40, 0xd1, 0x05, 0x9f, 0x39, 0xfd, 0x09, 0x8a, 0x8f, 0x68, 0x34, 0x84, 0xc1, 0xa5, 0x67, 0x12, 0xf8, 0x98, 0x92, 0x2f, 0xfd, 0x44},
+		dt2:   fp.Elt{0x68, 0xaa, 0x7a, 0x87, 0x05, 0x12, 0xc9, 0xab, 0x9e, 0xc4, 0xaa, 0xcc, 0x23, 0xe8, 0xd9, 0x26, 0x8c, 0x59, 0x43, 0xdd, 0xcb, 0x7d, 0x1b, 0x5a, 0xa8, 0x65, 0x0c, 0x9f, 0x68, 0x7b, 0x11, 0x6f},
+	},
+	{ /* 3P */
+		addYX: fp.Elt{0x30, 0x97, 0xee, 0x4c, 0xa8, 0xb0, 0x25, 0xaf, 0x8a, 0x4b, 0x86, 0xe8, 0x30, 0x84, 0x5a, 0x02, 0x32, 0x67, 0x01, 0x9f, 0x02, 0x50, 0x1b, 0xc1, 0xf4, 0xf8, 0x80, 0x9a, 0x1b, 0x4e, 0x16, 0x7a},
+		subYX: fp.Elt{0x65, 0xd2, 0xfc, 0xa4, 0xe8, 0x1f, 0x61, 0x56, 0x7d, 0xba, 0xc1, 0xe5, 0xfd, 0x53, 0xd3, 0x3b, 0xbd, 0xd6, 0x4b, 0x21, 0x1a, 0xf3, 0x31, 0x81, 0x62, 0xda, 0x5b, 0x55, 0x87, 0x15, 0xb9, 0x2a},
+		dt2:   fp.Elt{0x89, 0xd8, 0xd0, 0x0d, 0x3f, 0x93, 0xae, 0x14, 0x62, 0xda, 0x35, 0x1c, 0x22, 0x23, 0x94, 0x58, 0x4c, 0xdb, 0xf2, 0x8c, 0x45, 0xe5, 0x70, 0xd1, 0xc6, 0xb4, 0xb9, 0x12, 0xaf, 0x26, 0x28, 0x5a},
+	},
+	{ /* 5P */
+		addYX: fp.Elt{0x33, 0xbb, 0xa5, 0x08, 0x44, 0xbc, 0x12, 0xa2, 0x02, 0xed, 0x5e, 0xc7, 0xc3, 0x48, 0x50, 0x8d, 0x44, 0xec, 0xbf, 0x5a, 0x0c, 0xeb, 0x1b, 0xdd, 0xeb, 0x06, 0xe2, 0x46, 0xf1, 0xcc, 0x45, 0x29},
+		subYX: fp.Elt{0xba, 0xd6, 0x47, 0xa4, 0xc3, 0x82, 0x91, 0x7f, 0xb7, 0x29, 0x27, 0x4b, 0xd1, 0x14, 0x00, 0xd5, 0x87, 0xa0, 0x64, 0xb8, 0x1c, 0xf1, 0x3c, 0xe3, 0xf3, 0x55, 0x1b, 0xeb, 0x73, 0x7e, 0x4a, 0x15},
+		dt2:   fp.Elt{0x85, 0x82, 0x2a, 0x81, 0xf1, 0xdb, 0xbb, 0xbc, 0xfc, 0xd1, 0xbd, 0xd0, 0x07, 0x08, 0x0e, 0x27, 0x2d, 0xa7, 0xbd, 0x1b, 0x0b, 0x67, 0x1b, 0xb4, 0x9a, 0xb6, 0x3b, 0x6b, 0x69, 0xbe, 0xaa, 0x43},
+	},
+	{ /* 7P */
+		addYX: fp.Elt{0xbf, 0xa3, 0x4e, 0x94, 0xd0, 0x5c, 0x1a, 0x6b, 0xd2, 0xc0, 0x9d, 0xb3, 0x3a, 0x35, 0x70, 0x74, 0x49, 0x2e, 0x54, 0x28, 0x82, 0x52, 0xb2, 0x71, 0x7e, 0x92, 0x3c, 0x28, 0x69, 0xea, 0x1b, 0x46},
+		subYX: fp.Elt{0xb1, 0x21, 0x32, 0xaa, 0x9a, 0x2c, 0x6f, 0xba, 0xa7, 0x23, 0xba, 0x3b, 0x53, 0x21, 0xa0, 0x6c, 0x3a, 0x2c, 0x19, 0x92, 0x4f, 0x76, 0xea, 0x9d, 0xe0, 0x17, 0x53, 0x2e, 0x5d, 0xdd, 0x6e, 0x1d},
+		dt2:   fp.Elt{0xa2, 0xb3, 0xb8, 0x01, 0xc8, 0x6d, 0x83, 0xf1, 0x9a, 0xa4, 0x3e, 0x05, 0x47, 0x5f, 0x03, 0xb3, 0xf3, 0xad, 0x77, 0x58, 0xba, 0x41, 0x9c, 0x52, 0xa7, 0x90, 0x0f, 0x6a, 0x1c, 0xbb, 0x9f, 0x7a},
+	},
+	{ /* 9P */
+		addYX: fp.Elt{0x2f, 0x63, 0xa8, 0xa6, 0x8a, 0x67, 0x2e, 0x9b, 0xc5, 0x46, 0xbc, 0x51, 0x6f, 0x9e, 0x50, 0xa6, 0xb5, 0xf5, 0x86, 0xc6, 0xc9, 0x33, 0xb2, 0xce, 0x59, 0x7f, 0xdd, 0x8a, 0x33, 0xed, 0xb9, 0x34},
+		subYX: fp.Elt{0x64, 0x80, 0x9d, 0x03, 0x7e, 0x21, 0x6e, 0xf3, 0x9b, 0x41, 0x20, 0xf5, 0xb6, 0x81, 0xa0, 0x98, 0x44, 0xb0, 0x5e, 0xe7, 0x08, 0xc6, 0xcb, 0x96, 0x8f, 0x9c, 0xdc, 0xfa, 0x51, 0x5a, 0xc0, 0x49},
+		dt2:   fp.Elt{0x1b, 0xaf, 0x45, 0x90, 0xbf, 0xe8, 0xb4, 0x06, 0x2f, 0xd2, 0x19, 0xa7, 0xe8, 0x83, 0xff, 0xe2, 0x16, 0xcf, 0xd4, 0x93, 0x29, 0xfc, 0xf6, 0xaa, 0x06, 0x8b, 0x00, 0x1b, 0x02, 0x72, 0xc1, 0x73},
+	},
+	{ /* 11P */
+		addYX: fp.Elt{0xde, 0x2a, 0x80, 0x8a, 0x84, 0x00, 0xbf, 0x2f, 0x27, 0x2e, 0x30, 0x02, 0xcf, 0xfe, 0xd9, 0xe5, 0x06, 0x34, 0x70, 0x17, 0x71, 0x84, 0x3e, 0x11, 0xaf, 0x8f, 0x6d, 0x54, 0xe2, 0xaa, 0x75, 0x42},
+		subYX: fp.Elt{0x48, 0x43, 0x86, 0x49, 0x02, 0x5b, 0x5f, 0x31, 0x81, 0x83, 0x08, 0x77, 0x69, 0xb3, 0xd6, 0x3e, 0x95, 0xeb, 0x8d, 0x6a, 0x55, 0x75, 0xa0, 0xa3, 0x7f, 0xc7, 0xd5, 0x29, 0x80, 0x59, 0xab, 0x18},
+		dt2:   fp.Elt{0xe9, 0x89, 0x60, 0xfd, 0xc5, 0x2c, 0x2b, 0xd8, 0xa4, 0xe4, 0x82, 0x32, 0xa1, 0xb4, 0x1e, 0x03, 0x22, 0x86, 0x1a, 0xb5, 0x99, 0x11, 0x31, 0x44, 0x48, 0xf9, 0x3d, 0xb5, 0x22, 0x55, 0xc6, 0x3d},
+	},
+	{ /* 13P */
+		addYX: fp.Elt{0x6d, 0x7f, 0x00, 0xa2, 0x22, 0xc2, 0x70, 0xbf, 0xdb, 0xde, 0xbc, 0xb5, 0x9a, 0xb3, 0x84, 0xbf, 0x07, 0xba, 0x07, 0xfb, 0x12, 0x0e, 0x7a, 0x53, 0x41, 0xf2, 0x46, 0xc3, 0xee, 0xd7, 0x4f, 0x23},
+		subYX: fp.Elt{0x93, 0xbf, 0x7f, 0x32, 0x3b, 0x01, 0x6f, 0x50, 0x6b, 0x6f, 0x77, 0x9b, 0xc9, 0xeb, 0xfc, 0xae, 0x68, 0x59, 0xad, 0xaa, 0x32, 0xb2, 0x12, 0x9d, 0xa7, 0x24, 0x60, 0x17, 0x2d, 0x88, 0x67, 0x02},
+		dt2:   fp.Elt{0x78, 0xa3, 0x2e, 0x73, 0x19, 0xa1, 0x60, 0x53, 0x71, 0xd4, 0x8d, 0xdf, 0xb1, 0xe6, 0x37, 0x24, 0x33, 0xe5, 0xa7, 0x91, 0xf8, 0x37, 0xef, 0xa2, 0x63, 0x78, 0x09, 0xaa, 0xfd, 0xa6, 0x7b, 0x49},
+	},
+	{ /* 15P */
+		addYX: fp.Elt{0xa0, 0xea, 0xcf, 0x13, 0x03, 0xcc, 0xce, 0x24, 0x6d, 0x24, 0x9c, 0x18, 0x8d, 0xc2, 0x48, 0x86, 0xd0, 0xd4, 0xf2, 0xc1, 0xfa, 0xbd, 0xbd, 0x2d, 0x2b, 0xe7, 0x2d, 0xf1, 0x17, 0x29, 0xe2, 0x61},
+		subYX: fp.Elt{0x0b, 0xcf, 0x8c, 0x46, 0x86, 0xcd, 0x0b, 0x04, 0xd6, 0x10, 0x99, 0x2a, 0xa4, 0x9b, 0x82, 0xd3, 0x92, 0x51, 0xb2, 0x07, 0x08, 0x30, 0x08, 0x75, 0xbf, 0x5e, 0xd0, 0x18, 0x42, 0xcd, 0xb5, 0x43},
+		dt2:   fp.Elt{0x16, 0xb5, 0xd0, 0x9b, 0x2f, 0x76, 0x9a, 0x5d, 0xee, 0xde, 0x3f, 0x37, 0x4e, 0xaf, 0x38, 0xeb, 0x70, 0x42, 0xd6, 0x93, 0x7d, 0x5a, 0x2e, 0x03, 0x42, 0xd8, 0xe4, 0x0a, 0x21, 0x61, 0x1d, 0x51},
+	},
+	{ /* 17P */
+		addYX: fp.Elt{0x81, 0x9d, 0x0e, 0x95, 0xef, 0x76, 0xc6, 0x92, 0x4f, 0x04, 0xd7, 0xc0, 0xcd, 0x20, 0x46, 0xa5, 0x48, 0x12, 0x8f, 0x6f, 0x64, 0x36, 0x9b, 0xaa, 0xe3, 0x55, 0xb8, 0xdd, 0x24, 0x59, 0x32, 0x6d},
+		subYX: fp.Elt{0x87, 0xde, 0x20, 0x44, 0x48, 0x86, 0x13, 0x08, 0xb4, 0xed, 0x92, 0xb5, 0x16, 0xf0, 0x1c, 0x8a, 0x25, 0x2d, 0x94, 0x29, 0x27, 0x4e, 0xfa, 0x39, 0x10, 0x28, 0x48, 0xe2, 0x6f, 0xfe, 0xa7, 0x71},
+		dt2:   fp.Elt{0x54, 0xc8, 0xc8, 0xa5, 0xb8, 0x82, 0x71, 0x6c, 0x03, 0x2a, 0x5f, 0xfe, 0x79, 0x14, 0xfd, 0x33, 0x0c, 0x8d, 0x77, 0x83, 0x18, 0x59, 0xcf, 0x72, 0xa9, 0xea, 0x9e, 0x55, 0xb6, 0xc4, 0x46, 0x47},
+	},
+	{ /* 19P */
+		addYX: fp.Elt{0x2b, 0x9a, 0xc6, 0x6d, 0x3c, 0x7b, 0x77, 0xd3, 0x17, 0xf6, 0x89, 0x6f, 0x27, 0xb2, 0xfa, 0xde, 0xb5, 0x16, 0x3a, 0xb5, 0xf7, 0x1c, 0x65, 0x45, 0xb7, 0x9f, 0xfe, 0x34, 0xde, 0x51, 0x9a, 0x5c},
+		subYX: fp.Elt{0x47, 0x11, 0x74, 0x64, 0xc8, 0x46, 0x85, 0x34, 0x49, 0xc8, 0xfc, 0x0e, 0xdd, 0xae, 0x35, 0x7d, 0x32, 0xa3, 0x72, 0x06, 0x76, 0x9a, 0x93, 0xff, 0xd6, 0xe6, 0xb5, 0x7d, 0x49, 0x63, 0x96, 0x21},
+		dt2:   fp.Elt{0x67, 0x0e, 0xf1, 0x79, 0xcf, 0xf1, 0x10, 0xf5, 0x5b, 0x51, 0x58, 0xe6, 0xa1, 0xda, 0xdd, 0xff, 0x77, 0x22, 0x14, 0x10, 0x17, 0xa7, 0xc3, 0x09, 0xbb, 0x23, 0x82, 0x60, 0x3c, 0x50, 0x04, 0x48},
+	},
+	{ /* 21P */
+		addYX: fp.Elt{0xc7, 0x7f, 0xa3, 0x2c, 0xd0, 0x9e, 0x24, 0xc4, 0xab, 0xac, 0x15, 0xa6, 0xe3, 0xa0, 0x59, 0xa0, 0x23, 0x0e, 0x6e, 0xc9, 0xd7, 0x6e, 0xa9, 0x88, 0x6d, 0x69, 0x50, 0x16, 0xa5, 0x98, 0x33, 0x55},
+		subYX: fp.Elt{0x75, 0xd1, 0x36, 0x3a, 0xd2, 0x21, 0x68, 0x3b, 0x32, 0x9e, 0x9b, 0xe9, 0xa7, 0x0a, 0xb4, 0xbb, 0x47, 0x8a, 0x83, 0x20, 0xe4, 0x5c, 0x9e, 0x5d, 0x5e, 0x4c, 0xde, 0x58, 0x88, 0x09, 0x1e, 0x77},
+		dt2:   fp.Elt{0xdf, 0x1e, 0x45, 0x78, 0xd2, 0xf5, 0x12, 0x9a, 0xcb, 0x9c, 0x89, 0x85, 0x79, 0x5d, 0xda, 0x3a, 0x08, 0x95, 0xa5, 0x9f, 0x2d, 0x4a, 0x7f, 0x47, 0x11, 0xa6, 0xf5, 0x8f, 0xd6, 0xd1, 0x5e, 0x5a},
+	},
+	{ /* 23P */
+		addYX: fp.Elt{0x83, 0x0e, 0x15, 0xfe, 0x2a, 0x12, 0x95, 0x11, 0xd8, 0x35, 0x4b, 0x7e, 0x25, 0x9a, 0x20, 0xcf, 0x20, 0x1e, 0x71, 0x1e, 0x29, 0xf8, 0x87, 0x73, 0xf0, 0x92, 0xbf, 0xd8, 0x97, 0xb8, 0xac, 0x44},
+		subYX: fp.Elt{0x59, 0x73, 0x52, 0x58, 0xc5, 0xe0, 0xe5, 0xba, 0x7e, 0x9d, 0xdb, 0xca, 0x19, 0x5c, 0x2e, 0x39, 0xe9, 0xab, 0x1c, 0xda, 0x1e, 0x3c, 0x65, 0x28, 0x44, 0xdc, 0xef, 0x5f, 0x13, 0x60, 0x9b, 0x01},
+		dt2:   fp.Elt{0x83, 0x4b, 0x13, 0x5e, 0x14, 0x68, 0x60, 0x1e, 0x16, 0x4c, 0x30, 0x24, 0x4f, 0xe6, 0xf5, 0xc4, 0xd7, 0x3e, 0x1a, 0xfc, 0xa8, 0x88, 0x6e, 0x50, 0x92, 0x2f, 0xad, 0xe6, 0xfd, 0x49, 0x0c, 0x15},
+	},
+	{ /* 25P */
+		addYX: fp.Elt{0x38, 0x11, 0x47, 0x09, 0x95, 0xf2, 0x7b, 0x8e, 0x51, 0xa6, 0x75, 0x4f, 0x39, 0xef, 0x6f, 0x5d, 0xad, 0x08, 0xa7, 0x25, 0xc4, 0x79, 0xaf, 0x10, 0x22, 0x99, 0xb9, 0x5b, 0x07, 0x5a, 0x2b, 0x6b},
+		subYX: fp.Elt{0x68, 0xa8, 0xdc, 0x9c, 0x3c, 0x86, 0x49, 0xb8, 0xd0, 0x4a, 0x71, 0xb8, 0xdb, 0x44, 0x3f, 0xc8, 0x8d, 0x16, 0x36, 0x0c, 0x56, 0xe3, 0x3e, 0xfe, 0xc1, 0xfb, 0x05, 0x1e, 0x79, 0xd7, 0xa6, 0x78},
+		dt2:   fp.Elt{0x76, 0xb9, 0xa0, 0x47, 0x4b, 0x70, 0xbf, 0x58, 0xd5, 0x48, 0x17, 0x74, 0x55, 0xb3, 0x01, 0xa6, 0x90, 0xf5, 0x42, 0xd5, 0xb1, 0x1f, 0x2b, 0xaa, 0x00, 0x5d, 0xd5, 0x4a, 0xfc, 0x7f, 0x5c, 0x72},
+	},
+	{ /* 27P */
+		addYX: fp.Elt{0xb2, 0x99, 0xcf, 0xd1, 0x15, 0x67, 0x42, 0xe4, 0x34, 0x0d, 0xa2, 0x02, 0x11, 0xd5, 0x52, 0x73, 0x9f, 0x10, 0x12, 0x8b, 0x7b, 0x15, 0xd1, 0x23, 0xa3, 0xf3, 0xb1, 0x7c, 0x27, 0xc9, 0x4c, 0x79},
+		subYX: fp.Elt{0xc0, 0x98, 0xd0, 0x1c, 0xf7, 0x2b, 0x80, 0x91, 0x66, 0x63, 0x5e, 0xed, 0xa4, 0x6c, 0x41, 0xfe, 0x4c, 0x99, 0x02, 0x49, 0x71, 0x5d, 0x58, 0xdf, 0xe7, 0xfa, 0x55, 0xf8, 0x25, 0x46, 0xd5, 0x4c},
+		dt2:   fp.Elt{0x53, 0x50, 0xac, 0xc2, 0x26, 0xc4, 0xf6, 0x4a, 0x58, 0x72, 0xf6, 0x32, 0xad, 0xed, 0x9a, 0xbc, 0x21, 0x10, 0x31, 0x0a, 0xf1, 0x32, 0xd0, 0x2a, 0x85, 0x8e, 0xcc, 0x6f, 0x7b, 0x35, 0x08, 0x70},
+	},
+	{ /* 29P */
+		addYX: fp.Elt{0x01, 0x3f, 0x77, 0x38, 0x27, 0x67, 0x88, 0x0b, 0xfb, 0xcc, 0xfb, 0x95, 0xfa, 0xc8, 0xcc, 0xb8, 0xb6, 0x29, 0xad, 0xb9, 0xa3, 0xd5, 0x2d, 0x8d, 0x6a, 0x0f, 0xad, 0x51, 0x98, 0x7e, 0xef, 0x06},
+		subYX: fp.Elt{0x34, 0x4a, 0x58, 0x82, 0xbb, 0x9f, 0x1b, 0xd0, 0x2b, 0x79, 0xb4, 0xd2, 0x63, 0x64, 0xab, 0x47, 0x02, 0x62, 0x53, 0x48, 0x9c, 0x63, 0x31, 0xb6, 0x28, 0xd4, 0xd6, 0x69, 0x36, 0x2a, 0xa9, 0x13},
+		dt2:   fp.Elt{0xe5, 0x7d, 0x57, 0xc0, 0x1c, 0x77, 0x93, 0xca, 0x5c, 0xdc, 0x35, 0x50, 0x1e, 0xe4, 0x40, 0x75, 0x71, 0xe0, 0x02, 0xd8, 0x01, 0x0f, 0x68, 0x24, 0x6a, 0xf8, 0x2a, 0x8a, 0xdf, 0x6d, 0x29, 0x3c},
+	},
+	{ /* 31P */
+		addYX: fp.Elt{0x13, 0xa7, 0x14, 0xd9, 0xf9, 0x15, 0xad, 0xae, 0x12, 0xf9, 0x8f, 0x8c, 0xf9, 0x7b, 0x2f, 0xa9, 0x30, 0xd7, 0x53, 0x9f, 0x17, 0x23, 0xf8, 0xaf, 0xba, 0x77, 0x0c, 0x49, 0x93, 0xd3, 0x99, 0x7a},
+		subYX: fp.Elt{0x41, 0x25, 0x1f, 0xbb, 0x2e, 0x4d, 0xeb, 0xfc, 0x1f, 0xb9, 0xad, 0x40, 0xc7, 0x10, 0x95, 0xb8, 0x05, 0xad, 0xa1, 0xd0, 0x7d, 0xa3, 0x71, 0xfc, 0x7b, 0x71, 0x47, 0x07, 0x70, 0x2c, 0x89, 0x0a},
+		dt2:   fp.Elt{0xe8, 0xa3, 0xbd, 0x36, 0x24, 0xed, 0x52, 0x8f, 0x94, 0x07, 0xe8, 0x57, 0x41, 0xc8, 0xa8, 0x77, 0xe0, 0x9c, 0x2f, 0x26, 0x63, 0x65, 0xa9, 0xa5, 0xd2, 0xf7, 0x02, 0x83, 0xd2, 0x62, 0x67, 0x28},
+	},
+	{ /* 33P */
+		addYX: fp.Elt{0x25, 0x5b, 0xe3, 0x3c, 0x09, 0x36, 0x78, 0x4e, 0x97, 0xaa, 0x6b, 0xb2, 0x1d, 0x18, 0xe1, 0x82, 0x3f, 0xb8, 0xc7, 0xcb, 0xd3, 0x92, 0xc1, 0x0c, 0x3a, 0x9d, 0x9d, 0x6a, 0x04, 0xda, 0xf1, 0x32},
+		subYX: fp.Elt{0xbd, 0xf5, 0x2e, 0xce, 0x2b, 0x8e, 0x55, 0x7c, 0x63, 0xbc, 0x47, 0x67, 0xb4, 0x6c, 0x98, 0xe4, 0xb8, 0x89, 0xbb, 0x3b, 0x9f, 0x17, 0x4a, 0x15, 0x7a, 0x76, 0xf1, 0xd6, 0xa3, 0xf2, 0x86, 0x76},
+		dt2:   fp.Elt{0x6a, 0x7c, 0x59, 0x6d, 0xa6, 0x12, 0x8d, 0xaa, 0x2b, 0x85, 0xd3, 0x04, 0x03, 0x93, 0x11, 0x8f, 0x22, 0xb0, 0x09, 0xc2, 0x73, 0xdc, 0x91, 0x3f, 0xa6, 0x28, 0xad, 0xa9, 0xf8, 0x05, 0x13, 0x56},
+	},
+	{ /* 35P */
+		addYX: fp.Elt{0xd1, 0xae, 0x92, 0xec, 0x8d, 0x97, 0x0c, 0x10, 0xe5, 0x73, 0x6d, 0x4d, 0x43, 0xd5, 0x43, 0xca, 0x48, 0xba, 0x47, 0xd8, 0x22, 0x1b, 0x13, 0x83, 0x2c, 0x4d, 0x5d, 0xe3, 0x53, 0xec, 0xaa},
+		subYX: fp.Elt{0xd5, 0xc0, 0xb0, 0xe7, 0x28, 0xcc, 0x22, 0x67, 0x53, 0x5c, 0x07, 0xdb, 0xbb, 0xe9, 0x9d, 0x70, 0x61, 0x0a, 0x01, 0xd7, 0xa7, 0x8d, 0xf6, 0xca, 0x6c, 0xcc, 0x57, 0x2c, 0xef, 0x1a, 0x0a, 0x03},
+		dt2:   fp.Elt{0xaa, 0xd2, 0x3a, 0x00, 0x73, 0xf7, 0xb1, 0x7b, 0x08, 0x66, 0x21, 0x2b, 0x80, 0x29, 0x3f, 0x0b, 0x3e, 0xd2, 0x0e, 0x52, 0x86, 0xdc, 0x21, 0x78, 0x80, 0x54, 0x06, 0x24, 0x1c, 0x9c, 0xbe, 0x20},
+	},
+	{ /* 37P */
+		addYX: fp.Elt{0xa6, 0x73, 0x96, 0x24, 0xd8, 0x87, 0x53, 0xe1, 0x93, 0xe4, 0x46, 0xf5, 0x2d, 0xbc, 0x43, 0x59, 0xb5, 0x63, 0x6f, 0xc3, 0x81, 0x9a, 0x7f, 0x1c, 0xde, 0xc1, 0x0a, 0x1f, 0x36, 0xb3, 0x0a, 0x75},
+		subYX: fp.Elt{0x60, 0x5e, 0x02, 0xe2, 0x4a, 0xe4, 0xe0, 0x20, 0x38, 0xb9, 0xdc, 0xcb, 0x2f, 0x3b, 0x3b, 0xb0, 0x1c, 0x0d, 0x5a, 0xf9, 0x9c, 0x63, 0x5d, 0x10, 0x11, 0xe3, 0x67, 0x50, 0x54, 0x4c, 0x76, 0x69},
+		dt2:   fp.Elt{0x37, 0x10, 0xf8, 0xa2, 0x83, 0x32, 0x8a, 0x1e, 0xf1, 0xcb, 0x7f, 0xbd, 0x23, 0xda, 0x2e, 0x6f, 0x63, 0x25, 0x2e, 0xac, 0x5b, 0xd1, 0x2f, 0xb7, 0x40, 0x50, 0x07, 0xb7, 0x3f, 0x6b, 0xf9, 0x54},
+	},
+	{ /* 39P */
+		addYX: fp.Elt{0x79, 0x92, 0x66, 0x29, 0x04, 0xf2, 0xad, 0x0f, 0x4a, 0x72, 0x7d, 0x7d, 0x04, 0xa2, 0xdd, 0x3a, 0xf1, 0x60, 0x57, 0x8c, 0x82, 0x94, 0x3d, 0x6f, 0x9e, 0x53, 0xb7, 0x2b, 0xc5, 0xe9, 0x7f, 0x3d},
+		subYX: fp.Elt{0xcd, 0x1e, 0xb1, 0x16, 0xc6, 0xaf, 0x7d, 0x17, 0x79, 0x64, 0x57, 0xfa, 0x9c, 0x4b, 0x76, 0x89, 0x85, 0xe7, 0xec, 0xe6, 0x10, 0xa1, 0xa8, 0xb7, 0xf0, 0xdb, 0x85, 0xbe, 0x9f, 0x83, 0xe6, 0x78},
+		dt2:   fp.Elt{0x6b, 0x85, 0xb8, 0x37, 0xf7, 0x2d, 0x33, 0x70, 0x8a, 0x17, 0x1a, 0x04, 0x43, 0x5d, 0xd0, 0x75, 0x22, 0x9e, 0xe5, 0xa0, 0x4a, 0xf7, 0x0f, 0x32, 0x42, 0x82, 0x08, 0x50, 0xf3, 0x68, 0xf2, 0x70},
+	},
+	{ /* 41P */
+		addYX: fp.Elt{0x47, 0x5f, 0x80, 0xb1, 0x83, 0x45, 0x86, 0x66, 0x19, 0x7c, 0xdd, 0x60, 0xd1, 0xc5, 0x35, 0xf5, 0x06, 0xb0, 0x4c, 0x1e, 0xb7, 0x4e, 0x87, 0xe9, 0xd9, 0x89, 0xd8, 0xfa, 0x5c, 0x34, 0x0d, 0x7c},
+		subYX: fp.Elt{0x55, 0xf3, 0xdc, 0x70, 0x20, 0x11, 0x24, 0x23, 0x17, 0xe1, 0xfc, 0xe7, 0x7e, 0xc9, 0x0c, 0x38, 0x98, 0xb6, 0x52, 0x35, 0xed, 0xde, 0x1d, 0xb3, 0xb9, 0xc4, 0xb8, 0x39, 0xc0, 0x56, 0x4e, 0x40},
+		dt2:   fp.Elt{0x8a, 0x33, 0x78, 0x8c, 0x4b, 0x1f, 0x1f, 0x59, 0xe1, 0xb5, 0xe0, 0x67, 0xb1, 0x6a, 0x36, 0xa0, 0x44, 0x3d, 0x5f, 0xb4, 0x52, 0x41, 0xbc, 0x5c, 0x77, 0xc7, 0xae, 0x2a, 0x76, 0x54, 0xd7, 0x20},
+	},
+	{ /* 43P */
+		addYX: fp.Elt{0x58, 0xb7, 0x3b, 0xc7, 0x6f, 0xc3, 0x8f, 0x5e, 0x9a, 0xbb, 0x3c, 0x36, 0xa5, 0x43, 0xe5, 0xac, 0x22, 0xc9, 0x3b, 0x90, 0x7d, 0x4a, 0x93, 0xa9, 0x62, 0xec, 0xce, 0xf3, 0x46, 0x1e, 0x8f, 0x2b},
+		subYX: fp.Elt{0x43, 0xf5, 0xb9, 0x35, 0xb1, 0xfe, 0x74, 0x9d, 0x6c, 0x95, 0x8c, 0xde, 0xf1, 0x7d, 0xb3, 0x84, 0xa9, 0x8b, 0x13, 0x57, 0x07, 0x2b, 0x32, 0xe9, 0xe1, 0x4c, 0x0b, 0x79, 0xa8, 0xad, 0xb8, 0x38},
+		dt2:   fp.Elt{0x5d, 0xf9, 0x51, 0xdf, 0x9c, 0x4a, 0xc0, 0xb5, 0xac, 0xde, 0x1f, 0xcb, 0xae, 0x52, 0x39, 0x2b, 0xda, 0x66, 0x8b, 0x32, 0x8b, 0x6d, 0x10, 0x1d, 0x53, 0x19, 0xba, 0xce, 0x32, 0xeb, 0x9a, 0x04},
+	},
+	{ /* 45P */
+		addYX: fp.Elt{0x31, 0x79, 0xfc, 0x75, 0x0b, 0x7d, 0x50, 0xaa, 0xd3, 0x25, 0x67, 0x7a, 0x4b, 0x92, 0xef, 0x0f, 0x30, 0x39, 0x6b, 0x39, 0x2b, 0x54, 0x82, 0x1d, 0xfc, 0x74, 0xf6, 0x30, 0x75, 0xe1, 0x5e, 0x79},
+		subYX: fp.Elt{0x7e, 0xfe, 0xdc, 0x63, 0x3c, 0x7d, 0x76, 0xd7, 0x40, 0x6e, 0x85, 0x97, 0x48, 0x59, 0x9c, 0x20, 0x13, 0x7c, 0x4f, 0xe1, 0x61, 0x68, 0x67, 0xb6, 0xfc, 0x25, 0xd6, 0xc8, 0xe0, 0x65, 0xc6, 0x51},
+		dt2:   fp.Elt{0x81, 0xbd, 0xec, 0x52, 0x0a, 0x5b, 0x4a, 0x25, 0xe7, 0xaf, 0x34, 0xe0, 0x6e, 0x1f, 0x41, 0x5d, 0x31, 0x4a, 0xee, 0xca, 0x0d, 0x4d, 0xa2, 0xe6, 0x77, 0x44, 0xc5, 0x9d, 0xf4, 0x9b, 0xd1, 0x6c},
+	},
+	{ /* 47P */
+		addYX: fp.Elt{0x86, 0xc3, 0xaf, 0x65, 0x21, 0x61, 0xfe, 0x1f, 0x10, 0x1b, 0xd5, 0xb8, 0x88, 0x2a, 0x2a, 0x08, 0xaa, 0x0b, 0x99, 0x20, 0x7e, 0x62, 0xf6, 0x76, 0xe7, 0x43, 0x9e, 0x42, 0xa7, 0xb3, 0x01, 0x5e},
+		subYX: fp.Elt{0xa3, 0x9c, 0x17, 0x52, 0x90, 0x61, 0x87, 0x7e, 0x85, 0x9f, 0x2c, 0x0b, 0x06, 0x0a, 0x1d, 0x57, 0x1e, 0x71, 0x99, 0x84, 0xa8, 0xba, 0xa2, 0x80, 0x38, 0xe6, 0xb2, 0x40, 0xdb, 0xf3, 0x20, 0x75},
+		dt2:   fp.Elt{0xa1, 0x57, 0x93, 0xd3, 0xe3, 0x0b, 0xb5, 0x3d, 0xa5, 0x94, 0x9e, 0x59, 0xdd, 0x6c, 0x7b, 0x96, 0x6e, 0x1e, 0x31, 0xdf, 0x64, 0x9a, 0x30, 0x1a, 0x86, 0xc9, 0xf3, 0xce, 0x9c, 0x2c, 0x09, 0x71},
+	},
+	{ /* 49P */
+		addYX: fp.Elt{0xcf, 0x1d, 0x05, 0x74, 0xac, 0xd8, 0x6b, 0x85, 0x1e, 0xaa, 0xb7, 0x55, 0x08, 0xa4, 0xf6, 0x03, 0xeb, 0x3c, 0x74, 0xc9, 0xcb, 0xe7, 0x4a, 0x3a, 0xde, 0xab, 0x37, 0x71, 0xbb, 0xa5, 0x73, 0x41},
+		subYX: fp.Elt{0x8c, 0x91, 0x64, 0x03, 0x3f, 0x52, 0xd8, 0x53, 0x1c, 0x6b, 0xab, 0x3f, 0xf4, 0x04, 0xb4, 0xa2, 0xa4, 0xe5, 0x81, 0x66, 0x9e, 0x4a, 0x0b, 0x08, 0xa7, 0x7b, 0x25, 0xd0, 0x03, 0x5b, 0xa1, 0x0e},
+		dt2:   fp.Elt{0x8a, 0x21, 0xf9, 0xf0, 0x31, 0x6e, 0xc5, 0x17, 0x08, 0x47, 0xfc, 0x1a, 0x2b, 0x6e, 0x69, 0x5a, 0x76, 0xf1, 0xb2, 0xf4, 0x68, 0x16, 0x93, 0xf7, 0x67, 0x3a, 0x4e, 0x4a, 0x61, 0x65, 0xc5, 0x5f},
+	},
+	{ /* 51P */
+		addYX: fp.Elt{0x8e, 0x98, 0x90, 0x77, 0xe6, 0xe1, 0x92, 0x48, 0x22, 0xd7, 0x5c, 0x1c, 0x0f, 0x95, 0xd5, 0x01, 0xed, 0x3e, 0x92, 0xe5, 0x9a, 0x81, 0xb0, 0xe3, 0x1b, 0x65, 0x46, 0x9d, 0x40, 0xc7, 0x14, 0x32},
+		subYX: fp.Elt{0xe5, 0x7a, 0x6d, 0xc4, 0x0d, 0x57, 0x6e, 0x13, 0x8f, 0xdc, 0xf8, 0x54, 0xcc, 0xaa, 0xd0, 0x0f, 0x86, 0xad, 0x0d, 0x31, 0x03, 0x9f, 0x54, 0x59, 0xa1, 0x4a, 0x45, 0x4c, 0x41, 0x1c, 0x71, 0x62},
+		dt2:   fp.Elt{0x70, 0x17, 0x65, 0x06, 0x74, 0x82, 0x29, 0x13, 0x36, 0x94, 0x27, 0x8a, 0x66, 0xa0, 0xa4, 0x3b, 0x3c, 0x22, 0x5d, 0x18, 0xec, 0xb8, 0xb6, 0xd9, 0x3c, 0x83, 0xcb, 0x3e, 0x07, 0x94, 0xea, 0x5b},
+	},
+	{ /* 53P */
+		addYX: fp.Elt{0xf8, 0xd2, 0x43, 0xf3, 0x63, 0xce, 0x70, 0xb4, 0xf1, 0xe8, 0x43, 0x05, 0x8f, 0xba, 0x67, 0x00, 0x6f, 0x7b, 0x11, 0xa2, 0xa1, 0x51, 0xda, 0x35, 0x2f, 0xbd, 0xf1, 0x44, 0x59, 0x78, 0xd0, 0x4a},
+		subYX: fp.Elt{0xe4, 0x9b, 0xc8, 0x12, 0x09, 0xbf, 0x1d, 0x64, 0x9c, 0x57, 0x6e, 0x7d, 0x31, 0x8b, 0xf3, 0xac, 0x65, 0xb0, 0x97, 0xf6, 0x02, 0x9e, 0xfe, 0xab, 0xec, 0x1e, 0xf6, 0x48, 0xc1, 0xd5, 0xac, 0x3a},
+		dt2:   fp.Elt{0x01, 0x83, 0x31, 0xc3, 0x34, 0x3b, 0x8e, 0x85, 0x26, 0x68, 0x31, 0x07, 0x47, 0xc0, 0x99, 0xdc, 0x8c, 0xa8, 0x9d, 0xd3, 0x2e, 0x5b, 0x08, 0x34, 0x3d, 0x85, 0x02, 0xd9, 0xb1, 0x0c, 0xff, 0x3a},
+	},
+	{ /* 55P */
+		addYX: fp.Elt{0x05, 0x35, 0xc5, 0xf4, 0x0b, 0x43, 0x26, 0x92, 0x83, 0x22, 0x1f, 0x26, 0x13, 0x9c, 0xe4, 0x68, 0xc6, 0x27, 0xd3, 0x8f, 0x78, 0x33, 0xef, 0x09, 0x7f, 0x9e, 0xd9, 0x2b, 0x73, 0x9f, 0xcf, 0x2c},
+		subYX: fp.Elt{0x5e, 0x40, 0x20, 0x3a, 0xeb, 0xc7, 0xc5, 0x87, 0xc9, 0x56, 0xad, 0xed, 0xef, 0x11, 0xe3, 0x8e, 0xf9, 0xd5, 0x29, 0xad, 0x48, 0x2e, 0x25, 0x29, 0x1d, 0x25, 0xcd, 0xf4, 0x86, 0x7e, 0x0e, 0x11},
+		dt2:   fp.Elt{0xe4, 0xf5, 0x03, 0xd6, 0x9e, 0xd8, 0xc0, 0x57, 0x0c, 0x20, 0xb0, 0xf0, 0x28, 0x86, 0x88, 0x12, 0xb7, 0x3b, 0x2e, 0xa0, 0x09, 0x27, 0x17, 0x53, 0x37, 0x3a, 0x69, 0xb9, 0xe0, 0x57, 0xc5, 0x05},
+	},
+	{ /* 57P */
+		addYX: fp.Elt{0xb0, 0x0e, 0xc2, 0x89, 0xb0, 0xbb, 0x76, 0xf7, 0x5c, 0xd8, 0x0f, 0xfa, 0xf6, 0x5b, 0xf8, 0x61, 0xfb, 0x21, 0x44, 0x63, 0x4e, 0x3f, 0xb9, 0xb6, 0x05, 0x12, 0x86, 0x41, 0x08, 0xef, 0x9f, 0x28},
+		subYX: fp.Elt{0x6f, 0x7e, 0xc9, 0x1f, 0x31, 0xce, 0xf9, 0xd8, 0xae, 0xfd, 0xf9, 0x11, 0x30, 0x26, 0x3f, 0x7a, 0xdd, 0x25, 0xed, 0x8b, 0xa0, 0x7e, 0x5b, 0xe1, 0x5a, 0x87, 0xe9, 0x8f, 0x17, 0x4c, 0x15, 0x6e},
+		dt2:   fp.Elt{0xbf, 0x9a, 0xd6, 0xfe, 0x36, 0x63, 0x61, 0xcf, 0x4f, 0xc9, 0x35, 0x83, 0xe7, 0xe4, 0x16, 0x9b, 0xe7, 0x7f, 0x3a, 0x75, 0x65, 0x97, 0x78, 0x13, 0x19, 0xa3, 0x5c, 0xa9, 0x42, 0xf6, 0xfb, 0x6a},
+	},
+	{ /* 59P */
+		addYX: fp.Elt{0xcc, 0xa8, 0x13, 0xf9, 0x70, 0x50, 0xe5, 0x5d, 0x61, 0xf5, 0x0c, 0x2b, 0x7b, 0x16, 0x1d, 0x7d, 0x89, 0xd4, 0xea, 0x90, 0xb6, 0x56, 0x29, 0xda, 0xd9, 0x1e, 0x80, 0xdb, 0xce, 0x93, 0xc0, 0x12},
+		subYX: fp.Elt{0xc1, 0xd2, 0xf5, 0x62, 0x0c, 0xde, 0xa8, 0x7d, 0x9a, 0x7b, 0x0e, 0xb0, 0xa4, 0x3d, 0xfc, 0x98, 0xe0, 0x70, 0xad, 0x0d, 0xda, 0x6a, 0xeb, 0x7d, 0xc4, 0x38, 0x50, 0xb9, 0x51, 0xb8, 0xb4, 0x0d},
+		dt2:   fp.Elt{0x0f, 0x19, 0xb8, 0x08, 0x93, 0x7f, 0x14, 0xfc, 0x10, 0xe3, 0x1a, 0xa1, 0xa0, 0x9d, 0x96, 0x06, 0xfd, 0xd7, 0xc7, 0xda, 0x72, 0x55, 0xe7, 0xce, 0xe6, 0x5c, 0x63, 0xc6, 0x99, 0x87, 0xaa, 0x33},
+	},
+	{ /* 61P */
+		addYX: fp.Elt{0xb1, 0x6c, 0x15, 0xfc, 0x88, 0xf5, 0x48, 0x83, 0x27, 0x6d, 0x0a, 0x1a, 0x9b, 0xba, 0xa2, 0x6d, 0xb6, 0x5a, 0xca, 0x87, 0x5c, 0x2d, 0x26, 0xe2, 0xa6, 0x89, 0xd5, 0xc8, 0xc1, 0xd0, 0x2c, 0x21},
+		subYX: fp.Elt{0xf2, 0x5c, 0x08, 0xbd, 0x1e, 0xf5, 0x0f, 0xaf, 0x1f, 0x3f, 0xd3, 0x67, 0x89, 0x1a, 0xf5, 0x78, 0x3c, 0x03, 0x60, 0x50, 0xe1, 0xbf, 0xc2, 0x6e, 0x86, 0x1a, 0xe2, 0xe8, 0x29, 0x6f, 0x3c, 0x23},
+		dt2:   fp.Elt{0x81, 0xc7, 0x18, 0x7f, 0x10, 0xd5, 0xf4, 0xd2, 0x28, 0x9d, 0x7e, 0x52, 0xf2, 0xcd, 0x2e, 0x12, 0x41, 0x33, 0x3d, 0x3d, 0x2a, 0x86, 0x0a, 0xa7, 0xe3, 0x4c, 0x91, 0x11, 0x89, 0x77, 0xb7, 0x1d},
+	},
+	{ /* 63P */
+		addYX: fp.Elt{0xb6, 0x1a, 0x70, 0xdd, 0x69, 0x47, 0x39, 0xb3, 0xa5, 0x8d, 0xcf, 0x19, 0xd4, 0xde, 0xb8, 0xe2, 0x52, 0xc8, 0x2a, 0xfd, 0x61, 0x41, 0xdf, 0x15, 0xbe, 0x24, 0x7d, 0x01, 0x8a, 0xca, 0xe2, 0x7a},
+		subYX: fp.Elt{0x6f, 0xc2, 0x6b, 0x7c, 0x39, 0x52, 0xf3, 0xdd, 0x13, 0x01, 0xd5, 0x53, 0xcc, 0xe2, 0x97, 0x7a, 0x30, 0xa3, 0x79, 0xbf, 0x3a, 0xf4, 0x74, 0x7c, 0xfc, 0xad, 0xe2, 0x26, 0xad, 0x97, 0xad, 0x31},
+		dt2:   fp.Elt{0x62, 0xb9, 0x20, 0x09, 0xed, 0x17, 0xe8, 0xb7, 0x9d, 0xda, 0x19, 0x3f, 0xcc, 0x18, 0x85, 0x1e, 0x64, 0x0a, 0x56, 0x25, 0x4f, 0xc1, 0x91, 0xe4, 0x83, 0x2c, 0x62, 0xa6, 0x53, 0xfc, 0xd1, 0x1e},
+	},
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go b/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go
new file mode 100644
index 00000000..324bd8f3
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed448/ed448.go
@@ -0,0 +1,411 @@
+// Package ed448 implements Ed448 signature scheme as described in RFC-8032.
+//
+// This package implements two signature variants.
+//
+//	| Scheme Name | Sign Function     | Verification  | Context           |
+//	|-------------|-------------------|---------------|-------------------|
+//	| Ed448       | Sign              | Verify        | Yes, can be empty |
+//	| Ed448Ph     | SignPh            | VerifyPh      | Yes, can be empty |
+//	| All above   | (PrivateKey).Sign | VerifyAny     | As above          |
+//
+// Specific functions for sign and verify are defined. A generic signing
+// function for all schemes is available through the crypto.Signer interface,
+// which is implemented by the PrivateKey type. A correspond all-in-one
+// verification method is provided by the VerifyAny function.
+//
+// Both schemes require a context string for domain separation. This parameter
+// is passed using a SignerOptions struct defined in this package.
+//
+// References:
+//
+//   - RFC8032: https://rfc-editor.org/rfc/rfc8032.txt
+//   - EdDSA for more curves: https://eprint.iacr.org/2015/677
+//   - High-speed high-security signatures: https://doi.org/10.1007/s13389-012-0027-1
+package ed448
+
+import (
+	"bytes"
+	"crypto"
+	cryptoRand "crypto/rand"
+	"crypto/subtle"
+	"errors"
+	"fmt"
+	"io"
+	"strconv"
+
+	"github.com/cloudflare/circl/ecc/goldilocks"
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/sign"
+)
+
+const (
+	// ContextMaxSize is the maximum length (in bytes) allowed for context.
+	ContextMaxSize = 255
+	// PublicKeySize is the length in bytes of Ed448 public keys.
+	PublicKeySize = 57
+	// PrivateKeySize is the length in bytes of Ed448 private keys.
+	PrivateKeySize = 114
+	// SignatureSize is the length in bytes of signatures.
+	SignatureSize = 114
+	// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
+	SeedSize = 57
+)
+
+const (
+	paramB   = 456 / 8    // Size of keys in bytes.
+	hashSize = 2 * paramB // Size of the hash function's output.
+)
+
+// SignerOptions implements crypto.SignerOpts and augments with parameters
+// that are specific to the Ed448 signature schemes.
+type SignerOptions struct {
+	// Hash must be crypto.Hash(0) for both Ed448 and Ed448Ph.
+	crypto.Hash
+
+	// Context is an optional domain separation string for signing.
+	// Its length must be less or equal than 255 bytes.
+	Context string
+
+	// Scheme is an identifier for choosing a signature scheme.
+	Scheme SchemeID
+}
+
+// SchemeID is an identifier for each signature scheme.
+type SchemeID uint
+
+const (
+	ED448 SchemeID = iota
+	ED448Ph
+)
+
+// PublicKey is the type of Ed448 public keys.
+type PublicKey []byte
+
+// Equal reports whether pub and x have the same value.
+func (pub PublicKey) Equal(x crypto.PublicKey) bool {
+	xx, ok := x.(PublicKey)
+	return ok && bytes.Equal(pub, xx)
+}
+
+// PrivateKey is the type of Ed448 private keys. It implements crypto.Signer.
+type PrivateKey []byte
+
+// Equal reports whether priv and x have the same value.
+func (priv PrivateKey) Equal(x crypto.PrivateKey) bool {
+	xx, ok := x.(PrivateKey)
+	return ok && subtle.ConstantTimeCompare(priv, xx) == 1
+}
+
+// Public returns the PublicKey corresponding to priv.
+func (priv PrivateKey) Public() crypto.PublicKey {
+	publicKey := make([]byte, PublicKeySize)
+	copy(publicKey, priv[SeedSize:])
+	return PublicKey(publicKey)
+}
+
+// Seed returns the private key seed corresponding to priv. It is provided for
+// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
+// in this package.
+func (priv PrivateKey) Seed() []byte {
+	seed := make([]byte, SeedSize)
+	copy(seed, priv[:SeedSize])
+	return seed
+}
+
+func (priv PrivateKey) Scheme() sign.Scheme { return sch }
+
+func (pub PublicKey) Scheme() sign.Scheme { return sch }
+
+func (priv PrivateKey) MarshalBinary() (data []byte, err error) {
+	privateKey := make(PrivateKey, PrivateKeySize)
+	copy(privateKey, priv)
+	return privateKey, nil
+}
+
+func (pub PublicKey) MarshalBinary() (data []byte, err error) {
+	publicKey := make(PublicKey, PublicKeySize)
+	copy(publicKey, pub)
+	return publicKey, nil
+}
+
+// Sign creates a signature of a message given a key pair.
+// This function supports all the two signature variants defined in RFC-8032,
+// namely Ed448 (or pure EdDSA) and Ed448Ph.
+// The opts.HashFunc() must return zero to the specify Ed448 variant. This can
+// be achieved by passing crypto.Hash(0) as the value for opts.
+// Use an Options struct to pass a bool indicating that the ed448Ph variant
+// should be used.
+// The struct can also be optionally used to pass a context string for signing.
+func (priv PrivateKey) Sign(
+	rand io.Reader,
+	message []byte,
+	opts crypto.SignerOpts,
+) (signature []byte, err error) {
+	var ctx string
+	var scheme SchemeID
+
+	if o, ok := opts.(SignerOptions); ok {
+		ctx = o.Context
+		scheme = o.Scheme
+	}
+
+	switch true {
+	case scheme == ED448 && opts.HashFunc() == crypto.Hash(0):
+		return Sign(priv, message, ctx), nil
+	case scheme == ED448Ph && opts.HashFunc() == crypto.Hash(0):
+		return SignPh(priv, message, ctx), nil
+	default:
+		return nil, errors.New("ed448: bad hash algorithm")
+	}
+}
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
+	if rand == nil {
+		rand = cryptoRand.Reader
+	}
+
+	seed := make(PrivateKey, SeedSize)
+	if _, err := io.ReadFull(rand, seed); err != nil {
+		return nil, nil, err
+	}
+
+	privateKey := NewKeyFromSeed(seed)
+	publicKey := make([]byte, PublicKeySize)
+	copy(publicKey, privateKey[SeedSize:])
+
+	return publicKey, privateKey, nil
+}
+
+// NewKeyFromSeed calculates a private key from a seed. It will panic if
+// len(seed) is not SeedSize. This function is provided for interoperability
+// with RFC 8032. RFC 8032's private keys correspond to seeds in this
+// package.
+func NewKeyFromSeed(seed []byte) PrivateKey {
+	privateKey := make([]byte, PrivateKeySize)
+	newKeyFromSeed(privateKey, seed)
+	return privateKey
+}
+
+func newKeyFromSeed(privateKey, seed []byte) {
+	if l := len(seed); l != SeedSize {
+		panic("ed448: bad seed length: " + strconv.Itoa(l))
+	}
+
+	var h [hashSize]byte
+	H := sha3.NewShake256()
+	_, _ = H.Write(seed)
+	_, _ = H.Read(h[:])
+	s := &goldilocks.Scalar{}
+	deriveSecretScalar(s, h[:paramB])
+
+	copy(privateKey[:SeedSize], seed)
+	_ = goldilocks.Curve{}.ScalarBaseMult(s).ToBytes(privateKey[SeedSize:])
+}
+
+func signAll(signature []byte, privateKey PrivateKey, message, ctx []byte, preHash bool) {
+	if len(ctx) > ContextMaxSize {
+		panic(fmt.Errorf("ed448: bad context length: " + strconv.Itoa(len(ctx))))
+	}
+
+	H := sha3.NewShake256()
+	var PHM []byte
+
+	if preHash {
+		var h [64]byte
+		_, _ = H.Write(message)
+		_, _ = H.Read(h[:])
+		PHM = h[:]
+		H.Reset()
+	} else {
+		PHM = message
+	}
+
+	// 1.  Hash the 57-byte private key using SHAKE256(x, 114).
+	var h [hashSize]byte
+	_, _ = H.Write(privateKey[:SeedSize])
+	_, _ = H.Read(h[:])
+	s := &goldilocks.Scalar{}
+	deriveSecretScalar(s, h[:paramB])
+	prefix := h[paramB:]
+
+	// 2.  Compute SHAKE256(dom4(F, C) || prefix || PH(M), 114).
+	var rPM [hashSize]byte
+	H.Reset()
+
+	writeDom(&H, ctx, preHash)
+
+	_, _ = H.Write(prefix)
+	_, _ = H.Write(PHM)
+	_, _ = H.Read(rPM[:])
+
+	// 3.  Compute the point [r]B.
+	r := &goldilocks.Scalar{}
+	r.FromBytes(rPM[:])
+	R := (&[paramB]byte{})[:]
+	if err := (goldilocks.Curve{}.ScalarBaseMult(r).ToBytes(R)); err != nil {
+		panic(err)
+	}
+	// 4.  Compute SHAKE256(dom4(F, C) || R || A || PH(M), 114)
+	var hRAM [hashSize]byte
+	H.Reset()
+
+	writeDom(&H, ctx, preHash)
+
+	_, _ = H.Write(R)
+	_, _ = H.Write(privateKey[SeedSize:])
+	_, _ = H.Write(PHM)
+	_, _ = H.Read(hRAM[:])
+
+	// 5.  Compute S = (r + k * s) mod order.
+	k := &goldilocks.Scalar{}
+	k.FromBytes(hRAM[:])
+	S := &goldilocks.Scalar{}
+	S.Mul(k, s)
+	S.Add(S, r)
+
+	// 6.  The signature is the concatenation of R and S.
+	copy(signature[:paramB], R[:])
+	copy(signature[paramB:], S[:])
+}
+
+// Sign signs the message with privateKey and returns a signature.
+// This function supports the signature variant defined in RFC-8032: Ed448,
+// also known as the pure version of EdDSA.
+// It will panic if len(privateKey) is not PrivateKeySize.
+func Sign(priv PrivateKey, message []byte, ctx string) []byte {
+	signature := make([]byte, SignatureSize)
+	signAll(signature, priv, message, []byte(ctx), false)
+	return signature
+}
+
+// SignPh creates a signature of a message given a keypair.
+// This function supports the signature variant defined in RFC-8032: Ed448ph,
+// meaning it internally hashes the message using SHAKE-256.
+// Context could be passed to this function, which length should be no more than
+// 255. It can be empty.
+func SignPh(priv PrivateKey, message []byte, ctx string) []byte {
+	signature := make([]byte, SignatureSize)
+	signAll(signature, priv, message, []byte(ctx), true)
+	return signature
+}
+
+func verify(public PublicKey, message, signature, ctx []byte, preHash bool) bool {
+	if len(public) != PublicKeySize ||
+		len(signature) != SignatureSize ||
+		len(ctx) > ContextMaxSize ||
+		!isLessThanOrder(signature[paramB:]) {
+		return false
+	}
+
+	P, err := goldilocks.FromBytes(public)
+	if err != nil {
+		return false
+	}
+
+	H := sha3.NewShake256()
+	var PHM []byte
+
+	if preHash {
+		var h [64]byte
+		_, _ = H.Write(message)
+		_, _ = H.Read(h[:])
+		PHM = h[:]
+		H.Reset()
+	} else {
+		PHM = message
+	}
+
+	var hRAM [hashSize]byte
+	R := signature[:paramB]
+
+	writeDom(&H, ctx, preHash)
+
+	_, _ = H.Write(R)
+	_, _ = H.Write(public)
+	_, _ = H.Write(PHM)
+	_, _ = H.Read(hRAM[:])
+
+	k := &goldilocks.Scalar{}
+	k.FromBytes(hRAM[:])
+	S := &goldilocks.Scalar{}
+	S.FromBytes(signature[paramB:])
+
+	encR := (&[paramB]byte{})[:]
+	P.Neg()
+	_ = goldilocks.Curve{}.CombinedMult(S, k, P).ToBytes(encR)
+	return bytes.Equal(R, encR)
+}
+
+// VerifyAny returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded.
+// This function supports all the two signature variants defined in RFC-8032,
+// namely Ed448 (or pure EdDSA) and Ed448Ph.
+// The opts.HashFunc() must return zero, this can be achieved by passing
+// crypto.Hash(0) as the value for opts.
+// Use a SignerOptions struct to pass a context string for signing.
+func VerifyAny(public PublicKey, message, signature []byte, opts crypto.SignerOpts) bool {
+	var ctx string
+	var scheme SchemeID
+	if o, ok := opts.(SignerOptions); ok {
+		ctx = o.Context
+		scheme = o.Scheme
+	}
+
+	switch true {
+	case scheme == ED448 && opts.HashFunc() == crypto.Hash(0):
+		return Verify(public, message, signature, ctx)
+	case scheme == ED448Ph && opts.HashFunc() == crypto.Hash(0):
+		return VerifyPh(public, message, signature, ctx)
+	default:
+		return false
+	}
+}
+
+// Verify returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded.
+// This function supports the signature variant defined in RFC-8032: Ed448,
+// also known as the pure version of EdDSA.
+func Verify(public PublicKey, message, signature []byte, ctx string) bool {
+	return verify(public, message, signature, []byte(ctx), false)
+}
+
+// VerifyPh returns true if the signature is valid. Failure cases are invalid
+// signature, or when the public key cannot be decoded.
+// This function supports the signature variant defined in RFC-8032: Ed448ph,
+// meaning it internally hashes the message using SHAKE-256.
+// Context could be passed to this function, which length should be no more than
+// 255. It can be empty.
+func VerifyPh(public PublicKey, message, signature []byte, ctx string) bool {
+	return verify(public, message, signature, []byte(ctx), true)
+}
+
+func deriveSecretScalar(s *goldilocks.Scalar, h []byte) {
+	h[0] &= 0xFC        // The two least significant bits of the first octet are cleared,
+	h[paramB-1] = 0x00  // all eight bits the last octet are cleared, and
+	h[paramB-2] |= 0x80 // the highest bit of the second to last octet is set.
+	s.FromBytes(h[:paramB])
+}
+
+// isLessThanOrder returns true if 0 <= x < order and if the last byte of x is zero.
+func isLessThanOrder(x []byte) bool {
+	order := goldilocks.Curve{}.Order()
+	i := len(order) - 1
+	for i > 0 && x[i] == order[i] {
+		i--
+	}
+	return x[paramB-1] == 0 && x[i] < order[i]
+}
+
+func writeDom(h io.Writer, ctx []byte, preHash bool) {
+	dom4 := "SigEd448"
+	_, _ = h.Write([]byte(dom4))
+
+	if preHash {
+		_, _ = h.Write([]byte{byte(0x01), byte(len(ctx))})
+	} else {
+		_, _ = h.Write([]byte{byte(0x00), byte(len(ctx))})
+	}
+	_, _ = h.Write(ctx)
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/ed448/signapi.go b/vendor/github.com/cloudflare/circl/sign/ed448/signapi.go
new file mode 100644
index 00000000..22da8bc0
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/ed448/signapi.go
@@ -0,0 +1,87 @@
+package ed448
+
+import (
+	"crypto/rand"
+	"encoding/asn1"
+
+	"github.com/cloudflare/circl/sign"
+)
+
+var sch sign.Scheme = &scheme{}
+
+// Scheme returns a signature interface.
+func Scheme() sign.Scheme { return sch }
+
+type scheme struct{}
+
+func (*scheme) Name() string          { return "Ed448" }
+func (*scheme) PublicKeySize() int    { return PublicKeySize }
+func (*scheme) PrivateKeySize() int   { return PrivateKeySize }
+func (*scheme) SignatureSize() int    { return SignatureSize }
+func (*scheme) SeedSize() int         { return SeedSize }
+func (*scheme) TLSIdentifier() uint   { return 0x0808 }
+func (*scheme) SupportsContext() bool { return true }
+func (*scheme) Oid() asn1.ObjectIdentifier {
+	return asn1.ObjectIdentifier{1, 3, 101, 113}
+}
+
+func (*scheme) GenerateKey() (sign.PublicKey, sign.PrivateKey, error) {
+	return GenerateKey(rand.Reader)
+}
+
+func (*scheme) Sign(
+	sk sign.PrivateKey,
+	message []byte,
+	opts *sign.SignatureOpts,
+) []byte {
+	priv, ok := sk.(PrivateKey)
+	if !ok {
+		panic(sign.ErrTypeMismatch)
+	}
+	ctx := ""
+	if opts != nil {
+		ctx = opts.Context
+	}
+	return Sign(priv, message, ctx)
+}
+
+func (*scheme) Verify(
+	pk sign.PublicKey,
+	message, signature []byte,
+	opts *sign.SignatureOpts,
+) bool {
+	pub, ok := pk.(PublicKey)
+	if !ok {
+		panic(sign.ErrTypeMismatch)
+	}
+	ctx := ""
+	if opts != nil {
+		ctx = opts.Context
+	}
+	return Verify(pub, message, signature, ctx)
+}
+
+func (*scheme) DeriveKey(seed []byte) (sign.PublicKey, sign.PrivateKey) {
+	privateKey := NewKeyFromSeed(seed)
+	publicKey := make(PublicKey, PublicKeySize)
+	copy(publicKey, privateKey[SeedSize:])
+	return publicKey, privateKey
+}
+
+func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (sign.PublicKey, error) {
+	if len(buf) < PublicKeySize {
+		return nil, sign.ErrPubKeySize
+	}
+	pub := make(PublicKey, PublicKeySize)
+	copy(pub, buf[:PublicKeySize])
+	return pub, nil
+}
+
+func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (sign.PrivateKey, error) {
+	if len(buf) < PrivateKeySize {
+		return nil, sign.ErrPrivKeySize
+	}
+	priv := make(PrivateKey, PrivateKeySize)
+	copy(priv, buf[:PrivateKeySize])
+	return priv, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/eddilithium2/eddilithium.go b/vendor/github.com/cloudflare/circl/sign/eddilithium2/eddilithium.go
new file mode 100644
index 00000000..9ab44019
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/eddilithium2/eddilithium.go
@@ -0,0 +1,239 @@
+// Package eddilithium2 implements the hybrid signature scheme Ed25519-Dilithium2.
+package eddilithium2
+
+import (
+	"crypto"
+	cryptoRand "crypto/rand"
+	"errors"
+	"io"
+
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/sign"
+	"github.com/cloudflare/circl/sign/dilithium/mode2"
+	"github.com/cloudflare/circl/sign/ed25519"
+)
+
+const (
+	// SeedSize is the length of the seed for NewKeyFromSeed
+	SeedSize = mode2.SeedSize // = ed25519.SeedSize = 32
+
+	// PublicKeySize is the length in bytes of the packed public key.
+	PublicKeySize = mode2.PublicKeySize + ed25519.PublicKeySize
+
+	// PrivateKeySize is the length in bytes of the packed public key.
+	PrivateKeySize = mode2.PrivateKeySize + ed25519.SeedSize
+
+	// SignatureSize is the length in bytes of the signatures.
+	SignatureSize = mode2.SignatureSize + ed25519.SignatureSize
+)
+
+// PublicKey is the type of an EdDilithium2 public key.
+type PublicKey struct {
+	e ed25519.PublicKey
+	d mode2.PublicKey
+}
+
+// PrivateKey is the type of an EdDilithium2 private key.
+type PrivateKey struct {
+	e ed25519.PrivateKey
+	d mode2.PrivateKey
+}
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
+	var seed [SeedSize]byte
+	if rand == nil {
+		rand = cryptoRand.Reader
+	}
+	_, err := io.ReadFull(rand, seed[:])
+	if err != nil {
+		return nil, nil, err
+	}
+
+	pk, sk := NewKeyFromSeed(&seed)
+	return pk, sk, nil
+}
+
+// NewKeyFromSeed derives a public/private key pair using the given seed.
+func NewKeyFromSeed(seed *[SeedSize]byte) (*PublicKey, *PrivateKey) {
+	var seed1 [32]byte
+	var seed2 [ed25519.SeedSize]byte
+
+	// Internally, Ed25519 and Dilithium hash the seeds they are passed again
+	// with different hash functions, so it would be safe to use exactly the
+	// same seed for Ed25519 and Dilithium here.  However, in general, when
+	// combining any two signature schemes it might not be the case that this
+	// is safe.  Setting a bad example here isn't worth the tiny gain in
+	// performance.
+
+	h := sha3.NewShake256()
+	_, _ = h.Write(seed[:])
+	_, _ = h.Read(seed1[:])
+	_, _ = h.Read(seed2[:])
+	dpk, dsk := mode2.NewKeyFromSeed(&seed1)
+	esk := ed25519.NewKeyFromSeed(seed2[:])
+
+	return &PublicKey{esk.Public().(ed25519.PublicKey), *dpk}, &PrivateKey{esk, *dsk}
+}
+
+// SignTo signs the given message and writes the signature into signature.
+// It will panic if signature is not of length at least SignatureSize.
+func SignTo(sk *PrivateKey, msg []byte, signature []byte) {
+	mode2.SignTo(
+		&sk.d,
+		msg,
+		signature[:mode2.SignatureSize],
+	)
+	esig := ed25519.Sign(
+		sk.e,
+		msg,
+	)
+	copy(signature[mode2.SignatureSize:], esig[:])
+}
+
+// Verify checks whether the given signature by pk on msg is valid.
+func Verify(pk *PublicKey, msg []byte, signature []byte) bool {
+	if !mode2.Verify(
+		&pk.d,
+		msg,
+		signature[:mode2.SignatureSize],
+	) {
+		return false
+	}
+	if !ed25519.Verify(
+		pk.e,
+		msg,
+		signature[mode2.SignatureSize:],
+	) {
+		return false
+	}
+	return true
+}
+
+// Unpack unpacks pk to the public key encoded in buf.
+func (pk *PublicKey) Unpack(buf *[PublicKeySize]byte) {
+	var tmp [mode2.PublicKeySize]byte
+	copy(tmp[:], buf[:mode2.PublicKeySize])
+	pk.d.Unpack(&tmp)
+	pk.e = make([]byte, ed25519.PublicKeySize)
+	copy(pk.e, buf[mode2.PublicKeySize:])
+}
+
+// Unpack sets sk to the private key encoded in buf.
+func (sk *PrivateKey) Unpack(buf *[PrivateKeySize]byte) {
+	var tmp [mode2.PrivateKeySize]byte
+	copy(tmp[:], buf[:mode2.PrivateKeySize])
+	sk.d.Unpack(&tmp)
+	sk.e = ed25519.NewKeyFromSeed(buf[mode2.PrivateKeySize:])
+}
+
+// Pack packs the public key into buf.
+func (pk *PublicKey) Pack(buf *[PublicKeySize]byte) {
+	var tmp [mode2.PublicKeySize]byte
+	pk.d.Pack(&tmp)
+	copy(buf[:mode2.PublicKeySize], tmp[:])
+	copy(buf[mode2.PublicKeySize:], pk.e)
+}
+
+// Pack packs the private key into buf.
+func (sk *PrivateKey) Pack(buf *[PrivateKeySize]byte) {
+	var tmp [mode2.PrivateKeySize]byte
+	sk.d.Pack(&tmp)
+	copy(buf[:mode2.PrivateKeySize], tmp[:])
+	copy(buf[mode2.PrivateKeySize:], sk.e.Seed())
+}
+
+// Bytes packs the public key.
+func (pk *PublicKey) Bytes() []byte {
+	return append(pk.d.Bytes(), pk.e...)
+}
+
+// Bytes packs the private key.
+func (sk *PrivateKey) Bytes() []byte {
+	return append(sk.d.Bytes(), sk.e.Seed()...)
+}
+
+// MarshalBinary packs the public key.
+func (pk *PublicKey) MarshalBinary() ([]byte, error) {
+	return pk.Bytes(), nil
+}
+
+// MarshalBinary packs the private key.
+func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
+	return sk.Bytes(), nil
+}
+
+// UnmarshalBinary the public key from data.
+func (pk *PublicKey) UnmarshalBinary(data []byte) error {
+	if len(data) != PublicKeySize {
+		return errors.New("packed public key must be of eddilithium2.PublicKeySize bytes")
+	}
+	var buf [PublicKeySize]byte
+	copy(buf[:], data)
+	pk.Unpack(&buf)
+	return nil
+}
+
+// UnmarshalBinary unpacks the private key from data.
+func (sk *PrivateKey) UnmarshalBinary(data []byte) error {
+	if len(data) != PrivateKeySize {
+		return errors.New("packed private key must be of eddilithium2.PrivateKeySize bytes")
+	}
+	var buf [PrivateKeySize]byte
+	copy(buf[:], data)
+	sk.Unpack(&buf)
+	return nil
+}
+
+func (sk *PrivateKey) Scheme() sign.Scheme { return sch }
+func (pk *PublicKey) Scheme() sign.Scheme  { return sch }
+
+func (sk *PrivateKey) Equal(other crypto.PrivateKey) bool {
+	castOther, ok := other.(*PrivateKey)
+	if !ok {
+		return false
+	}
+	return castOther.e.Equal(sk.e) && castOther.d.Equal(&sk.d)
+}
+
+func (pk *PublicKey) Equal(other crypto.PublicKey) bool {
+	castOther, ok := other.(*PublicKey)
+	if !ok {
+		return false
+	}
+	return castOther.e.Equal(pk.e) && castOther.d.Equal(&pk.d)
+}
+
+// Sign signs the given message.
+//
+// opts.HashFunc() must return zero, which can be achieved by passing
+// crypto.Hash(0) for opts.  rand is ignored.  Will only return an error
+// if opts.HashFunc() is non-zero.
+//
+// This function is used to make PrivateKey implement the crypto.Signer
+// interface.  The package-level SignTo function might be more convenient
+// to use.
+func (sk *PrivateKey) Sign(
+	rand io.Reader, msg []byte, opts crypto.SignerOpts,
+) (signature []byte, err error) {
+	var sig [SignatureSize]byte
+
+	if opts.HashFunc() != crypto.Hash(0) {
+		return nil, errors.New("eddilithium2: cannot sign hashed message")
+	}
+
+	SignTo(sk, msg, sig[:])
+	return sig[:], nil
+}
+
+// Public computes the public key corresponding to this private key.
+//
+// Returns a *PublicKey.  The type crypto.PublicKey is used to make
+// PrivateKey implement the crypto.Signer interface.
+func (sk *PrivateKey) Public() crypto.PublicKey {
+	return &PublicKey{
+		sk.e.Public().(ed25519.PublicKey),
+		*sk.d.Public().(*mode2.PublicKey),
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/eddilithium2/signapi.go b/vendor/github.com/cloudflare/circl/sign/eddilithium2/signapi.go
new file mode 100644
index 00000000..0339243e
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/eddilithium2/signapi.go
@@ -0,0 +1,93 @@
+package eddilithium2
+
+import (
+	"crypto/rand"
+	"encoding/asn1"
+
+	"github.com/cloudflare/circl/sign"
+)
+
+var sch sign.Scheme = &scheme{}
+
+// Scheme returns a signature interface.
+func Scheme() sign.Scheme { return sch }
+
+type scheme struct{}
+
+func (*scheme) Name() string          { return "Ed25519-Dilithium2" }
+func (*scheme) PublicKeySize() int    { return PublicKeySize }
+func (*scheme) PrivateKeySize() int   { return PrivateKeySize }
+func (*scheme) SignatureSize() int    { return SignatureSize }
+func (*scheme) SeedSize() int         { return SeedSize }
+func (*scheme) TLSIdentifier() uint   { return 0xfe61 /* temp*/ }
+func (*scheme) SupportsContext() bool { return false }
+func (*scheme) Oid() asn1.ObjectIdentifier {
+	return asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 44363, 45, 9}
+}
+
+func (*scheme) GenerateKey() (sign.PublicKey, sign.PrivateKey, error) {
+	return GenerateKey(rand.Reader)
+}
+
+func (*scheme) Sign(
+	sk sign.PrivateKey,
+	message []byte,
+	opts *sign.SignatureOpts,
+) []byte {
+	priv, ok := sk.(*PrivateKey)
+	if !ok {
+		panic(sign.ErrTypeMismatch)
+	}
+	if opts != nil && opts.Context != "" {
+		panic(sign.ErrContextNotSupported)
+	}
+	var sig [SignatureSize]byte
+	SignTo(priv, message, sig[:])
+	return sig[:]
+}
+
+func (*scheme) Verify(
+	pk sign.PublicKey,
+	message, signature []byte,
+	opts *sign.SignatureOpts,
+) bool {
+	pub, ok := pk.(*PublicKey)
+	if !ok {
+		panic(sign.ErrTypeMismatch)
+	}
+	if opts != nil && opts.Context != "" {
+		panic(sign.ErrContextNotSupported)
+	}
+	return Verify(pub, message, signature)
+}
+
+func (*scheme) DeriveKey(seed []byte) (sign.PublicKey, sign.PrivateKey) {
+	if len(seed) != SeedSize {
+		panic(sign.ErrSeedSize)
+	}
+	var tmp [SeedSize]byte
+	copy(tmp[:], seed)
+	return NewKeyFromSeed(&tmp)
+}
+
+func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (sign.PublicKey, error) {
+	if len(buf) != PublicKeySize {
+		return nil, sign.ErrPubKeySize
+	}
+	var tmp [PublicKeySize]byte
+	copy(tmp[:], buf)
+	var ret PublicKey
+	ret.Unpack(&tmp)
+	return &ret, nil
+}
+
+func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (sign.PrivateKey, error) {
+	if len(buf) != PrivateKeySize {
+		return nil, sign.ErrPrivKeySize
+	}
+	var tmp [PrivateKeySize]byte
+	copy(tmp[:], buf)
+	var ret PrivateKey
+	ret.Unpack(&tmp)
+	return &ret, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/eddilithium3/eddilithium.go b/vendor/github.com/cloudflare/circl/sign/eddilithium3/eddilithium.go
new file mode 100644
index 00000000..d1c8d629
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/eddilithium3/eddilithium.go
@@ -0,0 +1,234 @@
+// Package eddilithium3 implements the hybrid signature scheme Ed448-Dilithium3.
+package eddilithium3
+
+import (
+	"crypto"
+	cryptoRand "crypto/rand"
+	"errors"
+	"io"
+
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/sign"
+	"github.com/cloudflare/circl/sign/dilithium/mode3"
+	"github.com/cloudflare/circl/sign/ed448"
+)
+
+const (
+	// SeedSize is the length of the seed for NewKeyFromSeed
+	SeedSize = ed448.SeedSize // > mode3.SeedSize
+
+	// PublicKeySize is the length in bytes of the packed public key.
+	PublicKeySize = mode3.PublicKeySize + ed448.PublicKeySize
+
+	// PrivateKeySize is the length in bytes of the packed public key.
+	PrivateKeySize = mode3.PrivateKeySize + ed448.SeedSize
+
+	// SignatureSize is the length in bytes of the signatures.
+	SignatureSize = mode3.SignatureSize + ed448.SignatureSize
+)
+
+// PublicKey is the type of an EdDilithium3 public key.
+type PublicKey struct {
+	e ed448.PublicKey
+	d mode3.PublicKey
+}
+
+// PrivateKey is the type of an EdDilithium3 private key.
+type PrivateKey struct {
+	e ed448.PrivateKey
+	d mode3.PrivateKey
+}
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, crypto/rand.Reader will be used.
+func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
+	var seed [SeedSize]byte
+	if rand == nil {
+		rand = cryptoRand.Reader
+	}
+	_, err := io.ReadFull(rand, seed[:])
+	if err != nil {
+		return nil, nil, err
+	}
+
+	pk, sk := NewKeyFromSeed(&seed)
+	return pk, sk, nil
+}
+
+// NewKeyFromSeed derives a public/private key pair using the given seed.
+func NewKeyFromSeed(seed *[SeedSize]byte) (*PublicKey, *PrivateKey) {
+	var seed1 [32]byte
+	var seed2 [ed448.SeedSize]byte
+
+	h := sha3.NewShake256()
+	_, _ = h.Write(seed[:])
+	_, _ = h.Read(seed1[:])
+	_, _ = h.Read(seed2[:])
+	dpk, dsk := mode3.NewKeyFromSeed(&seed1)
+	esk := ed448.NewKeyFromSeed(seed2[:])
+
+	return &PublicKey{esk.Public().(ed448.PublicKey), *dpk}, &PrivateKey{esk, *dsk}
+}
+
+// SignTo signs the given message and writes the signature into signature.
+// It will panic if signature is not of length at least SignatureSize.
+func SignTo(sk *PrivateKey, msg []byte, signature []byte) {
+	mode3.SignTo(
+		&sk.d,
+		msg,
+		signature[:mode3.SignatureSize],
+	)
+	esig := ed448.Sign(
+		sk.e,
+		msg,
+		"",
+	)
+	copy(signature[mode3.SignatureSize:], esig[:])
+}
+
+// Verify checks whether the given signature by pk on msg is valid.
+func Verify(pk *PublicKey, msg []byte, signature []byte) bool {
+	if !mode3.Verify(
+		&pk.d,
+		msg,
+		signature[:mode3.SignatureSize],
+	) {
+		return false
+	}
+	if !ed448.Verify(
+		pk.e,
+		msg,
+		signature[mode3.SignatureSize:],
+		"",
+	) {
+		return false
+	}
+	return true
+}
+
+// Unpack unpacks pk to the public key encoded in buf.
+func (pk *PublicKey) Unpack(buf *[PublicKeySize]byte) {
+	var tmp [mode3.PublicKeySize]byte
+	copy(tmp[:], buf[:mode3.PublicKeySize])
+	pk.d.Unpack(&tmp)
+	pk.e = make([]byte, ed448.PublicKeySize)
+	copy(pk.e, buf[mode3.PublicKeySize:])
+}
+
+// Unpack sets sk to the private key encoded in buf.
+func (sk *PrivateKey) Unpack(buf *[PrivateKeySize]byte) {
+	var tmp [mode3.PrivateKeySize]byte
+	copy(tmp[:], buf[:mode3.PrivateKeySize])
+	sk.d.Unpack(&tmp)
+	sk.e = ed448.NewKeyFromSeed(buf[mode3.PrivateKeySize:])
+}
+
+// Pack packs the public key into buf.
+func (pk *PublicKey) Pack(buf *[PublicKeySize]byte) {
+	var tmp [mode3.PublicKeySize]byte
+	pk.d.Pack(&tmp)
+	copy(buf[:mode3.PublicKeySize], tmp[:])
+	copy(buf[mode3.PublicKeySize:], pk.e)
+}
+
+// Pack packs the private key into buf.
+func (sk *PrivateKey) Pack(buf *[PrivateKeySize]byte) {
+	var tmp [mode3.PrivateKeySize]byte
+	sk.d.Pack(&tmp)
+	copy(buf[:mode3.PrivateKeySize], tmp[:])
+	copy(buf[mode3.PrivateKeySize:], sk.e.Seed())
+}
+
+// Bytes packs the public key.
+func (pk *PublicKey) Bytes() []byte {
+	return append(pk.d.Bytes(), pk.e...)
+}
+
+// Bytes packs the private key.
+func (sk *PrivateKey) Bytes() []byte {
+	return append(sk.d.Bytes(), sk.e.Seed()...)
+}
+
+// MarshalBinary packs the public key.
+func (pk *PublicKey) MarshalBinary() ([]byte, error) {
+	return pk.Bytes(), nil
+}
+
+// MarshalBinary packs the private key.
+func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
+	return sk.Bytes(), nil
+}
+
+// UnmarshalBinary the public key from data.
+func (pk *PublicKey) UnmarshalBinary(data []byte) error {
+	if len(data) != PublicKeySize {
+		return errors.New("packed public key must be of eddilithium4.PublicKeySize bytes")
+	}
+	var buf [PublicKeySize]byte
+	copy(buf[:], data)
+	pk.Unpack(&buf)
+	return nil
+}
+
+// UnmarshalBinary unpacks the private key from data.
+func (sk *PrivateKey) UnmarshalBinary(data []byte) error {
+	if len(data) != PrivateKeySize {
+		return errors.New("packed private key must be of eddilithium4.PrivateKeySize bytes")
+	}
+	var buf [PrivateKeySize]byte
+	copy(buf[:], data)
+	sk.Unpack(&buf)
+	return nil
+}
+
+func (sk *PrivateKey) Scheme() sign.Scheme { return sch }
+func (pk *PublicKey) Scheme() sign.Scheme  { return sch }
+
+func (sk *PrivateKey) Equal(other crypto.PrivateKey) bool {
+	castOther, ok := other.(*PrivateKey)
+	if !ok {
+		return false
+	}
+	return castOther.e.Equal(sk.e) && castOther.d.Equal(&sk.d)
+}
+
+func (pk *PublicKey) Equal(other crypto.PublicKey) bool {
+	castOther, ok := other.(*PublicKey)
+	if !ok {
+		return false
+	}
+	return castOther.e.Equal(pk.e) && castOther.d.Equal(&pk.d)
+}
+
+// Sign signs the given message.
+//
+// opts.HashFunc() must return zero, which can be achieved by passing
+// crypto.Hash(0) for opts.  rand is ignored.  Will only return an error
+// if opts.HashFunc() is non-zero.
+//
+// This function is used to make PrivateKey implement the crypto.Signer
+// interface.  The package-level SignTo function might be more convenient
+// to use.
+func (sk *PrivateKey) Sign(
+	rand io.Reader, msg []byte, opts crypto.SignerOpts,
+) (signature []byte, err error) {
+	var sig [SignatureSize]byte
+
+	if opts.HashFunc() != crypto.Hash(0) {
+		return nil, errors.New("eddilithium4: cannot sign hashed message")
+	}
+
+	SignTo(sk, msg, sig[:])
+	return sig[:], nil
+}
+
+// Public computes the public key corresponding to this private key.
+//
+// Returns a *PublicKey.  The type crypto.PublicKey is used to make
+// PrivateKey implement the crypto.Signer interface.
+func (sk *PrivateKey) Public() crypto.PublicKey {
+	return &PublicKey{
+		sk.e.Public().(ed448.PublicKey),
+		*sk.d.Public().(*mode3.PublicKey),
+	}
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/eddilithium3/signapi.go b/vendor/github.com/cloudflare/circl/sign/eddilithium3/signapi.go
new file mode 100644
index 00000000..1c345cfb
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/eddilithium3/signapi.go
@@ -0,0 +1,93 @@
+package eddilithium3
+
+import (
+	"crypto/rand"
+	"encoding/asn1"
+
+	"github.com/cloudflare/circl/sign"
+)
+
+var sch sign.Scheme = &scheme{}
+
+// Scheme returns a signature interface.
+func Scheme() sign.Scheme { return sch }
+
+type scheme struct{}
+
+func (*scheme) Name() string          { return "Ed448-Dilithium3" }
+func (*scheme) PublicKeySize() int    { return PublicKeySize }
+func (*scheme) PrivateKeySize() int   { return PrivateKeySize }
+func (*scheme) SignatureSize() int    { return SignatureSize }
+func (*scheme) SeedSize() int         { return SeedSize }
+func (*scheme) TLSIdentifier() uint   { return 0xfe62 /* temp */ }
+func (*scheme) SupportsContext() bool { return false }
+func (*scheme) Oid() asn1.ObjectIdentifier {
+	return asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 44363, 45, 10}
+}
+
+func (*scheme) GenerateKey() (sign.PublicKey, sign.PrivateKey, error) {
+	return GenerateKey(rand.Reader)
+}
+
+func (*scheme) Sign(
+	sk sign.PrivateKey,
+	message []byte,
+	opts *sign.SignatureOpts,
+) []byte {
+	priv, ok := sk.(*PrivateKey)
+	if !ok {
+		panic(sign.ErrTypeMismatch)
+	}
+	if opts != nil && opts.Context != "" {
+		panic(sign.ErrContextNotSupported)
+	}
+	var sig [SignatureSize]byte
+	SignTo(priv, message, sig[:])
+	return sig[:]
+}
+
+func (*scheme) Verify(
+	pk sign.PublicKey,
+	message, signature []byte,
+	opts *sign.SignatureOpts,
+) bool {
+	pub, ok := pk.(*PublicKey)
+	if !ok {
+		panic(sign.ErrTypeMismatch)
+	}
+	if opts != nil && opts.Context != "" {
+		panic(sign.ErrContextNotSupported)
+	}
+	return Verify(pub, message, signature)
+}
+
+func (*scheme) DeriveKey(seed []byte) (sign.PublicKey, sign.PrivateKey) {
+	if len(seed) != SeedSize {
+		panic(sign.ErrSeedSize)
+	}
+	var tmp [SeedSize]byte
+	copy(tmp[:], seed)
+	return NewKeyFromSeed(&tmp)
+}
+
+func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (sign.PublicKey, error) {
+	if len(buf) != PublicKeySize {
+		return nil, sign.ErrPubKeySize
+	}
+	var tmp [PublicKeySize]byte
+	copy(tmp[:], buf)
+	var ret PublicKey
+	ret.Unpack(&tmp)
+	return &ret, nil
+}
+
+func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (sign.PrivateKey, error) {
+	if len(buf) != PrivateKeySize {
+		return nil, sign.ErrPrivKeySize
+	}
+	var tmp [PrivateKeySize]byte
+	copy(tmp[:], buf)
+	var ret PrivateKey
+	ret.Unpack(&tmp)
+	return &ret, nil
+}
diff --git a/vendor/github.com/cloudflare/circl/sign/schemes/schemes.go b/vendor/github.com/cloudflare/circl/sign/schemes/schemes.go
new file mode 100644
index 00000000..66ee6125
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/schemes/schemes.go
@@ -0,0 +1,46 @@
+// Package schemes contains a register of signature algorithms.
+//
+// Implemented schemes:
+//
+//	Ed25519
+//	Ed448
+//	Ed25519-Dilithium2
+//	Ed448-Dilithium3
+package schemes
+
+import (
+	"strings"
+
+	"github.com/cloudflare/circl/sign"
+	"github.com/cloudflare/circl/sign/ed25519"
+	"github.com/cloudflare/circl/sign/ed448"
+	"github.com/cloudflare/circl/sign/eddilithium2"
+	"github.com/cloudflare/circl/sign/eddilithium3"
+)
+
+var allSchemes = [...]sign.Scheme{
+	ed25519.Scheme(),
+	ed448.Scheme(),
+	eddilithium2.Scheme(),
+	eddilithium3.Scheme(),
+}
+
+var allSchemeNames map[string]sign.Scheme
+
+func init() {
+	allSchemeNames = make(map[string]sign.Scheme)
+	for _, scheme := range allSchemes {
+		allSchemeNames[strings.ToLower(scheme.Name())] = scheme
+	}
+}
+
+// ByName returns the scheme with the given name and nil if it is not
+// supported.
+//
+// Names are case insensitive.
+func ByName(name string) sign.Scheme {
+	return allSchemeNames[strings.ToLower(name)]
+}
+
+// All returns all signature schemes supported.
+func All() []sign.Scheme { a := allSchemes; return a[:] }
diff --git a/vendor/github.com/cloudflare/circl/sign/sign.go b/vendor/github.com/cloudflare/circl/sign/sign.go
new file mode 100644
index 00000000..13b20fa4
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/sign/sign.go
@@ -0,0 +1,110 @@
+// Package sign provides unified interfaces for signature schemes.
+//
+// A register of schemes is available in the package
+//
+//	github.com/cloudflare/circl/sign/schemes
+package sign
+
+import (
+	"crypto"
+	"encoding"
+	"errors"
+)
+
+type SignatureOpts struct {
+	// If non-empty, includes the given context in the signature if supported
+	// and will cause an error during signing otherwise.
+	Context string
+}
+
+// A public key is used to verify a signature set by the corresponding private
+// key.
+type PublicKey interface {
+	// Returns the signature scheme for this public key.
+	Scheme() Scheme
+	Equal(crypto.PublicKey) bool
+	encoding.BinaryMarshaler
+	crypto.PublicKey
+}
+
+// A private key allows one to create signatures.
+type PrivateKey interface {
+	// Returns the signature scheme for this private key.
+	Scheme() Scheme
+	Equal(crypto.PrivateKey) bool
+	// For compatibility with Go standard library
+	crypto.Signer
+	crypto.PrivateKey
+	encoding.BinaryMarshaler
+}
+
+// A Scheme represents a specific instance of a signature scheme.
+type Scheme interface {
+	// Name of the scheme.
+	Name() string
+
+	// GenerateKey creates a new key-pair.
+	GenerateKey() (PublicKey, PrivateKey, error)
+
+	// Creates a signature using the PrivateKey on the given message and
+	// returns the signature. opts are additional options which can be nil.
+	//
+	// Panics if key is nil or wrong type or opts context is not supported.
+	Sign(sk PrivateKey, message []byte, opts *SignatureOpts) []byte
+
+	// Checks whether the given signature is a valid signature set by
+	// the private key corresponding to the given public key on the
+	// given message. opts are additional options which can be nil.
+	//
+	// Panics if key is nil or wrong type or opts context is not supported.
+	Verify(pk PublicKey, message []byte, signature []byte, opts *SignatureOpts) bool
+
+	// Deterministically derives a keypair from a seed. If you're unsure,
+	// you're better off using GenerateKey().
+	//
+	// Panics if seed is not of length SeedSize().
+	DeriveKey(seed []byte) (PublicKey, PrivateKey)
+
+	// Unmarshals a PublicKey from the provided buffer.
+	UnmarshalBinaryPublicKey([]byte) (PublicKey, error)
+
+	// Unmarshals a PublicKey from the provided buffer.
+	UnmarshalBinaryPrivateKey([]byte) (PrivateKey, error)
+
+	// Size of binary marshalled public keys.
+	PublicKeySize() int
+
+	// Size of binary marshalled public keys.
+	PrivateKeySize() int
+
+	// Size of signatures.
+	SignatureSize() int
+
+	// Size of seeds.
+	SeedSize() int
+
+	// Returns whether contexts are supported.
+	SupportsContext() bool
+}
+
+var (
+	// ErrTypeMismatch is the error used if types of, for instance, private
+	// and public keys don't match.
+	ErrTypeMismatch = errors.New("types mismatch")
+
+	// ErrSeedSize is the error used if the provided seed is of the wrong
+	// size.
+	ErrSeedSize = errors.New("wrong seed size")
+
+	// ErrPubKeySize is the error used if the provided public key is of
+	// the wrong size.
+	ErrPubKeySize = errors.New("wrong size for public key")
+
+	// ErrPrivKeySize is the error used if the provided private key is of
+	// the wrong size.
+	ErrPrivKeySize = errors.New("wrong size for private key")
+
+	// ErrContextNotSupported is the error used if a context is not
+	// supported.
+	ErrContextNotSupported = errors.New("context not supported")
+)
diff --git a/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x.go b/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x.go
new file mode 100644
index 00000000..20ac96f0
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x.go
@@ -0,0 +1,163 @@
+// Package keccakf1600 provides a two and four-way Keccak-f[1600] permutation in parallel.
+//
+// Keccak-f[1600] is the permutation underlying several algorithms such as
+// Keccak, SHA3 and SHAKE. Running two or four permutations in parallel is
+// useful in some scenarios like in hash-based signatures.
+//
+// # Limitations
+//
+// Note that not all the architectures support SIMD instructions. This package
+// uses AVX2 instructions that are available in some AMD64 architectures
+// and  NEON instructions that are available in some ARM64 architectures.
+//
+// For those systems not supporting these, the package still provides the
+// expected functionality by means of a generic and slow implementation.
+// The recommendation is to beforehand verify IsEnabledX4() and IsEnabledX2()
+// to determine if the current system supports the SIMD implementation.
+package keccakf1600
+
+import (
+	"runtime"
+	"unsafe"
+
+	"github.com/cloudflare/circl/internal/sha3"
+	"golang.org/x/sys/cpu"
+)
+
+// StateX4 contains state for the four-way permutation including the four
+// interleaved [25]uint64 buffers. Call Initialize() before use to initialize
+// and get a pointer to the interleaved buffer.
+type StateX4 struct {
+	// Go guarantees a to be aligned on 8 bytes, whereas we need it to be
+	// aligned on 32 bytes for bet performance.  Thus we leave some headroom
+	// to be able to move the start of the state.
+
+	// 4 x 25 uint64s for the interleaved states and three uint64s headroom
+	// to fix alignment.
+	a [103]uint64
+
+	// Offset into a that is 32 byte aligned.
+	offset int
+
+	// If true, permute will use 12-round keccak instead of 24-round keccak
+	turbo bool
+}
+
+// StateX2 contains state for the two-way permutation including the two
+// interleaved [25]uint64 buffers. Call Initialize() before use to initialize
+// and get a pointer to the interleaved buffer.
+type StateX2 struct {
+	// Go guarantees a to be aligned on 8 bytes, whereas we need it to be
+	// aligned on 32 bytes for bet performance.  Thus we leave some headroom
+	// to be able to move the start of the state.
+
+	// 2 x 25 uint64s for the interleaved states and three uint64s headroom
+	// to fix alignment.
+	a [53]uint64
+
+	// Offset into a that is 32 byte aligned.
+	offset int
+
+	// If true, permute will use 12-round keccak instead of 24-round keccak
+	turbo bool
+}
+
+// IsEnabledX4 returns true if the architecture supports a four-way SIMD
+// implementation provided in this package.
+func IsEnabledX4() bool { return cpu.X86.HasAVX2 }
+
+// IsEnabledX2 returns true if the architecture supports a two-way SIMD
+// implementation provided in this package.
+func IsEnabledX2() bool { return enabledX2 }
+
+// Initialize the state and returns the buffer on which the four permutations
+// will act: a uint64 slice of length 100.  The first permutation will act
+// on {a[0], a[4], ..., a[96]}, the second on {a[1], a[5], ..., a[97]}, etc.
+// If turbo is true, applies 12-round variant instead of the usual 24.
+func (s *StateX4) Initialize(turbo bool) []uint64 {
+	s.turbo = turbo
+	rp := unsafe.Pointer(&s.a[0])
+
+	// uint64s are always aligned by a multiple of 8.  Compute the remainder
+	// of the address modulo 32 divided by 8.
+	rem := (int(uintptr(rp)&31) >> 3)
+
+	if rem != 0 {
+		s.offset = 4 - rem
+	}
+
+	// The slice we return will be aligned on 32 byte boundary.
+	return s.a[s.offset : s.offset+100]
+}
+
+// Initialize the state and returns the buffer on which the two permutations
+// will act: a uint64 slice of length 50.  The first permutation will act
+// on {a[0], a[2], ..., a[48]} and the second on {a[1], a[3], ..., a[49]}.
+// If turbo is true, applies 12-round variant instead of the usual 24.
+func (s *StateX2) Initialize(turbo bool) []uint64 {
+	s.turbo = turbo
+	rp := unsafe.Pointer(&s.a[0])
+
+	// uint64s are always aligned by a multiple of 8.  Compute the remainder
+	// of the address modulo 32 divided by 8.
+	rem := (int(uintptr(rp)&31) >> 3)
+
+	if rem != 0 {
+		s.offset = 4 - rem
+	}
+
+	// The slice we return will be aligned on 32 byte boundary.
+	return s.a[s.offset : s.offset+50]
+}
+
+// Permute performs the four parallel Keccak-f[1600]s interleaved on the slice
+// returned from Initialize().
+func (s *StateX4) Permute() {
+	if IsEnabledX4() {
+		permuteSIMDx4(s.a[s.offset:], s.turbo)
+	} else {
+		permuteScalarX4(s.a[s.offset:], s.turbo) // A slower generic implementation.
+	}
+}
+
+// Permute performs the two parallel Keccak-f[1600]s interleaved on the slice
+// returned from Initialize().
+func (s *StateX2) Permute() {
+	if IsEnabledX2() {
+		permuteSIMDx2(s.a[s.offset:], s.turbo)
+	} else {
+		permuteScalarX2(s.a[s.offset:], s.turbo) // A slower generic implementation.
+	}
+}
+
+func permuteScalarX4(a []uint64, turbo bool) {
+	var buf [25]uint64
+	for i := 0; i < 4; i++ {
+		for j := 0; j < 25; j++ {
+			buf[j] = a[4*j+i]
+		}
+		sha3.KeccakF1600(&buf, turbo)
+		for j := 0; j < 25; j++ {
+			a[4*j+i] = buf[j]
+		}
+	}
+}
+
+func permuteScalarX2(a []uint64, turbo bool) {
+	var buf [25]uint64
+	for i := 0; i < 2; i++ {
+		for j := 0; j < 25; j++ {
+			buf[j] = a[2*j+i]
+		}
+		sha3.KeccakF1600(&buf, turbo)
+		for j := 0; j < 25; j++ {
+			a[2*j+i] = buf[j]
+		}
+	}
+}
+
+var enabledX2 bool
+
+func init() {
+	enabledX2 = runtime.GOARCH == "arm64" && runtime.GOOS == "darwin"
+}
diff --git a/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.go b/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.go
new file mode 100644
index 00000000..0cb9692c
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.go
@@ -0,0 +1,13 @@
+//go:build arm64 && go1.16 && !purego
+// +build arm64,go1.16,!purego
+
+package keccakf1600
+
+import "github.com/cloudflare/circl/internal/sha3"
+
+func permuteSIMDx2(state []uint64, turbo bool) { f1600x2ARM(&state[0], &sha3.RC, turbo) }
+
+func permuteSIMDx4(state []uint64, turbo bool) { permuteScalarX4(state, turbo) }
+
+//go:noescape
+func f1600x2ARM(state *uint64, rc *[24]uint64, turbo bool)
diff --git a/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.s b/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.s
new file mode 100644
index 00000000..998aeca5
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x2_arm64.s
@@ -0,0 +1,136 @@
+// +build arm64,go1.16,!purego
+
+// Taken from https://github.com/bwesterb/armed-keccak
+
+#include "textflag.h"
+
+// func f1600x2ARM(state *uint64, rc *[24]uint64, turbo bool)
+TEXT ·f1600x2ARM(SB), NOSPLIT, $0-17
+    MOVD state+0(FP), R0
+    MOVD rc+8(FP), R1
+    MOVD R0, R2
+    MOVD $24, R3
+
+    VLD1.P 64(R0), [ V0.B16,  V1.B16,  V2.B16,  V3.B16]
+    VLD1.P 64(R0), [ V4.B16,  V5.B16,  V6.B16,  V7.B16]
+    VLD1.P 64(R0), [ V8.B16,  V9.B16, V10.B16, V11.B16]
+    VLD1.P 64(R0), [V12.B16, V13.B16, V14.B16, V15.B16]
+    VLD1.P 64(R0), [V16.B16, V17.B16, V18.B16, V19.B16]
+    VLD1.P 64(R0), [V20.B16, V21.B16, V22.B16, V23.B16]
+    VLD1.P (R0),   [V24.B16]
+
+    MOVBU turbo+16(FP), R4
+    CBZ R4, loop
+
+    SUB  $12, R3, R3
+    ADD  $96, R1, R1
+
+loop:
+    // Execute theta but without xorring into the state yet.
+    VEOR3 V10.B16, V5.B16, V0.B16, V25.B16
+    VEOR3 V11.B16, V6.B16, V1.B16, V26.B16
+    VEOR3 V12.B16, V7.B16, V2.B16, V27.B16
+    VEOR3 V13.B16, V8.B16, V3.B16, V28.B16
+    VEOR3 V14.B16, V9.B16, V4.B16, V29.B16
+
+    VEOR3 V20.B16, V15.B16, V25.B16, V25.B16
+    VEOR3 V21.B16, V16.B16, V26.B16, V26.B16
+    VEOR3 V22.B16, V17.B16, V27.B16, V27.B16
+    VEOR3 V23.B16, V18.B16, V28.B16, V28.B16
+    VEOR3 V24.B16, V19.B16, V29.B16, V29.B16
+
+    // Xor parities from step theta into the state at the same time as
+    // exeuting rho and pi.   
+    VRAX1 V26.D2, V29.D2, V30.D2
+    VRAX1 V29.D2, V27.D2, V29.D2
+    VRAX1 V27.D2, V25.D2, V27.D2
+    VRAX1 V25.D2, V28.D2, V25.D2
+    VRAX1 V28.D2, V26.D2, V28.D2
+
+    VEOR V30.B16, V0.B16, V0.B16
+    VMOV V1.B16, V31.B16
+
+    VXAR $20, V27.D2,  V6.D2,  V1.D2   
+    VXAR $44, V25.D2,  V9.D2,  V6.D2   
+    VXAR $3 , V28.D2, V22.D2,  V9.D2   
+    VXAR $25, V25.D2, V14.D2, V22.D2  
+    VXAR $46, V30.D2, V20.D2, V14.D2  
+    VXAR $2 , V28.D2,  V2.D2, V20.D2  
+    VXAR $21, V28.D2, V12.D2,  V2.D2  
+    VXAR $39, V29.D2, V13.D2, V12.D2  
+    VXAR $56, V25.D2, V19.D2, V13.D2  
+    VXAR $8 , V29.D2, V23.D2, V19.D2  
+    VXAR $23, V30.D2, V15.D2, V23.D2  
+    VXAR $37, V25.D2,  V4.D2, V15.D2  
+    VXAR $50, V25.D2, V24.D2,  V4.D2   
+    VXAR $62, V27.D2, V21.D2, V24.D2  
+    VXAR $9 , V29.D2,  V8.D2, V21.D2  
+    VXAR $19, V27.D2, V16.D2,  V8.D2   
+    VXAR $28, V30.D2,  V5.D2, V16.D2  
+    VXAR $36, V29.D2,  V3.D2,  V5.D2   
+    VXAR $43, V29.D2, V18.D2,  V3.D2   
+    VXAR $49, V28.D2, V17.D2, V18.D2  
+    VXAR $54, V27.D2, V11.D2, V17.D2  
+    VXAR $58, V28.D2,  V7.D2, V11.D2  
+    VXAR $61, V30.D2, V10.D2,  V7.D2   
+    VXAR $63, V27.D2, V31.D2, V10.D2  
+
+    // Chi
+    VBCAX V1.B16, V2.B16, V0.B16, V25.B16
+    VBCAX V2.B16, V3.B16, V1.B16, V26.B16
+    VBCAX V3.B16, V4.B16, V2.B16,  V2.B16
+    VBCAX V4.B16, V0.B16, V3.B16,  V3.B16
+    VBCAX V0.B16, V1.B16, V4.B16,  V4.B16
+    VMOV V25.B16, V0.B16
+    VMOV V26.B16, V1.B16
+
+    VBCAX V6.B16, V7.B16, V5.B16, V25.B16
+    VBCAX V7.B16, V8.B16, V6.B16, V26.B16
+    VBCAX V8.B16, V9.B16, V7.B16,  V7.B16
+    VBCAX V9.B16, V5.B16, V8.B16,  V8.B16
+    VBCAX V5.B16, V6.B16, V9.B16,  V9.B16
+    VMOV V25.B16, V5.B16
+    VMOV V26.B16, V6.B16
+
+    VBCAX V11.B16, V12.B16, V10.B16, V25.B16
+    VBCAX V12.B16, V13.B16, V11.B16, V26.B16
+    VBCAX V13.B16, V14.B16, V12.B16, V12.B16
+    VBCAX V14.B16, V10.B16, V13.B16, V13.B16
+    VBCAX V10.B16, V11.B16, V14.B16, V14.B16
+    VMOV V25.B16, V10.B16
+    VMOV V26.B16, V11.B16
+
+    VBCAX V16.B16, V17.B16, V15.B16, V25.B16
+    VBCAX V17.B16, V18.B16, V16.B16, V26.B16
+    VBCAX V18.B16, V19.B16, V17.B16, V17.B16
+    VBCAX V19.B16, V15.B16, V18.B16, V18.B16
+    VBCAX V15.B16, V16.B16, V19.B16, V19.B16
+    VMOV V25.B16, V15.B16
+    VMOV V26.B16, V16.B16
+
+    VBCAX V21.B16, V22.B16, V20.B16, V25.B16
+    VBCAX V22.B16, V23.B16, V21.B16, V26.B16
+    VBCAX V23.B16, V24.B16, V22.B16, V22.B16
+    VBCAX V24.B16, V20.B16, V23.B16, V23.B16
+    VBCAX V20.B16, V21.B16, V24.B16, V24.B16
+    VMOV V25.B16, V20.B16
+    VMOV V26.B16, V21.B16
+
+    // Iota
+    VLD1R.P 8(R1), [V25.D2]
+    VEOR V25.B16, V0.B16, V0.B16
+
+    SUBS $1, R3, R3
+    CBNZ R3, loop
+
+    MOVD R2, R0
+
+    VST1.P [ V0.B16,  V1.B16,  V2.B16,  V3.B16], 64(R0) 
+    VST1.P [ V4.B16,  V5.B16,  V6.B16,  V7.B16], 64(R0)
+    VST1.P [ V8.B16,  V9.B16, V10.B16, V11.B16], 64(R0)
+    VST1.P [V12.B16, V13.B16, V14.B16, V15.B16], 64(R0)
+    VST1.P [V16.B16, V17.B16, V18.B16, V19.B16], 64(R0)
+    VST1.P [V20.B16, V21.B16, V22.B16, V23.B16], 64(R0)
+    VST1.P [V24.B16], (R0)
+
+    RET
diff --git a/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.go b/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.go
new file mode 100644
index 00000000..bf5b865d
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.go
@@ -0,0 +1,10 @@
+//go:build amd64 && !purego
+// +build amd64,!purego
+
+package keccakf1600
+
+import "github.com/cloudflare/circl/internal/sha3"
+
+func permuteSIMDx4(state []uint64, turbo bool) { f1600x4AVX2(&state[0], &sha3.RC, turbo) }
+
+func permuteSIMDx2(state []uint64, turbo bool) { permuteScalarX2(state, turbo) }
diff --git a/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.s b/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.s
new file mode 100644
index 00000000..67b64550
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4_amd64.s
@@ -0,0 +1,899 @@
+// Code generated by command: go run src.go -out ../../f1600x4_amd64.s -stubs ../../f1600x4stubs_amd64.go -pkg keccakf1600. DO NOT EDIT.
+
+//go:build amd64 && !purego
+
+#include "textflag.h"
+
+// func f1600x4AVX2(state *uint64, rc *[24]uint64, turbo bool)
+// Requires: AVX, AVX2
+TEXT ·f1600x4AVX2(SB), NOSPLIT, $0-17
+	MOVQ    state+0(FP), AX
+	MOVQ    rc+8(FP), CX
+	MOVQ    $0x0000000000000006, DX
+	MOVBQZX turbo+16(FP), BX
+	TESTQ   BX, BX
+	JZ      loop
+	MOVQ    $0x0000000000000003, DX
+	ADDQ    $0x60, CX
+
+loop:
+	VMOVDQA      (AX), Y0
+	VMOVDQA      32(AX), Y1
+	VMOVDQA      64(AX), Y2
+	VMOVDQA      96(AX), Y3
+	VMOVDQA      128(AX), Y4
+	VPXOR        160(AX), Y0, Y0
+	VPXOR        192(AX), Y1, Y1
+	VPXOR        224(AX), Y2, Y2
+	VPXOR        256(AX), Y3, Y3
+	VPXOR        288(AX), Y4, Y4
+	VPXOR        320(AX), Y0, Y0
+	VPXOR        352(AX), Y1, Y1
+	VPXOR        384(AX), Y2, Y2
+	VPXOR        416(AX), Y3, Y3
+	VPXOR        448(AX), Y4, Y4
+	VPXOR        480(AX), Y0, Y0
+	VPXOR        512(AX), Y1, Y1
+	VPXOR        544(AX), Y2, Y2
+	VPXOR        576(AX), Y3, Y3
+	VPXOR        608(AX), Y4, Y4
+	VPXOR        640(AX), Y0, Y0
+	VPXOR        672(AX), Y1, Y1
+	VPXOR        704(AX), Y2, Y2
+	VPXOR        736(AX), Y3, Y3
+	VPXOR        768(AX), Y4, Y4
+	VPSLLQ       $0x01, Y1, Y5
+	VPSLLQ       $0x01, Y2, Y6
+	VPSLLQ       $0x01, Y3, Y7
+	VPSLLQ       $0x01, Y4, Y8
+	VPSLLQ       $0x01, Y0, Y9
+	VPSRLQ       $0x3f, Y1, Y10
+	VPSRLQ       $0x3f, Y2, Y11
+	VPSRLQ       $0x3f, Y3, Y12
+	VPSRLQ       $0x3f, Y4, Y13
+	VPSRLQ       $0x3f, Y0, Y14
+	VPOR         Y5, Y10, Y10
+	VPOR         Y6, Y11, Y11
+	VPOR         Y7, Y12, Y12
+	VPOR         Y8, Y13, Y13
+	VPOR         Y9, Y14, Y14
+	VPXOR        Y10, Y4, Y10
+	VPXOR        Y11, Y0, Y11
+	VPXOR        Y12, Y1, Y12
+	VPXOR        Y13, Y2, Y13
+	VPXOR        Y14, Y3, Y14
+	VPXOR        (AX), Y10, Y0
+	VPXOR        192(AX), Y11, Y1
+	VPXOR        384(AX), Y12, Y2
+	VPXOR        576(AX), Y13, Y3
+	VPXOR        768(AX), Y14, Y4
+	VPSLLQ       $0x2c, Y1, Y6
+	VPSLLQ       $0x2b, Y2, Y7
+	VPSLLQ       $0x15, Y3, Y8
+	VPSLLQ       $0x0e, Y4, Y9
+	VPSRLQ       $0x14, Y1, Y1
+	VPSRLQ       $0x15, Y2, Y2
+	VPSRLQ       $0x2b, Y3, Y3
+	VPSRLQ       $0x32, Y4, Y4
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VPBROADCASTQ (CX), Y0
+	VPXOR        Y0, Y5, Y5
+	VMOVDQA      Y5, (AX)
+	VMOVDQA      Y6, 192(AX)
+	VMOVDQA      Y7, 384(AX)
+	VMOVDQA      Y8, 576(AX)
+	VMOVDQA      Y9, 768(AX)
+	VPXOR        96(AX), Y13, Y0
+	VPXOR        288(AX), Y14, Y1
+	VPXOR        320(AX), Y10, Y2
+	VPXOR        512(AX), Y11, Y3
+	VPXOR        704(AX), Y12, Y4
+	VPSLLQ       $0x1c, Y0, Y5
+	VPSLLQ       $0x14, Y1, Y6
+	VPSLLQ       $0x03, Y2, Y7
+	VPSLLQ       $0x2d, Y3, Y8
+	VPSLLQ       $0x3d, Y4, Y9
+	VPSRLQ       $0x24, Y0, Y0
+	VPSRLQ       $0x2c, Y1, Y1
+	VPSRLQ       $0x3d, Y2, Y2
+	VPSRLQ       $0x13, Y3, Y3
+	VPSRLQ       $0x03, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 320(AX)
+	VMOVDQA      Y6, 512(AX)
+	VMOVDQA      Y7, 704(AX)
+	VMOVDQA      Y8, 96(AX)
+	VMOVDQA      Y9, 288(AX)
+	VPXOR        32(AX), Y11, Y0
+	VPXOR        224(AX), Y12, Y1
+	VPXOR        416(AX), Y13, Y2
+	VPXOR        608(AX), Y14, Y3
+	VPXOR        640(AX), Y10, Y4
+	VPSLLQ       $0x01, Y0, Y5
+	VPSLLQ       $0x06, Y1, Y6
+	VPSLLQ       $0x19, Y2, Y7
+	VPSLLQ       $0x08, Y3, Y8
+	VPSLLQ       $0x12, Y4, Y9
+	VPSRLQ       $0x3f, Y0, Y0
+	VPSRLQ       $0x3a, Y1, Y1
+	VPSRLQ       $0x27, Y2, Y2
+	VPSRLQ       $0x38, Y3, Y3
+	VPSRLQ       $0x2e, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 640(AX)
+	VMOVDQA      Y6, 32(AX)
+	VMOVDQA      Y7, 224(AX)
+	VMOVDQA      Y8, 416(AX)
+	VMOVDQA      Y9, 608(AX)
+	VPXOR        128(AX), Y14, Y0
+	VPXOR        160(AX), Y10, Y1
+	VPXOR        352(AX), Y11, Y2
+	VPXOR        544(AX), Y12, Y3
+	VPXOR        736(AX), Y13, Y4
+	VPSLLQ       $0x1b, Y0, Y5
+	VPSLLQ       $0x24, Y1, Y6
+	VPSLLQ       $0x0a, Y2, Y7
+	VPSLLQ       $0x0f, Y3, Y8
+	VPSLLQ       $0x38, Y4, Y9
+	VPSRLQ       $0x25, Y0, Y0
+	VPSRLQ       $0x1c, Y1, Y1
+	VPSRLQ       $0x36, Y2, Y2
+	VPSRLQ       $0x31, Y3, Y3
+	VPSRLQ       $0x08, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 160(AX)
+	VMOVDQA      Y6, 352(AX)
+	VMOVDQA      Y7, 544(AX)
+	VMOVDQA      Y8, 736(AX)
+	VMOVDQA      Y9, 128(AX)
+	VPXOR        64(AX), Y12, Y0
+	VPXOR        256(AX), Y13, Y1
+	VPXOR        448(AX), Y14, Y2
+	VPXOR        480(AX), Y10, Y3
+	VPXOR        672(AX), Y11, Y4
+	VPSLLQ       $0x3e, Y0, Y5
+	VPSLLQ       $0x37, Y1, Y6
+	VPSLLQ       $0x27, Y2, Y7
+	VPSLLQ       $0x29, Y3, Y8
+	VPSLLQ       $0x02, Y4, Y9
+	VPSRLQ       $0x02, Y0, Y0
+	VPSRLQ       $0x09, Y1, Y1
+	VPSRLQ       $0x19, Y2, Y2
+	VPSRLQ       $0x17, Y3, Y3
+	VPSRLQ       $0x3e, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 480(AX)
+	VMOVDQA      Y6, 672(AX)
+	VMOVDQA      Y7, 64(AX)
+	VMOVDQA      Y8, 256(AX)
+	VMOVDQA      Y9, 448(AX)
+	VMOVDQA      (AX), Y0
+	VMOVDQA      32(AX), Y1
+	VMOVDQA      64(AX), Y2
+	VMOVDQA      96(AX), Y3
+	VMOVDQA      128(AX), Y4
+	VPXOR        160(AX), Y0, Y0
+	VPXOR        192(AX), Y1, Y1
+	VPXOR        224(AX), Y2, Y2
+	VPXOR        256(AX), Y3, Y3
+	VPXOR        288(AX), Y4, Y4
+	VPXOR        320(AX), Y0, Y0
+	VPXOR        352(AX), Y1, Y1
+	VPXOR        384(AX), Y2, Y2
+	VPXOR        416(AX), Y3, Y3
+	VPXOR        448(AX), Y4, Y4
+	VPXOR        480(AX), Y0, Y0
+	VPXOR        512(AX), Y1, Y1
+	VPXOR        544(AX), Y2, Y2
+	VPXOR        576(AX), Y3, Y3
+	VPXOR        608(AX), Y4, Y4
+	VPXOR        640(AX), Y0, Y0
+	VPXOR        672(AX), Y1, Y1
+	VPXOR        704(AX), Y2, Y2
+	VPXOR        736(AX), Y3, Y3
+	VPXOR        768(AX), Y4, Y4
+	VPSLLQ       $0x01, Y1, Y5
+	VPSLLQ       $0x01, Y2, Y6
+	VPSLLQ       $0x01, Y3, Y7
+	VPSLLQ       $0x01, Y4, Y8
+	VPSLLQ       $0x01, Y0, Y9
+	VPSRLQ       $0x3f, Y1, Y10
+	VPSRLQ       $0x3f, Y2, Y11
+	VPSRLQ       $0x3f, Y3, Y12
+	VPSRLQ       $0x3f, Y4, Y13
+	VPSRLQ       $0x3f, Y0, Y14
+	VPOR         Y5, Y10, Y10
+	VPOR         Y6, Y11, Y11
+	VPOR         Y7, Y12, Y12
+	VPOR         Y8, Y13, Y13
+	VPOR         Y9, Y14, Y14
+	VPXOR        Y10, Y4, Y10
+	VPXOR        Y11, Y0, Y11
+	VPXOR        Y12, Y1, Y12
+	VPXOR        Y13, Y2, Y13
+	VPXOR        Y14, Y3, Y14
+	VPXOR        (AX), Y10, Y0
+	VPXOR        512(AX), Y11, Y1
+	VPXOR        224(AX), Y12, Y2
+	VPXOR        736(AX), Y13, Y3
+	VPXOR        448(AX), Y14, Y4
+	VPSLLQ       $0x2c, Y1, Y6
+	VPSLLQ       $0x2b, Y2, Y7
+	VPSLLQ       $0x15, Y3, Y8
+	VPSLLQ       $0x0e, Y4, Y9
+	VPSRLQ       $0x14, Y1, Y1
+	VPSRLQ       $0x15, Y2, Y2
+	VPSRLQ       $0x2b, Y3, Y3
+	VPSRLQ       $0x32, Y4, Y4
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VPBROADCASTQ 8(CX), Y0
+	VPXOR        Y0, Y5, Y5
+	VMOVDQA      Y5, (AX)
+	VMOVDQA      Y6, 512(AX)
+	VMOVDQA      Y7, 224(AX)
+	VMOVDQA      Y8, 736(AX)
+	VMOVDQA      Y9, 448(AX)
+	VPXOR        576(AX), Y13, Y0
+	VPXOR        288(AX), Y14, Y1
+	VPXOR        640(AX), Y10, Y2
+	VPXOR        352(AX), Y11, Y3
+	VPXOR        64(AX), Y12, Y4
+	VPSLLQ       $0x1c, Y0, Y5
+	VPSLLQ       $0x14, Y1, Y6
+	VPSLLQ       $0x03, Y2, Y7
+	VPSLLQ       $0x2d, Y3, Y8
+	VPSLLQ       $0x3d, Y4, Y9
+	VPSRLQ       $0x24, Y0, Y0
+	VPSRLQ       $0x2c, Y1, Y1
+	VPSRLQ       $0x3d, Y2, Y2
+	VPSRLQ       $0x13, Y3, Y3
+	VPSRLQ       $0x03, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 640(AX)
+	VMOVDQA      Y6, 352(AX)
+	VMOVDQA      Y7, 64(AX)
+	VMOVDQA      Y8, 576(AX)
+	VMOVDQA      Y9, 288(AX)
+	VPXOR        192(AX), Y11, Y0
+	VPXOR        704(AX), Y12, Y1
+	VPXOR        416(AX), Y13, Y2
+	VPXOR        128(AX), Y14, Y3
+	VPXOR        480(AX), Y10, Y4
+	VPSLLQ       $0x01, Y0, Y5
+	VPSLLQ       $0x06, Y1, Y6
+	VPSLLQ       $0x19, Y2, Y7
+	VPSLLQ       $0x08, Y3, Y8
+	VPSLLQ       $0x12, Y4, Y9
+	VPSRLQ       $0x3f, Y0, Y0
+	VPSRLQ       $0x3a, Y1, Y1
+	VPSRLQ       $0x27, Y2, Y2
+	VPSRLQ       $0x38, Y3, Y3
+	VPSRLQ       $0x2e, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 480(AX)
+	VMOVDQA      Y6, 192(AX)
+	VMOVDQA      Y7, 704(AX)
+	VMOVDQA      Y8, 416(AX)
+	VMOVDQA      Y9, 128(AX)
+	VPXOR        768(AX), Y14, Y0
+	VPXOR        320(AX), Y10, Y1
+	VPXOR        32(AX), Y11, Y2
+	VPXOR        544(AX), Y12, Y3
+	VPXOR        256(AX), Y13, Y4
+	VPSLLQ       $0x1b, Y0, Y5
+	VPSLLQ       $0x24, Y1, Y6
+	VPSLLQ       $0x0a, Y2, Y7
+	VPSLLQ       $0x0f, Y3, Y8
+	VPSLLQ       $0x38, Y4, Y9
+	VPSRLQ       $0x25, Y0, Y0
+	VPSRLQ       $0x1c, Y1, Y1
+	VPSRLQ       $0x36, Y2, Y2
+	VPSRLQ       $0x31, Y3, Y3
+	VPSRLQ       $0x08, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 320(AX)
+	VMOVDQA      Y6, 32(AX)
+	VMOVDQA      Y7, 544(AX)
+	VMOVDQA      Y8, 256(AX)
+	VMOVDQA      Y9, 768(AX)
+	VPXOR        384(AX), Y12, Y0
+	VPXOR        96(AX), Y13, Y1
+	VPXOR        608(AX), Y14, Y2
+	VPXOR        160(AX), Y10, Y3
+	VPXOR        672(AX), Y11, Y4
+	VPSLLQ       $0x3e, Y0, Y5
+	VPSLLQ       $0x37, Y1, Y6
+	VPSLLQ       $0x27, Y2, Y7
+	VPSLLQ       $0x29, Y3, Y8
+	VPSLLQ       $0x02, Y4, Y9
+	VPSRLQ       $0x02, Y0, Y0
+	VPSRLQ       $0x09, Y1, Y1
+	VPSRLQ       $0x19, Y2, Y2
+	VPSRLQ       $0x17, Y3, Y3
+	VPSRLQ       $0x3e, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 160(AX)
+	VMOVDQA      Y6, 672(AX)
+	VMOVDQA      Y7, 384(AX)
+	VMOVDQA      Y8, 96(AX)
+	VMOVDQA      Y9, 608(AX)
+	VMOVDQA      (AX), Y0
+	VMOVDQA      32(AX), Y1
+	VMOVDQA      64(AX), Y2
+	VMOVDQA      96(AX), Y3
+	VMOVDQA      128(AX), Y4
+	VPXOR        160(AX), Y0, Y0
+	VPXOR        192(AX), Y1, Y1
+	VPXOR        224(AX), Y2, Y2
+	VPXOR        256(AX), Y3, Y3
+	VPXOR        288(AX), Y4, Y4
+	VPXOR        320(AX), Y0, Y0
+	VPXOR        352(AX), Y1, Y1
+	VPXOR        384(AX), Y2, Y2
+	VPXOR        416(AX), Y3, Y3
+	VPXOR        448(AX), Y4, Y4
+	VPXOR        480(AX), Y0, Y0
+	VPXOR        512(AX), Y1, Y1
+	VPXOR        544(AX), Y2, Y2
+	VPXOR        576(AX), Y3, Y3
+	VPXOR        608(AX), Y4, Y4
+	VPXOR        640(AX), Y0, Y0
+	VPXOR        672(AX), Y1, Y1
+	VPXOR        704(AX), Y2, Y2
+	VPXOR        736(AX), Y3, Y3
+	VPXOR        768(AX), Y4, Y4
+	VPSLLQ       $0x01, Y1, Y5
+	VPSLLQ       $0x01, Y2, Y6
+	VPSLLQ       $0x01, Y3, Y7
+	VPSLLQ       $0x01, Y4, Y8
+	VPSLLQ       $0x01, Y0, Y9
+	VPSRLQ       $0x3f, Y1, Y10
+	VPSRLQ       $0x3f, Y2, Y11
+	VPSRLQ       $0x3f, Y3, Y12
+	VPSRLQ       $0x3f, Y4, Y13
+	VPSRLQ       $0x3f, Y0, Y14
+	VPOR         Y5, Y10, Y10
+	VPOR         Y6, Y11, Y11
+	VPOR         Y7, Y12, Y12
+	VPOR         Y8, Y13, Y13
+	VPOR         Y9, Y14, Y14
+	VPXOR        Y10, Y4, Y10
+	VPXOR        Y11, Y0, Y11
+	VPXOR        Y12, Y1, Y12
+	VPXOR        Y13, Y2, Y13
+	VPXOR        Y14, Y3, Y14
+	VPXOR        (AX), Y10, Y0
+	VPXOR        352(AX), Y11, Y1
+	VPXOR        704(AX), Y12, Y2
+	VPXOR        256(AX), Y13, Y3
+	VPXOR        608(AX), Y14, Y4
+	VPSLLQ       $0x2c, Y1, Y6
+	VPSLLQ       $0x2b, Y2, Y7
+	VPSLLQ       $0x15, Y3, Y8
+	VPSLLQ       $0x0e, Y4, Y9
+	VPSRLQ       $0x14, Y1, Y1
+	VPSRLQ       $0x15, Y2, Y2
+	VPSRLQ       $0x2b, Y3, Y3
+	VPSRLQ       $0x32, Y4, Y4
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VPBROADCASTQ 16(CX), Y0
+	VPXOR        Y0, Y5, Y5
+	VMOVDQA      Y5, (AX)
+	VMOVDQA      Y6, 352(AX)
+	VMOVDQA      Y7, 704(AX)
+	VMOVDQA      Y8, 256(AX)
+	VMOVDQA      Y9, 608(AX)
+	VPXOR        736(AX), Y13, Y0
+	VPXOR        288(AX), Y14, Y1
+	VPXOR        480(AX), Y10, Y2
+	VPXOR        32(AX), Y11, Y3
+	VPXOR        384(AX), Y12, Y4
+	VPSLLQ       $0x1c, Y0, Y5
+	VPSLLQ       $0x14, Y1, Y6
+	VPSLLQ       $0x03, Y2, Y7
+	VPSLLQ       $0x2d, Y3, Y8
+	VPSLLQ       $0x3d, Y4, Y9
+	VPSRLQ       $0x24, Y0, Y0
+	VPSRLQ       $0x2c, Y1, Y1
+	VPSRLQ       $0x3d, Y2, Y2
+	VPSRLQ       $0x13, Y3, Y3
+	VPSRLQ       $0x03, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 480(AX)
+	VMOVDQA      Y6, 32(AX)
+	VMOVDQA      Y7, 384(AX)
+	VMOVDQA      Y8, 736(AX)
+	VMOVDQA      Y9, 288(AX)
+	VPXOR        512(AX), Y11, Y0
+	VPXOR        64(AX), Y12, Y1
+	VPXOR        416(AX), Y13, Y2
+	VPXOR        768(AX), Y14, Y3
+	VPXOR        160(AX), Y10, Y4
+	VPSLLQ       $0x01, Y0, Y5
+	VPSLLQ       $0x06, Y1, Y6
+	VPSLLQ       $0x19, Y2, Y7
+	VPSLLQ       $0x08, Y3, Y8
+	VPSLLQ       $0x12, Y4, Y9
+	VPSRLQ       $0x3f, Y0, Y0
+	VPSRLQ       $0x3a, Y1, Y1
+	VPSRLQ       $0x27, Y2, Y2
+	VPSRLQ       $0x38, Y3, Y3
+	VPSRLQ       $0x2e, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 160(AX)
+	VMOVDQA      Y6, 512(AX)
+	VMOVDQA      Y7, 64(AX)
+	VMOVDQA      Y8, 416(AX)
+	VMOVDQA      Y9, 768(AX)
+	VPXOR        448(AX), Y14, Y0
+	VPXOR        640(AX), Y10, Y1
+	VPXOR        192(AX), Y11, Y2
+	VPXOR        544(AX), Y12, Y3
+	VPXOR        96(AX), Y13, Y4
+	VPSLLQ       $0x1b, Y0, Y5
+	VPSLLQ       $0x24, Y1, Y6
+	VPSLLQ       $0x0a, Y2, Y7
+	VPSLLQ       $0x0f, Y3, Y8
+	VPSLLQ       $0x38, Y4, Y9
+	VPSRLQ       $0x25, Y0, Y0
+	VPSRLQ       $0x1c, Y1, Y1
+	VPSRLQ       $0x36, Y2, Y2
+	VPSRLQ       $0x31, Y3, Y3
+	VPSRLQ       $0x08, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 640(AX)
+	VMOVDQA      Y6, 192(AX)
+	VMOVDQA      Y7, 544(AX)
+	VMOVDQA      Y8, 96(AX)
+	VMOVDQA      Y9, 448(AX)
+	VPXOR        224(AX), Y12, Y0
+	VPXOR        576(AX), Y13, Y1
+	VPXOR        128(AX), Y14, Y2
+	VPXOR        320(AX), Y10, Y3
+	VPXOR        672(AX), Y11, Y4
+	VPSLLQ       $0x3e, Y0, Y5
+	VPSLLQ       $0x37, Y1, Y6
+	VPSLLQ       $0x27, Y2, Y7
+	VPSLLQ       $0x29, Y3, Y8
+	VPSLLQ       $0x02, Y4, Y9
+	VPSRLQ       $0x02, Y0, Y0
+	VPSRLQ       $0x09, Y1, Y1
+	VPSRLQ       $0x19, Y2, Y2
+	VPSRLQ       $0x17, Y3, Y3
+	VPSRLQ       $0x3e, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 320(AX)
+	VMOVDQA      Y6, 672(AX)
+	VMOVDQA      Y7, 224(AX)
+	VMOVDQA      Y8, 576(AX)
+	VMOVDQA      Y9, 128(AX)
+	VMOVDQA      (AX), Y0
+	VMOVDQA      32(AX), Y1
+	VMOVDQA      64(AX), Y2
+	VMOVDQA      96(AX), Y3
+	VMOVDQA      128(AX), Y4
+	VPXOR        160(AX), Y0, Y0
+	VPXOR        192(AX), Y1, Y1
+	VPXOR        224(AX), Y2, Y2
+	VPXOR        256(AX), Y3, Y3
+	VPXOR        288(AX), Y4, Y4
+	VPXOR        320(AX), Y0, Y0
+	VPXOR        352(AX), Y1, Y1
+	VPXOR        384(AX), Y2, Y2
+	VPXOR        416(AX), Y3, Y3
+	VPXOR        448(AX), Y4, Y4
+	VPXOR        480(AX), Y0, Y0
+	VPXOR        512(AX), Y1, Y1
+	VPXOR        544(AX), Y2, Y2
+	VPXOR        576(AX), Y3, Y3
+	VPXOR        608(AX), Y4, Y4
+	VPXOR        640(AX), Y0, Y0
+	VPXOR        672(AX), Y1, Y1
+	VPXOR        704(AX), Y2, Y2
+	VPXOR        736(AX), Y3, Y3
+	VPXOR        768(AX), Y4, Y4
+	VPSLLQ       $0x01, Y1, Y5
+	VPSLLQ       $0x01, Y2, Y6
+	VPSLLQ       $0x01, Y3, Y7
+	VPSLLQ       $0x01, Y4, Y8
+	VPSLLQ       $0x01, Y0, Y9
+	VPSRLQ       $0x3f, Y1, Y10
+	VPSRLQ       $0x3f, Y2, Y11
+	VPSRLQ       $0x3f, Y3, Y12
+	VPSRLQ       $0x3f, Y4, Y13
+	VPSRLQ       $0x3f, Y0, Y14
+	VPOR         Y5, Y10, Y10
+	VPOR         Y6, Y11, Y11
+	VPOR         Y7, Y12, Y12
+	VPOR         Y8, Y13, Y13
+	VPOR         Y9, Y14, Y14
+	VPXOR        Y10, Y4, Y10
+	VPXOR        Y11, Y0, Y11
+	VPXOR        Y12, Y1, Y12
+	VPXOR        Y13, Y2, Y13
+	VPXOR        Y14, Y3, Y14
+	VPXOR        (AX), Y10, Y0
+	VPXOR        32(AX), Y11, Y1
+	VPXOR        64(AX), Y12, Y2
+	VPXOR        96(AX), Y13, Y3
+	VPXOR        128(AX), Y14, Y4
+	VPSLLQ       $0x2c, Y1, Y6
+	VPSLLQ       $0x2b, Y2, Y7
+	VPSLLQ       $0x15, Y3, Y8
+	VPSLLQ       $0x0e, Y4, Y9
+	VPSRLQ       $0x14, Y1, Y1
+	VPSRLQ       $0x15, Y2, Y2
+	VPSRLQ       $0x2b, Y3, Y3
+	VPSRLQ       $0x32, Y4, Y4
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VPBROADCASTQ 24(CX), Y0
+	VPXOR        Y0, Y5, Y5
+	VMOVDQA      Y5, (AX)
+	VMOVDQA      Y6, 32(AX)
+	VMOVDQA      Y7, 64(AX)
+	VMOVDQA      Y8, 96(AX)
+	VMOVDQA      Y9, 128(AX)
+	VPXOR        256(AX), Y13, Y0
+	VPXOR        288(AX), Y14, Y1
+	VPXOR        160(AX), Y10, Y2
+	VPXOR        192(AX), Y11, Y3
+	VPXOR        224(AX), Y12, Y4
+	VPSLLQ       $0x1c, Y0, Y5
+	VPSLLQ       $0x14, Y1, Y6
+	VPSLLQ       $0x03, Y2, Y7
+	VPSLLQ       $0x2d, Y3, Y8
+	VPSLLQ       $0x3d, Y4, Y9
+	VPSRLQ       $0x24, Y0, Y0
+	VPSRLQ       $0x2c, Y1, Y1
+	VPSRLQ       $0x3d, Y2, Y2
+	VPSRLQ       $0x13, Y3, Y3
+	VPSRLQ       $0x03, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 160(AX)
+	VMOVDQA      Y6, 192(AX)
+	VMOVDQA      Y7, 224(AX)
+	VMOVDQA      Y8, 256(AX)
+	VMOVDQA      Y9, 288(AX)
+	VPXOR        352(AX), Y11, Y0
+	VPXOR        384(AX), Y12, Y1
+	VPXOR        416(AX), Y13, Y2
+	VPXOR        448(AX), Y14, Y3
+	VPXOR        320(AX), Y10, Y4
+	VPSLLQ       $0x01, Y0, Y5
+	VPSLLQ       $0x06, Y1, Y6
+	VPSLLQ       $0x19, Y2, Y7
+	VPSLLQ       $0x08, Y3, Y8
+	VPSLLQ       $0x12, Y4, Y9
+	VPSRLQ       $0x3f, Y0, Y0
+	VPSRLQ       $0x3a, Y1, Y1
+	VPSRLQ       $0x27, Y2, Y2
+	VPSRLQ       $0x38, Y3, Y3
+	VPSRLQ       $0x2e, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 320(AX)
+	VMOVDQA      Y6, 352(AX)
+	VMOVDQA      Y7, 384(AX)
+	VMOVDQA      Y8, 416(AX)
+	VMOVDQA      Y9, 448(AX)
+	VPXOR        608(AX), Y14, Y0
+	VPXOR        480(AX), Y10, Y1
+	VPXOR        512(AX), Y11, Y2
+	VPXOR        544(AX), Y12, Y3
+	VPXOR        576(AX), Y13, Y4
+	VPSLLQ       $0x1b, Y0, Y5
+	VPSLLQ       $0x24, Y1, Y6
+	VPSLLQ       $0x0a, Y2, Y7
+	VPSLLQ       $0x0f, Y3, Y8
+	VPSLLQ       $0x38, Y4, Y9
+	VPSRLQ       $0x25, Y0, Y0
+	VPSRLQ       $0x1c, Y1, Y1
+	VPSRLQ       $0x36, Y2, Y2
+	VPSRLQ       $0x31, Y3, Y3
+	VPSRLQ       $0x08, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 480(AX)
+	VMOVDQA      Y6, 512(AX)
+	VMOVDQA      Y7, 544(AX)
+	VMOVDQA      Y8, 576(AX)
+	VMOVDQA      Y9, 608(AX)
+	VPXOR        704(AX), Y12, Y0
+	VPXOR        736(AX), Y13, Y1
+	VPXOR        768(AX), Y14, Y2
+	VPXOR        640(AX), Y10, Y3
+	VPXOR        672(AX), Y11, Y4
+	VPSLLQ       $0x3e, Y0, Y5
+	VPSLLQ       $0x37, Y1, Y6
+	VPSLLQ       $0x27, Y2, Y7
+	VPSLLQ       $0x29, Y3, Y8
+	VPSLLQ       $0x02, Y4, Y9
+	VPSRLQ       $0x02, Y0, Y0
+	VPSRLQ       $0x09, Y1, Y1
+	VPSRLQ       $0x19, Y2, Y2
+	VPSRLQ       $0x17, Y3, Y3
+	VPSRLQ       $0x3e, Y4, Y4
+	VPOR         Y5, Y0, Y0
+	VPOR         Y6, Y1, Y1
+	VPOR         Y7, Y2, Y2
+	VPOR         Y8, Y3, Y3
+	VPOR         Y9, Y4, Y4
+	VPANDN       Y2, Y1, Y5
+	VPANDN       Y3, Y2, Y6
+	VPANDN       Y4, Y3, Y7
+	VPANDN       Y0, Y4, Y8
+	VPANDN       Y1, Y0, Y9
+	VPXOR        Y0, Y5, Y5
+	VPXOR        Y1, Y6, Y6
+	VPXOR        Y2, Y7, Y7
+	VPXOR        Y3, Y8, Y8
+	VPXOR        Y4, Y9, Y9
+	VMOVDQA      Y5, 640(AX)
+	VMOVDQA      Y6, 672(AX)
+	VMOVDQA      Y7, 704(AX)
+	VMOVDQA      Y8, 736(AX)
+	VMOVDQA      Y9, 768(AX)
+	ADDQ         $0x20, CX
+	SUBQ         $0x00000001, DX
+	JNZ          loop
+	RET
diff --git a/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4stubs_amd64.go b/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4stubs_amd64.go
new file mode 100644
index 00000000..102fdd04
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/simd/keccakf1600/f1600x4stubs_amd64.go
@@ -0,0 +1,8 @@
+// Code generated by command: go run src.go -out ../../f1600x4_amd64.s -stubs ../../f1600x4stubs_amd64.go -pkg keccakf1600. DO NOT EDIT.
+
+//go:build amd64 && !purego
+
+package keccakf1600
+
+//go:noescape
+func f1600x4AVX2(state *uint64, rc *[24]uint64, turbo bool)
diff --git a/vendor/github.com/cloudflare/circl/simd/keccakf1600/fallback.go b/vendor/github.com/cloudflare/circl/simd/keccakf1600/fallback.go
new file mode 100644
index 00000000..0da75e9b
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/simd/keccakf1600/fallback.go
@@ -0,0 +1,8 @@
+//go:build (!amd64 && !arm64) || (arm64 && !go1.16) || purego
+// +build !amd64,!arm64 arm64,!go1.16 purego
+
+package keccakf1600
+
+func permuteSIMDx2(state []uint64, turbo bool) { permuteScalarX2(state, turbo) }
+
+func permuteSIMDx4(state []uint64, turbo bool) { permuteScalarX4(state, turbo) }
diff --git a/vendor/github.com/cloudflare/circl/xof/k12/k12.go b/vendor/github.com/cloudflare/circl/xof/k12/k12.go
new file mode 100644
index 00000000..bbd33d11
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/xof/k12/k12.go
@@ -0,0 +1,400 @@
+// k12 implements the KangarooTwelve XOF.
+//
+// KangarooTwelve is being standardised at the CFRG working group
+// of the IRTF. This package implements draft 10.
+//
+// https://datatracker.ietf.org/doc/draft-irtf-cfrg-kangarootwelve/10/
+package k12
+
+import (
+	"encoding/binary"
+
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/simd/keccakf1600"
+)
+
+const chunkSize = 8192 // aka B
+
+// KangarooTwelve splits the message into chunks of 8192 bytes each.
+// The first chunk is absorbed directly in a TurboSHAKE128 instance, which
+// we call the stalk. The subsequent chunks aren't absorbed directly, but
+// instead their hash is absorbed: they're like leafs on a stalk.
+// If we have a fast TurboSHAKE128 available, we buffer chunks until we have
+// enough to do the parallel TurboSHAKE128. If not, we absorb directly into
+// a separate TurboSHAKE128 state.
+
+type State struct {
+	initialTodo int // Bytes left to absorb for the first chunk.
+
+	stalk sha3.State
+
+	context []byte // context string "C" provided by the user
+
+	// buffer of incoming data so we can do parallel TurboSHAKE128:
+	// nil when we haven't absorbed the first chunk yet;
+	// empty if we have, but we do not have a fast parallel TurboSHAKE128;
+	// and chunkSize*lanes in length if we have.
+	buf []byte
+
+	offset int // offset in buf or bytes written to leaf
+
+	// Number of chunk hashes ("CV_i") absorbed into the stalk.
+	chunk uint
+
+	// TurboSHAKE128 instance to compute the leaf in case we don't have
+	// a fast parallel TurboSHAKE128, viz when lanes == 1.
+	leaf *sha3.State
+
+	lanes uint8 // number of TurboSHAKE128s to compute in parallel
+}
+
+// NewDraft10 creates a new instance of Kangaroo12 draft version -10.
+func NewDraft10(c []byte) State {
+	var lanes byte = 1
+
+	if keccakf1600.IsEnabledX4() {
+		lanes = 4
+	} else if keccakf1600.IsEnabledX2() {
+		lanes = 2
+	}
+
+	return newDraft10(c, lanes)
+}
+
+func newDraft10(c []byte, lanes byte) State {
+	return State{
+		initialTodo: chunkSize,
+		stalk:       sha3.NewTurboShake128(0x07),
+		context:     c,
+		lanes:       lanes,
+	}
+}
+
+func (s *State) Reset() {
+	s.initialTodo = chunkSize
+	s.stalk.Reset()
+	s.stalk.SwitchDS(0x07)
+	s.buf = nil
+	s.offset = 0
+	s.chunk = 0
+}
+
+func (s *State) Clone() State {
+	stalk := s.stalk.Clone().(*sha3.State)
+	ret := State{
+		initialTodo: s.initialTodo,
+		stalk:       *stalk,
+		context:     s.context,
+		offset:      s.offset,
+		chunk:       s.chunk,
+		lanes:       s.lanes,
+	}
+
+	if s.leaf != nil {
+		ret.leaf = s.leaf.Clone().(*sha3.State)
+	}
+
+	if s.buf != nil {
+		ret.buf = make([]byte, len(s.buf))
+		copy(ret.buf, s.buf)
+	}
+
+	return ret
+}
+
+func Draft10Sum(hash []byte, msg []byte, c []byte) {
+	// TODO Tweak number of lanes depending on the length of the message
+	s := NewDraft10(c)
+	_, _ = s.Write(msg)
+	_, _ = s.Read(hash)
+}
+
+func (s *State) Write(p []byte) (int, error) {
+	written := len(p)
+
+	// The first chunk is written directly to the stalk.
+	if s.initialTodo > 0 {
+		taken := s.initialTodo
+		if len(p) < taken {
+			taken = len(p)
+		}
+		headP := p[:taken]
+		_, _ = s.stalk.Write(headP)
+		s.initialTodo -= taken
+		p = p[taken:]
+	}
+
+	if len(p) == 0 {
+		return written, nil
+	}
+
+	// If this is the first bit of data written after the initial chunk,
+	// we're out of the fast-path and allocate some buffers.
+	if s.buf == nil {
+		if s.lanes != 1 {
+			s.buf = make([]byte, int(s.lanes)*chunkSize)
+		} else {
+			// We create the buffer to signal we're past the first chunk,
+			// but do not use it.
+			s.buf = make([]byte, 0)
+			h := sha3.NewTurboShake128(0x0B)
+			s.leaf = &h
+		}
+		_, _ = s.stalk.Write([]byte{0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
+		s.stalk.SwitchDS(0x06)
+	}
+
+	// If we're just using one lane, we don't need to cache in a buffer
+	// for parallel hashing. Instead, we feed directly to TurboSHAKE.
+	if s.lanes == 1 {
+		for len(p) > 0 {
+			// Write to current leaf.
+			to := chunkSize - s.offset
+			if len(p) < to {
+				to = len(p)
+			}
+			_, _ = s.leaf.Write(p[:to])
+			p = p[to:]
+			s.offset += to
+
+			// Did we fill the chunk?
+			if s.offset == chunkSize {
+				var cv [32]byte
+				_, _ = s.leaf.Read(cv[:])
+				_, _ = s.stalk.Write(cv[:])
+				s.leaf.Reset()
+				s.offset = 0
+				s.chunk++
+			}
+		}
+
+		return written, nil
+	}
+
+	// If we can't fill all our lanes or the buffer isn't empty, we write the
+	// data to the buffer.
+	if s.offset != 0 || len(p) < len(s.buf) {
+		to := len(s.buf) - s.offset
+		if len(p) < to {
+			to = len(p)
+		}
+		p2 := p[:to]
+		p = p[to:]
+		copy(s.buf[s.offset:], p2)
+		s.offset += to
+	}
+
+	// Absorb the buffer if we filled it
+	if s.offset == len(s.buf) {
+		s.writeX(s.buf)
+		s.offset = 0
+	}
+
+	// Note that at this point we may assume that s.offset = 0 if len(p) != 0
+	if len(p) != 0 && s.offset != 0 {
+		panic("shouldn't happen")
+	}
+
+	// Absorb a bunch of chunks at the same time.
+	if len(p) >= int(s.lanes)*chunkSize {
+		p = s.writeX(p)
+	}
+
+	// Put the remainder in the buffer.
+	if len(p) > 0 {
+		copy(s.buf, p)
+		s.offset = len(p)
+	}
+
+	return written, nil
+}
+
+// Absorb a multiple of a multiple of lanes * chunkSize.
+// Returns the remainder.
+func (s *State) writeX(p []byte) []byte {
+	switch s.lanes {
+	case 4:
+		return s.writeX4(p)
+	default:
+		return s.writeX2(p)
+	}
+}
+
+func (s *State) writeX4(p []byte) []byte {
+	for len(p) >= 4*chunkSize {
+		var x4 keccakf1600.StateX4
+		a := x4.Initialize(true)
+
+		for offset := 0; offset < 48*168; offset += 168 {
+			for i := 0; i < 21; i++ {
+				a[i*4] ^= binary.LittleEndian.Uint64(
+					p[8*i+offset:],
+				)
+				a[i*4+1] ^= binary.LittleEndian.Uint64(
+					p[chunkSize+8*i+offset:],
+				)
+				a[i*4+2] ^= binary.LittleEndian.Uint64(
+					p[chunkSize*2+8*i+offset:],
+				)
+				a[i*4+3] ^= binary.LittleEndian.Uint64(
+					p[chunkSize*3+8*i+offset:],
+				)
+			}
+
+			x4.Permute()
+		}
+
+		for i := 0; i < 16; i++ {
+			a[i*4] ^= binary.LittleEndian.Uint64(
+				p[8*i+48*168:],
+			)
+			a[i*4+1] ^= binary.LittleEndian.Uint64(
+				p[chunkSize+8*i+48*168:],
+			)
+			a[i*4+2] ^= binary.LittleEndian.Uint64(
+				p[chunkSize*2+8*i+48*168:],
+			)
+			a[i*4+3] ^= binary.LittleEndian.Uint64(
+				p[chunkSize*3+8*i+48*168:],
+			)
+		}
+
+		a[16*4] ^= 0x0b
+		a[16*4+1] ^= 0x0b
+		a[16*4+2] ^= 0x0b
+		a[16*4+3] ^= 0x0b
+		a[20*4] ^= 0x80 << 56
+		a[20*4+1] ^= 0x80 << 56
+		a[20*4+2] ^= 0x80 << 56
+		a[20*4+3] ^= 0x80 << 56
+
+		x4.Permute()
+
+		var buf [32 * 4]byte
+		for i := 0; i < 4; i++ {
+			binary.LittleEndian.PutUint64(buf[8*i:], a[4*i])
+			binary.LittleEndian.PutUint64(buf[32+8*i:], a[4*i+1])
+			binary.LittleEndian.PutUint64(buf[32*2+8*i:], a[4*i+2])
+			binary.LittleEndian.PutUint64(buf[32*3+8*i:], a[4*i+3])
+		}
+
+		_, _ = s.stalk.Write(buf[:])
+		p = p[chunkSize*4:]
+		s.chunk += 4
+	}
+
+	return p
+}
+
+func (s *State) writeX2(p []byte) []byte {
+	// TODO On M2 Pro, 1/3 of the time is spent on this function
+	// and LittleEndian.Uint64 excluding the actual permutation.
+	// Rewriting in assembler might be worthwhile.
+	for len(p) >= 2*chunkSize {
+		var x2 keccakf1600.StateX2
+		a := x2.Initialize(true)
+
+		for offset := 0; offset < 48*168; offset += 168 {
+			for i := 0; i < 21; i++ {
+				a[i*2] ^= binary.LittleEndian.Uint64(
+					p[8*i+offset:],
+				)
+				a[i*2+1] ^= binary.LittleEndian.Uint64(
+					p[chunkSize+8*i+offset:],
+				)
+			}
+
+			x2.Permute()
+		}
+
+		for i := 0; i < 16; i++ {
+			a[i*2] ^= binary.LittleEndian.Uint64(
+				p[8*i+48*168:],
+			)
+			a[i*2+1] ^= binary.LittleEndian.Uint64(
+				p[chunkSize+8*i+48*168:],
+			)
+		}
+
+		a[16*2] ^= 0x0b
+		a[16*2+1] ^= 0x0b
+		a[20*2] ^= 0x80 << 56
+		a[20*2+1] ^= 0x80 << 56
+
+		x2.Permute()
+
+		var buf [32 * 2]byte
+		for i := 0; i < 4; i++ {
+			binary.LittleEndian.PutUint64(buf[8*i:], a[2*i])
+			binary.LittleEndian.PutUint64(buf[32+8*i:], a[2*i+1])
+		}
+
+		_, _ = s.stalk.Write(buf[:])
+		p = p[chunkSize*2:]
+		s.chunk += 2
+	}
+
+	return p
+}
+
+func (s *State) Read(p []byte) (int, error) {
+	if s.stalk.IsAbsorbing() {
+		// Write context string C
+		_, _ = s.Write(s.context)
+
+		// Write length_encode( |C| )
+		var buf [9]byte
+		binary.BigEndian.PutUint64(buf[:8], uint64(len(s.context)))
+
+		// Find first non-zero digit in big endian encoding of context length
+		i := 0
+		for buf[i] == 0 && i < 8 {
+			i++
+		}
+
+		buf[8] = byte(8 - i) // number of bytes to represent |C|
+		_, _ = s.Write(buf[i:])
+
+		// We need to write the chunk number if we're past the first chunk.
+		if s.buf != nil {
+			// Write last remaining chunk(s)
+			var cv [32]byte
+			if s.lanes == 1 {
+				if s.offset != 0 {
+					_, _ = s.leaf.Read(cv[:])
+					_, _ = s.stalk.Write(cv[:])
+					s.chunk++
+				}
+			} else {
+				remainingBuf := s.buf[:s.offset]
+				for len(remainingBuf) > 0 {
+					h := sha3.NewTurboShake128(0x0B)
+					to := chunkSize
+					if len(remainingBuf) < to {
+						to = len(remainingBuf)
+					}
+					_, _ = h.Write(remainingBuf[:to])
+					_, _ = h.Read(cv[:])
+					_, _ = s.stalk.Write(cv[:])
+					s.chunk++
+					remainingBuf = remainingBuf[to:]
+				}
+			}
+
+			// Write length_encode( chunk )
+			binary.BigEndian.PutUint64(buf[:8], uint64(s.chunk))
+
+			// Find first non-zero digit in big endian encoding of number of chunks
+			i = 0
+			for buf[i] == 0 && i < 8 {
+				i++
+			}
+
+			buf[8] = byte(8 - i) // number of bytes to represent number of chunks.
+			_, _ = s.stalk.Write(buf[i:])
+			_, _ = s.stalk.Write([]byte{0xff, 0xff})
+		}
+	}
+
+	return s.stalk.Read(p)
+}
diff --git a/vendor/github.com/cloudflare/circl/xof/xof.go b/vendor/github.com/cloudflare/circl/xof/xof.go
new file mode 100644
index 00000000..33485cac
--- /dev/null
+++ b/vendor/github.com/cloudflare/circl/xof/xof.go
@@ -0,0 +1,85 @@
+// Package xof provides an interface for eXtendable-Output Functions.
+//
+// # Available Functions
+//
+// SHAKE functions are defined in FIPS-202, see https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf.
+// BLAKE2Xb and BLAKE2Xs are defined in https://www.blake2.net/blake2x.pdf.
+package xof
+
+import (
+	"io"
+
+	"github.com/cloudflare/circl/internal/sha3"
+	"github.com/cloudflare/circl/xof/k12"
+
+	"golang.org/x/crypto/blake2b"
+	"golang.org/x/crypto/blake2s"
+)
+
+// XOF defines the interface to hash functions that support arbitrary-length output.
+type XOF interface {
+	// Write absorbs more data into the XOF's state. It panics if called
+	// after Read.
+	io.Writer
+
+	// Read reads more output from the XOF. It returns io.EOF if the limit
+	// has been reached.
+	io.Reader
+
+	// Clone returns a copy of the XOF in its current state.
+	Clone() XOF
+
+	// Reset restores the XOF to its initial state and discards all data appended by Write.
+	Reset()
+}
+
+type ID uint
+
+const (
+	SHAKE128 ID = iota + 1
+	SHAKE256
+	BLAKE2XB
+	BLAKE2XS
+	K12D10
+)
+
+func (x ID) New() XOF {
+	switch x {
+	case SHAKE128:
+		s := sha3.NewShake128()
+		return shakeBody{&s}
+	case SHAKE256:
+		s := sha3.NewShake256()
+		return shakeBody{&s}
+	case BLAKE2XB:
+		x, _ := blake2b.NewXOF(blake2b.OutputLengthUnknown, nil)
+		return blake2xb{x}
+	case BLAKE2XS:
+		x, _ := blake2s.NewXOF(blake2s.OutputLengthUnknown, nil)
+		return blake2xs{x}
+	case K12D10:
+		x := k12.NewDraft10([]byte{})
+		return k12d10{&x}
+	default:
+		panic("crypto: requested unavailable XOF function")
+	}
+}
+
+type shakeBody struct{ sha3.ShakeHash }
+
+func (s shakeBody) Clone() XOF { return shakeBody{s.ShakeHash.Clone()} }
+
+type blake2xb struct{ blake2b.XOF }
+
+func (s blake2xb) Clone() XOF { return blake2xb{s.XOF.Clone()} }
+
+type blake2xs struct{ blake2s.XOF }
+
+func (s blake2xs) Clone() XOF { return blake2xs{s.XOF.Clone()} }
+
+type k12d10 struct{ *k12.State }
+
+func (s k12d10) Clone() XOF {
+	x := s.State.Clone()
+	return k12d10{&x}
+}
diff --git a/vendor/github.com/gaukas/godicttls/.gitignore b/vendor/github.com/gaukas/godicttls/.gitignore
deleted file mode 100644
index 66fd13c9..00000000
--- a/vendor/github.com/gaukas/godicttls/.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/go-logr/logr/.golangci.yaml b/vendor/github.com/go-logr/logr/.golangci.yaml
index 94ff801d..0cffafa7 100644
--- a/vendor/github.com/go-logr/logr/.golangci.yaml
+++ b/vendor/github.com/go-logr/logr/.golangci.yaml
@@ -6,7 +6,6 @@ linters:
   disable-all: true
   enable:
     - asciicheck
-    - deadcode
     - errcheck
     - forcetypeassert
     - gocritic
@@ -18,10 +17,8 @@ linters:
     - misspell
     - revive
     - staticcheck
-    - structcheck
     - typecheck
     - unused
-    - varcheck
 
 issues:
   exclude-use-default: false
diff --git a/vendor/github.com/go-logr/logr/README.md b/vendor/github.com/go-logr/logr/README.md
index ab593118..7c7f0c69 100644
--- a/vendor/github.com/go-logr/logr/README.md
+++ b/vendor/github.com/go-logr/logr/README.md
@@ -1,6 +1,8 @@
 # A minimal logging API for Go
 
 [![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/logr.svg)](https://pkg.go.dev/github.com/go-logr/logr)
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-logr/logr)](https://goreportcard.com/report/github.com/go-logr/logr)
+[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/go-logr/logr/badge)](https://securityscorecards.dev/viewer/?platform=github.com&org=go-logr&repo=logr)
 
 logr offers an(other) opinion on how Go programs and libraries can do logging
 without becoming coupled to a particular logging implementation.  This is not
@@ -73,6 +75,30 @@ received:
 If the Go standard library had defined an interface for logging, this project
 probably would not be needed.  Alas, here we are.
 
+When the Go developers started developing such an interface with
+[slog](https://github.com/golang/go/issues/56345), they adopted some of the
+logr design but also left out some parts and changed others:
+
+| Feature | logr | slog |
+|---------|------|------|
+| High-level API | `Logger` (passed by value) | `Logger` (passed by [pointer](https://github.com/golang/go/issues/59126)) |
+| Low-level API | `LogSink` | `Handler` |
+| Stack unwinding | done by `LogSink` | done by `Logger` |
+| Skipping helper functions | `WithCallDepth`, `WithCallStackHelper` | [not supported by Logger](https://github.com/golang/go/issues/59145) |
+| Generating a value for logging on demand | `Marshaler` | `LogValuer` |
+| Log levels | >= 0, higher meaning "less important" | positive and negative, with 0 for "info" and higher meaning "more important" |
+| Error log entries | always logged, don't have a verbosity level | normal log entries with level >= `LevelError` |
+| Passing logger via context | `NewContext`, `FromContext` | no API |
+| Adding a name to a logger | `WithName` | no API |
+| Modify verbosity of log entries in a call chain | `V` | no API |
+| Grouping of key/value pairs | not supported | `WithGroup`, `GroupValue` |
+| Pass context for extracting additional values | no API | API variants like `InfoCtx` |
+
+The high-level slog API is explicitly meant to be one of many different APIs
+that can be layered on top of a shared `slog.Handler`. logr is one such
+alternative API, with [interoperability](#slog-interoperability) provided by
+some conversion functions.
+
 ### Inspiration
 
 Before you consider this package, please read [this blog post by the
@@ -118,6 +144,103 @@ There are implementations for the following logging libraries:
 - **github.com/go-kit/log**: [gokitlogr](https://github.com/tonglil/gokitlogr) (also compatible with github.com/go-kit/kit/log since v0.12.0)
 - **bytes.Buffer** (writing to a buffer): [bufrlogr](https://github.com/tonglil/buflogr) (useful for ensuring values were logged, like during testing)
 
+## slog interoperability
+
+Interoperability goes both ways, using the `logr.Logger` API with a `slog.Handler`
+and using the `slog.Logger` API with a `logr.LogSink`. `FromSlogHandler` and
+`ToSlogHandler` convert between a `logr.Logger` and a `slog.Handler`.
+As usual, `slog.New` can be used to wrap such a `slog.Handler` in the high-level
+slog API.
+
+### Using a `logr.LogSink` as backend for slog
+
+Ideally, a logr sink implementation should support both logr and slog by
+implementing both the normal logr interface(s) and `SlogSink`.  Because
+of a conflict in the parameters of the common `Enabled` method, it is [not
+possible to implement both slog.Handler and logr.Sink in the same
+type](https://github.com/golang/go/issues/59110).
+
+If both are supported, log calls can go from the high-level APIs to the backend
+without the need to convert parameters. `FromSlogHandler` and `ToSlogHandler` can
+convert back and forth without adding additional wrappers, with one exception:
+when `Logger.V` was used to adjust the verbosity for a `slog.Handler`, then
+`ToSlogHandler` has to use a wrapper which adjusts the verbosity for future
+log calls.
+
+Such an implementation should also support values that implement specific
+interfaces from both packages for logging (`logr.Marshaler`, `slog.LogValuer`,
+`slog.GroupValue`). logr does not convert those.
+
+Not supporting slog has several drawbacks:
+- Recording source code locations works correctly if the handler gets called
+  through `slog.Logger`, but may be wrong in other cases. That's because a
+  `logr.Sink` does its own stack unwinding instead of using the program counter
+  provided by the high-level API.
+- slog levels <= 0 can be mapped to logr levels by negating the level without a
+  loss of information. But all slog levels > 0 (e.g. `slog.LevelWarning` as
+  used by `slog.Logger.Warn`) must be mapped to 0 before calling the sink
+  because logr does not support "more important than info" levels.
+- The slog group concept is supported by prefixing each key in a key/value
+  pair with the group names, separated by a dot. For structured output like
+  JSON it would be better to group the key/value pairs inside an object.
+- Special slog values and interfaces don't work as expected.
+- The overhead is likely to be higher.
+
+These drawbacks are severe enough that applications using a mixture of slog and
+logr should switch to a different backend.
+
+### Using a `slog.Handler` as backend for logr
+
+Using a plain `slog.Handler` without support for logr works better than the
+other direction:
+- All logr verbosity levels can be mapped 1:1 to their corresponding slog level
+  by negating them.
+- Stack unwinding is done by the `SlogSink` and the resulting program
+  counter is passed to the `slog.Handler`.
+- Names added via `Logger.WithName` are gathered and recorded in an additional
+  attribute with `logger` as key and the names separated by slash as value.
+- `Logger.Error` is turned into a log record with `slog.LevelError` as level
+  and an additional attribute with `err` as key, if an error was provided.
+
+The main drawback is that `logr.Marshaler` will not be supported. Types should
+ideally support both `logr.Marshaler` and `slog.Valuer`. If compatibility
+with logr implementations without slog support is not important, then
+`slog.Valuer` is sufficient.
+
+### Context support for slog
+
+Storing a logger in a `context.Context` is not supported by
+slog. `NewContextWithSlogLogger` and `FromContextAsSlogLogger` can be
+used to fill this gap. They store and retrieve a `slog.Logger` pointer
+under the same context key that is also used by `NewContext` and
+`FromContext` for `logr.Logger` value.
+
+When `NewContextWithSlogLogger` is followed by `FromContext`, the latter will
+automatically convert the `slog.Logger` to a
+`logr.Logger`. `FromContextAsSlogLogger` does the same for the other direction.
+
+With this approach, binaries which use either slog or logr are as efficient as
+possible with no unnecessary allocations. This is also why the API stores a
+`slog.Logger` pointer: when storing a `slog.Handler`, creating a `slog.Logger`
+on retrieval would need to allocate one.
+
+The downside is that switching back and forth needs more allocations. Because
+logr is the API that is already in use by different packages, in particular
+Kubernetes, the recommendation is to use the `logr.Logger` API in code which
+uses contextual logging.
+
+An alternative to adding values to a logger and storing that logger in the
+context is to store the values in the context and to configure a logging
+backend to extract those values when emitting log entries. This only works when
+log calls are passed the context, which is not supported by the logr API.
+
+With the slog API, it is possible, but not
+required. https://github.com/veqryn/slog-context is a package for slog which
+provides additional support code for this approach. It also contains wrappers
+for the context functions in logr, so developers who prefer to not use the logr
+APIs directly can use those instead and the resulting code will still be
+interoperable with logr.
+
 ## FAQ
 
 ### Conceptual
@@ -241,7 +364,9 @@ Otherwise, you can start out with `0` as "you always want to see this",
 
 Then gradually choose levels in between as you need them, working your way
 down from 10 (for debug and trace style logs) and up from 1 (for chattier
-info-type logs.)
+info-type logs). For reference, slog pre-defines -4 for debug logs
+(corresponds to 4 in logr), which matches what is
+[recommended for Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use).
 
 #### How do I choose my keys?
 
diff --git a/vendor/github.com/go-logr/logr/SECURITY.md b/vendor/github.com/go-logr/logr/SECURITY.md
new file mode 100644
index 00000000..1ca756fc
--- /dev/null
+++ b/vendor/github.com/go-logr/logr/SECURITY.md
@@ -0,0 +1,18 @@
+# Security Policy
+
+If you have discovered a security vulnerability in this project, please report it
+privately. **Do not disclose it as a public issue.** This gives us time to work with you
+to fix the issue before public exposure, reducing the chance that the exploit will be
+used before a patch is released.
+
+You may submit the report in the following ways:
+
+- send an email to go-logr-security@googlegroups.com
+- send us a [private vulnerability report](https://github.com/go-logr/logr/security/advisories/new)
+
+Please provide the following information in your report:
+
+- A description of the vulnerability and its impact
+- How to reproduce the issue
+
+We ask that you give us 90 days to work on a fix before public exposure.
diff --git a/vendor/gopkg.in/yaml.v2/NOTICE b/vendor/github.com/go-logr/logr/context.go
similarity index 51%
rename from vendor/gopkg.in/yaml.v2/NOTICE
rename to vendor/github.com/go-logr/logr/context.go
index 866d74a7..de8bcc3a 100644
--- a/vendor/gopkg.in/yaml.v2/NOTICE
+++ b/vendor/github.com/go-logr/logr/context.go
@@ -1,4 +1,5 @@
-Copyright 2011-2016 Canonical Ltd.
+/*
+Copyright 2023 The logr Authors.
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
@@ -11,3 +12,22 @@ 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 logr
+
+// contextKey is how we find Loggers in a context.Context. With Go < 1.21,
+// the value is always a Logger value. With Go >= 1.21, the value can be a
+// Logger value or a slog.Logger pointer.
+type contextKey struct{}
+
+// notFoundError exists to carry an IsNotFound method.
+type notFoundError struct{}
+
+func (notFoundError) Error() string {
+	return "no logr.Logger was present"
+}
+
+func (notFoundError) IsNotFound() bool {
+	return true
+}
diff --git a/vendor/github.com/go-logr/logr/context_noslog.go b/vendor/github.com/go-logr/logr/context_noslog.go
new file mode 100644
index 00000000..f012f9a1
--- /dev/null
+++ b/vendor/github.com/go-logr/logr/context_noslog.go
@@ -0,0 +1,49 @@
+//go:build !go1.21
+// +build !go1.21
+
+/*
+Copyright 2019 The logr 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 logr
+
+import (
+	"context"
+)
+
+// FromContext returns a Logger from ctx or an error if no Logger is found.
+func FromContext(ctx context.Context) (Logger, error) {
+	if v, ok := ctx.Value(contextKey{}).(Logger); ok {
+		return v, nil
+	}
+
+	return Logger{}, notFoundError{}
+}
+
+// FromContextOrDiscard returns a Logger from ctx.  If no Logger is found, this
+// returns a Logger that discards all log messages.
+func FromContextOrDiscard(ctx context.Context) Logger {
+	if v, ok := ctx.Value(contextKey{}).(Logger); ok {
+		return v
+	}
+
+	return Discard()
+}
+
+// NewContext returns a new Context, derived from ctx, which carries the
+// provided Logger.
+func NewContext(ctx context.Context, logger Logger) context.Context {
+	return context.WithValue(ctx, contextKey{}, logger)
+}
diff --git a/vendor/github.com/go-logr/logr/context_slog.go b/vendor/github.com/go-logr/logr/context_slog.go
new file mode 100644
index 00000000..065ef0b8
--- /dev/null
+++ b/vendor/github.com/go-logr/logr/context_slog.go
@@ -0,0 +1,83 @@
+//go:build go1.21
+// +build go1.21
+
+/*
+Copyright 2019 The logr 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 logr
+
+import (
+	"context"
+	"fmt"
+	"log/slog"
+)
+
+// FromContext returns a Logger from ctx or an error if no Logger is found.
+func FromContext(ctx context.Context) (Logger, error) {
+	v := ctx.Value(contextKey{})
+	if v == nil {
+		return Logger{}, notFoundError{}
+	}
+
+	switch v := v.(type) {
+	case Logger:
+		return v, nil
+	case *slog.Logger:
+		return FromSlogHandler(v.Handler()), nil
+	default:
+		// Not reached.
+		panic(fmt.Sprintf("unexpected value type for logr context key: %T", v))
+	}
+}
+
+// FromContextAsSlogLogger returns a slog.Logger from ctx or nil if no such Logger is found.
+func FromContextAsSlogLogger(ctx context.Context) *slog.Logger {
+	v := ctx.Value(contextKey{})
+	if v == nil {
+		return nil
+	}
+
+	switch v := v.(type) {
+	case Logger:
+		return slog.New(ToSlogHandler(v))
+	case *slog.Logger:
+		return v
+	default:
+		// Not reached.
+		panic(fmt.Sprintf("unexpected value type for logr context key: %T", v))
+	}
+}
+
+// FromContextOrDiscard returns a Logger from ctx.  If no Logger is found, this
+// returns a Logger that discards all log messages.
+func FromContextOrDiscard(ctx context.Context) Logger {
+	if logger, err := FromContext(ctx); err == nil {
+		return logger
+	}
+	return Discard()
+}
+
+// NewContext returns a new Context, derived from ctx, which carries the
+// provided Logger.
+func NewContext(ctx context.Context, logger Logger) context.Context {
+	return context.WithValue(ctx, contextKey{}, logger)
+}
+
+// NewContextWithSlogLogger returns a new Context, derived from ctx, which carries the
+// provided slog.Logger.
+func NewContextWithSlogLogger(ctx context.Context, logger *slog.Logger) context.Context {
+	return context.WithValue(ctx, contextKey{}, logger)
+}
diff --git a/vendor/github.com/go-logr/logr/discard.go b/vendor/github.com/go-logr/logr/discard.go
index 9d92a38f..99fe8be9 100644
--- a/vendor/github.com/go-logr/logr/discard.go
+++ b/vendor/github.com/go-logr/logr/discard.go
@@ -20,35 +20,5 @@ package logr
 // used whenever the caller is not interested in the logs.  Logger instances
 // produced by this function always compare as equal.
 func Discard() Logger {
-	return Logger{
-		level: 0,
-		sink:  discardLogSink{},
-	}
-}
-
-// discardLogSink is a LogSink that discards all messages.
-type discardLogSink struct{}
-
-// Verify that it actually implements the interface
-var _ LogSink = discardLogSink{}
-
-func (l discardLogSink) Init(RuntimeInfo) {
-}
-
-func (l discardLogSink) Enabled(int) bool {
-	return false
-}
-
-func (l discardLogSink) Info(int, string, ...interface{}) {
-}
-
-func (l discardLogSink) Error(error, string, ...interface{}) {
-}
-
-func (l discardLogSink) WithValues(...interface{}) LogSink {
-	return l
-}
-
-func (l discardLogSink) WithName(string) LogSink {
-	return l
+	return New(nil)
 }
diff --git a/vendor/github.com/go-logr/logr/funcr/funcr.go b/vendor/github.com/go-logr/logr/funcr/funcr.go
index 7accdb0c..30568e76 100644
--- a/vendor/github.com/go-logr/logr/funcr/funcr.go
+++ b/vendor/github.com/go-logr/logr/funcr/funcr.go
@@ -21,13 +21,13 @@ limitations under the License.
 // github.com/go-logr/logr.LogSink with output through an arbitrary
 // "write" function.  See New and NewJSON for details.
 //
-// Custom LogSinks
+// # Custom LogSinks
 //
 // For users who need more control, a funcr.Formatter can be embedded inside
 // your own custom LogSink implementation. This is useful when the LogSink
 // needs to implement additional methods, for example.
 //
-// Formatting
+// # Formatting
 //
 // This will respect logr.Marshaler, fmt.Stringer, and error interfaces for
 // values which are being logged.  When rendering a struct, funcr will use Go's
@@ -37,6 +37,7 @@ package funcr
 import (
 	"bytes"
 	"encoding"
+	"encoding/json"
 	"fmt"
 	"path/filepath"
 	"reflect"
@@ -99,6 +100,11 @@ type Options struct {
 	// details, see docs for Go's time.Layout.
 	TimestampFormat string
 
+	// LogInfoLevel tells funcr what key to use to log the info level.
+	// If not specified, the info level will be logged as "level".
+	// If this is set to "", the info level will not be logged at all.
+	LogInfoLevel *string
+
 	// Verbosity tells funcr which V logs to produce.  Higher values enable
 	// more logs.  Info logs at or below this level will be written, while logs
 	// above this level will be discarded.
@@ -115,17 +121,17 @@ type Options struct {
 	// Equivalent hooks are offered for key-value pairs saved via
 	// logr.Logger.WithValues or Formatter.AddValues (see RenderValuesHook) and
 	// for user-provided pairs (see RenderArgsHook).
-	RenderBuiltinsHook func(kvList []interface{}) []interface{}
+	RenderBuiltinsHook func(kvList []any) []any
 
 	// RenderValuesHook is the same as RenderBuiltinsHook, except that it is
 	// only called for key-value pairs saved via logr.Logger.WithValues.  See
 	// RenderBuiltinsHook for more details.
-	RenderValuesHook func(kvList []interface{}) []interface{}
+	RenderValuesHook func(kvList []any) []any
 
 	// RenderArgsHook is the same as RenderBuiltinsHook, except that it is only
 	// called for key-value pairs passed directly to Info and Error.  See
 	// RenderBuiltinsHook for more details.
-	RenderArgsHook func(kvList []interface{}) []interface{}
+	RenderArgsHook func(kvList []any) []any
 
 	// MaxLogDepth tells funcr how many levels of nested fields (e.g. a struct
 	// that contains a struct, etc.) it may log.  Every time it finds a struct,
@@ -162,7 +168,7 @@ func (l fnlogger) WithName(name string) logr.LogSink {
 	return &l
 }
 
-func (l fnlogger) WithValues(kvList ...interface{}) logr.LogSink {
+func (l fnlogger) WithValues(kvList ...any) logr.LogSink {
 	l.Formatter.AddValues(kvList)
 	return &l
 }
@@ -172,12 +178,12 @@ func (l fnlogger) WithCallDepth(depth int) logr.LogSink {
 	return &l
 }
 
-func (l fnlogger) Info(level int, msg string, kvList ...interface{}) {
+func (l fnlogger) Info(level int, msg string, kvList ...any) {
 	prefix, args := l.FormatInfo(level, msg, kvList)
 	l.write(prefix, args)
 }
 
-func (l fnlogger) Error(err error, msg string, kvList ...interface{}) {
+func (l fnlogger) Error(err error, msg string, kvList ...any) {
 	prefix, args := l.FormatError(err, msg, kvList)
 	l.write(prefix, args)
 }
@@ -212,12 +218,16 @@ func newFormatter(opts Options, outfmt outputFormat) Formatter {
 	if opts.MaxLogDepth == 0 {
 		opts.MaxLogDepth = defaultMaxLogDepth
 	}
+	if opts.LogInfoLevel == nil {
+		opts.LogInfoLevel = new(string)
+		*opts.LogInfoLevel = "level"
+	}
 	f := Formatter{
 		outputFormat: outfmt,
 		prefix:       "",
 		values:       nil,
 		depth:        0,
-		opts:         opts,
+		opts:         &opts,
 	}
 	return f
 }
@@ -228,10 +238,12 @@ func newFormatter(opts Options, outfmt outputFormat) Formatter {
 type Formatter struct {
 	outputFormat outputFormat
 	prefix       string
-	values       []interface{}
+	values       []any
 	valuesStr    string
 	depth        int
-	opts         Options
+	opts         *Options
+	groupName    string // for slog groups
+	groups       []groupDef
 }
 
 // outputFormat indicates which outputFormat to use.
@@ -244,70 +256,139 @@ const (
 	outputJSON
 )
 
+// groupDef represents a saved group.  The values may be empty, but we don't
+// know if we need to render the group until the final record is rendered.
+type groupDef struct {
+	name   string
+	values string
+}
+
 // PseudoStruct is a list of key-value pairs that gets logged as a struct.
-type PseudoStruct []interface{}
+type PseudoStruct []any
 
 // render produces a log line, ready to use.
-func (f Formatter) render(builtins, args []interface{}) string {
+func (f Formatter) render(builtins, args []any) string {
 	// Empirically bytes.Buffer is faster than strings.Builder for this.
 	buf := bytes.NewBuffer(make([]byte, 0, 1024))
+
 	if f.outputFormat == outputJSON {
-		buf.WriteByte('{')
+		buf.WriteByte('{') // for the whole record
 	}
+
+	// Render builtins
 	vals := builtins
 	if hook := f.opts.RenderBuiltinsHook; hook != nil {
 		vals = hook(f.sanitize(vals))
 	}
-	f.flatten(buf, vals, false, false) // keys are ours, no need to escape
+	f.flatten(buf, vals, false) // keys are ours, no need to escape
 	continuing := len(builtins) > 0
-	if len(f.valuesStr) > 0 {
+
+	// Turn the inner-most group into a string
+	argsStr := func() string {
+		buf := bytes.NewBuffer(make([]byte, 0, 1024))
+
+		vals = args
+		if hook := f.opts.RenderArgsHook; hook != nil {
+			vals = hook(f.sanitize(vals))
+		}
+		f.flatten(buf, vals, true) // escape user-provided keys
+
+		return buf.String()
+	}()
+
+	// Render the stack of groups from the inside out.
+	bodyStr := f.renderGroup(f.groupName, f.valuesStr, argsStr)
+	for i := len(f.groups) - 1; i >= 0; i-- {
+		grp := &f.groups[i]
+		if grp.values == "" && bodyStr == "" {
+			// no contents, so we must elide the whole group
+			continue
+		}
+		bodyStr = f.renderGroup(grp.name, grp.values, bodyStr)
+	}
+
+	if bodyStr != "" {
 		if continuing {
-			if f.outputFormat == outputJSON {
-				buf.WriteByte(',')
-			} else {
-				buf.WriteByte(' ')
-			}
+			buf.WriteByte(f.comma())
 		}
+		buf.WriteString(bodyStr)
+	}
+
+	if f.outputFormat == outputJSON {
+		buf.WriteByte('}') // for the whole record
+	}
+
+	return buf.String()
+}
+
+// renderGroup returns a string representation of the named group with rendered
+// values and args.  If the name is empty, this will return the values and args,
+// joined.  If the name is not empty, this will return a single key-value pair,
+// where the value is a grouping of the values and args.  If the values and
+// args are both empty, this will return an empty string, even if the name was
+// specified.
+func (f Formatter) renderGroup(name string, values string, args string) string {
+	buf := bytes.NewBuffer(make([]byte, 0, 1024))
+
+	needClosingBrace := false
+	if name != "" && (values != "" || args != "") {
+		buf.WriteString(f.quoted(name, true)) // escape user-provided keys
+		buf.WriteByte(f.colon())
+		buf.WriteByte('{')
+		needClosingBrace = true
+	}
+
+	continuing := false
+	if values != "" {
+		buf.WriteString(values)
 		continuing = true
-		buf.WriteString(f.valuesStr)
 	}
-	vals = args
-	if hook := f.opts.RenderArgsHook; hook != nil {
-		vals = hook(f.sanitize(vals))
+
+	if args != "" {
+		if continuing {
+			buf.WriteByte(f.comma())
+		}
+		buf.WriteString(args)
 	}
-	f.flatten(buf, vals, continuing, true) // escape user-provided keys
-	if f.outputFormat == outputJSON {
+
+	if needClosingBrace {
 		buf.WriteByte('}')
 	}
+
 	return buf.String()
 }
 
-// flatten renders a list of key-value pairs into a buffer.  If continuing is
-// true, it assumes that the buffer has previous values and will emit a
-// separator (which depends on the output format) before the first pair it
-// writes.  If escapeKeys is true, the keys are assumed to have
-// non-JSON-compatible characters in them and must be evaluated for escapes.
+// flatten renders a list of key-value pairs into a buffer.  If escapeKeys is
+// true, the keys are assumed to have non-JSON-compatible characters in them
+// and must be evaluated for escapes.
 //
 // This function returns a potentially modified version of kvList, which
 // ensures that there is a value for every key (adding a value if needed) and
 // that each key is a string (substituting a key if needed).
-func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing bool, escapeKeys bool) []interface{} {
+func (f Formatter) flatten(buf *bytes.Buffer, kvList []any, escapeKeys bool) []any {
 	// This logic overlaps with sanitize() but saves one type-cast per key,
 	// which can be measurable.
 	if len(kvList)%2 != 0 {
 		kvList = append(kvList, noValue)
 	}
+	copied := false
 	for i := 0; i < len(kvList); i += 2 {
 		k, ok := kvList[i].(string)
 		if !ok {
+			if !copied {
+				newList := make([]any, len(kvList))
+				copy(newList, kvList)
+				kvList = newList
+				copied = true
+			}
 			k = f.nonStringKey(kvList[i])
 			kvList[i] = k
 		}
 		v := kvList[i+1]
 
-		if i > 0 || continuing {
+		if i > 0 {
 			if f.outputFormat == outputJSON {
-				buf.WriteByte(',')
+				buf.WriteByte(f.comma())
 			} else {
 				// In theory the format could be something we don't understand.  In
 				// practice, we control it, so it won't be.
@@ -315,25 +396,36 @@ func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing b
 			}
 		}
 
-		if escapeKeys {
-			buf.WriteString(prettyString(k))
-		} else {
-			// this is faster
-			buf.WriteByte('"')
-			buf.WriteString(k)
-			buf.WriteByte('"')
-		}
-		if f.outputFormat == outputJSON {
-			buf.WriteByte(':')
-		} else {
-			buf.WriteByte('=')
-		}
+		buf.WriteString(f.quoted(k, escapeKeys))
+		buf.WriteByte(f.colon())
 		buf.WriteString(f.pretty(v))
 	}
 	return kvList
 }
 
-func (f Formatter) pretty(value interface{}) string {
+func (f Formatter) quoted(str string, escape bool) string {
+	if escape {
+		return prettyString(str)
+	}
+	// this is faster
+	return `"` + str + `"`
+}
+
+func (f Formatter) comma() byte {
+	if f.outputFormat == outputJSON {
+		return ','
+	}
+	return ' '
+}
+
+func (f Formatter) colon() byte {
+	if f.outputFormat == outputJSON {
+		return ':'
+	}
+	return '='
+}
+
+func (f Formatter) pretty(value any) string {
 	return f.prettyWithFlags(value, 0, 0)
 }
 
@@ -342,7 +434,7 @@ const (
 )
 
 // TODO: This is not fast. Most of the overhead goes here.
-func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) string {
+func (f Formatter) prettyWithFlags(value any, flags uint32, depth int) string {
 	if depth > f.opts.MaxLogDepth {
 		return `"<max-log-depth-exceeded>"`
 	}
@@ -406,12 +498,12 @@ func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) s
 		}
 		for i := 0; i < len(v); i += 2 {
 			if i > 0 {
-				buf.WriteByte(',')
+				buf.WriteByte(f.comma())
 			}
 			k, _ := v[i].(string) // sanitize() above means no need to check success
 			// arbitrary keys might need escaping
 			buf.WriteString(prettyString(k))
-			buf.WriteByte(':')
+			buf.WriteByte(f.colon())
 			buf.WriteString(f.prettyWithFlags(v[i+1], 0, depth+1))
 		}
 		if flags&flagRawStruct == 0 {
@@ -447,6 +539,7 @@ func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) s
 		if flags&flagRawStruct == 0 {
 			buf.WriteByte('{')
 		}
+		printComma := false // testing i>0 is not enough because of JSON omitted fields
 		for i := 0; i < t.NumField(); i++ {
 			fld := t.Field(i)
 			if fld.PkgPath != "" {
@@ -478,9 +571,10 @@ func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) s
 			if omitempty && isEmpty(v.Field(i)) {
 				continue
 			}
-			if i > 0 {
-				buf.WriteByte(',')
+			if printComma {
+				buf.WriteByte(f.comma())
 			}
+			printComma = true // if we got here, we are rendering a field
 			if fld.Anonymous && fld.Type.Kind() == reflect.Struct && name == "" {
 				buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), flags|flagRawStruct, depth+1))
 				continue
@@ -489,10 +583,8 @@ func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) s
 				name = fld.Name
 			}
 			// field names can't contain characters which need escaping
-			buf.WriteByte('"')
-			buf.WriteString(name)
-			buf.WriteByte('"')
-			buf.WriteByte(':')
+			buf.WriteString(f.quoted(name, false))
+			buf.WriteByte(f.colon())
 			buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), 0, depth+1))
 		}
 		if flags&flagRawStruct == 0 {
@@ -500,10 +592,24 @@ func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) s
 		}
 		return buf.String()
 	case reflect.Slice, reflect.Array:
+		// If this is outputing as JSON make sure this isn't really a json.RawMessage.
+		// If so just emit "as-is" and don't pretty it as that will just print
+		// it as [X,Y,Z,...] which isn't terribly useful vs the string form you really want.
+		if f.outputFormat == outputJSON {
+			if rm, ok := value.(json.RawMessage); ok {
+				// If it's empty make sure we emit an empty value as the array style would below.
+				if len(rm) > 0 {
+					buf.Write(rm)
+				} else {
+					buf.WriteString("null")
+				}
+				return buf.String()
+			}
+		}
 		buf.WriteByte('[')
 		for i := 0; i < v.Len(); i++ {
 			if i > 0 {
-				buf.WriteByte(',')
+				buf.WriteByte(f.comma())
 			}
 			e := v.Index(i)
 			buf.WriteString(f.prettyWithFlags(e.Interface(), 0, depth+1))
@@ -517,7 +623,7 @@ func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) s
 		i := 0
 		for it.Next() {
 			if i > 0 {
-				buf.WriteByte(',')
+				buf.WriteByte(f.comma())
 			}
 			// If a map key supports TextMarshaler, use it.
 			keystr := ""
@@ -539,7 +645,7 @@ func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) s
 				}
 			}
 			buf.WriteString(keystr)
-			buf.WriteByte(':')
+			buf.WriteByte(f.colon())
 			buf.WriteString(f.prettyWithFlags(it.Value().Interface(), 0, depth+1))
 			i++
 		}
@@ -597,7 +703,7 @@ func isEmpty(v reflect.Value) bool {
 	return false
 }
 
-func invokeMarshaler(m logr.Marshaler) (ret interface{}) {
+func invokeMarshaler(m logr.Marshaler) (ret any) {
 	defer func() {
 		if r := recover(); r != nil {
 			ret = fmt.Sprintf("<panic: %s>", r)
@@ -658,12 +764,12 @@ func (f Formatter) caller() Caller {
 
 const noValue = "<no-value>"
 
-func (f Formatter) nonStringKey(v interface{}) string {
+func (f Formatter) nonStringKey(v any) string {
 	return fmt.Sprintf("<non-string-key: %s>", f.snippet(v))
 }
 
 // snippet produces a short snippet string of an arbitrary value.
-func (f Formatter) snippet(v interface{}) string {
+func (f Formatter) snippet(v any) string {
 	const snipLen = 16
 
 	snip := f.pretty(v)
@@ -676,7 +782,7 @@ func (f Formatter) snippet(v interface{}) string {
 // sanitize ensures that a list of key-value pairs has a value for every key
 // (adding a value if needed) and that each key is a string (substituting a key
 // if needed).
-func (f Formatter) sanitize(kvList []interface{}) []interface{} {
+func (f Formatter) sanitize(kvList []any) []any {
 	if len(kvList)%2 != 0 {
 		kvList = append(kvList, noValue)
 	}
@@ -689,6 +795,24 @@ func (f Formatter) sanitize(kvList []interface{}) []interface{} {
 	return kvList
 }
 
+// startGroup opens a new group scope (basically a sub-struct), which locks all
+// the current saved values and starts them anew.  This is needed to satisfy
+// slog.
+func (f *Formatter) startGroup(name string) {
+	// Unnamed groups are just inlined.
+	if name == "" {
+		return
+	}
+
+	n := len(f.groups)
+	f.groups = append(f.groups[:n:n], groupDef{f.groupName, f.valuesStr})
+
+	// Start collecting new values.
+	f.groupName = name
+	f.valuesStr = ""
+	f.values = nil
+}
+
 // Init configures this Formatter from runtime info, such as the call depth
 // imposed by logr itself.
 // Note that this receiver is a pointer, so depth can be saved.
@@ -710,8 +834,8 @@ func (f Formatter) GetDepth() int {
 // FormatInfo renders an Info log message into strings.  The prefix will be
 // empty when no names were set (via AddNames), or when the output is
 // configured for JSON.
-func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (prefix, argsStr string) {
-	args := make([]interface{}, 0, 64) // using a constant here impacts perf
+func (f Formatter) FormatInfo(level int, msg string, kvList []any) (prefix, argsStr string) {
+	args := make([]any, 0, 64) // using a constant here impacts perf
 	prefix = f.prefix
 	if f.outputFormat == outputJSON {
 		args = append(args, "logger", prefix)
@@ -723,15 +847,18 @@ func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (pref
 	if policy := f.opts.LogCaller; policy == All || policy == Info {
 		args = append(args, "caller", f.caller())
 	}
-	args = append(args, "level", level, "msg", msg)
+	if key := *f.opts.LogInfoLevel; key != "" {
+		args = append(args, key, level)
+	}
+	args = append(args, "msg", msg)
 	return prefix, f.render(args, kvList)
 }
 
 // FormatError renders an Error log message into strings.  The prefix will be
-// empty when no names were set (via AddNames),  or when the output is
+// empty when no names were set (via AddNames), or when the output is
 // configured for JSON.
-func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string) {
-	args := make([]interface{}, 0, 64) // using a constant here impacts perf
+func (f Formatter) FormatError(err error, msg string, kvList []any) (prefix, argsStr string) {
+	args := make([]any, 0, 64) // using a constant here impacts perf
 	prefix = f.prefix
 	if f.outputFormat == outputJSON {
 		args = append(args, "logger", prefix)
@@ -744,12 +871,12 @@ func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (pre
 		args = append(args, "caller", f.caller())
 	}
 	args = append(args, "msg", msg)
-	var loggableErr interface{}
+	var loggableErr any
 	if err != nil {
 		loggableErr = err.Error()
 	}
 	args = append(args, "error", loggableErr)
-	return f.prefix, f.render(args, kvList)
+	return prefix, f.render(args, kvList)
 }
 
 // AddName appends the specified name.  funcr uses '/' characters to separate
@@ -764,7 +891,7 @@ func (f *Formatter) AddName(name string) {
 
 // AddValues adds key-value pairs to the set of saved values to be logged with
 // each log line.
-func (f *Formatter) AddValues(kvList []interface{}) {
+func (f *Formatter) AddValues(kvList []any) {
 	// Three slice args forces a copy.
 	n := len(f.values)
 	f.values = append(f.values[:n:n], kvList...)
@@ -776,7 +903,7 @@ func (f *Formatter) AddValues(kvList []interface{}) {
 
 	// Pre-render values, so we don't have to do it on each Info/Error call.
 	buf := bytes.NewBuffer(make([]byte, 0, 1024))
-	f.flatten(buf, vals, false, true) // escape user-provided keys
+	f.flatten(buf, vals, true) // escape user-provided keys
 	f.valuesStr = buf.String()
 }
 
diff --git a/vendor/github.com/go-logr/logr/funcr/slogsink.go b/vendor/github.com/go-logr/logr/funcr/slogsink.go
new file mode 100644
index 00000000..7bd84761
--- /dev/null
+++ b/vendor/github.com/go-logr/logr/funcr/slogsink.go
@@ -0,0 +1,105 @@
+//go:build go1.21
+// +build go1.21
+
+/*
+Copyright 2023 The logr 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 funcr
+
+import (
+	"context"
+	"log/slog"
+
+	"github.com/go-logr/logr"
+)
+
+var _ logr.SlogSink = &fnlogger{}
+
+const extraSlogSinkDepth = 3 // 2 for slog, 1 for SlogSink
+
+func (l fnlogger) Handle(_ context.Context, record slog.Record) error {
+	kvList := make([]any, 0, 2*record.NumAttrs())
+	record.Attrs(func(attr slog.Attr) bool {
+		kvList = attrToKVs(attr, kvList)
+		return true
+	})
+
+	if record.Level >= slog.LevelError {
+		l.WithCallDepth(extraSlogSinkDepth).Error(nil, record.Message, kvList...)
+	} else {
+		level := l.levelFromSlog(record.Level)
+		l.WithCallDepth(extraSlogSinkDepth).Info(level, record.Message, kvList...)
+	}
+	return nil
+}
+
+func (l fnlogger) WithAttrs(attrs []slog.Attr) logr.SlogSink {
+	kvList := make([]any, 0, 2*len(attrs))
+	for _, attr := range attrs {
+		kvList = attrToKVs(attr, kvList)
+	}
+	l.AddValues(kvList)
+	return &l
+}
+
+func (l fnlogger) WithGroup(name string) logr.SlogSink {
+	l.startGroup(name)
+	return &l
+}
+
+// attrToKVs appends a slog.Attr to a logr-style kvList.  It handle slog Groups
+// and other details of slog.
+func attrToKVs(attr slog.Attr, kvList []any) []any {
+	attrVal := attr.Value.Resolve()
+	if attrVal.Kind() == slog.KindGroup {
+		groupVal := attrVal.Group()
+		grpKVs := make([]any, 0, 2*len(groupVal))
+		for _, attr := range groupVal {
+			grpKVs = attrToKVs(attr, grpKVs)
+		}
+		if attr.Key == "" {
+			// slog says we have to inline these
+			kvList = append(kvList, grpKVs...)
+		} else {
+			kvList = append(kvList, attr.Key, PseudoStruct(grpKVs))
+		}
+	} else if attr.Key != "" {
+		kvList = append(kvList, attr.Key, attrVal.Any())
+	}
+
+	return kvList
+}
+
+// levelFromSlog adjusts the level by the logger's verbosity and negates it.
+// It ensures that the result is >= 0. This is necessary because the result is
+// passed to a LogSink and that API did not historically document whether
+// levels could be negative or what that meant.
+//
+// Some example usage:
+//
+//	logrV0 := getMyLogger()
+//	logrV2 := logrV0.V(2)
+//	slogV2 := slog.New(logr.ToSlogHandler(logrV2))
+//	slogV2.Debug("msg") // =~ logrV2.V(4) =~ logrV0.V(6)
+//	slogV2.Info("msg")  // =~  logrV2.V(0) =~ logrV0.V(2)
+//	slogv2.Warn("msg")  // =~ logrV2.V(-4) =~ logrV0.V(0)
+func (l fnlogger) levelFromSlog(level slog.Level) int {
+	result := -level
+	if result < 0 {
+		result = 0 // because LogSink doesn't expect negative V levels
+	}
+	return int(result)
+}
diff --git a/vendor/github.com/go-logr/logr/logr.go b/vendor/github.com/go-logr/logr/logr.go
index c3b56b3d..b4428e10 100644
--- a/vendor/github.com/go-logr/logr/logr.go
+++ b/vendor/github.com/go-logr/logr/logr.go
@@ -21,7 +21,7 @@ limitations under the License.
 // to back that API.  Packages in the Go ecosystem can depend on this package,
 // while callers can implement logging with whatever backend is appropriate.
 //
-// Usage
+// # Usage
 //
 // Logging is done using a Logger instance.  Logger is a concrete type with
 // methods, which defers the actual logging to a LogSink interface.  The main
@@ -30,16 +30,20 @@ limitations under the License.
 // "structured logging".
 //
 // With Go's standard log package, we might write:
-//   log.Printf("setting target value %s", targetValue)
+//
+//	log.Printf("setting target value %s", targetValue)
 //
 // With logr's structured logging, we'd write:
-//   logger.Info("setting target", "value", targetValue)
+//
+//	logger.Info("setting target", "value", targetValue)
 //
 // Errors are much the same.  Instead of:
-//   log.Printf("failed to open the pod bay door for user %s: %v", user, err)
+//
+//	log.Printf("failed to open the pod bay door for user %s: %v", user, err)
 //
 // We'd write:
-//   logger.Error(err, "failed to open the pod bay door", "user", user)
+//
+//	logger.Error(err, "failed to open the pod bay door", "user", user)
 //
 // Info() and Error() are very similar, but they are separate methods so that
 // LogSink implementations can choose to do things like attach additional
@@ -47,7 +51,7 @@ limitations under the License.
 // always logged, regardless of the current verbosity.  If there is no error
 // instance available, passing nil is valid.
 //
-// Verbosity
+// # Verbosity
 //
 // Often we want to log information only when the application in "verbose
 // mode".  To write log lines that are more verbose, Logger has a V() method.
@@ -58,20 +62,22 @@ limitations under the License.
 // Error messages do not have a verbosity level and are always logged.
 //
 // Where we might have written:
-//   if flVerbose >= 2 {
-//       log.Printf("an unusual thing happened")
-//   }
+//
+//	if flVerbose >= 2 {
+//	    log.Printf("an unusual thing happened")
+//	}
 //
 // We can write:
-//   logger.V(2).Info("an unusual thing happened")
 //
-// Logger Names
+//	logger.V(2).Info("an unusual thing happened")
+//
+// # Logger Names
 //
 // Logger instances can have name strings so that all messages logged through
 // that instance have additional context.  For example, you might want to add
 // a subsystem name:
 //
-//   logger.WithName("compactor").Info("started", "time", time.Now())
+//	logger.WithName("compactor").Info("started", "time", time.Now())
 //
 // The WithName() method returns a new Logger, which can be passed to
 // constructors or other functions for further use.  Repeated use of WithName()
@@ -82,25 +88,27 @@ limitations under the License.
 // joining operation (e.g. whitespace, commas, periods, slashes, brackets,
 // quotes, etc).
 //
-// Saved Values
+// # Saved Values
 //
 // Logger instances can store any number of key/value pairs, which will be
 // logged alongside all messages logged through that instance.  For example,
 // you might want to create a Logger instance per managed object:
 //
 // With the standard log package, we might write:
-//   log.Printf("decided to set field foo to value %q for object %s/%s",
-//       targetValue, object.Namespace, object.Name)
+//
+//	log.Printf("decided to set field foo to value %q for object %s/%s",
+//	    targetValue, object.Namespace, object.Name)
 //
 // With logr we'd write:
-//   // Elsewhere: set up the logger to log the object name.
-//   obj.logger = mainLogger.WithValues(
-//       "name", obj.name, "namespace", obj.namespace)
 //
-//   // later on...
-//   obj.logger.Info("setting foo", "value", targetValue)
+//	// Elsewhere: set up the logger to log the object name.
+//	obj.logger = mainLogger.WithValues(
+//	    "name", obj.name, "namespace", obj.namespace)
 //
-// Best Practices
+//	// later on...
+//	obj.logger.Info("setting foo", "value", targetValue)
+//
+// # Best Practices
 //
 // Logger has very few hard rules, with the goal that LogSink implementations
 // might have a lot of freedom to differentiate.  There are, however, some
@@ -119,20 +127,20 @@ limitations under the License.
 // such a value can call its methods without having to check whether the
 // instance is ready for use.
 //
-// Calling methods with the null logger (Logger{}) as instance will crash
-// because it has no LogSink. Therefore this null logger should never be passed
-// around. For cases where passing a logger is optional, a pointer to Logger
+// The zero logger (= Logger{}) is identical to Discard() and discards all log
+// entries. Code that receives a Logger by value can simply call it, the methods
+// will never crash. For cases where passing a logger is optional, a pointer to Logger
 // should be used.
 //
-// Key Naming Conventions
+// # Key Naming Conventions
 //
 // Keys are not strictly required to conform to any specification or regex, but
 // it is recommended that they:
-//   * be human-readable and meaningful (not auto-generated or simple ordinals)
-//   * be constant (not dependent on input data)
-//   * contain only printable characters
-//   * not contain whitespace or punctuation
-//   * use lower case for simple keys and lowerCamelCase for more complex ones
+//   - be human-readable and meaningful (not auto-generated or simple ordinals)
+//   - be constant (not dependent on input data)
+//   - contain only printable characters
+//   - not contain whitespace or punctuation
+//   - use lower case for simple keys and lowerCamelCase for more complex ones
 //
 // These guidelines help ensure that log data is processed properly regardless
 // of the log implementation.  For example, log implementations will try to
@@ -141,51 +149,54 @@ limitations under the License.
 // While users are generally free to use key names of their choice, it's
 // generally best to avoid using the following keys, as they're frequently used
 // by implementations:
-//   * "caller": the calling information (file/line) of a particular log line
-//   * "error": the underlying error value in the `Error` method
-//   * "level": the log level
-//   * "logger": the name of the associated logger
-//   * "msg": the log message
-//   * "stacktrace": the stack trace associated with a particular log line or
-//                   error (often from the `Error` message)
-//   * "ts": the timestamp for a log line
+//   - "caller": the calling information (file/line) of a particular log line
+//   - "error": the underlying error value in the `Error` method
+//   - "level": the log level
+//   - "logger": the name of the associated logger
+//   - "msg": the log message
+//   - "stacktrace": the stack trace associated with a particular log line or
+//     error (often from the `Error` message)
+//   - "ts": the timestamp for a log line
 //
 // Implementations are encouraged to make use of these keys to represent the
 // above concepts, when necessary (for example, in a pure-JSON output form, it
 // would be necessary to represent at least message and timestamp as ordinary
 // named values).
 //
-// Break Glass
+// # Break Glass
 //
 // Implementations may choose to give callers access to the underlying
 // logging implementation.  The recommended pattern for this is:
-//   // Underlier exposes access to the underlying logging implementation.
-//   // Since callers only have a logr.Logger, they have to know which
-//   // implementation is in use, so this interface is less of an abstraction
-//   // and more of way to test type conversion.
-//   type Underlier interface {
-//       GetUnderlying() <underlying-type>
-//   }
+//
+//	// Underlier exposes access to the underlying logging implementation.
+//	// Since callers only have a logr.Logger, they have to know which
+//	// implementation is in use, so this interface is less of an abstraction
+//	// and more of way to test type conversion.
+//	type Underlier interface {
+//	    GetUnderlying() <underlying-type>
+//	}
 //
 // Logger grants access to the sink to enable type assertions like this:
-//   func DoSomethingWithImpl(log logr.Logger) {
-//       if underlier, ok := log.GetSink()(impl.Underlier) {
-//          implLogger := underlier.GetUnderlying()
-//          ...
-//       }
-//   }
+//
+//	func DoSomethingWithImpl(log logr.Logger) {
+//	    if underlier, ok := log.GetSink().(impl.Underlier); ok {
+//	       implLogger := underlier.GetUnderlying()
+//	       ...
+//	    }
+//	}
 //
 // Custom `With*` functions can be implemented by copying the complete
 // Logger struct and replacing the sink in the copy:
-//   // WithFooBar changes the foobar parameter in the log sink and returns a
-//   // new logger with that modified sink.  It does nothing for loggers where
-//   // the sink doesn't support that parameter.
-//   func WithFoobar(log logr.Logger, foobar int) logr.Logger {
-//      if foobarLogSink, ok := log.GetSink()(FoobarSink); ok {
-//         log = log.WithSink(foobarLogSink.WithFooBar(foobar))
-//      }
-//      return log
-//   }
+//
+//	// WithFooBar changes the foobar parameter in the log sink and returns a
+//	// new logger with that modified sink.  It does nothing for loggers where
+//	// the sink doesn't support that parameter.
+//	func WithFoobar(log logr.Logger, foobar int) logr.Logger {
+//	   if foobarLogSink, ok := log.GetSink().(FoobarSink); ok {
+//	      log = log.WithSink(foobarLogSink.WithFooBar(foobar))
+//	   }
+//	   return log
+//	}
 //
 // Don't use New to construct a new Logger with a LogSink retrieved from an
 // existing Logger. Source code attribution might not work correctly and
@@ -196,16 +207,15 @@ limitations under the License.
 // those.
 package logr
 
-import (
-	"context"
-)
-
 // New returns a new Logger instance.  This is primarily used by libraries
-// implementing LogSink, rather than end users.
+// implementing LogSink, rather than end users.  Passing a nil sink will create
+// a Logger which discards all log lines.
 func New(sink LogSink) Logger {
 	logger := Logger{}
 	logger.setSink(sink)
-	sink.Init(runtimeInfo)
+	if sink != nil {
+		sink.Init(runtimeInfo)
+	}
 	return logger
 }
 
@@ -244,7 +254,13 @@ type Logger struct {
 // Enabled tests whether this Logger is enabled.  For example, commandline
 // flags might be used to set the logging verbosity and disable some info logs.
 func (l Logger) Enabled() bool {
-	return l.sink.Enabled(l.level)
+	// Some implementations of LogSink look at the caller in Enabled (e.g.
+	// different verbosity levels per package or file), but we only pass one
+	// CallDepth in (via Init).  This means that all calls from Logger to the
+	// LogSink's Enabled, Info, and Error methods must have the same number of
+	// frames.  In other words, Logger methods can't call other Logger methods
+	// which call these LogSink methods unless we do it the same in all paths.
+	return l.sink != nil && l.sink.Enabled(l.level)
 }
 
 // Info logs a non-error message with the given key/value pairs as context.
@@ -253,8 +269,11 @@ func (l Logger) Enabled() bool {
 // line.  The key/value pairs can then be used to add additional variable
 // information.  The key/value pairs must alternate string keys and arbitrary
 // values.
-func (l Logger) Info(msg string, keysAndValues ...interface{}) {
-	if l.Enabled() {
+func (l Logger) Info(msg string, keysAndValues ...any) {
+	if l.sink == nil {
+		return
+	}
+	if l.sink.Enabled(l.level) { // see comment in Enabled
 		if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
 			withHelper.GetCallStackHelper()()
 		}
@@ -272,7 +291,10 @@ func (l Logger) Info(msg string, keysAndValues ...interface{}) {
 // while the err argument should be used to attach the actual error that
 // triggered this log line, if present. The err parameter is optional
 // and nil may be passed instead of an error instance.
-func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) {
+func (l Logger) Error(err error, msg string, keysAndValues ...any) {
+	if l.sink == nil {
+		return
+	}
 	if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
 		withHelper.GetCallStackHelper()()
 	}
@@ -284,6 +306,9 @@ func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) {
 // level means a log message is less important.  Negative V-levels are treated
 // as 0.
 func (l Logger) V(level int) Logger {
+	if l.sink == nil {
+		return l
+	}
 	if level < 0 {
 		level = 0
 	}
@@ -291,9 +316,19 @@ func (l Logger) V(level int) Logger {
 	return l
 }
 
+// GetV returns the verbosity level of the logger. If the logger's LogSink is
+// nil as in the Discard logger, this will always return 0.
+func (l Logger) GetV() int {
+	// 0 if l.sink nil because of the if check in V above.
+	return l.level
+}
+
 // WithValues returns a new Logger instance with additional key/value pairs.
 // See Info for documentation on how key/value pairs work.
-func (l Logger) WithValues(keysAndValues ...interface{}) Logger {
+func (l Logger) WithValues(keysAndValues ...any) Logger {
+	if l.sink == nil {
+		return l
+	}
 	l.setSink(l.sink.WithValues(keysAndValues...))
 	return l
 }
@@ -304,6 +339,9 @@ func (l Logger) WithValues(keysAndValues ...interface{}) Logger {
 // contain only letters, digits, and hyphens (see the package documentation for
 // more information).
 func (l Logger) WithName(name string) Logger {
+	if l.sink == nil {
+		return l
+	}
 	l.setSink(l.sink.WithName(name))
 	return l
 }
@@ -324,6 +362,9 @@ func (l Logger) WithName(name string) Logger {
 // WithCallDepth(1) because it works with implementions that support the
 // CallDepthLogSink and/or CallStackHelperLogSink interfaces.
 func (l Logger) WithCallDepth(depth int) Logger {
+	if l.sink == nil {
+		return l
+	}
 	if withCallDepth, ok := l.sink.(CallDepthLogSink); ok {
 		l.setSink(withCallDepth.WithCallDepth(depth))
 	}
@@ -345,6 +386,9 @@ func (l Logger) WithCallDepth(depth int) Logger {
 // implementation does not support either of these, the original Logger will be
 // returned.
 func (l Logger) WithCallStackHelper() (func(), Logger) {
+	if l.sink == nil {
+		return func() {}, l
+	}
 	var helper func()
 	if withCallDepth, ok := l.sink.(CallDepthLogSink); ok {
 		l.setSink(withCallDepth.WithCallDepth(1))
@@ -357,43 +401,9 @@ func (l Logger) WithCallStackHelper() (func(), Logger) {
 	return helper, l
 }
 
-// contextKey is how we find Loggers in a context.Context.
-type contextKey struct{}
-
-// FromContext returns a Logger from ctx or an error if no Logger is found.
-func FromContext(ctx context.Context) (Logger, error) {
-	if v, ok := ctx.Value(contextKey{}).(Logger); ok {
-		return v, nil
-	}
-
-	return Logger{}, notFoundError{}
-}
-
-// notFoundError exists to carry an IsNotFound method.
-type notFoundError struct{}
-
-func (notFoundError) Error() string {
-	return "no logr.Logger was present"
-}
-
-func (notFoundError) IsNotFound() bool {
-	return true
-}
-
-// FromContextOrDiscard returns a Logger from ctx.  If no Logger is found, this
-// returns a Logger that discards all log messages.
-func FromContextOrDiscard(ctx context.Context) Logger {
-	if v, ok := ctx.Value(contextKey{}).(Logger); ok {
-		return v
-	}
-
-	return Discard()
-}
-
-// NewContext returns a new Context, derived from ctx, which carries the
-// provided Logger.
-func NewContext(ctx context.Context, logger Logger) context.Context {
-	return context.WithValue(ctx, contextKey{}, logger)
+// IsZero returns true if this logger is an uninitialized zero value
+func (l Logger) IsZero() bool {
+	return l.sink == nil
 }
 
 // RuntimeInfo holds information that the logr "core" library knows which
@@ -427,22 +437,22 @@ type LogSink interface {
 	// The level argument is provided for optional logging.  This method will
 	// only be called when Enabled(level) is true. See Logger.Info for more
 	// details.
-	Info(level int, msg string, keysAndValues ...interface{})
+	Info(level int, msg string, keysAndValues ...any)
 
 	// Error logs an error, with the given message and key/value pairs as
 	// context.  See Logger.Error for more details.
-	Error(err error, msg string, keysAndValues ...interface{})
+	Error(err error, msg string, keysAndValues ...any)
 
 	// WithValues returns a new LogSink with additional key/value pairs.  See
 	// Logger.WithValues for more details.
-	WithValues(keysAndValues ...interface{}) LogSink
+	WithValues(keysAndValues ...any) LogSink
 
 	// WithName returns a new LogSink with the specified name appended.  See
 	// Logger.WithName for more details.
 	WithName(name string) LogSink
 }
 
-// CallDepthLogSink represents a Logger that knows how to climb the call stack
+// CallDepthLogSink represents a LogSink that knows how to climb the call stack
 // to identify the original call site and can offset the depth by a specified
 // number of frames.  This is useful for users who have helper functions
 // between the "real" call site and the actual calls to Logger methods.
@@ -467,7 +477,7 @@ type CallDepthLogSink interface {
 	WithCallDepth(depth int) LogSink
 }
 
-// CallStackHelperLogSink represents a Logger that knows how to climb
+// CallStackHelperLogSink represents a LogSink that knows how to climb
 // the call stack to identify the original call site and can skip
 // intermediate helper functions if they mark themselves as
 // helper. Go's testing package uses that approach.
@@ -506,5 +516,5 @@ type Marshaler interface {
 	//     with exported fields
 	//
 	// It may return any value of any type.
-	MarshalLog() interface{}
+	MarshalLog() any
 }
diff --git a/vendor/github.com/go-logr/logr/sloghandler.go b/vendor/github.com/go-logr/logr/sloghandler.go
new file mode 100644
index 00000000..82d1ba49
--- /dev/null
+++ b/vendor/github.com/go-logr/logr/sloghandler.go
@@ -0,0 +1,192 @@
+//go:build go1.21
+// +build go1.21
+
+/*
+Copyright 2023 The logr 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 logr
+
+import (
+	"context"
+	"log/slog"
+)
+
+type slogHandler struct {
+	// May be nil, in which case all logs get discarded.
+	sink LogSink
+	// Non-nil if sink is non-nil and implements SlogSink.
+	slogSink SlogSink
+
+	// groupPrefix collects values from WithGroup calls. It gets added as
+	// prefix to value keys when handling a log record.
+	groupPrefix string
+
+	// levelBias can be set when constructing the handler to influence the
+	// slog.Level of log records. A positive levelBias reduces the
+	// slog.Level value. slog has no API to influence this value after the
+	// handler got created, so it can only be set indirectly through
+	// Logger.V.
+	levelBias slog.Level
+}
+
+var _ slog.Handler = &slogHandler{}
+
+// groupSeparator is used to concatenate WithGroup names and attribute keys.
+const groupSeparator = "."
+
+// GetLevel is used for black box unit testing.
+func (l *slogHandler) GetLevel() slog.Level {
+	return l.levelBias
+}
+
+func (l *slogHandler) Enabled(_ context.Context, level slog.Level) bool {
+	return l.sink != nil && (level >= slog.LevelError || l.sink.Enabled(l.levelFromSlog(level)))
+}
+
+func (l *slogHandler) Handle(ctx context.Context, record slog.Record) error {
+	if l.slogSink != nil {
+		// Only adjust verbosity level of log entries < slog.LevelError.
+		if record.Level < slog.LevelError {
+			record.Level -= l.levelBias
+		}
+		return l.slogSink.Handle(ctx, record)
+	}
+
+	// No need to check for nil sink here because Handle will only be called
+	// when Enabled returned true.
+
+	kvList := make([]any, 0, 2*record.NumAttrs())
+	record.Attrs(func(attr slog.Attr) bool {
+		kvList = attrToKVs(attr, l.groupPrefix, kvList)
+		return true
+	})
+	if record.Level >= slog.LevelError {
+		l.sinkWithCallDepth().Error(nil, record.Message, kvList...)
+	} else {
+		level := l.levelFromSlog(record.Level)
+		l.sinkWithCallDepth().Info(level, record.Message, kvList...)
+	}
+	return nil
+}
+
+// sinkWithCallDepth adjusts the stack unwinding so that when Error or Info
+// are called by Handle, code in slog gets skipped.
+//
+// This offset currently (Go 1.21.0) works for calls through
+// slog.New(ToSlogHandler(...)).  There's no guarantee that the call
+// chain won't change. Wrapping the handler will also break unwinding. It's
+// still better than not adjusting at all....
+//
+// This cannot be done when constructing the handler because FromSlogHandler needs
+// access to the original sink without this adjustment. A second copy would
+// work, but then WithAttrs would have to be called for both of them.
+func (l *slogHandler) sinkWithCallDepth() LogSink {
+	if sink, ok := l.sink.(CallDepthLogSink); ok {
+		return sink.WithCallDepth(2)
+	}
+	return l.sink
+}
+
+func (l *slogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
+	if l.sink == nil || len(attrs) == 0 {
+		return l
+	}
+
+	clone := *l
+	if l.slogSink != nil {
+		clone.slogSink = l.slogSink.WithAttrs(attrs)
+		clone.sink = clone.slogSink
+	} else {
+		kvList := make([]any, 0, 2*len(attrs))
+		for _, attr := range attrs {
+			kvList = attrToKVs(attr, l.groupPrefix, kvList)
+		}
+		clone.sink = l.sink.WithValues(kvList...)
+	}
+	return &clone
+}
+
+func (l *slogHandler) WithGroup(name string) slog.Handler {
+	if l.sink == nil {
+		return l
+	}
+	if name == "" {
+		// slog says to inline empty groups
+		return l
+	}
+	clone := *l
+	if l.slogSink != nil {
+		clone.slogSink = l.slogSink.WithGroup(name)
+		clone.sink = clone.slogSink
+	} else {
+		clone.groupPrefix = addPrefix(clone.groupPrefix, name)
+	}
+	return &clone
+}
+
+// attrToKVs appends a slog.Attr to a logr-style kvList.  It handle slog Groups
+// and other details of slog.
+func attrToKVs(attr slog.Attr, groupPrefix string, kvList []any) []any {
+	attrVal := attr.Value.Resolve()
+	if attrVal.Kind() == slog.KindGroup {
+		groupVal := attrVal.Group()
+		grpKVs := make([]any, 0, 2*len(groupVal))
+		prefix := groupPrefix
+		if attr.Key != "" {
+			prefix = addPrefix(groupPrefix, attr.Key)
+		}
+		for _, attr := range groupVal {
+			grpKVs = attrToKVs(attr, prefix, grpKVs)
+		}
+		kvList = append(kvList, grpKVs...)
+	} else if attr.Key != "" {
+		kvList = append(kvList, addPrefix(groupPrefix, attr.Key), attrVal.Any())
+	}
+
+	return kvList
+}
+
+func addPrefix(prefix, name string) string {
+	if prefix == "" {
+		return name
+	}
+	if name == "" {
+		return prefix
+	}
+	return prefix + groupSeparator + name
+}
+
+// levelFromSlog adjusts the level by the logger's verbosity and negates it.
+// It ensures that the result is >= 0. This is necessary because the result is
+// passed to a LogSink and that API did not historically document whether
+// levels could be negative or what that meant.
+//
+// Some example usage:
+//
+//	logrV0 := getMyLogger()
+//	logrV2 := logrV0.V(2)
+//	slogV2 := slog.New(logr.ToSlogHandler(logrV2))
+//	slogV2.Debug("msg") // =~ logrV2.V(4) =~ logrV0.V(6)
+//	slogV2.Info("msg")  // =~  logrV2.V(0) =~ logrV0.V(2)
+//	slogv2.Warn("msg")  // =~ logrV2.V(-4) =~ logrV0.V(0)
+func (l *slogHandler) levelFromSlog(level slog.Level) int {
+	result := -level
+	result += l.levelBias // in case the original Logger had a V level
+	if result < 0 {
+		result = 0 // because LogSink doesn't expect negative V levels
+	}
+	return int(result)
+}
diff --git a/vendor/github.com/go-logr/logr/slogr.go b/vendor/github.com/go-logr/logr/slogr.go
new file mode 100644
index 00000000..28a83d02
--- /dev/null
+++ b/vendor/github.com/go-logr/logr/slogr.go
@@ -0,0 +1,100 @@
+//go:build go1.21
+// +build go1.21
+
+/*
+Copyright 2023 The logr 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 logr
+
+import (
+	"context"
+	"log/slog"
+)
+
+// FromSlogHandler returns a Logger which writes to the slog.Handler.
+//
+// The logr verbosity level is mapped to slog levels such that V(0) becomes
+// slog.LevelInfo and V(4) becomes slog.LevelDebug.
+func FromSlogHandler(handler slog.Handler) Logger {
+	if handler, ok := handler.(*slogHandler); ok {
+		if handler.sink == nil {
+			return Discard()
+		}
+		return New(handler.sink).V(int(handler.levelBias))
+	}
+	return New(&slogSink{handler: handler})
+}
+
+// ToSlogHandler returns a slog.Handler which writes to the same sink as the Logger.
+//
+// The returned logger writes all records with level >= slog.LevelError as
+// error log entries with LogSink.Error, regardless of the verbosity level of
+// the Logger:
+//
+//	logger := <some Logger with 0 as verbosity level>
+//	slog.New(ToSlogHandler(logger.V(10))).Error(...) -> logSink.Error(...)
+//
+// The level of all other records gets reduced by the verbosity
+// level of the Logger and the result is negated. If it happens
+// to be negative, then it gets replaced by zero because a LogSink
+// is not expected to handled negative levels:
+//
+//	slog.New(ToSlogHandler(logger)).Debug(...) -> logger.GetSink().Info(level=4, ...)
+//	slog.New(ToSlogHandler(logger)).Warning(...) -> logger.GetSink().Info(level=0, ...)
+//	slog.New(ToSlogHandler(logger)).Info(...) -> logger.GetSink().Info(level=0, ...)
+//	slog.New(ToSlogHandler(logger.V(4))).Info(...) -> logger.GetSink().Info(level=4, ...)
+func ToSlogHandler(logger Logger) slog.Handler {
+	if sink, ok := logger.GetSink().(*slogSink); ok && logger.GetV() == 0 {
+		return sink.handler
+	}
+
+	handler := &slogHandler{sink: logger.GetSink(), levelBias: slog.Level(logger.GetV())}
+	if slogSink, ok := handler.sink.(SlogSink); ok {
+		handler.slogSink = slogSink
+	}
+	return handler
+}
+
+// SlogSink is an optional interface that a LogSink can implement to support
+// logging through the slog.Logger or slog.Handler APIs better. It then should
+// also support special slog values like slog.Group. When used as a
+// slog.Handler, the advantages are:
+//
+//   - stack unwinding gets avoided in favor of logging the pre-recorded PC,
+//     as intended by slog
+//   - proper grouping of key/value pairs via WithGroup
+//   - verbosity levels > slog.LevelInfo can be recorded
+//   - less overhead
+//
+// Both APIs (Logger and slog.Logger/Handler) then are supported equally
+// well. Developers can pick whatever API suits them better and/or mix
+// packages which use either API in the same binary with a common logging
+// implementation.
+//
+// This interface is necessary because the type implementing the LogSink
+// interface cannot also implement the slog.Handler interface due to the
+// different prototype of the common Enabled method.
+//
+// An implementation could support both interfaces in two different types, but then
+// additional interfaces would be needed to convert between those types in FromSlogHandler
+// and ToSlogHandler.
+type SlogSink interface {
+	LogSink
+
+	Handle(ctx context.Context, record slog.Record) error
+	WithAttrs(attrs []slog.Attr) SlogSink
+	WithGroup(name string) SlogSink
+}
diff --git a/vendor/github.com/go-logr/logr/slogsink.go b/vendor/github.com/go-logr/logr/slogsink.go
new file mode 100644
index 00000000..4060fcbc
--- /dev/null
+++ b/vendor/github.com/go-logr/logr/slogsink.go
@@ -0,0 +1,120 @@
+//go:build go1.21
+// +build go1.21
+
+/*
+Copyright 2023 The logr 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 logr
+
+import (
+	"context"
+	"log/slog"
+	"runtime"
+	"time"
+)
+
+var (
+	_ LogSink          = &slogSink{}
+	_ CallDepthLogSink = &slogSink{}
+	_ Underlier        = &slogSink{}
+)
+
+// Underlier is implemented by the LogSink returned by NewFromLogHandler.
+type Underlier interface {
+	// GetUnderlying returns the Handler used by the LogSink.
+	GetUnderlying() slog.Handler
+}
+
+const (
+	// nameKey is used to log the `WithName` values as an additional attribute.
+	nameKey = "logger"
+
+	// errKey is used to log the error parameter of Error as an additional attribute.
+	errKey = "err"
+)
+
+type slogSink struct {
+	callDepth int
+	name      string
+	handler   slog.Handler
+}
+
+func (l *slogSink) Init(info RuntimeInfo) {
+	l.callDepth = info.CallDepth
+}
+
+func (l *slogSink) GetUnderlying() slog.Handler {
+	return l.handler
+}
+
+func (l *slogSink) WithCallDepth(depth int) LogSink {
+	newLogger := *l
+	newLogger.callDepth += depth
+	return &newLogger
+}
+
+func (l *slogSink) Enabled(level int) bool {
+	return l.handler.Enabled(context.Background(), slog.Level(-level))
+}
+
+func (l *slogSink) Info(level int, msg string, kvList ...interface{}) {
+	l.log(nil, msg, slog.Level(-level), kvList...)
+}
+
+func (l *slogSink) Error(err error, msg string, kvList ...interface{}) {
+	l.log(err, msg, slog.LevelError, kvList...)
+}
+
+func (l *slogSink) log(err error, msg string, level slog.Level, kvList ...interface{}) {
+	var pcs [1]uintptr
+	// skip runtime.Callers, this function, Info/Error, and all helper functions above that.
+	runtime.Callers(3+l.callDepth, pcs[:])
+
+	record := slog.NewRecord(time.Now(), level, msg, pcs[0])
+	if l.name != "" {
+		record.AddAttrs(slog.String(nameKey, l.name))
+	}
+	if err != nil {
+		record.AddAttrs(slog.Any(errKey, err))
+	}
+	record.Add(kvList...)
+	_ = l.handler.Handle(context.Background(), record)
+}
+
+func (l slogSink) WithName(name string) LogSink {
+	if l.name != "" {
+		l.name += "/"
+	}
+	l.name += name
+	return &l
+}
+
+func (l slogSink) WithValues(kvList ...interface{}) LogSink {
+	l.handler = l.handler.WithAttrs(kvListToAttrs(kvList...))
+	return &l
+}
+
+func kvListToAttrs(kvList ...interface{}) []slog.Attr {
+	// We don't need the record itself, only its Add method.
+	record := slog.NewRecord(time.Time{}, 0, "", 0)
+	record.Add(kvList...)
+	attrs := make([]slog.Attr, 0, record.NumAttrs())
+	record.Attrs(func(attr slog.Attr) bool {
+		attrs = append(attrs, attr)
+		return true
+	})
+	return attrs
+}
diff --git a/vendor/github.com/go-openapi/analysis/.golangci.yml b/vendor/github.com/go-openapi/analysis/.golangci.yml
index e24a6c14..22f8d21c 100644
--- a/vendor/github.com/go-openapi/analysis/.golangci.yml
+++ b/vendor/github.com/go-openapi/analysis/.golangci.yml
@@ -4,53 +4,58 @@ linters-settings:
   golint:
     min-confidence: 0
   gocyclo:
-    min-complexity: 40
-  gocognit:
-    min-complexity: 40
+    min-complexity: 45
   maligned:
     suggest-new: true
   dupl:
-    threshold: 150
+    threshold: 200
   goconst:
     min-len: 2
-    min-occurrences: 4
+    min-occurrences: 3
 
 linters:
   enable-all: true
   disable:
     - maligned
+    - unparam
     - lll
-    - gochecknoglobals
     - gochecknoinits
-    # scopelint is useful, but also reports false positives
-    # that unfortunately can't be disabled. So we disable the
-    # linter rather than changing code that works.
-    # see: https://github.com/kyoh86/scopelint/issues/4
-    - scopelint
+    - gochecknoglobals
+    - funlen
     - godox
     - gocognit
-    #- whitespace
+    - whitespace
     - wsl
-    - funlen
-    - testpackage
     - wrapcheck
-    #- nlreturn
+    - testpackage
+    - nlreturn
     - gomnd
-    - goerr113
     - exhaustivestruct
-    #- errorlint
-    #- nestif
-    - gofumpt
+    - goerr113
+    - errorlint
+    - nestif
     - godot
-    - gci
-    - dogsled
+    - gofumpt
     - paralleltest
     - tparallel
     - thelper
     - ifshort
-    - forbidigo
-    - cyclop
-    - varnamelen
     - exhaustruct
+    - varnamelen
+    - gci
+    - depguard
+    - errchkjson
+    - inamedparam
     - nonamedreturns
+    - musttag
+    - ireturn
+    - forcetypeassert
+    - cyclop
+    # deprecated linters
+    - deadcode
+    - interfacer
+    - scopelint
+    - varcheck
+    - structcheck
+    - golint
     - nosnakecase
diff --git a/vendor/github.com/go-openapi/analysis/README.md b/vendor/github.com/go-openapi/analysis/README.md
index aad6da10..e005d4b3 100644
--- a/vendor/github.com/go-openapi/analysis/README.md
+++ b/vendor/github.com/go-openapi/analysis/README.md
@@ -1,8 +1,5 @@
-# OpenAPI initiative analysis
+# OpenAPI analysis [![Build Status](https://github.com/go-openapi/analysis/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/analysis/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/analysis/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/analysis)
 
-[![Build Status](https://travis-ci.org/go-openapi/analysis.svg?branch=master)](https://travis-ci.org/go-openapi/analysis)
-[![Build status](https://ci.appveyor.com/api/projects/status/x377t5o9ennm847o/branch/master?svg=true)](https://ci.appveyor.com/project/casualjim/go-openapi/analysis/branch/master)
-[![codecov](https://codecov.io/gh/go-openapi/analysis/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/analysis)
 [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
 [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/analysis/master/LICENSE)
 [![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/analysis.svg)](https://pkg.go.dev/github.com/go-openapi/analysis)
@@ -13,12 +10,12 @@ A foundational library to analyze an OAI specification document for easier reaso
 
 ## What's inside?
 
-* A analyzer providing methods to walk the functional content of a specification
+* An analyzer providing methods to walk the functional content of a specification
 * A spec flattener producing a self-contained document bundle, while preserving `$ref`s
 * A spec merger ("mixin") to merge several spec documents into a primary spec
 * A spec "fixer" ensuring that response descriptions are non empty
 
-[Documentation](https://godoc.org/github.com/go-openapi/analysis)
+[Documentation](https://pkg.go.dev/github.com/go-openapi/analysis)
 
 ## FAQ
 
@@ -28,4 +25,3 @@ A foundational library to analyze an OAI specification document for easier reaso
 > This package currently only supports OpenAPI 2.0 (aka Swagger 2.0).
 > There is no plan to make it evolve toward supporting OpenAPI 3.x.
 > This [discussion thread](https://github.com/go-openapi/spec/issues/21) relates the full story.
->
diff --git a/vendor/github.com/go-openapi/analysis/appveyor.yml b/vendor/github.com/go-openapi/analysis/appveyor.yml
deleted file mode 100644
index c2f6fd73..00000000
--- a/vendor/github.com/go-openapi/analysis/appveyor.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-version: "0.1.{build}"
-
-clone_folder: C:\go-openapi\analysis
-shallow_clone: true # for startup speed
-pull_requests:
-  do_not_increment_build_number: true
-
-#skip_tags: true
-#skip_branch_with_pr: true
-
-# appveyor.yml
-build: off
-
-environment:
-  GOPATH: c:\gopath
-
-stack: go 1.16
-
-test_script:
-  - go test -v -timeout 20m ./...
-
-deploy: off
-
-notifications:
-  - provider: Slack
-    incoming_webhook: https://hooks.slack.com/services/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
-    auth_token:
-      secure: Sf7kZf7ZGbnwWUMpffHwMu5A0cHkLK2MYY32LNTPj4+/3qC3Ghl7+9v4TSLOqOlCwdRNjOGblAq7s+GDJed6/xgRQl1JtCi1klzZNrYX4q01pgTPvvGcwbBkIYgeMaPeIRcK9OZnud7sRXdttozgTOpytps2U6Js32ip7uj5mHSg2ub0FwoSJwlS6dbezZ8+eDhoha0F/guY99BEwx8Bd+zROrT2TFGsSGOFGN6wFc7moCqTHO/YkWib13a2QNXqOxCCVBy/lt76Wp+JkeFppjHlzs/2lP3EAk13RIUAaesdEUHvIHrzCyNJEd3/+KO2DzsWOYfpktd+KBCvgaYOsoo7ubdT3IROeAegZdCgo/6xgCEsmFc9ZcqCfN5yNx2A+BZ2Vwmpws+bQ1E1+B5HDzzaiLcYfG4X2O210QVGVDLWsv1jqD+uPYeHY2WRfh5ZsIUFvaqgUEnwHwrK44/8REAhQavt1QAj5uJpsRd7CkRVPWRNK+yIky+wgbVUFEchRNmS55E7QWf+W4+4QZkQi7vUTMc9nbTUu2Es9NfvfudOpM2wZbn98fjpb/qq/nRv6Bk+ca+7XD5/IgNLMbWp2ouDdzbiHLCOfDUiHiDJhLfFZx9Bwo7ZwfzeOlbrQX66bx7xRKYmOe4DLrXhNcpbsMa8qbfxlZRCmYbubB/Y8h4=
-    channel: bots
-    on_build_success: false
-    on_build_failure: true
-    on_build_status_changed: true
diff --git a/vendor/github.com/go-openapi/analysis/doc.go b/vendor/github.com/go-openapi/analysis/doc.go
index d5294c09..e8d9f9b1 100644
--- a/vendor/github.com/go-openapi/analysis/doc.go
+++ b/vendor/github.com/go-openapi/analysis/doc.go
@@ -16,27 +16,27 @@
 Package analysis provides methods to work with a Swagger specification document from
 package go-openapi/spec.
 
-Analyzing a specification
+## Analyzing a specification
 
 An analysed specification object (type Spec) provides methods to work with swagger definition.
 
-Flattening or expanding a specification
+## Flattening or expanding a specification
 
 Flattening a specification bundles all remote $ref in the main spec document.
 Depending on flattening options, additional preprocessing may take place:
   - full flattening: replacing all inline complex constructs by a named entry in #/definitions
   - expand: replace all $ref's in the document by their expanded content
 
-Merging several specifications
+## Merging several specifications
 
 Mixin several specifications merges all Swagger constructs, and warns about found conflicts.
 
-Fixing a specification
+## Fixing a specification
 
 Unmarshalling a specification with golang json unmarshalling may lead to
 some unwanted result on present but empty fields.
 
-Analyzing a Swagger schema
+## Analyzing a Swagger schema
 
 Swagger schemas are analyzed to determine their complexity and qualify their content.
 */
diff --git a/vendor/github.com/go-openapi/analysis/flatten.go b/vendor/github.com/go-openapi/analysis/flatten.go
index 0576220f..ebedcc9d 100644
--- a/vendor/github.com/go-openapi/analysis/flatten.go
+++ b/vendor/github.com/go-openapi/analysis/flatten.go
@@ -62,28 +62,26 @@ func newContext() *context {
 //
 // There is a minimal and a full flattening mode.
 //
-//
 // Minimally flattening a spec means:
-//  - Expanding parameters, responses, path items, parameter items and header items (references to schemas are left
-//    unscathed)
-//  - Importing external (http, file) references so they become internal to the document
-//  - Moving every JSON pointer to a $ref to a named definition (i.e. the reworked spec does not contain pointers
-//    like "$ref": "#/definitions/myObject/allOfs/1")
+//   - Expanding parameters, responses, path items, parameter items and header items (references to schemas are left
+//     unscathed)
+//   - Importing external (http, file) references so they become internal to the document
+//   - Moving every JSON pointer to a $ref to a named definition (i.e. the reworked spec does not contain pointers
+//     like "$ref": "#/definitions/myObject/allOfs/1")
 //
 // A minimally flattened spec thus guarantees the following properties:
-//  - all $refs point to a local definition (i.e. '#/definitions/...')
-//  - definitions are unique
+//   - all $refs point to a local definition (i.e. '#/definitions/...')
+//   - definitions are unique
 //
 // NOTE: arbitrary JSON pointers (other than $refs to top level definitions) are rewritten as definitions if they
 // represent a complex schema or express commonality in the spec.
 // Otherwise, they are simply expanded.
 // Self-referencing JSON pointers cannot resolve to a type and trigger an error.
 //
-//
 // Minimal flattening is necessary and sufficient for codegen rendering using go-swagger.
 //
 // Fully flattening a spec means:
-//  - Moving every complex inline schema to be a definition with an auto-generated name in a depth-first fashion.
+//   - Moving every complex inline schema to be a definition with an auto-generated name in a depth-first fashion.
 //
 // By complex, we mean every JSON object with some properties.
 // Arrays, when they do not define a tuple,
@@ -93,22 +91,21 @@ func newContext() *context {
 // have been created.
 //
 // Available flattening options:
-//  - Minimal: stops flattening after minimal $ref processing, leaving schema constructs untouched
-//  - Expand: expand all $ref's in the document (inoperant if Minimal set to true)
-//  - Verbose: croaks about name conflicts detected
-//  - RemoveUnused: removes unused parameters, responses and definitions after expansion/flattening
+//   - Minimal: stops flattening after minimal $ref processing, leaving schema constructs untouched
+//   - Expand: expand all $ref's in the document (inoperant if Minimal set to true)
+//   - Verbose: croaks about name conflicts detected
+//   - RemoveUnused: removes unused parameters, responses and definitions after expansion/flattening
 //
 // NOTE: expansion removes all $ref save circular $ref, which remain in place
 //
 // TODO: additional options
-//  - ProgagateNameExtensions: ensure that created entries properly follow naming rules when their parent have set a
-//    x-go-name extension
-//  - LiftAllOfs:
-//     - limit the flattening of allOf members when simple objects
-//     - merge allOf with validation only
-//     - merge allOf with extensions only
-//     - ...
-//
+//   - ProgagateNameExtensions: ensure that created entries properly follow naming rules when their parent have set a
+//     x-go-name extension
+//   - LiftAllOfs:
+//   - limit the flattening of allOf members when simple objects
+//   - merge allOf with validation only
+//   - merge allOf with extensions only
+//   - ...
 func Flatten(opts FlattenOpts) error {
 	debugLog("FlattenOpts: %#v", opts)
 
@@ -270,6 +267,12 @@ func nameInlinedSchemas(opts *FlattenOpts) error {
 }
 
 func removeUnused(opts *FlattenOpts) {
+	for removeUnusedSinglePass(opts) {
+		// continue until no unused definition remains
+	}
+}
+
+func removeUnusedSinglePass(opts *FlattenOpts) (hasRemoved bool) {
 	expected := make(map[string]struct{})
 	for k := range opts.Swagger().Definitions {
 		expected[path.Join(definitionsPath, jsonpointer.Escape(k))] = struct{}{}
@@ -280,6 +283,7 @@ func removeUnused(opts *FlattenOpts) {
 	}
 
 	for k := range expected {
+		hasRemoved = true
 		debugLog("removing unused definition %s", path.Base(k))
 		if opts.Verbose {
 			log.Printf("info: removing unused definition: %s", path.Base(k))
@@ -288,6 +292,8 @@ func removeUnused(opts *FlattenOpts) {
 	}
 
 	opts.Spec.reload() // re-analyze
+
+	return hasRemoved
 }
 
 func importKnownRef(entry sortref.RefRevIdx, refStr, newName string, opts *FlattenOpts) error {
@@ -334,7 +340,7 @@ func importNewRef(entry sortref.RefRevIdx, refStr string, opts *FlattenOpts) err
 	}
 
 	// generate a unique name - isOAIGen means that a naming conflict was resolved by changing the name
-	newName, isOAIGen = uniqifyName(opts.Swagger().Definitions, nameFromRef(entry.Ref))
+	newName, isOAIGen = uniqifyName(opts.Swagger().Definitions, nameFromRef(entry.Ref, opts))
 	debugLog("new name for [%s]: %s - with name conflict:%t", strings.Join(entry.Keys, ", "), newName, isOAIGen)
 
 	opts.flattenContext.resolved[refStr] = newName
@@ -488,9 +494,9 @@ func stripPointersAndOAIGen(opts *FlattenOpts) error {
 // stripOAIGen strips the spec from unnecessary OAIGen constructs, initially created to dedupe flattened definitions.
 //
 // A dedupe is deemed unnecessary whenever:
-//  - the only conflict is with its (single) parent: OAIGen is merged into its parent (reinlining)
-//  - there is a conflict with multiple parents: merge OAIGen in first parent, the rewrite other parents to point to
-//    the first parent.
+//   - the only conflict is with its (single) parent: OAIGen is merged into its parent (reinlining)
+//   - there is a conflict with multiple parents: merge OAIGen in first parent, the rewrite other parents to point to
+//     the first parent.
 //
 // This function returns true whenever it re-inlined a complex schema, so the caller may chose to iterate
 // pointer and name resolution again.
@@ -652,6 +658,7 @@ func namePointers(opts *FlattenOpts) error {
 
 	refsToReplace := make(map[string]SchemaRef, len(opts.Spec.references.schemas))
 	for k, ref := range opts.Spec.references.allRefs {
+		debugLog("name pointers: %q => %#v", k, ref)
 		if path.Dir(ref.String()) == definitionsPath {
 			// this a ref to a top-level definition: ok
 			continue
@@ -769,6 +776,10 @@ func flattenAnonPointer(key string, v SchemaRef, refsToReplace map[string]Schema
 
 	// identifying edge case when the namer did nothing because we point to a non-schema object
 	// no definition is created and we expand the $ref for all callers
+	debugLog("decide what to do with the schema pointed to: asch.IsSimpleSchema=%t, len(callers)=%d, parts.IsSharedParam=%t, parts.IsSharedResponse=%t",
+		asch.IsSimpleSchema, len(callers), parts.IsSharedParam(), parts.IsSharedResponse(),
+	)
+
 	if (!asch.IsSimpleSchema || len(callers) > 1) && !parts.IsSharedParam() && !parts.IsSharedResponse() {
 		debugLog("replace JSON pointer at [%s] by definition: %s", key, v.Ref.String())
 		if err := namer.Name(v.Ref.String(), v.Schema, asch); err != nil {
@@ -791,6 +802,7 @@ func flattenAnonPointer(key string, v SchemaRef, refsToReplace map[string]Schema
 		return nil
 	}
 
+	// everything that is a simple schema and not factorizable is expanded
 	debugLog("expand JSON pointer for key=%s", key)
 
 	if err := replace.UpdateRefWithSchema(opts.Swagger(), key, v.Schema); err != nil {
diff --git a/vendor/github.com/go-openapi/analysis/flatten_name.go b/vendor/github.com/go-openapi/analysis/flatten_name.go
index 3ad2ccfb..c7d7938e 100644
--- a/vendor/github.com/go-openapi/analysis/flatten_name.go
+++ b/vendor/github.com/go-openapi/analysis/flatten_name.go
@@ -33,12 +33,14 @@ func (isn *InlineSchemaNamer) Name(key string, schema *spec.Schema, aschema *Ana
 		}
 
 		// create unique name
-		newName, isOAIGen := uniqifyName(isn.Spec.Definitions, swag.ToJSONName(name))
+		mangle := mangler(isn.opts)
+		newName, isOAIGen := uniqifyName(isn.Spec.Definitions, mangle(name))
 
 		// clone schema
 		sch := schutils.Clone(schema)
 
 		// replace values on schema
+		debugLog("rewriting schema to ref: key=%s with new name: %s", key, newName)
 		if err := replace.RewriteSchemaToRef(isn.Spec, key,
 			spec.MustCreateRef(path.Join(definitionsPath, newName))); err != nil {
 			return fmt.Errorf("error while creating definition %q from inline schema: %w", newName, err)
@@ -149,13 +151,15 @@ func namesFromKey(parts sortref.SplitKey, aschema *AnalyzedSchema, operations ma
 		startIndex int
 	)
 
-	if parts.IsOperation() {
+	switch {
+	case parts.IsOperation():
 		baseNames, startIndex = namesForOperation(parts, operations)
-	}
-
-	// definitions
-	if parts.IsDefinition() {
+	case parts.IsDefinition():
 		baseNames, startIndex = namesForDefinition(parts)
+	default:
+		// this a non-standard pointer: build a name by concatenating its parts
+		baseNames = [][]string{parts}
+		startIndex = len(baseNames) + 1
 	}
 
 	result := make([]string, 0, len(baseNames))
@@ -169,6 +173,7 @@ func namesFromKey(parts sortref.SplitKey, aschema *AnalyzedSchema, operations ma
 	}
 	sort.Strings(result)
 
+	debugLog("names from parts: %v => %v", parts, result)
 	return result
 }
 
@@ -256,10 +261,20 @@ func partAdder(aschema *AnalyzedSchema) sortref.PartAdder {
 	}
 }
 
-func nameFromRef(ref spec.Ref) string {
+func mangler(o *FlattenOpts) func(string) string {
+	if o.KeepNames {
+		return func(in string) string { return in }
+	}
+
+	return swag.ToJSONName
+}
+
+func nameFromRef(ref spec.Ref, o *FlattenOpts) string {
+	mangle := mangler(o)
+
 	u := ref.GetURL()
 	if u.Fragment != "" {
-		return swag.ToJSONName(path.Base(u.Fragment))
+		return mangle(path.Base(u.Fragment))
 	}
 
 	if u.Path != "" {
@@ -267,19 +282,19 @@ func nameFromRef(ref spec.Ref) string {
 		if bn != "" && bn != "/" {
 			ext := path.Ext(bn)
 			if ext != "" {
-				return swag.ToJSONName(bn[:len(bn)-len(ext)])
+				return mangle(bn[:len(bn)-len(ext)])
 			}
 
-			return swag.ToJSONName(bn)
+			return mangle(bn)
 		}
 	}
 
-	return swag.ToJSONName(strings.ReplaceAll(u.Host, ".", " "))
+	return mangle(strings.ReplaceAll(u.Host, ".", " "))
 }
 
 // GenLocation indicates from which section of the specification (models or operations) a definition has been created.
 //
-// This is reflected in the output spec with a "x-go-gen-location" extension. At the moment, this is is provided
+// This is reflected in the output spec with a "x-go-gen-location" extension. At the moment, this is provided
 // for information only.
 func GenLocation(parts sortref.SplitKey) string {
 	switch {
diff --git a/vendor/github.com/go-openapi/analysis/flatten_options.go b/vendor/github.com/go-openapi/analysis/flatten_options.go
index c5bb97b0..c943fe1e 100644
--- a/vendor/github.com/go-openapi/analysis/flatten_options.go
+++ b/vendor/github.com/go-openapi/analysis/flatten_options.go
@@ -26,6 +26,7 @@ type FlattenOpts struct {
 	Verbose         bool // enable some reporting on possible name conflicts detected
 	RemoveUnused    bool // When true, remove unused parameters, responses and definitions after expansion/flattening
 	ContinueOnError bool // Continue when spec expansion issues are found
+	KeepNames       bool // Do not attempt to jsonify names from references when flattening
 
 	/* Extra keys */
 	_ struct{} // require keys
diff --git a/vendor/github.com/go-openapi/analysis/internal/debug/debug.go b/vendor/github.com/go-openapi/analysis/internal/debug/debug.go
index ec0fec02..39f55a97 100644
--- a/vendor/github.com/go-openapi/analysis/internal/debug/debug.go
+++ b/vendor/github.com/go-openapi/analysis/internal/debug/debug.go
@@ -29,7 +29,7 @@ var (
 // GetLogger provides a prefix debug logger
 func GetLogger(prefix string, debug bool) func(string, ...interface{}) {
 	if debug {
-		logger := log.New(output, fmt.Sprintf("%s:", prefix), log.LstdFlags)
+		logger := log.New(output, prefix+":", log.LstdFlags)
 
 		return func(msg string, args ...interface{}) {
 			_, file1, pos1, _ := runtime.Caller(1)
@@ -37,5 +37,5 @@ func GetLogger(prefix string, debug bool) func(string, ...interface{}) {
 		}
 	}
 
-	return func(msg string, args ...interface{}) {}
+	return func(_ string, _ ...interface{}) {}
 }
diff --git a/vendor/github.com/go-openapi/analysis/internal/flatten/replace/replace.go b/vendor/github.com/go-openapi/analysis/internal/flatten/replace/replace.go
index 26c2a05a..c0f43e72 100644
--- a/vendor/github.com/go-openapi/analysis/internal/flatten/replace/replace.go
+++ b/vendor/github.com/go-openapi/analysis/internal/flatten/replace/replace.go
@@ -1,6 +1,7 @@
 package replace
 
 import (
+	"encoding/json"
 	"fmt"
 	"net/url"
 	"os"
@@ -40,6 +41,8 @@ func RewriteSchemaToRef(sp *spec.Swagger, key string, ref spec.Ref) error {
 		if refable.Schema != nil {
 			refable.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
 		}
+	case map[string]interface{}: // this happens e.g. if a schema points to an extension unmarshaled as map[string]interface{}
+		return rewriteParentRef(sp, key, ref)
 	default:
 		return fmt.Errorf("no schema with ref found at %s for %T", key, value)
 	}
@@ -120,6 +123,9 @@ func rewriteParentRef(sp *spec.Swagger, key string, ref spec.Ref) error {
 	case spec.SchemaProperties:
 		container[entry] = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
 
+	case *interface{}:
+		*container = spec.Schema{SchemaProps: spec.SchemaProps{Ref: ref}}
+
 	// NOTE: can't have case *spec.SchemaOrBool = parent in this case is *Schema
 
 	default:
@@ -318,8 +324,8 @@ type DeepestRefResult struct {
 }
 
 // DeepestRef finds the first definition ref, from a cascade of nested refs which are not definitions.
-//  - if no definition is found, returns the deepest ref.
-//  - pointers to external files are expanded
+//   - if no definition is found, returns the deepest ref.
+//   - pointers to external files are expanded
 //
 // NOTE: all external $ref's are assumed to be already expanded at this stage.
 func DeepestRef(sp *spec.Swagger, opts *spec.ExpandOptions, ref spec.Ref) (*DeepestRefResult, error) {
@@ -385,8 +391,9 @@ DOWNREF:
 			err := asSchema.UnmarshalJSON(asJSON)
 			if err != nil {
 				return nil,
-					fmt.Errorf("invalid type for resolved JSON pointer %s. Expected a schema a, got: %T",
-						currentRef.String(), value)
+					fmt.Errorf("invalid type for resolved JSON pointer %s. Expected a schema a, got: %T (%v)",
+						currentRef.String(), value, err,
+					)
 			}
 			warnings = append(warnings, fmt.Sprintf("found $ref %q (response) interpreted as schema", currentRef.String()))
 
@@ -402,8 +409,9 @@ DOWNREF:
 			var asSchema spec.Schema
 			if err := asSchema.UnmarshalJSON(asJSON); err != nil {
 				return nil,
-					fmt.Errorf("invalid type for resolved JSON pointer %s. Expected a schema a, got: %T",
-						currentRef.String(), value)
+					fmt.Errorf("invalid type for resolved JSON pointer %s. Expected a schema a, got: %T (%v)",
+						currentRef.String(), value, err,
+					)
 			}
 
 			warnings = append(warnings, fmt.Sprintf("found $ref %q (parameter) interpreted as schema", currentRef.String()))
@@ -414,9 +422,25 @@ DOWNREF:
 			currentRef = asSchema.Ref
 
 		default:
-			return nil,
-				fmt.Errorf("unhandled type to resolve JSON pointer %s. Expected a Schema, got: %T",
-					currentRef.String(), value)
+			// fallback: attempts to resolve the pointer as a schema
+			if refable == nil {
+				break DOWNREF
+			}
+
+			asJSON, _ := json.Marshal(refable)
+			var asSchema spec.Schema
+			if err := asSchema.UnmarshalJSON(asJSON); err != nil {
+				return nil,
+					fmt.Errorf("unhandled type to resolve JSON pointer %s. Expected a Schema, got: %T (%v)",
+						currentRef.String(), value, err,
+					)
+			}
+			warnings = append(warnings, fmt.Sprintf("found $ref %q (%T) interpreted as schema", currentRef.String(), refable))
+
+			if asSchema.Ref.String() == "" {
+				break DOWNREF
+			}
+			currentRef = asSchema.Ref
 		}
 	}
 
diff --git a/vendor/github.com/go-openapi/analysis/internal/flatten/sortref/keys.go b/vendor/github.com/go-openapi/analysis/internal/flatten/sortref/keys.go
index 18e552ea..ac80fc2e 100644
--- a/vendor/github.com/go-openapi/analysis/internal/flatten/sortref/keys.go
+++ b/vendor/github.com/go-openapi/analysis/internal/flatten/sortref/keys.go
@@ -69,7 +69,7 @@ func KeyParts(key string) SplitKey {
 	return res
 }
 
-// SplitKey holds of the parts of a /-separated key, soi that their location may be determined.
+// SplitKey holds of the parts of a /-separated key, so that their location may be determined.
 type SplitKey []string
 
 // IsDefinition is true when the split key is in the #/definitions section of a spec
diff --git a/vendor/github.com/go-openapi/analysis/mixin.go b/vendor/github.com/go-openapi/analysis/mixin.go
index b2530526..7785a29b 100644
--- a/vendor/github.com/go-openapi/analysis/mixin.go
+++ b/vendor/github.com/go-openapi/analysis/mixin.go
@@ -53,7 +53,7 @@ import (
 // collisions.
 func Mixin(primary *spec.Swagger, mixins ...*spec.Swagger) []string {
 	skipped := make([]string, 0, len(mixins))
-	opIds := getOpIds(primary)
+	opIDs := getOpIDs(primary)
 	initPrimary(primary)
 
 	for i, m := range mixins {
@@ -74,7 +74,7 @@ func Mixin(primary *spec.Swagger, mixins ...*spec.Swagger) []string {
 		skipped = append(skipped, mergeDefinitions(primary, m)...)
 
 		// merging paths requires a map of operationIDs to work with
-		skipped = append(skipped, mergePaths(primary, m, opIds, i)...)
+		skipped = append(skipped, mergePaths(primary, m, opIDs, i)...)
 
 		skipped = append(skipped, mergeParameters(primary, m)...)
 
@@ -84,9 +84,9 @@ func Mixin(primary *spec.Swagger, mixins ...*spec.Swagger) []string {
 	return skipped
 }
 
-// getOpIds extracts all the paths.<path>.operationIds from the given
+// getOpIDs extracts all the paths.<path>.operationIds from the given
 // spec and returns them as the keys in a map with 'true' values.
-func getOpIds(s *spec.Swagger) map[string]bool {
+func getOpIDs(s *spec.Swagger) map[string]bool {
 	rv := make(map[string]bool)
 	if s.Paths == nil {
 		return rv
@@ -179,7 +179,7 @@ func mergeDefinitions(primary *spec.Swagger, m *spec.Swagger) (skipped []string)
 	return
 }
 
-func mergePaths(primary *spec.Swagger, m *spec.Swagger, opIds map[string]bool, mixIndex int) (skipped []string) {
+func mergePaths(primary *spec.Swagger, m *spec.Swagger, opIDs map[string]bool, mixIndex int) (skipped []string) {
 	if m.Paths != nil {
 		for k, v := range m.Paths.Paths {
 			if _, exists := primary.Paths.Paths[k]; exists {
@@ -198,10 +198,10 @@ func mergePaths(primary *spec.Swagger, m *spec.Swagger, opIds map[string]bool, m
 			// all the proivded specs are already unique.
 			piops := pathItemOps(v)
 			for _, piop := range piops {
-				if opIds[piop.ID] {
+				if opIDs[piop.ID] {
 					piop.ID = fmt.Sprintf("%v%v%v", piop.ID, "Mixin", mixIndex)
 				}
-				opIds[piop.ID] = true
+				opIDs[piop.ID] = true
 			}
 			primary.Paths.Paths[k] = v
 		}
@@ -367,7 +367,7 @@ func mergeSwaggerProps(primary *spec.Swagger, m *spec.Swagger) []string {
 	return skipped
 }
 
-// nolint: unparam
+//nolint:unparam
 func mergeExternalDocs(primary *spec.ExternalDocumentation, m *spec.ExternalDocumentation) []string {
 	if primary.Description == "" {
 		primary.Description = m.Description
diff --git a/vendor/github.com/go-openapi/analysis/schema.go b/vendor/github.com/go-openapi/analysis/schema.go
index fc055095..ab190db5 100644
--- a/vendor/github.com/go-openapi/analysis/schema.go
+++ b/vendor/github.com/go-openapi/analysis/schema.go
@@ -1,7 +1,7 @@
 package analysis
 
 import (
-	"fmt"
+	"errors"
 
 	"github.com/go-openapi/spec"
 	"github.com/go-openapi/strfmt"
@@ -19,7 +19,7 @@ type SchemaOpts struct {
 // patterns.
 func Schema(opts SchemaOpts) (*AnalyzedSchema, error) {
 	if opts.Schema == nil {
-		return nil, fmt.Errorf("no schema to analyze")
+		return nil, errors.New("no schema to analyze")
 	}
 
 	a := &AnalyzedSchema{
@@ -247,10 +247,10 @@ func (a *AnalyzedSchema) isArrayType() bool {
 // isAnalyzedAsComplex determines if an analyzed schema is eligible to flattening (i.e. it is "complex").
 //
 // Complex means the schema is any of:
-//  - a simple type (primitive)
-//  - an array of something (items are possibly complex ; if this is the case, items will generate a definition)
-//  - a map of something (additionalProperties are possibly complex ; if this is the case, additionalProperties will
-//    generate a definition)
+//   - a simple type (primitive)
+//   - an array of something (items are possibly complex ; if this is the case, items will generate a definition)
+//   - a map of something (additionalProperties are possibly complex ; if this is the case, additionalProperties will
+//     generate a definition)
 func (a *AnalyzedSchema) isAnalyzedAsComplex() bool {
 	return !a.IsSimpleSchema && !a.IsArray && !a.IsMap
 }
diff --git a/vendor/github.com/go-openapi/errors/.golangci.yml b/vendor/github.com/go-openapi/errors/.golangci.yml
index 4e1fc0c7..cf88ead3 100644
--- a/vendor/github.com/go-openapi/errors/.golangci.yml
+++ b/vendor/github.com/go-openapi/errors/.golangci.yml
@@ -4,45 +4,59 @@ linters-settings:
   golint:
     min-confidence: 0
   gocyclo:
-    min-complexity: 30
+    min-complexity: 45
   maligned:
     suggest-new: true
   dupl:
-    threshold: 100
+    threshold: 200
   goconst:
     min-len: 2
-    min-occurrences: 4
+    min-occurrences: 3
+
 linters:
   enable-all: true
   disable:
+    - errname # this repo doesn't follow the convention advised by this linter
     - maligned
+    - unparam
     - lll
+    - gochecknoinits
     - gochecknoglobals
+    - funlen
     - godox
     - gocognit
     - whitespace
     - wsl
-    - funlen
-    - gochecknoglobals
-    - gochecknoinits
-    - scopelint
     - wrapcheck
-    - exhaustivestruct
-    - exhaustive
-    - nlreturn
     - testpackage
-    - gci
-    - gofumpt
-    - goerr113
+    - nlreturn
     - gomnd
-    - tparallel
+    - exhaustivestruct
+    - goerr113
+    - errorlint
     - nestif
     - godot
-    - errorlint
+    - gofumpt
     - paralleltest
     - tparallel
-    - cyclop
-    - errname
-    - varnamelen
+    - thelper
+    - ifshort
     - exhaustruct
-    - maintidx
+    - varnamelen
+    - gci
+    - depguard
+    - errchkjson
+    - inamedparam
+    - nonamedreturns
+    - musttag
+    - ireturn
+    - forcetypeassert
+    - cyclop
+    # deprecated linters
+    - deadcode
+    - interfacer
+    - scopelint
+    - varcheck
+    - structcheck
+    - golint
+    - nosnakecase
diff --git a/vendor/github.com/go-openapi/errors/README.md b/vendor/github.com/go-openapi/errors/README.md
index 4aac049e..6d57ea55 100644
--- a/vendor/github.com/go-openapi/errors/README.md
+++ b/vendor/github.com/go-openapi/errors/README.md
@@ -1,11 +1,8 @@
-# OpenAPI errors
+# OpenAPI errors [![Build Status](https://github.com/go-openapi/errors/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/errors/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/errors/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/errors)
 
-[![Build Status](https://travis-ci.org/go-openapi/errors.svg?branch=master)](https://travis-ci.org/go-openapi/errors)
-[![codecov](https://codecov.io/gh/go-openapi/errors/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/errors)
 [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
 [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/errors/master/LICENSE)
 [![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/errors.svg)](https://pkg.go.dev/github.com/go-openapi/errors)
-[![GolangCI](https://golangci.com/badges/github.com/go-openapi/errors.svg)](https://golangci.com)
 [![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/errors)](https://goreportcard.com/report/github.com/go-openapi/errors)
 
 Shared errors and error interface used throughout the various libraries found in the go-openapi toolkit.
diff --git a/vendor/github.com/go-openapi/errors/api.go b/vendor/github.com/go-openapi/errors/api.go
index c13f3435..5320cb96 100644
--- a/vendor/github.com/go-openapi/errors/api.go
+++ b/vendor/github.com/go-openapi/errors/api.go
@@ -55,9 +55,15 @@ func (a apiError) MarshalJSON() ([]byte, error) {
 // New creates a new API error with a code and a message
 func New(code int32, message string, args ...interface{}) Error {
 	if len(args) > 0 {
-		return &apiError{code, fmt.Sprintf(message, args...)}
+		return &apiError{
+			code:    code,
+			message: fmt.Sprintf(message, args...),
+		}
+	}
+	return &apiError{
+		code:    code,
+		message: message,
 	}
-	return &apiError{code, message}
 }
 
 // NotFound creates a new not found error
@@ -130,10 +136,14 @@ func flattenComposite(errs *CompositeError) *CompositeError {
 // MethodNotAllowed creates a new method not allowed error
 func MethodNotAllowed(requested string, allow []string) Error {
 	msg := fmt.Sprintf("method %s is not allowed, but [%s] are", requested, strings.Join(allow, ","))
-	return &MethodNotAllowedError{code: http.StatusMethodNotAllowed, Allowed: allow, message: msg}
+	return &MethodNotAllowedError{
+		code:    http.StatusMethodNotAllowed,
+		Allowed: allow,
+		message: msg,
+	}
 }
 
-// ServeError the error handler interface implementation
+// ServeError implements the http error handler interface
 func ServeError(rw http.ResponseWriter, r *http.Request, err error) {
 	rw.Header().Set("Content-Type", "application/json")
 	switch e := err.(type) {
diff --git a/vendor/github.com/go-openapi/errors/schema.go b/vendor/github.com/go-openapi/errors/schema.go
index da5f6c78..cf7ac2ed 100644
--- a/vendor/github.com/go-openapi/errors/schema.go
+++ b/vendor/github.com/go-openapi/errors/schema.go
@@ -120,6 +120,10 @@ func (c *CompositeError) Error() string {
 	return c.message
 }
 
+func (c *CompositeError) Unwrap() []error {
+	return c.Errors
+}
+
 // MarshalJSON implements the JSON encoding interface
 func (c CompositeError) MarshalJSON() ([]byte, error) {
 	return json.Marshal(map[string]interface{}{
@@ -133,7 +137,7 @@ func (c CompositeError) MarshalJSON() ([]byte, error) {
 func CompositeValidationError(errors ...error) *CompositeError {
 	return &CompositeError{
 		code:    CompositeErrorCode,
-		Errors:  append([]error{}, errors...),
+		Errors:  append(make([]error, 0, len(errors)), errors...),
 		message: "validation failure list",
 	}
 }
diff --git a/vendor/github.com/go-openapi/jsonpointer/.golangci.yml b/vendor/github.com/go-openapi/jsonpointer/.golangci.yml
new file mode 100644
index 00000000..22f8d21c
--- /dev/null
+++ b/vendor/github.com/go-openapi/jsonpointer/.golangci.yml
@@ -0,0 +1,61 @@
+linters-settings:
+  govet:
+    check-shadowing: true
+  golint:
+    min-confidence: 0
+  gocyclo:
+    min-complexity: 45
+  maligned:
+    suggest-new: true
+  dupl:
+    threshold: 200
+  goconst:
+    min-len: 2
+    min-occurrences: 3
+
+linters:
+  enable-all: true
+  disable:
+    - maligned
+    - unparam
+    - lll
+    - gochecknoinits
+    - gochecknoglobals
+    - funlen
+    - godox
+    - gocognit
+    - whitespace
+    - wsl
+    - wrapcheck
+    - testpackage
+    - nlreturn
+    - gomnd
+    - exhaustivestruct
+    - goerr113
+    - errorlint
+    - nestif
+    - godot
+    - gofumpt
+    - paralleltest
+    - tparallel
+    - thelper
+    - ifshort
+    - exhaustruct
+    - varnamelen
+    - gci
+    - depguard
+    - errchkjson
+    - inamedparam
+    - nonamedreturns
+    - musttag
+    - ireturn
+    - forcetypeassert
+    - cyclop
+    # deprecated linters
+    - deadcode
+    - interfacer
+    - scopelint
+    - varcheck
+    - structcheck
+    - golint
+    - nosnakecase
diff --git a/vendor/github.com/go-openapi/jsonpointer/.travis.yml b/vendor/github.com/go-openapi/jsonpointer/.travis.yml
deleted file mode 100644
index 03a22fe0..00000000
--- a/vendor/github.com/go-openapi/jsonpointer/.travis.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-after_success:
-- bash <(curl -s https://codecov.io/bash)
-go:
-- 1.14.x
-- 1.15.x
-install:
-- GO111MODULE=off go get -u gotest.tools/gotestsum
-env:
-- GO111MODULE=on
-language: go
-notifications:
-  slack:
-    secure: a5VgoiwB1G/AZqzmephPZIhEB9avMlsWSlVnM1dSAtYAwdrQHGTQxAmpOxYIoSPDhWNN5bfZmjd29++UlTwLcHSR+e0kJhH6IfDlsHj/HplNCJ9tyI0zYc7XchtdKgeMxMzBKCzgwFXGSbQGydXTliDNBo0HOzmY3cou/daMFTP60K+offcjS+3LRAYb1EroSRXZqrk1nuF/xDL3792DZUdPMiFR/L/Df6y74D6/QP4sTkTDFQitz4Wy/7jbsfj8dG6qK2zivgV6/l+w4OVjFkxVpPXogDWY10vVXNVynqxfJ7to2d1I9lNCHE2ilBCkWMIPdyJF7hjF8pKW+82yP4EzRh0vu8Xn0HT5MZpQxdRY/YMxNrWaG7SxsoEaO4q5uhgdzAqLYY3TRa7MjIK+7Ur+aqOeTXn6OKwVi0CjvZ6mIU3WUKSwiwkFZMbjRAkSb5CYwMEfGFO/z964xz83qGt6WAtBXNotqCQpTIiKtDHQeLOMfksHImCg6JLhQcWBVxamVgu0G3Pdh8Y6DyPnxraXY95+QDavbjqv7TeYT9T/FNnrkXaTTK0s4iWE5H4ACU0Qvz0wUYgfQrZv0/Hp7V17+rabUwnzYySHCy9SWX/7OV9Cfh31iMp9ZIffr76xmmThtOEqs8TrTtU6BWI3rWwvA9cXQipZTVtL0oswrGw=
-script:
-- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...
diff --git a/vendor/github.com/go-openapi/jsonpointer/README.md b/vendor/github.com/go-openapi/jsonpointer/README.md
index 813788af..0108f1d5 100644
--- a/vendor/github.com/go-openapi/jsonpointer/README.md
+++ b/vendor/github.com/go-openapi/jsonpointer/README.md
@@ -1,6 +1,10 @@
-# gojsonpointer [![Build Status](https://travis-ci.org/go-openapi/jsonpointer.svg?branch=master)](https://travis-ci.org/go-openapi/jsonpointer) [![codecov](https://codecov.io/gh/go-openapi/jsonpointer/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonpointer) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
+# gojsonpointer [![Build Status](https://github.com/go-openapi/jsonpointer/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/jsonpointer/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/jsonpointer/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonpointer)
+
+[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
+[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonpointer/master/LICENSE)
+[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/jsonpointer.svg)](https://pkg.go.dev/github.com/go-openapi/jsonpointer)
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/jsonpointer)](https://goreportcard.com/report/github.com/go-openapi/jsonpointer)
 
-[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonpointer/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/jsonpointer?status.svg)](http://godoc.org/github.com/go-openapi/jsonpointer)
 An implementation of JSON Pointer - Go language
 
 ## Status
diff --git a/vendor/github.com/go-openapi/jsonpointer/pointer.go b/vendor/github.com/go-openapi/jsonpointer/pointer.go
index 7df9853d..d970c7cf 100644
--- a/vendor/github.com/go-openapi/jsonpointer/pointer.go
+++ b/vendor/github.com/go-openapi/jsonpointer/pointer.go
@@ -26,6 +26,7 @@
 package jsonpointer
 
 import (
+	"encoding/json"
 	"errors"
 	"fmt"
 	"reflect"
@@ -40,6 +41,7 @@ const (
 	pointerSeparator = `/`
 
 	invalidStart = `JSON pointer must be empty or start with a "` + pointerSeparator
+	notFound     = `Can't find the pointer in the document`
 )
 
 var jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem()
@@ -48,13 +50,13 @@ var jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem()
 // JSONPointable is an interface for structs to implement when they need to customize the
 // json pointer process
 type JSONPointable interface {
-	JSONLookup(string) (interface{}, error)
+	JSONLookup(string) (any, error)
 }
 
 // JSONSetable is an interface for structs to implement when they need to customize the
 // json pointer process
 type JSONSetable interface {
-	JSONSet(string, interface{}) error
+	JSONSet(string, any) error
 }
 
 // New creates a new json pointer for the given string
@@ -81,9 +83,7 @@ func (p *Pointer) parse(jsonPointerString string) error {
 			err = errors.New(invalidStart)
 		} else {
 			referenceTokens := strings.Split(jsonPointerString, pointerSeparator)
-			for _, referenceToken := range referenceTokens[1:] {
-				p.referenceTokens = append(p.referenceTokens, referenceToken)
-			}
+			p.referenceTokens = append(p.referenceTokens, referenceTokens[1:]...)
 		}
 	}
 
@@ -91,38 +91,58 @@ func (p *Pointer) parse(jsonPointerString string) error {
 }
 
 // Get uses the pointer to retrieve a value from a JSON document
-func (p *Pointer) Get(document interface{}) (interface{}, reflect.Kind, error) {
+func (p *Pointer) Get(document any) (any, reflect.Kind, error) {
 	return p.get(document, swag.DefaultJSONNameProvider)
 }
 
 // Set uses the pointer to set a value from a JSON document
-func (p *Pointer) Set(document interface{}, value interface{}) (interface{}, error) {
+func (p *Pointer) Set(document any, value any) (any, error) {
 	return document, p.set(document, value, swag.DefaultJSONNameProvider)
 }
 
 // GetForToken gets a value for a json pointer token 1 level deep
-func GetForToken(document interface{}, decodedToken string) (interface{}, reflect.Kind, error) {
+func GetForToken(document any, decodedToken string) (any, reflect.Kind, error) {
 	return getSingleImpl(document, decodedToken, swag.DefaultJSONNameProvider)
 }
 
 // SetForToken gets a value for a json pointer token 1 level deep
-func SetForToken(document interface{}, decodedToken string, value interface{}) (interface{}, error) {
+func SetForToken(document any, decodedToken string, value any) (any, error) {
 	return document, setSingleImpl(document, value, decodedToken, swag.DefaultJSONNameProvider)
 }
 
-func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) {
+func isNil(input any) bool {
+	if input == nil {
+		return true
+	}
+
+	kind := reflect.TypeOf(input).Kind()
+	switch kind { //nolint:exhaustive
+	case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan:
+		return reflect.ValueOf(input).IsNil()
+	default:
+		return false
+	}
+}
+
+func getSingleImpl(node any, decodedToken string, nameProvider *swag.NameProvider) (any, reflect.Kind, error) {
 	rValue := reflect.Indirect(reflect.ValueOf(node))
 	kind := rValue.Kind()
+	if isNil(node) {
+		return nil, kind, fmt.Errorf("nil value has not field %q", decodedToken)
+	}
 
-	if rValue.Type().Implements(jsonPointableType) {
-		r, err := node.(JSONPointable).JSONLookup(decodedToken)
+	switch typed := node.(type) {
+	case JSONPointable:
+		r, err := typed.JSONLookup(decodedToken)
 		if err != nil {
 			return nil, kind, err
 		}
 		return r, kind, nil
+	case *any: // case of a pointer to interface, that is not resolved by reflect.Indirect
+		return getSingleImpl(*typed, decodedToken, nameProvider)
 	}
 
-	switch kind {
+	switch kind { //nolint:exhaustive
 	case reflect.Struct:
 		nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
 		if !ok {
@@ -159,7 +179,7 @@ func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.Nam
 
 }
 
-func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *swag.NameProvider) error {
+func setSingleImpl(node, data any, decodedToken string, nameProvider *swag.NameProvider) error {
 	rValue := reflect.Indirect(reflect.ValueOf(node))
 
 	if ns, ok := node.(JSONSetable); ok { // pointer impl
@@ -170,7 +190,7 @@ func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *sw
 		return node.(JSONSetable).JSONSet(decodedToken, data)
 	}
 
-	switch rValue.Kind() {
+	switch rValue.Kind() { //nolint:exhaustive
 	case reflect.Struct:
 		nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
 		if !ok {
@@ -210,7 +230,7 @@ func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *sw
 
 }
 
-func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) {
+func (p *Pointer) get(node any, nameProvider *swag.NameProvider) (any, reflect.Kind, error) {
 
 	if nameProvider == nil {
 		nameProvider = swag.DefaultJSONNameProvider
@@ -231,8 +251,7 @@ func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interf
 		if err != nil {
 			return nil, knd, err
 		}
-		node, kind = r, knd
-
+		node = r
 	}
 
 	rValue := reflect.ValueOf(node)
@@ -241,11 +260,11 @@ func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interf
 	return node, kind, nil
 }
 
-func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) error {
+func (p *Pointer) set(node, data any, nameProvider *swag.NameProvider) error {
 	knd := reflect.ValueOf(node).Kind()
 
 	if knd != reflect.Ptr && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array {
-		return fmt.Errorf("only structs, pointers, maps and slices are supported for setting values")
+		return errors.New("only structs, pointers, maps and slices are supported for setting values")
 	}
 
 	if nameProvider == nil {
@@ -284,7 +303,7 @@ func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) e
 			continue
 		}
 
-		switch kind {
+		switch kind { //nolint:exhaustive
 		case reflect.Struct:
 			nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
 			if !ok {
@@ -363,6 +382,128 @@ func (p *Pointer) String() string {
 	return pointerString
 }
 
+func (p *Pointer) Offset(document string) (int64, error) {
+	dec := json.NewDecoder(strings.NewReader(document))
+	var offset int64
+	for _, ttk := range p.DecodedTokens() {
+		tk, err := dec.Token()
+		if err != nil {
+			return 0, err
+		}
+		switch tk := tk.(type) {
+		case json.Delim:
+			switch tk {
+			case '{':
+				offset, err = offsetSingleObject(dec, ttk)
+				if err != nil {
+					return 0, err
+				}
+			case '[':
+				offset, err = offsetSingleArray(dec, ttk)
+				if err != nil {
+					return 0, err
+				}
+			default:
+				return 0, fmt.Errorf("invalid token %#v", tk)
+			}
+		default:
+			return 0, fmt.Errorf("invalid token %#v", tk)
+		}
+	}
+	return offset, nil
+}
+
+func offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) {
+	for dec.More() {
+		offset := dec.InputOffset()
+		tk, err := dec.Token()
+		if err != nil {
+			return 0, err
+		}
+		switch tk := tk.(type) {
+		case json.Delim:
+			switch tk {
+			case '{':
+				if err = drainSingle(dec); err != nil {
+					return 0, err
+				}
+			case '[':
+				if err = drainSingle(dec); err != nil {
+					return 0, err
+				}
+			}
+		case string:
+			if tk == decodedToken {
+				return offset, nil
+			}
+		default:
+			return 0, fmt.Errorf("invalid token %#v", tk)
+		}
+	}
+	return 0, fmt.Errorf("token reference %q not found", decodedToken)
+}
+
+func offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) {
+	idx, err := strconv.Atoi(decodedToken)
+	if err != nil {
+		return 0, fmt.Errorf("token reference %q is not a number: %v", decodedToken, err)
+	}
+	var i int
+	for i = 0; i < idx && dec.More(); i++ {
+		tk, err := dec.Token()
+		if err != nil {
+			return 0, err
+		}
+
+		if delim, isDelim := tk.(json.Delim); isDelim {
+			switch delim {
+			case '{':
+				if err = drainSingle(dec); err != nil {
+					return 0, err
+				}
+			case '[':
+				if err = drainSingle(dec); err != nil {
+					return 0, err
+				}
+			}
+		}
+	}
+
+	if !dec.More() {
+		return 0, fmt.Errorf("token reference %q not found", decodedToken)
+	}
+	return dec.InputOffset(), nil
+}
+
+// drainSingle drains a single level of object or array.
+// The decoder has to guarantee the beginning delim (i.e. '{' or '[') has been consumed.
+func drainSingle(dec *json.Decoder) error {
+	for dec.More() {
+		tk, err := dec.Token()
+		if err != nil {
+			return err
+		}
+		if delim, isDelim := tk.(json.Delim); isDelim {
+			switch delim {
+			case '{':
+				if err = drainSingle(dec); err != nil {
+					return err
+				}
+			case '[':
+				if err = drainSingle(dec); err != nil {
+					return err
+				}
+			}
+		}
+	}
+
+	// Consumes the ending delim
+	if _, err := dec.Token(); err != nil {
+		return err
+	}
+	return nil
+}
+
 // Specific JSON pointer encoding here
 // ~0 => ~
 // ~1 => /
@@ -377,14 +518,14 @@ const (
 
 // Unescape unescapes a json pointer reference token string to the original representation
 func Unescape(token string) string {
-	step1 := strings.Replace(token, encRefTok1, decRefTok1, -1)
-	step2 := strings.Replace(step1, encRefTok0, decRefTok0, -1)
+	step1 := strings.ReplaceAll(token, encRefTok1, decRefTok1)
+	step2 := strings.ReplaceAll(step1, encRefTok0, decRefTok0)
 	return step2
 }
 
 // Escape escapes a pointer reference token string
 func Escape(token string) string {
-	step1 := strings.Replace(token, decRefTok0, encRefTok0, -1)
-	step2 := strings.Replace(step1, decRefTok1, encRefTok1, -1)
+	step1 := strings.ReplaceAll(token, decRefTok0, encRefTok0)
+	step2 := strings.ReplaceAll(step1, decRefTok1, encRefTok1)
 	return step2
 }
diff --git a/vendor/github.com/go-openapi/jsonreference/.golangci.yml b/vendor/github.com/go-openapi/jsonreference/.golangci.yml
index f9381aee..22f8d21c 100644
--- a/vendor/github.com/go-openapi/jsonreference/.golangci.yml
+++ b/vendor/github.com/go-openapi/jsonreference/.golangci.yml
@@ -4,38 +4,58 @@ linters-settings:
   golint:
     min-confidence: 0
   gocyclo:
-    min-complexity: 30
+    min-complexity: 45
   maligned:
     suggest-new: true
   dupl:
-    threshold: 100
+    threshold: 200
   goconst:
     min-len: 2
-    min-occurrences: 4
+    min-occurrences: 3
+
 linters:
   enable-all: true
   disable:
     - maligned
+    - unparam
     - lll
+    - gochecknoinits
     - gochecknoglobals
+    - funlen
     - godox
     - gocognit
     - whitespace
     - wsl
-    - funlen
-    - gochecknoglobals
-    - gochecknoinits
-    - scopelint
     - wrapcheck
-    - exhaustivestruct
-    - exhaustive
-    - nlreturn
     - testpackage
-    - gci
-    - gofumpt
-    - goerr113
+    - nlreturn
     - gomnd
-    - tparallel
+    - exhaustivestruct
+    - goerr113
+    - errorlint
     - nestif
     - godot
-    - errorlint
+    - gofumpt
+    - paralleltest
+    - tparallel
+    - thelper
+    - ifshort
+    - exhaustruct
+    - varnamelen
+    - gci
+    - depguard
+    - errchkjson
+    - inamedparam
+    - nonamedreturns
+    - musttag
+    - ireturn
+    - forcetypeassert
+    - cyclop
+    # deprecated linters
+    - deadcode
+    - interfacer
+    - scopelint
+    - varcheck
+    - structcheck
+    - golint
+    - nosnakecase
diff --git a/vendor/github.com/go-openapi/jsonreference/.travis.yml b/vendor/github.com/go-openapi/jsonreference/.travis.yml
deleted file mode 100644
index 05482f4b..00000000
--- a/vendor/github.com/go-openapi/jsonreference/.travis.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-after_success:
-- bash <(curl -s https://codecov.io/bash)
-go:
-- 1.14.x
-- 1.x
-install:
-- go get gotest.tools/gotestsum
-jobs:
-  include:
-  # include linting job, but only for latest go version and amd64 arch
-  - go: 1.x
-    arch: amd64
-    install:
-      go get github.com/golangci/golangci-lint/cmd/golangci-lint
-    script:
-    - golangci-lint run --new-from-rev master
-env:
-- GO111MODULE=on
-language: go
-notifications:
-  slack:
-    secure: OpQG/36F7DSF00HLm9WZMhyqFCYYyYTsVDObW226cWiR8PWYiNfLZiSEvIzT1Gx4dDjhigKTIqcLhG34CkL5iNXDjm9Yyo2RYhQPlK8NErNqUEXuBqn4RqYHW48VGhEhOyDd4Ei0E2FN5ZbgpvHgtpkdZ6XDi64r3Ac89isP9aPHXQTuv2Jog6b4/OKKiUTftLcTIst0p4Cp3gqOJWf1wnoj+IadWiECNVQT6zb47IYjtyw6+uV8iUjTzdKcRB6Zc6b4Dq7JAg1Zd7Jfxkql3hlKp4PNlRf9Cy7y5iA3G7MLyg3FcPX5z2kmcyPt2jOTRMBWUJ5zIQpOxizAcN8WsT3WWBL5KbuYK6k0PzujrIDLqdxGpNmjkkMfDBT9cKmZpm2FdW+oZgPFJP+oKmAo4u4KJz/vjiPTXgQlN5bmrLuRMCp+AwC5wkIohTqWZVPE2TK6ZSnMYcg/W39s+RP/9mJoyryAvPSpBOLTI+biCgaUCTOAZxNTWpMFc3tPYntc41WWkdKcooZ9JA5DwfcaVFyTGQ3YXz+HvX6G1z/gW0Q/A4dBi9mj2iE1xm7tRTT+4VQ2AXFvSEI1HJpfPgYnwAtwOD1v3Qm2EUHk9sCdtEDR4wVGEPIVn44GnwFMnGKx9JWppMPYwFu3SVDdHt+E+LOlhZUply11Aa+IVrT2KUQ=
-script:
-- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...
diff --git a/vendor/github.com/go-openapi/jsonreference/README.md b/vendor/github.com/go-openapi/jsonreference/README.md
index b94753aa..c7fc2049 100644
--- a/vendor/github.com/go-openapi/jsonreference/README.md
+++ b/vendor/github.com/go-openapi/jsonreference/README.md
@@ -1,15 +1,19 @@
-# gojsonreference [![Build Status](https://travis-ci.org/go-openapi/jsonreference.svg?branch=master)](https://travis-ci.org/go-openapi/jsonreference) [![codecov](https://codecov.io/gh/go-openapi/jsonreference/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonreference) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
+# gojsonreference [![Build Status](https://github.com/go-openapi/jsonreference/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/jsonreference/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/jsonreference/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonreference)
+
+[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
+[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonreference/master/LICENSE)
+[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/jsonreference.svg)](https://pkg.go.dev/github.com/go-openapi/jsonreference)
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/jsonreference)](https://goreportcard.com/report/github.com/go-openapi/jsonreference)
 
-[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonreference/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/jsonreference?status.svg)](http://godoc.org/github.com/go-openapi/jsonreference)
 An implementation of JSON Reference - Go language
 
 ## Status
 Feature complete. Stable API
 
 ## Dependencies
-https://github.com/go-openapi/jsonpointer
+* https://github.com/go-openapi/jsonpointer
 
 ## References
-http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07
 
-http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03
+* http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07
+* http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03
diff --git a/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go b/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
index 8956c308..f0610cf1 100644
--- a/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
+++ b/vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
@@ -7,8 +7,8 @@ import (
 )
 
 const (
-	defaultHttpPort  = ":80"
-	defaultHttpsPort = ":443"
+	defaultHTTPPort  = ":80"
+	defaultHTTPSPort = ":443"
 )
 
 // Regular expressions used by the normalizations
@@ -18,18 +18,24 @@ var rxDupSlashes = regexp.MustCompile(`/{2,}`)
 // NormalizeURL will normalize the specified URL
 // This was added to replace a previous call to the no longer maintained purell library:
 // The call that was used looked like the following:
-//   url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes))
+//
+//	url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes))
 //
 // To explain all that was included in the call above, purell.FlagsSafe was really just the following:
-//	  - FlagLowercaseScheme
-//	  - FlagLowercaseHost
-//	  - FlagRemoveDefaultPort
-//	  - FlagRemoveDuplicateSlashes (and this was mixed in with the |)
+//   - FlagLowercaseScheme
+//   - FlagLowercaseHost
+//   - FlagRemoveDefaultPort
+//   - FlagRemoveDuplicateSlashes (and this was mixed in with the |)
+//
+// This also normalizes the URL into its urlencoded form by removing RawPath and RawFragment.
 func NormalizeURL(u *url.URL) {
 	lowercaseScheme(u)
 	lowercaseHost(u)
 	removeDefaultPort(u)
 	removeDuplicateSlashes(u)
+
+	u.RawPath = ""
+	u.RawFragment = ""
 }
 
 func lowercaseScheme(u *url.URL) {
@@ -48,7 +54,7 @@ func removeDefaultPort(u *url.URL) {
 	if len(u.Host) > 0 {
 		scheme := strings.ToLower(u.Scheme)
 		u.Host = rxPort.ReplaceAllStringFunc(u.Host, func(val string) string {
-			if (scheme == "http" && val == defaultHttpPort) || (scheme == "https" && val == defaultHttpsPort) {
+			if (scheme == "http" && val == defaultHTTPPort) || (scheme == "https" && val == defaultHTTPSPort) {
 				return ""
 			}
 			return val
diff --git a/vendor/github.com/go-openapi/loads/.golangci.yml b/vendor/github.com/go-openapi/loads/.golangci.yml
index d48b4a51..22f8d21c 100644
--- a/vendor/github.com/go-openapi/loads/.golangci.yml
+++ b/vendor/github.com/go-openapi/loads/.golangci.yml
@@ -4,41 +4,58 @@ linters-settings:
   golint:
     min-confidence: 0
   gocyclo:
-    min-complexity: 30
+    min-complexity: 45
   maligned:
     suggest-new: true
   dupl:
-    threshold: 100
+    threshold: 200
   goconst:
     min-len: 2
-    min-occurrences: 4
+    min-occurrences: 3
 
 linters:
   enable-all: true
   disable:
     - maligned
+    - unparam
     - lll
-    - gochecknoglobals
     - gochecknoinits
+    - gochecknoglobals
+    - funlen
     - godox
     - gocognit
     - whitespace
     - wsl
-    - funlen
-    - gochecknoglobals
-    - gochecknoinits
-    - scopelint
     - wrapcheck
-    - exhaustivestruct
-    - exhaustive
-    - nlreturn
     - testpackage
-    - gci
-    - gofumpt
-    - goerr113
+    - nlreturn
     - gomnd
-    - tparallel
+    - exhaustivestruct
+    - goerr113
+    - errorlint
     - nestif
     - godot
-    - errorlint
+    - gofumpt
     - paralleltest
+    - tparallel
+    - thelper
+    - ifshort
+    - exhaustruct
+    - varnamelen
+    - gci
+    - depguard
+    - errchkjson
+    - inamedparam
+    - nonamedreturns
+    - musttag
+    - ireturn
+    - forcetypeassert
+    - cyclop
+    # deprecated linters
+    - deadcode
+    - interfacer
+    - scopelint
+    - varcheck
+    - structcheck
+    - golint
+    - nosnakecase
diff --git a/vendor/github.com/go-openapi/loads/README.md b/vendor/github.com/go-openapi/loads/README.md
index df1f6264..f8bd440d 100644
--- a/vendor/github.com/go-openapi/loads/README.md
+++ b/vendor/github.com/go-openapi/loads/README.md
@@ -1,4 +1,4 @@
-# Loads OAI specs  [![Build Status](https://travis-ci.org/go-openapi/loads.svg?branch=master)](https://travis-ci.org/go-openapi/loads) [![codecov](https://codecov.io/gh/go-openapi/loads/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/loads) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) [![Actions/Go Test Status](https://github.com/go-openapi/loads/workflows/Go%20Test/badge.svg)](https://github.com/go-openapi/loads/actions?query=workflow%3A"Go+Test")
+# Loads OAI specs [![Build Status](https://github.com/go-openapi/loads/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/loads/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/loads/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/loads)
 
 [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/loads/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/loads?status.svg)](http://godoc.org/github.com/go-openapi/loads)
 [![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/loads)](https://goreportcard.com/report/github.com/go-openapi/loads)
diff --git a/vendor/github.com/go-openapi/loads/doc.go b/vendor/github.com/go-openapi/loads/doc.go
index 3046da4c..5bcaef5d 100644
--- a/vendor/github.com/go-openapi/loads/doc.go
+++ b/vendor/github.com/go-openapi/loads/doc.go
@@ -12,10 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-/*
-Package loads provides document loading methods for swagger (OAI) specifications.
-
-It is used by other go-openapi packages to load and run analysis on local or remote spec documents.
-
-*/
+// Package loads provides document loading methods for swagger (OAI) specifications.
+//
+// It is used by other go-openapi packages to load and run analysis on local or remote spec documents.
 package loads
diff --git a/vendor/github.com/go-openapi/loads/loaders.go b/vendor/github.com/go-openapi/loads/loaders.go
index 44bd32b5..b2d1e034 100644
--- a/vendor/github.com/go-openapi/loads/loaders.go
+++ b/vendor/github.com/go-openapi/loads/loaders.go
@@ -21,7 +21,7 @@ var (
 func init() {
 	jsonLoader := &loader{
 		DocLoaderWithMatch: DocLoaderWithMatch{
-			Match: func(pth string) bool {
+			Match: func(_ string) bool {
 				return true
 			},
 			Fn: JSONDoc,
@@ -86,7 +86,7 @@ func (l *loader) Load(path string) (json.RawMessage, error) {
 		return nil, erp
 	}
 
-	var lastErr error = errors.New("no loader matched") // default error if no match was found
+	lastErr := errors.New("no loader matched") // default error if no match was found
 	for ldr := l; ldr != nil; ldr = ldr.Next {
 		if ldr.Match != nil && !ldr.Match(path) {
 			continue
@@ -118,9 +118,8 @@ func JSONDoc(path string) (json.RawMessage, error) {
 // This sets the configuration at the package level.
 //
 // NOTE:
-//  * this updates the default loader used by github.com/go-openapi/spec
-//  * since this sets package level globals, you shouln't call this concurrently
-//
+//   - this updates the default loader used by github.com/go-openapi/spec
+//   - since this sets package level globals, you shouln't call this concurrently
 func AddLoader(predicate DocMatcher, load DocLoader) {
 	loaders = loaders.WithHead(&loader{
 		DocLoaderWithMatch: DocLoaderWithMatch{
diff --git a/vendor/github.com/go-openapi/loads/spec.go b/vendor/github.com/go-openapi/loads/spec.go
index 93c8d4b8..c9039cd5 100644
--- a/vendor/github.com/go-openapi/loads/spec.go
+++ b/vendor/github.com/go-openapi/loads/spec.go
@@ -38,8 +38,8 @@ type Document struct {
 	specFilePath string
 	origSpec     *spec.Swagger
 	schema       *spec.Schema
-	raw          json.RawMessage
 	pathLoader   *loader
+	raw          json.RawMessage
 }
 
 // JSONSpec loads a spec from a json document
@@ -49,7 +49,14 @@ func JSONSpec(path string, options ...LoaderOption) (*Document, error) {
 		return nil, err
 	}
 	// convert to json
-	return Analyzed(data, "", options...)
+	doc, err := Analyzed(data, "", options...)
+	if err != nil {
+		return nil, err
+	}
+
+	doc.specFilePath = path
+
+	return doc, nil
 }
 
 // Embedded returns a Document based on embedded specs. No analysis is required
@@ -71,7 +78,6 @@ func Embedded(orig, flat json.RawMessage, options ...LoaderOption) (*Document, e
 
 // Spec loads a new spec document from a local or remote path
 func Spec(path string, options ...LoaderOption) (*Document, error) {
-
 	ldr := loaderFromOptions(options)
 
 	b, err := ldr.Load(path)
@@ -84,12 +90,10 @@ func Spec(path string, options ...LoaderOption) (*Document, error) {
 		return nil, err
 	}
 
-	if document != nil {
-		document.specFilePath = path
-		document.pathLoader = ldr
-	}
+	document.specFilePath = path
+	document.pathLoader = ldr
 
-	return document, err
+	return document, nil
 }
 
 // Analyzed creates a new analyzed spec document for a root json.RawMessage.
@@ -117,7 +121,7 @@ func Analyzed(data json.RawMessage, version string, options ...LoaderOption) (*D
 	}
 
 	d := &Document{
-		Analyzer:   analysis.New(swspec),
+		Analyzer:   analysis.New(swspec), // NOTE: at this moment, analysis does not follow $refs to documents outside the root doc
 		schema:     spec.MustLoadSwagger20Schema(),
 		spec:       swspec,
 		raw:        raw,
@@ -152,9 +156,8 @@ func trimData(in json.RawMessage) (json.RawMessage, error) {
 	return d, nil
 }
 
-// Expanded expands the ref fields in the spec document and returns a new spec document
+// Expanded expands the $ref fields in the spec document and returns a new spec document
 func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
-
 	swspec := new(spec.Swagger)
 	if err := json.Unmarshal(d.raw, swspec); err != nil {
 		return nil, err
@@ -163,6 +166,9 @@ func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
 	var expandOptions *spec.ExpandOptions
 	if len(options) > 0 {
 		expandOptions = options[0]
+		if expandOptions.RelativeBase == "" {
+			expandOptions.RelativeBase = d.specFilePath
+		}
 	} else {
 		expandOptions = &spec.ExpandOptions{
 			RelativeBase: d.specFilePath,
@@ -194,7 +200,7 @@ func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
 	return dd, nil
 }
 
-// BasePath the base path for this spec
+// BasePath the base path for the API specified by this spec
 func (d *Document) BasePath() string {
 	return d.spec.BasePath
 }
@@ -242,8 +248,11 @@ func (d *Document) ResetDefinitions() *Document {
 
 // Pristine creates a new pristine document instance based on the input data
 func (d *Document) Pristine() *Document {
-	dd, _ := Analyzed(d.Raw(), d.Version())
+	raw, _ := json.Marshal(d.Spec())
+	dd, _ := Analyzed(raw, d.Version())
 	dd.pathLoader = d.pathLoader
+	dd.specFilePath = d.specFilePath
+
 	return dd
 }
 
diff --git a/vendor/github.com/go-openapi/runtime/.golangci.yml b/vendor/github.com/go-openapi/runtime/.golangci.yml
index b1aa7928..1c75557b 100644
--- a/vendor/github.com/go-openapi/runtime/.golangci.yml
+++ b/vendor/github.com/go-openapi/runtime/.golangci.yml
@@ -1,44 +1,62 @@
 linters-settings:
   govet:
-    # Using err repeatedly considered as shadowing.
-    check-shadowing: false
+    check-shadowing: true
   golint:
     min-confidence: 0
   gocyclo:
-    min-complexity: 30
+    min-complexity: 45
   maligned:
     suggest-new: true
   dupl:
-    threshold: 100
+    threshold: 200
   goconst:
     min-len: 2
-    min-occurrences: 4
+    min-occurrences: 3
+
 linters:
+  enable-all: true
   disable:
+    - nilerr # nilerr crashes on this repo
     - maligned
+    - unparam
     - lll
+    - gochecknoinits
     - gochecknoglobals
+    - funlen
     - godox
     - gocognit
     - whitespace
     - wsl
-    - funlen
-    - gochecknoglobals
-    - gochecknoinits
-    - scopelint
     - wrapcheck
-    - exhaustivestruct
-    - exhaustive
-    - nlreturn
     - testpackage
-    - gci
-    - gofumpt
-    - goerr113
+    - nlreturn
     - gomnd
-    - tparallel
+    - exhaustivestruct
+    - goerr113
+    - errorlint
     - nestif
     - godot
-    - errorlint
-    - noctx
+    - gofumpt
+    - paralleltest
+    - tparallel
+    - thelper
+    - ifshort
+    - exhaustruct
+    - varnamelen
+    - gci
+    - depguard
+    - errchkjson
+    - inamedparam
+    - nonamedreturns
+    - musttag
+    - ireturn
+    - forcetypeassert
+    - cyclop
+    # deprecated linters
+    - deadcode
     - interfacer
-    - nilerr
+    - scopelint
+    - varcheck
+    - structcheck
+    - golint
+    - nosnakecase
diff --git a/vendor/github.com/go-openapi/runtime/README.md b/vendor/github.com/go-openapi/runtime/README.md
index 5b1ec649..b07e0ad9 100644
--- a/vendor/github.com/go-openapi/runtime/README.md
+++ b/vendor/github.com/go-openapi/runtime/README.md
@@ -1,7 +1,10 @@
-# runtime [![Build Status](https://travis-ci.org/go-openapi/runtime.svg?branch=client-context)](https://travis-ci.org/go-openapi/runtime) [![codecov](https://codecov.io/gh/go-openapi/runtime/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/runtime) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
+# runtime [![Build Status](https://github.com/go-openapi/runtime/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/runtime/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/runtime/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/runtime)
 
-[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/runtime/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/runtime?status.svg)](http://godoc.org/github.com/go-openapi/runtime)
+[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
+[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/runtime/master/LICENSE) 
+[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/runtime.svg)](https://pkg.go.dev/github.com/go-openapi/runtime)
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/runtime)](https://goreportcard.com/report/github.com/go-openapi/runtime)
 
-# golang Open-API toolkit - runtime
+# go OpenAPI toolkit runtime
 
-The runtime component for use in codegeneration or as untyped usage.
+The runtime component for use in code generation or as untyped usage.
diff --git a/vendor/github.com/go-openapi/runtime/bytestream.go b/vendor/github.com/go-openapi/runtime/bytestream.go
index 6eb6ceb5..f8fb4822 100644
--- a/vendor/github.com/go-openapi/runtime/bytestream.go
+++ b/vendor/github.com/go-openapi/runtime/bytestream.go
@@ -38,9 +38,16 @@ type byteStreamOpts struct {
 	Close bool
 }
 
-// ByteStreamConsumer creates a consumer for byte streams,
-// takes a Writer/BinaryUnmarshaler interface or binary slice by reference,
-// and reads from the provided reader
+// ByteStreamConsumer creates a consumer for byte streams.
+//
+// The consumer consumes from a provided reader into the data passed by reference.
+//
+// Supported output underlying types and interfaces, prioritized in this order:
+// - io.ReaderFrom (for maximum control)
+// - io.Writer (performs io.Copy)
+// - encoding.BinaryUnmarshaler
+// - *string
+// - *[]byte
 func ByteStreamConsumer(opts ...byteStreamOpt) Consumer {
 	var vals byteStreamOpts
 	for _, opt := range opts {
@@ -51,44 +58,70 @@ func ByteStreamConsumer(opts ...byteStreamOpt) Consumer {
 		if reader == nil {
 			return errors.New("ByteStreamConsumer requires a reader") // early exit
 		}
+		if data == nil {
+			return errors.New("nil destination for ByteStreamConsumer")
+		}
 
-		close := defaultCloser
+		closer := defaultCloser
 		if vals.Close {
-			if cl, ok := reader.(io.Closer); ok {
-				close = cl.Close
+			if cl, isReaderCloser := reader.(io.Closer); isReaderCloser {
+				closer = cl.Close
 			}
 		}
-		//nolint:errcheck // closing a reader wouldn't fail.
-		defer close()
+		defer func() {
+			_ = closer()
+		}()
 
-		if wrtr, ok := data.(io.Writer); ok {
-			_, err := io.Copy(wrtr, reader)
+		if readerFrom, isReaderFrom := data.(io.ReaderFrom); isReaderFrom {
+			_, err := readerFrom.ReadFrom(reader)
 			return err
 		}
 
-		buf := new(bytes.Buffer)
+		if writer, isDataWriter := data.(io.Writer); isDataWriter {
+			_, err := io.Copy(writer, reader)
+			return err
+		}
+
+		// buffers input before writing to data
+		var buf bytes.Buffer
 		_, err := buf.ReadFrom(reader)
 		if err != nil {
 			return err
 		}
 		b := buf.Bytes()
 
-		if bu, ok := data.(encoding.BinaryUnmarshaler); ok {
-			return bu.UnmarshalBinary(b)
-		}
+		switch destinationPointer := data.(type) {
+		case encoding.BinaryUnmarshaler:
+			return destinationPointer.UnmarshalBinary(b)
+		case *any:
+			switch (*destinationPointer).(type) {
+			case string:
+				*destinationPointer = string(b)
+
+				return nil
+
+			case []byte:
+				*destinationPointer = b
 
-		if data != nil {
-			if str, ok := data.(*string); ok {
-				*str = string(b)
 				return nil
 			}
-		}
+		default:
+			// check for the underlying type to be pointer to []byte or string,
+			if ptr := reflect.TypeOf(data); ptr.Kind() != reflect.Ptr {
+				return errors.New("destination must be a pointer")
+			}
 
-		if t := reflect.TypeOf(data); data != nil && t.Kind() == reflect.Ptr {
 			v := reflect.Indirect(reflect.ValueOf(data))
-			if t = v.Type(); t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8 {
+			t := v.Type()
+
+			switch {
+			case t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8:
 				v.SetBytes(b)
 				return nil
+
+			case t.Kind() == reflect.String:
+				v.SetString(string(b))
+				return nil
 			}
 		}
 
@@ -97,67 +130,87 @@ func ByteStreamConsumer(opts ...byteStreamOpt) Consumer {
 	})
 }
 
-// ByteStreamProducer creates a producer for byte streams,
-// takes a Reader/BinaryMarshaler interface or binary slice,
-// and writes to a writer (essentially a pipe)
+// ByteStreamProducer creates a producer for byte streams.
+//
+// The producer takes input data then writes to an output writer (essentially as a pipe).
+//
+// Supported input underlying types and interfaces, prioritized in this order:
+// - io.WriterTo (for maximum control)
+// - io.Reader (performs io.Copy). A ReadCloser is closed before exiting.
+// - encoding.BinaryMarshaler
+// - error (writes as a string)
+// - []byte
+// - string
+// - struct, other slices: writes as JSON
 func ByteStreamProducer(opts ...byteStreamOpt) Producer {
 	var vals byteStreamOpts
 	for _, opt := range opts {
 		opt(&vals)
 	}
+
 	return ProducerFunc(func(writer io.Writer, data interface{}) error {
 		if writer == nil {
 			return errors.New("ByteStreamProducer requires a writer") // early exit
 		}
-		close := defaultCloser
+		if data == nil {
+			return errors.New("nil data for ByteStreamProducer")
+		}
+
+		closer := defaultCloser
 		if vals.Close {
-			if cl, ok := writer.(io.Closer); ok {
-				close = cl.Close
+			if cl, isWriterCloser := writer.(io.Closer); isWriterCloser {
+				closer = cl.Close
 			}
 		}
-		//nolint:errcheck // TODO: closing a writer would fail.
-		defer close()
+		defer func() {
+			_ = closer()
+		}()
 
-		if rc, ok := data.(io.ReadCloser); ok {
+		if rc, isDataCloser := data.(io.ReadCloser); isDataCloser {
 			defer rc.Close()
 		}
 
-		if rdr, ok := data.(io.Reader); ok {
-			_, err := io.Copy(writer, rdr)
+		switch origin := data.(type) {
+		case io.WriterTo:
+			_, err := origin.WriteTo(writer)
+			return err
+
+		case io.Reader:
+			_, err := io.Copy(writer, origin)
 			return err
-		}
 
-		if bm, ok := data.(encoding.BinaryMarshaler); ok {
-			bytes, err := bm.MarshalBinary()
+		case encoding.BinaryMarshaler:
+			bytes, err := origin.MarshalBinary()
 			if err != nil {
 				return err
 			}
 
 			_, err = writer.Write(bytes)
 			return err
-		}
-
-		if data != nil {
-			if str, ok := data.(string); ok {
-				_, err := writer.Write([]byte(str))
-				return err
-			}
 
-			if e, ok := data.(error); ok {
-				_, err := writer.Write([]byte(e.Error()))
-				return err
-			}
+		case error:
+			_, err := writer.Write([]byte(origin.Error()))
+			return err
 
+		default:
 			v := reflect.Indirect(reflect.ValueOf(data))
-			if t := v.Type(); t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8 {
+			t := v.Type()
+
+			switch {
+			case t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8:
 				_, err := writer.Write(v.Bytes())
 				return err
-			}
-			if t := v.Type(); t.Kind() == reflect.Struct || t.Kind() == reflect.Slice {
+
+			case t.Kind() == reflect.String:
+				_, err := writer.Write([]byte(v.String()))
+				return err
+
+			case t.Kind() == reflect.Struct || t.Kind() == reflect.Slice:
 				b, err := swag.WriteJSON(data)
 				if err != nil {
 					return err
 				}
+
 				_, err = writer.Write(b)
 				return err
 			}
diff --git a/vendor/github.com/go-openapi/runtime/client/keepalive.go b/vendor/github.com/go-openapi/runtime/client/keepalive.go
index bc7b7fa4..7dd6b51c 100644
--- a/vendor/github.com/go-openapi/runtime/client/keepalive.go
+++ b/vendor/github.com/go-openapi/runtime/client/keepalive.go
@@ -48,8 +48,7 @@ func (d *drainingReadCloser) Close() error {
 		// If the reader side (a HTTP server) is misbehaving, it still may send
 		// some bytes, but the closer ignores them to keep the underling
 		// connection open.
-		//nolint:errcheck
-		io.Copy(io.Discard, d.rdr)
+		_, _ = io.Copy(io.Discard, d.rdr)
 	}
 	return d.rdr.Close()
 }
diff --git a/vendor/github.com/go-openapi/runtime/client/opentelemetry.go b/vendor/github.com/go-openapi/runtime/client/opentelemetry.go
index 8a38ea3e..256cd1b4 100644
--- a/vendor/github.com/go-openapi/runtime/client/opentelemetry.go
+++ b/vendor/github.com/go-openapi/runtime/client/opentelemetry.go
@@ -11,7 +11,8 @@ import (
 	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/codes"
 	"go.opentelemetry.io/otel/propagation"
-	semconv "go.opentelemetry.io/otel/semconv/v1.12.0"
+	semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
+	"go.opentelemetry.io/otel/semconv/v1.17.0/httpconv"
 	"go.opentelemetry.io/otel/trace"
 )
 
@@ -131,8 +132,11 @@ func (t *openTelemetryTransport) Submit(op *runtime.ClientOperation) (interface{
 	op.Reader = runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
 		if span != nil {
 			statusCode := response.Code()
-			span.SetAttributes(attribute.Int(string(semconv.HTTPStatusCodeKey), statusCode))
-			span.SetStatus(semconv.SpanStatusFromHTTPStatusCodeAndSpanKind(statusCode, trace.SpanKindClient))
+			// NOTE: this is replaced by semconv.HTTPResponseStatusCode in semconv v1.21
+			span.SetAttributes(semconv.HTTPStatusCode(statusCode))
+			// NOTE: the conversion from HTTP status code to trace code is no longer available with
+			// semconv v1.21
+			span.SetStatus(httpconv.ServerStatus(statusCode))
 		}
 
 		return reader.ReadResponse(response, consumer)
diff --git a/vendor/github.com/go-openapi/runtime/client/request.go b/vendor/github.com/go-openapi/runtime/client/request.go
index 4c00ed3a..c4a891d0 100644
--- a/vendor/github.com/go-openapi/runtime/client/request.go
+++ b/vendor/github.com/go-openapi/runtime/client/request.go
@@ -16,6 +16,7 @@ package client
 
 import (
 	"bytes"
+	"context"
 	"fmt"
 	"io"
 	"log"
@@ -35,7 +36,7 @@ import (
 )
 
 // NewRequest creates a new swagger http client request
-func newRequest(method, pathPattern string, writer runtime.ClientRequestWriter) (*request, error) {
+func newRequest(method, pathPattern string, writer runtime.ClientRequestWriter) *request {
 	return &request{
 		pathPattern: pathPattern,
 		method:      method,
@@ -44,7 +45,7 @@ func newRequest(method, pathPattern string, writer runtime.ClientRequestWriter)
 		query:       make(url.Values),
 		timeout:     DefaultTimeout,
 		getBody:     getRequestBuffer,
-	}, nil
+	}
 }
 
 // Request represents a swagger client request.
@@ -102,7 +103,7 @@ func logClose(err error, pw *io.PipeWriter) {
 	}
 }
 
-func (r *request) buildHTTP(mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter) (*http.Request, error) {
+func (r *request) buildHTTP(mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter) (*http.Request, error) { //nolint:gocyclo,maintidx
 	// build the data
 	if err := r.writer.WriteToRequest(r, registry); err != nil {
 		return nil, err
@@ -170,7 +171,7 @@ func (r *request) buildHTTP(mediaType, basePath string, producers map[string]run
 						// Need to read the data so that we can detect the content type
 						buf := make([]byte, 512)
 						size, err := fi.Read(buf)
-						if err != nil {
+						if err != nil && err != io.EOF {
 							logClose(err, pw)
 							return
 						}
@@ -317,13 +318,13 @@ DoneChoosingBodySource:
 
 	urlPath := path.Join(basePathURL.Path, pathPatternURL.Path)
 	for k, v := range r.pathParams {
-		urlPath = strings.Replace(urlPath, "{"+k+"}", url.PathEscape(v), -1)
+		urlPath = strings.ReplaceAll(urlPath, "{"+k+"}", url.PathEscape(v))
 	}
 	if reinstateSlash {
-		urlPath = urlPath + "/"
+		urlPath += "/"
 	}
 
-	req, err := http.NewRequest(r.method, urlPath, body)
+	req, err := http.NewRequestWithContext(context.Background(), r.method, urlPath, body)
 	if err != nil {
 		return nil, err
 	}
@@ -361,7 +362,7 @@ func (r *request) GetMethod() string {
 func (r *request) GetPath() string {
 	path := r.pathPattern
 	for k, v := range r.pathParams {
-		path = strings.Replace(path, "{"+k+"}", v, -1)
+		path = strings.ReplaceAll(path, "{"+k+"}", v)
 	}
 	return path
 }
diff --git a/vendor/github.com/go-openapi/runtime/client/runtime.go b/vendor/github.com/go-openapi/runtime/client/runtime.go
index ccec0413..5bd4d75d 100644
--- a/vendor/github.com/go-openapi/runtime/client/runtime.go
+++ b/vendor/github.com/go-openapi/runtime/client/runtime.go
@@ -22,6 +22,7 @@ import (
 	"crypto/tls"
 	"crypto/x509"
 	"encoding/pem"
+	"errors"
 	"fmt"
 	"mime"
 	"net/http"
@@ -31,13 +32,18 @@ import (
 	"sync"
 	"time"
 
+	"github.com/go-openapi/strfmt"
 	"github.com/opentracing/opentracing-go"
 
 	"github.com/go-openapi/runtime"
 	"github.com/go-openapi/runtime/logger"
 	"github.com/go-openapi/runtime/middleware"
 	"github.com/go-openapi/runtime/yamlpc"
-	"github.com/go-openapi/strfmt"
+)
+
+const (
+	schemeHTTP  = "http"
+	schemeHTTPS = "https"
 )
 
 // TLSClientOptions to configure client authentication with mutual TLS
@@ -70,7 +76,7 @@ type TLSClientOptions struct {
 	LoadedCA *x509.Certificate
 
 	// LoadedCAPool specifies a pool of RootCAs to use when validating the server's TLS certificate.
-	// If set, it will be combined with the the other loaded certificates (see LoadedCA and CA).
+	// If set, it will be combined with the other loaded certificates (see LoadedCA and CA).
 	// If neither LoadedCA or CA is set, the provided pool with override the system
 	// certificate pool.
 	// The caller must not use the supplied pool after calling TLSClientAuth.
@@ -112,7 +118,9 @@ type TLSClientOptions struct {
 // TLSClientAuth creates a tls.Config for mutual auth
 func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
 	// create client tls config
-	cfg := &tls.Config{}
+	cfg := &tls.Config{
+		MinVersion: tls.VersionTLS12,
+	}
 
 	// load client cert if specified
 	if opts.Certificate != "" {
@@ -136,7 +144,7 @@ func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
 				return nil, fmt.Errorf("tls client priv key: %v", err)
 			}
 		default:
-			return nil, fmt.Errorf("tls client priv key: unsupported key type")
+			return nil, errors.New("tls client priv key: unsupported key type")
 		}
 
 		block = pem.Block{Type: "PRIVATE KEY", Bytes: keyBytes}
@@ -158,11 +166,12 @@ func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
 	// When no CA certificate is provided, default to the system cert pool
 	// that way when a request is made to a server known by the system trust store,
 	// the name is still verified
-	if opts.LoadedCA != nil {
+	switch {
+	case opts.LoadedCA != nil:
 		caCertPool := basePool(opts.LoadedCAPool)
 		caCertPool.AddCert(opts.LoadedCA)
 		cfg.RootCAs = caCertPool
-	} else if opts.CA != "" {
+	case opts.CA != "":
 		// load ca cert
 		caCert, err := os.ReadFile(opts.CA)
 		if err != nil {
@@ -171,7 +180,7 @@ func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
 		caCertPool := basePool(opts.LoadedCAPool)
 		caCertPool.AppendCertsFromPEM(caCert)
 		cfg.RootCAs = caCertPool
-	} else if opts.LoadedCAPool != nil {
+	case opts.LoadedCAPool != nil:
 		cfg.RootCAs = opts.LoadedCAPool
 	}
 
@@ -227,7 +236,7 @@ type Runtime struct {
 	Host     string
 	BasePath string
 	Formats  strfmt.Registry
-	Context  context.Context
+	Context  context.Context //nolint:containedctx  // we precisely want this type to contain the request context
 
 	Debug  bool
 	logger logger.Logger
@@ -316,7 +325,7 @@ func (r *Runtime) pickScheme(schemes []string) string {
 	if v := r.selectScheme(schemes); v != "" {
 		return v
 	}
-	return "http"
+	return schemeHTTP
 }
 
 func (r *Runtime) selectScheme(schemes []string) string {
@@ -327,9 +336,9 @@ func (r *Runtime) selectScheme(schemes []string) string {
 
 	scheme := schemes[0]
 	// prefer https, but skip when not possible
-	if scheme != "https" && schLen > 1 {
+	if scheme != schemeHTTPS && schLen > 1 {
 		for _, sch := range schemes {
-			if sch == "https" {
+			if sch == schemeHTTPS {
 				scheme = sch
 				break
 			}
@@ -368,17 +377,14 @@ func (r *Runtime) EnableConnectionReuse() {
 }
 
 // takes a client operation and creates equivalent http.Request
-func (r *Runtime) createHttpRequest(operation *runtime.ClientOperation) (*request, *http.Request, error) {
+func (r *Runtime) createHttpRequest(operation *runtime.ClientOperation) (*request, *http.Request, error) { //nolint:revive,stylecheck
 	params, _, auth := operation.Params, operation.Reader, operation.AuthInfo
 
-	request, err := newRequest(operation.Method, operation.PathPattern, params)
-	if err != nil {
-		return nil, nil, err
-	}
+	request := newRequest(operation.Method, operation.PathPattern, params)
 
 	var accept []string
 	accept = append(accept, operation.ProducesMediaTypes...)
-	if err = request.SetHeaderParam(runtime.HeaderAccept, accept...); err != nil {
+	if err := request.SetHeaderParam(runtime.HeaderAccept, accept...); err != nil {
 		return nil, nil, err
 	}
 
@@ -420,7 +426,7 @@ func (r *Runtime) createHttpRequest(operation *runtime.ClientOperation) (*reques
 	return request, req, nil
 }
 
-func (r *Runtime) CreateHttpRequest(operation *runtime.ClientOperation) (req *http.Request, err error) {
+func (r *Runtime) CreateHttpRequest(operation *runtime.ClientOperation) (req *http.Request, err error) { //nolint:revive,stylecheck
 	_, req, err = r.createHttpRequest(operation)
 	return
 }
@@ -450,27 +456,36 @@ func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error
 		r.logger.Debugf("%s\n", string(b))
 	}
 
-	var hasTimeout bool
-	pctx := operation.Context
-	if pctx == nil {
-		pctx = r.Context
-	} else {
-		hasTimeout = true
-	}
-	if pctx == nil {
-		pctx = context.Background()
+	var parentCtx context.Context
+	switch {
+	case operation.Context != nil:
+		parentCtx = operation.Context
+	case r.Context != nil:
+		parentCtx = r.Context
+	default:
+		parentCtx = context.Background()
 	}
-	var ctx context.Context
-	var cancel context.CancelFunc
-	if hasTimeout {
-		ctx, cancel = context.WithCancel(pctx)
+
+	var (
+		ctx    context.Context
+		cancel context.CancelFunc
+	)
+	if request.timeout == 0 {
+		// There may be a deadline in the context passed to the operation.
+		// Otherwise, there is no timeout set.
+		ctx, cancel = context.WithCancel(parentCtx)
 	} else {
-		ctx, cancel = context.WithTimeout(pctx, request.timeout)
+		// Sets the timeout passed from request params (by default runtime.DefaultTimeout).
+		// If there is already a deadline in the parent context, the shortest will
+		// apply.
+		ctx, cancel = context.WithTimeout(parentCtx, request.timeout)
 	}
 	defer cancel()
 
-	client := operation.Client
-	if client == nil {
+	var client *http.Client
+	if operation.Client != nil {
+		client = operation.Client
+	} else {
 		client = r.client
 	}
 	req = req.WithContext(ctx)
@@ -481,7 +496,7 @@ func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error
 	defer res.Body.Close()
 
 	ct := res.Header.Get(runtime.HeaderContentType)
-	if ct == "" { // this should really really never occur
+	if ct == "" { // this should really never occur
 		ct = r.DefaultMediaType
 	}
 
@@ -526,7 +541,7 @@ func (r *Runtime) SetLogger(logger logger.Logger) {
 	middleware.Logger = logger
 }
 
-type ClientResponseFunc = func(*http.Response) runtime.ClientResponse
+type ClientResponseFunc = func(*http.Response) runtime.ClientResponse //nolint:revive
 
 // SetResponseReader changes the response reader implementation.
 func (r *Runtime) SetResponseReader(f ClientResponseFunc) {
diff --git a/vendor/github.com/go-openapi/runtime/client_operation.go b/vendor/github.com/go-openapi/runtime/client_operation.go
index fa21eacf..5a5d6356 100644
--- a/vendor/github.com/go-openapi/runtime/client_operation.go
+++ b/vendor/github.com/go-openapi/runtime/client_operation.go
@@ -30,12 +30,12 @@ type ClientOperation struct {
 	AuthInfo           ClientAuthInfoWriter
 	Params             ClientRequestWriter
 	Reader             ClientResponseReader
-	Context            context.Context
+	Context            context.Context //nolint:containedctx // we precisely want this type to contain the request context
 	Client             *http.Client
 }
 
 // A ClientTransport implementor knows how to submit Request objects to some destination
 type ClientTransport interface {
-	//Submit(string, RequestWriter, ResponseReader, AuthInfoWriter) (interface{}, error)
+	// Submit(string, RequestWriter, ResponseReader, AuthInfoWriter) (interface{}, error)
 	Submit(*ClientOperation) (interface{}, error)
 }
diff --git a/vendor/github.com/go-openapi/runtime/client_request.go b/vendor/github.com/go-openapi/runtime/client_request.go
index d4d2b58f..4ebb2dea 100644
--- a/vendor/github.com/go-openapi/runtime/client_request.go
+++ b/vendor/github.com/go-openapi/runtime/client_request.go
@@ -37,8 +37,8 @@ type ClientRequestWriter interface {
 }
 
 // ClientRequest is an interface for things that know how to
-// add information to a swagger client request
-type ClientRequest interface {
+// add information to a swagger client request.
+type ClientRequest interface { //nolint:interfacebloat // a swagger-capable request is quite rich, hence the many getter/setters
 	SetHeaderParam(string, ...string) error
 
 	GetHeaderParams() http.Header
diff --git a/vendor/github.com/go-openapi/runtime/csv.go b/vendor/github.com/go-openapi/runtime/csv.go
index d807bd91..c9597bcd 100644
--- a/vendor/github.com/go-openapi/runtime/csv.go
+++ b/vendor/github.com/go-openapi/runtime/csv.go
@@ -16,62 +16,335 @@ package runtime
 
 import (
 	"bytes"
+	"context"
+	"encoding"
 	"encoding/csv"
 	"errors"
+	"fmt"
 	"io"
+	"reflect"
+
+	"golang.org/x/sync/errgroup"
 )
 
-// CSVConsumer creates a new CSV consumer
-func CSVConsumer() Consumer {
+// CSVConsumer creates a new CSV consumer.
+//
+// The consumer consumes CSV records from a provided reader into the data passed by reference.
+//
+// CSVOpts options may be specified to alter the default CSV behavior on the reader and the writer side (e.g. separator, skip header, ...).
+// The defaults are those of the standard library's csv.Reader and csv.Writer.
+//
+// Supported output underlying types and interfaces, prioritized in this order:
+// - *csv.Writer
+// - CSVWriter (writer options are ignored)
+// - io.Writer (as raw bytes)
+// - io.ReaderFrom (as raw bytes)
+// - encoding.BinaryUnmarshaler (as raw bytes)
+// - *[][]string (as a collection of records)
+// - *[]byte (as raw bytes)
+// - *string (a raw bytes)
+//
+// The consumer prioritizes situations where buffering the input is not required.
+func CSVConsumer(opts ...CSVOpt) Consumer {
+	o := csvOptsWithDefaults(opts)
+
 	return ConsumerFunc(func(reader io.Reader, data interface{}) error {
 		if reader == nil {
 			return errors.New("CSVConsumer requires a reader")
 		}
+		if data == nil {
+			return errors.New("nil destination for CSVConsumer")
+		}
 
 		csvReader := csv.NewReader(reader)
-		writer, ok := data.(io.Writer)
-		if !ok {
-			return errors.New("data type must be io.Writer")
+		o.applyToReader(csvReader)
+		closer := defaultCloser
+		if o.closeStream {
+			if cl, isReaderCloser := reader.(io.Closer); isReaderCloser {
+				closer = cl.Close
+			}
 		}
-		csvWriter := csv.NewWriter(writer)
-		records, err := csvReader.ReadAll()
-		if err != nil {
+		defer func() {
+			_ = closer()
+		}()
+
+		switch destination := data.(type) {
+		case *csv.Writer:
+			csvWriter := destination
+			o.applyToWriter(csvWriter)
+
+			return pipeCSV(csvWriter, csvReader, o)
+
+		case CSVWriter:
+			csvWriter := destination
+			// no writer options available
+
+			return pipeCSV(csvWriter, csvReader, o)
+
+		case io.Writer:
+			csvWriter := csv.NewWriter(destination)
+			o.applyToWriter(csvWriter)
+
+			return pipeCSV(csvWriter, csvReader, o)
+
+		case io.ReaderFrom:
+			var buf bytes.Buffer
+			csvWriter := csv.NewWriter(&buf)
+			o.applyToWriter(csvWriter)
+			if err := bufferedCSV(csvWriter, csvReader, o); err != nil {
+				return err
+			}
+			_, err := destination.ReadFrom(&buf)
+
 			return err
-		}
-		for _, r := range records {
-			if err := csvWriter.Write(r); err != nil {
+
+		case encoding.BinaryUnmarshaler:
+			var buf bytes.Buffer
+			csvWriter := csv.NewWriter(&buf)
+			o.applyToWriter(csvWriter)
+			if err := bufferedCSV(csvWriter, csvReader, o); err != nil {
 				return err
 			}
+
+			return destination.UnmarshalBinary(buf.Bytes())
+
+		default:
+			// support *[][]string, *[]byte, *string
+			if ptr := reflect.TypeOf(data); ptr.Kind() != reflect.Ptr {
+				return errors.New("destination must be a pointer")
+			}
+
+			v := reflect.Indirect(reflect.ValueOf(data))
+			t := v.Type()
+
+			switch {
+			case t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Slice && t.Elem().Elem().Kind() == reflect.String:
+				csvWriter := &csvRecordsWriter{}
+				// writer options are ignored
+				if err := pipeCSV(csvWriter, csvReader, o); err != nil {
+					return err
+				}
+
+				v.Grow(len(csvWriter.records))
+				v.SetCap(len(csvWriter.records)) // in case Grow was unnessary, trim down the capacity
+				v.SetLen(len(csvWriter.records))
+				reflect.Copy(v, reflect.ValueOf(csvWriter.records))
+
+				return nil
+
+			case t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8:
+				var buf bytes.Buffer
+				csvWriter := csv.NewWriter(&buf)
+				o.applyToWriter(csvWriter)
+				if err := bufferedCSV(csvWriter, csvReader, o); err != nil {
+					return err
+				}
+				v.SetBytes(buf.Bytes())
+
+				return nil
+
+			case t.Kind() == reflect.String:
+				var buf bytes.Buffer
+				csvWriter := csv.NewWriter(&buf)
+				o.applyToWriter(csvWriter)
+				if err := bufferedCSV(csvWriter, csvReader, o); err != nil {
+					return err
+				}
+				v.SetString(buf.String())
+
+				return nil
+
+			default:
+				return fmt.Errorf("%v (%T) is not supported by the CSVConsumer, %s",
+					data, data, "can be resolved by supporting CSVWriter/Writer/BinaryUnmarshaler interface",
+				)
+			}
 		}
-		csvWriter.Flush()
-		return nil
 	})
 }
 
-// CSVProducer creates a new CSV producer
-func CSVProducer() Producer {
+// CSVProducer creates a new CSV producer.
+//
+// The producer takes input data then writes as CSV to an output writer (essentially as a pipe).
+//
+// Supported input underlying types and interfaces, prioritized in this order:
+// - *csv.Reader
+// - CSVReader (reader options are ignored)
+// - io.Reader
+// - io.WriterTo
+// - encoding.BinaryMarshaler
+// - [][]string
+// - []byte
+// - string
+//
+// The producer prioritizes situations where buffering the input is not required.
+func CSVProducer(opts ...CSVOpt) Producer {
+	o := csvOptsWithDefaults(opts)
+
 	return ProducerFunc(func(writer io.Writer, data interface{}) error {
 		if writer == nil {
 			return errors.New("CSVProducer requires a writer")
 		}
+		if data == nil {
+			return errors.New("nil data for CSVProducer")
+		}
 
-		dataBytes, ok := data.([]byte)
-		if !ok {
-			return errors.New("data type must be byte array")
+		csvWriter := csv.NewWriter(writer)
+		o.applyToWriter(csvWriter)
+		closer := defaultCloser
+		if o.closeStream {
+			if cl, isWriterCloser := writer.(io.Closer); isWriterCloser {
+				closer = cl.Close
+			}
 		}
+		defer func() {
+			_ = closer()
+		}()
 
-		csvReader := csv.NewReader(bytes.NewBuffer(dataBytes))
-		records, err := csvReader.ReadAll()
-		if err != nil {
-			return err
+		if rc, isDataCloser := data.(io.ReadCloser); isDataCloser {
+			defer rc.Close()
 		}
-		csvWriter := csv.NewWriter(writer)
-		for _, r := range records {
-			if err := csvWriter.Write(r); err != nil {
+
+		switch origin := data.(type) {
+		case *csv.Reader:
+			csvReader := origin
+			o.applyToReader(csvReader)
+
+			return pipeCSV(csvWriter, csvReader, o)
+
+		case CSVReader:
+			csvReader := origin
+			// no reader options available
+
+			return pipeCSV(csvWriter, csvReader, o)
+
+		case io.Reader:
+			csvReader := csv.NewReader(origin)
+			o.applyToReader(csvReader)
+
+			return pipeCSV(csvWriter, csvReader, o)
+
+		case io.WriterTo:
+			// async piping of the writes performed by WriteTo
+			r, w := io.Pipe()
+			csvReader := csv.NewReader(r)
+			o.applyToReader(csvReader)
+
+			pipe, _ := errgroup.WithContext(context.Background())
+			pipe.Go(func() error {
+				_, err := origin.WriteTo(w)
+				_ = w.Close()
+				return err
+			})
+
+			pipe.Go(func() error {
+				defer func() {
+					_ = r.Close()
+				}()
+
+				return pipeCSV(csvWriter, csvReader, o)
+			})
+
+			return pipe.Wait()
+
+		case encoding.BinaryMarshaler:
+			buf, err := origin.MarshalBinary()
+			if err != nil {
 				return err
 			}
+			rdr := bytes.NewBuffer(buf)
+			csvReader := csv.NewReader(rdr)
+
+			return bufferedCSV(csvWriter, csvReader, o)
+
+		default:
+			// support [][]string, []byte, string (or pointers to those)
+			v := reflect.Indirect(reflect.ValueOf(data))
+			t := v.Type()
+
+			switch {
+			case t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Slice && t.Elem().Elem().Kind() == reflect.String:
+				csvReader := &csvRecordsWriter{
+					records: make([][]string, v.Len()),
+				}
+				reflect.Copy(reflect.ValueOf(csvReader.records), v)
+
+				return pipeCSV(csvWriter, csvReader, o)
+
+			case t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8:
+				buf := bytes.NewBuffer(v.Bytes())
+				csvReader := csv.NewReader(buf)
+				o.applyToReader(csvReader)
+
+				return bufferedCSV(csvWriter, csvReader, o)
+
+			case t.Kind() == reflect.String:
+				buf := bytes.NewBufferString(v.String())
+				csvReader := csv.NewReader(buf)
+				o.applyToReader(csvReader)
+
+				return bufferedCSV(csvWriter, csvReader, o)
+
+			default:
+				return fmt.Errorf("%v (%T) is not supported by the CSVProducer, %s",
+					data, data, "can be resolved by supporting CSVReader/Reader/BinaryMarshaler interface",
+				)
+			}
 		}
-		csvWriter.Flush()
-		return nil
 	})
 }
+
+// pipeCSV copies CSV records from a CSV reader to a CSV writer
+func pipeCSV(csvWriter CSVWriter, csvReader CSVReader, opts csvOpts) error {
+	for ; opts.skippedLines > 0; opts.skippedLines-- {
+		_, err := csvReader.Read()
+		if err != nil {
+			if errors.Is(err, io.EOF) {
+				return nil
+			}
+
+			return err
+		}
+	}
+
+	for {
+		record, err := csvReader.Read()
+		if err != nil {
+			if errors.Is(err, io.EOF) {
+				break
+			}
+
+			return err
+		}
+
+		if err := csvWriter.Write(record); err != nil {
+			return err
+		}
+	}
+
+	csvWriter.Flush()
+
+	return csvWriter.Error()
+}
+
+// bufferedCSV copies CSV records from a CSV reader to a CSV writer,
+// by first reading all records then writing them at once.
+func bufferedCSV(csvWriter *csv.Writer, csvReader *csv.Reader, opts csvOpts) error {
+	for ; opts.skippedLines > 0; opts.skippedLines-- {
+		_, err := csvReader.Read()
+		if err != nil {
+			if errors.Is(err, io.EOF) {
+				return nil
+			}
+
+			return err
+		}
+	}
+
+	records, err := csvReader.ReadAll()
+	if err != nil {
+		return err
+	}
+
+	return csvWriter.WriteAll(records)
+}
diff --git a/vendor/github.com/go-openapi/runtime/csv_options.go b/vendor/github.com/go-openapi/runtime/csv_options.go
new file mode 100644
index 00000000..c16464c5
--- /dev/null
+++ b/vendor/github.com/go-openapi/runtime/csv_options.go
@@ -0,0 +1,121 @@
+package runtime
+
+import (
+	"encoding/csv"
+	"io"
+)
+
+// CSVOpts alter the behavior of the CSV consumer or producer.
+type CSVOpt func(*csvOpts)
+
+type csvOpts struct {
+	csvReader    csv.Reader
+	csvWriter    csv.Writer
+	skippedLines int
+	closeStream  bool
+}
+
+// WithCSVReaderOpts specifies the options to csv.Reader
+// when reading CSV.
+func WithCSVReaderOpts(reader csv.Reader) CSVOpt {
+	return func(o *csvOpts) {
+		o.csvReader = reader
+	}
+}
+
+// WithCSVWriterOpts specifies the options to csv.Writer
+// when writing CSV.
+func WithCSVWriterOpts(writer csv.Writer) CSVOpt {
+	return func(o *csvOpts) {
+		o.csvWriter = writer
+	}
+}
+
+// WithCSVSkipLines will skip header lines.
+func WithCSVSkipLines(skipped int) CSVOpt {
+	return func(o *csvOpts) {
+		o.skippedLines = skipped
+	}
+}
+
+func WithCSVClosesStream() CSVOpt {
+	return func(o *csvOpts) {
+		o.closeStream = true
+	}
+}
+
+func (o csvOpts) applyToReader(in *csv.Reader) {
+	if o.csvReader.Comma != 0 {
+		in.Comma = o.csvReader.Comma
+	}
+	if o.csvReader.Comment != 0 {
+		in.Comment = o.csvReader.Comment
+	}
+	if o.csvReader.FieldsPerRecord != 0 {
+		in.FieldsPerRecord = o.csvReader.FieldsPerRecord
+	}
+
+	in.LazyQuotes = o.csvReader.LazyQuotes
+	in.TrimLeadingSpace = o.csvReader.TrimLeadingSpace
+	in.ReuseRecord = o.csvReader.ReuseRecord
+}
+
+func (o csvOpts) applyToWriter(in *csv.Writer) {
+	if o.csvWriter.Comma != 0 {
+		in.Comma = o.csvWriter.Comma
+	}
+	in.UseCRLF = o.csvWriter.UseCRLF
+}
+
+func csvOptsWithDefaults(opts []CSVOpt) csvOpts {
+	var o csvOpts
+	for _, apply := range opts {
+		apply(&o)
+	}
+
+	return o
+}
+
+type CSVWriter interface {
+	Write([]string) error
+	Flush()
+	Error() error
+}
+
+type CSVReader interface {
+	Read() ([]string, error)
+}
+
+var (
+	_ CSVWriter = &csvRecordsWriter{}
+	_ CSVReader = &csvRecordsWriter{}
+)
+
+// csvRecordsWriter is an internal container to move CSV records back and forth
+type csvRecordsWriter struct {
+	i       int
+	records [][]string
+}
+
+func (w *csvRecordsWriter) Write(record []string) error {
+	w.records = append(w.records, record)
+
+	return nil
+}
+
+func (w *csvRecordsWriter) Read() ([]string, error) {
+	if w.i >= len(w.records) {
+		return nil, io.EOF
+	}
+	defer func() {
+		w.i++
+	}()
+
+	return w.records[w.i], nil
+}
+
+func (w *csvRecordsWriter) Flush() {}
+
+func (w *csvRecordsWriter) Error() error {
+	return nil
+}
diff --git a/vendor/github.com/go-openapi/runtime/logger/standard.go b/vendor/github.com/go-openapi/runtime/logger/standard.go
index f7e67ebb..30035a77 100644
--- a/vendor/github.com/go-openapi/runtime/logger/standard.go
+++ b/vendor/github.com/go-openapi/runtime/logger/standard.go
@@ -5,6 +5,8 @@ import (
 	"os"
 )
 
+var _ Logger = StandardLogger{}
+
 type StandardLogger struct{}
 
 func (StandardLogger) Printf(format string, args ...interface{}) {
diff --git a/vendor/github.com/go-openapi/runtime/middleware/context.go b/vendor/github.com/go-openapi/runtime/middleware/context.go
index d21ae4e8..44cecf11 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/context.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/context.go
@@ -18,6 +18,8 @@ import (
 	stdContext "context"
 	"fmt"
 	"net/http"
+	"net/url"
+	"path"
 	"strings"
 	"sync"
 
@@ -35,12 +37,21 @@ import (
 
 // Debug when true turns on verbose logging
 var Debug = logger.DebugEnabled()
+
+// Logger is the standard libray logger used for printing debug messages
 var Logger logger.Logger = logger.StandardLogger{}
 
-func debugLog(format string, args ...interface{}) {
-	if Debug {
-		Logger.Printf(format, args...)
+func debugLogfFunc(lg logger.Logger) func(string, ...any) {
+	if logger.DebugEnabled() {
+		if lg == nil {
+			return Logger.Debugf
+		}
+
+		return lg.Debugf
 	}
+
+	// muted logger
+	return func(_ string, _ ...any) {}
 }
 
 // A Builder can create middlewares
@@ -73,10 +84,11 @@ func (fn ResponderFunc) WriteResponse(rw http.ResponseWriter, pr runtime.Produce
 // used throughout to store request context with the standard context attached
 // to the http.Request
 type Context struct {
-	spec     *loads.Document
-	analyzer *analysis.Spec
-	api      RoutableAPI
-	router   Router
+	spec      *loads.Document
+	analyzer  *analysis.Spec
+	api       RoutableAPI
+	router    Router
+	debugLogf func(string, ...any) // a logging function to debug context and all components using it
 }
 
 type routableUntypedAPI struct {
@@ -162,7 +174,7 @@ func (r *routableUntypedAPI) HandlerFor(method, path string) (http.Handler, bool
 	r.hlock.Unlock()
 	return handler, ok
 }
-func (r *routableUntypedAPI) ServeErrorFor(operationID string) func(http.ResponseWriter, *http.Request, error) {
+func (r *routableUntypedAPI) ServeErrorFor(_ string) func(http.ResponseWriter, *http.Request, error) {
 	return r.api.ServeError
 }
 func (r *routableUntypedAPI) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer {
@@ -189,7 +201,9 @@ func (r *routableUntypedAPI) DefaultConsumes() string {
 	return r.defaultConsumes
 }
 
-// NewRoutableContext creates a new context for a routable API
+// NewRoutableContext creates a new context for a routable API.
+//
+// If a nil Router is provided, the DefaultRouter (denco-based) will be used.
 func NewRoutableContext(spec *loads.Document, routableAPI RoutableAPI, routes Router) *Context {
 	var an *analysis.Spec
 	if spec != nil {
@@ -199,26 +213,40 @@ func NewRoutableContext(spec *loads.Document, routableAPI RoutableAPI, routes Ro
 	return NewRoutableContextWithAnalyzedSpec(spec, an, routableAPI, routes)
 }
 
-// NewRoutableContextWithAnalyzedSpec is like NewRoutableContext but takes in input the analysed spec too
+// NewRoutableContextWithAnalyzedSpec is like NewRoutableContext but takes as input an already analysed spec.
+//
+// If a nil Router is provided, the DefaultRouter (denco-based) will be used.
 func NewRoutableContextWithAnalyzedSpec(spec *loads.Document, an *analysis.Spec, routableAPI RoutableAPI, routes Router) *Context {
 	// Either there are no spec doc and analysis, or both of them.
 	if !((spec == nil && an == nil) || (spec != nil && an != nil)) {
 		panic(errors.New(http.StatusInternalServerError, "routable context requires either both spec doc and analysis, or none of them"))
 	}
 
-	ctx := &Context{spec: spec, api: routableAPI, analyzer: an, router: routes}
-	return ctx
+	return &Context{
+		spec:      spec,
+		api:       routableAPI,
+		analyzer:  an,
+		router:    routes,
+		debugLogf: debugLogfFunc(nil),
+	}
 }
 
-// NewContext creates a new context wrapper
+// NewContext creates a new context wrapper.
+//
+// If a nil Router is provided, the DefaultRouter (denco-based) will be used.
 func NewContext(spec *loads.Document, api *untyped.API, routes Router) *Context {
 	var an *analysis.Spec
 	if spec != nil {
 		an = analysis.New(spec.Spec())
 	}
-	ctx := &Context{spec: spec, analyzer: an}
+	ctx := &Context{
+		spec:      spec,
+		analyzer:  an,
+		router:    routes,
+		debugLogf: debugLogfFunc(nil),
+	}
 	ctx.api = newRoutableUntypedAPI(spec, api, ctx)
-	ctx.router = routes
+
 	return ctx
 }
 
@@ -282,6 +310,13 @@ func (c *Context) BasePath() string {
 	return c.spec.BasePath()
 }
 
+// SetLogger allows for injecting a logger to catch debug entries.
+//
+// The logger is enabled in DEBUG mode only.
+func (c *Context) SetLogger(lg logger.Logger) {
+	c.debugLogf = debugLogfFunc(lg)
+}
+
 // RequiredProduces returns the accepted content types for responses
 func (c *Context) RequiredProduces() []string {
 	return c.analyzer.RequiredProduces()
@@ -299,6 +334,7 @@ func (c *Context) BindValidRequest(request *http.Request, route *MatchedRoute, b
 		if err != nil {
 			res = append(res, err)
 		} else {
+			c.debugLogf("validating content type for %q against [%s]", ct, strings.Join(route.Consumes, ", "))
 			if err := validateContentType(route.Consumes, ct); err != nil {
 				res = append(res, err)
 			}
@@ -397,16 +433,16 @@ func (c *Context) ResponseFormat(r *http.Request, offers []string) (string, *htt
 	var rCtx = r.Context()
 
 	if v, ok := rCtx.Value(ctxResponseFormat).(string); ok {
-		debugLog("[%s %s] found response format %q in context", r.Method, r.URL.Path, v)
+		c.debugLogf("[%s %s] found response format %q in context", r.Method, r.URL.Path, v)
 		return v, r
 	}
 
 	format := NegotiateContentType(r, offers, "")
 	if format != "" {
-		debugLog("[%s %s] set response format %q in context", r.Method, r.URL.Path, format)
+		c.debugLogf("[%s %s] set response format %q in context", r.Method, r.URL.Path, format)
 		r = r.WithContext(stdContext.WithValue(rCtx, ctxResponseFormat, format))
 	}
-	debugLog("[%s %s] negotiated response format %q", r.Method, r.URL.Path, format)
+	c.debugLogf("[%s %s] negotiated response format %q", r.Method, r.URL.Path, format)
 	return format, r
 }
 
@@ -469,7 +505,7 @@ func (c *Context) BindAndValidate(request *http.Request, matched *MatchedRoute)
 	var rCtx = request.Context()
 
 	if v, ok := rCtx.Value(ctxBoundParams).(*validation); ok {
-		debugLog("got cached validation (valid: %t)", len(v.result) == 0)
+		c.debugLogf("got cached validation (valid: %t)", len(v.result) == 0)
 		if len(v.result) > 0 {
 			return v.bound, request, errors.CompositeValidationError(v.result...)
 		}
@@ -481,7 +517,7 @@ func (c *Context) BindAndValidate(request *http.Request, matched *MatchedRoute)
 	if len(result.result) > 0 {
 		return result.bound, request, errors.CompositeValidationError(result.result...)
 	}
-	debugLog("no validation errors found")
+	c.debugLogf("no validation errors found")
 	return result.bound, request, nil
 }
 
@@ -492,7 +528,7 @@ func (c *Context) NotFound(rw http.ResponseWriter, r *http.Request) {
 
 // Respond renders the response after doing some content negotiation
 func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []string, route *MatchedRoute, data interface{}) {
-	debugLog("responding to %s %s with produces: %v", r.Method, r.URL.Path, produces)
+	c.debugLogf("responding to %s %s with produces: %v", r.Method, r.URL.Path, produces)
 	offers := []string{}
 	for _, mt := range produces {
 		if mt != c.api.DefaultProduces() {
@@ -501,7 +537,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
 	}
 	// the default producer is last so more specific producers take precedence
 	offers = append(offers, c.api.DefaultProduces())
-	debugLog("offers: %v", offers)
+	c.debugLogf("offers: %v", offers)
 
 	var format string
 	format, r = c.ResponseFormat(r, offers)
@@ -516,7 +552,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
 			prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()}))
 			pr, ok := prods[c.api.DefaultProduces()]
 			if !ok {
-				panic(errors.New(http.StatusInternalServerError, "can't find a producer for "+format))
+				panic(errors.New(http.StatusInternalServerError, cantFindProducer(format)))
 			}
 			prod = pr
 		}
@@ -542,14 +578,14 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
 	}
 
 	if route == nil || route.Operation == nil {
-		rw.WriteHeader(200)
-		if r.Method == "HEAD" {
+		rw.WriteHeader(http.StatusOK)
+		if r.Method == http.MethodHead {
 			return
 		}
 		producers := c.api.ProducersFor(normalizeOffers(offers))
 		prod, ok := producers[format]
 		if !ok {
-			panic(errors.New(http.StatusInternalServerError, "can't find a producer for "+format))
+			panic(errors.New(http.StatusInternalServerError, cantFindProducer(format)))
 		}
 		if err := prod.Produce(rw, data); err != nil {
 			panic(err) // let the recovery middleware deal with this
@@ -559,7 +595,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
 
 	if _, code, ok := route.Operation.SuccessResponse(); ok {
 		rw.WriteHeader(code)
-		if code == 204 || r.Method == "HEAD" {
+		if code == http.StatusNoContent || r.Method == http.MethodHead {
 			return
 		}
 
@@ -570,7 +606,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
 				prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()}))
 				pr, ok := prods[c.api.DefaultProduces()]
 				if !ok {
-					panic(errors.New(http.StatusInternalServerError, "can't find a producer for "+format))
+					panic(errors.New(http.StatusInternalServerError, cantFindProducer(format)))
 				}
 				prod = pr
 			}
@@ -584,45 +620,92 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
 	c.api.ServeErrorFor(route.Operation.ID)(rw, r, errors.New(http.StatusInternalServerError, "can't produce response"))
 }
 
-func (c *Context) APIHandlerSwaggerUI(builder Builder) http.Handler {
+// APIHandlerSwaggerUI returns a handler to serve the API.
+//
+// This handler includes a swagger spec, router and the contract defined in the swagger spec.
+//
+// A spec UI (SwaggerUI) is served at {API base path}/docs and the spec document at /swagger.json
+// (these can be modified with uiOptions).
+func (c *Context) APIHandlerSwaggerUI(builder Builder, opts ...UIOption) http.Handler {
 	b := builder
 	if b == nil {
 		b = PassthroughBuilder
 	}
 
-	var title string
-	sp := c.spec.Spec()
-	if sp != nil && sp.Info != nil && sp.Info.Title != "" {
-		title = sp.Info.Title
-	}
+	specPath, uiOpts, specOpts := c.uiOptionsForHandler(opts)
+	var swaggerUIOpts SwaggerUIOpts
+	fromCommonToAnyOptions(uiOpts, &swaggerUIOpts)
+
+	return Spec(specPath, c.spec.Raw(), SwaggerUI(swaggerUIOpts, c.RoutesHandler(b)), specOpts...)
+}
 
-	swaggerUIOpts := SwaggerUIOpts{
-		BasePath: c.BasePath(),
-		Title:    title,
+// APIHandlerRapiDoc returns a handler to serve the API.
+//
+// This handler includes a swagger spec, router and the contract defined in the swagger spec.
+//
+// A spec UI (RapiDoc) is served at {API base path}/docs and the spec document at /swagger.json
+// (these can be modified with uiOptions).
+func (c *Context) APIHandlerRapiDoc(builder Builder, opts ...UIOption) http.Handler {
+	b := builder
+	if b == nil {
+		b = PassthroughBuilder
 	}
 
-	return Spec("", c.spec.Raw(), SwaggerUI(swaggerUIOpts, c.RoutesHandler(b)))
+	specPath, uiOpts, specOpts := c.uiOptionsForHandler(opts)
+	var rapidocUIOpts RapiDocOpts
+	fromCommonToAnyOptions(uiOpts, &rapidocUIOpts)
+
+	return Spec(specPath, c.spec.Raw(), RapiDoc(rapidocUIOpts, c.RoutesHandler(b)), specOpts...)
 }
 
-// APIHandler returns a handler to serve the API, this includes a swagger spec, router and the contract defined in the swagger spec
-func (c *Context) APIHandler(builder Builder) http.Handler {
+// APIHandler returns a handler to serve the API.
+//
+// This handler includes a swagger spec, router and the contract defined in the swagger spec.
+//
+// A spec UI (Redoc) is served at {API base path}/docs and the spec document at /swagger.json
+// (these can be modified with uiOptions).
+func (c *Context) APIHandler(builder Builder, opts ...UIOption) http.Handler {
 	b := builder
 	if b == nil {
 		b = PassthroughBuilder
 	}
 
+	specPath, uiOpts, specOpts := c.uiOptionsForHandler(opts)
+	var redocOpts RedocOpts
+	fromCommonToAnyOptions(uiOpts, &redocOpts)
+
+	return Spec(specPath, c.spec.Raw(), Redoc(redocOpts, c.RoutesHandler(b)), specOpts...)
+}
+
+func (c Context) uiOptionsForHandler(opts []UIOption) (string, uiOptions, []SpecOption) {
 	var title string
 	sp := c.spec.Spec()
 	if sp != nil && sp.Info != nil && sp.Info.Title != "" {
 		title = sp.Info.Title
 	}
 
-	redocOpts := RedocOpts{
-		BasePath: c.BasePath(),
-		Title:    title,
+	// default options (may be overridden)
+	optsForContext := []UIOption{
+		WithUIBasePath(c.BasePath()),
+		WithUITitle(title),
+	}
+	optsForContext = append(optsForContext, opts...)
+	uiOpts := uiOptionsWithDefaults(optsForContext)
+
+	// If spec URL is provided, there is a non-default path to serve the spec.
+	// This makes sure that the UI middleware is aligned with the Spec middleware.
+	u, _ := url.Parse(uiOpts.SpecURL)
+	var specPath string
+	if u != nil {
+		specPath = u.Path
+	}
+
+	pth, doc := path.Split(specPath)
+	if pth == "." {
+		pth = ""
 	}
 
-	return Spec("", c.spec.Raw(), Redoc(redocOpts, c.RoutesHandler(b)))
+	return pth, uiOpts, []SpecOption{WithSpecDocument(doc)}
 }
 
 // RoutesHandler returns a handler to serve the API, just the routes and the contract defined in the swagger spec
@@ -633,3 +716,7 @@ func (c *Context) RoutesHandler(builder Builder) http.Handler {
 	}
 	return NewRouter(c, b(NewOperationExecutor(c)))
 }
+
+func cantFindProducer(format string) string {
+	return "can't find a producer for " + format
+}
diff --git a/vendor/github.com/go-openapi/runtime/middleware/denco/router.go b/vendor/github.com/go-openapi/runtime/middleware/denco/router.go
index 5d2691ec..4377f77a 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/denco/router.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/denco/router.go
@@ -2,6 +2,7 @@
 package denco
 
 import (
+	"errors"
 	"fmt"
 	"sort"
 	"strings"
@@ -29,13 +30,13 @@ const (
 
 // Router represents a URL router.
 type Router struct {
+	param *doubleArray
 	// SizeHint expects the maximum number of path parameters in records to Build.
 	// SizeHint will be used to determine the capacity of the memory to allocate.
 	// By default, SizeHint will be determined from given records to Build.
 	SizeHint int
 
 	static map[string]interface{}
-	param  *doubleArray
 }
 
 // New returns a new Router.
@@ -51,7 +52,7 @@ func New() *Router {
 // params is a slice of the Param that arranged in the order in which parameters appeared.
 // e.g. when built routing path is "/path/to/:id/:name" and given path is "/path/to/1/alice". params order is [{"id": "1"}, {"name": "alice"}], not [{"name": "alice"}, {"id": "1"}].
 func (rt *Router) Lookup(path string) (data interface{}, params Params, found bool) {
-	if data, found := rt.static[path]; found {
+	if data, found = rt.static[path]; found {
 		return data, nil, true
 	}
 	if len(rt.param.node) == 1 {
@@ -71,7 +72,7 @@ func (rt *Router) Lookup(path string) (data interface{}, params Params, found bo
 func (rt *Router) Build(records []Record) error {
 	statics, params := makeRecords(records)
 	if len(params) > MaxSize {
-		return fmt.Errorf("denco: too many records")
+		return errors.New("denco: too many records")
 	}
 	if rt.SizeHint < 0 {
 		rt.SizeHint = 0
@@ -131,7 +132,8 @@ func newDoubleArray() *doubleArray {
 // baseCheck contains BASE, CHECK and Extra flags.
 // From the top, 22bits of BASE, 2bits of Extra flags and 8bits of CHECK.
 //
-//  BASE (22bit) | Extra flags (2bit) | CHECK (8bit)
+//	BASE (22bit) | Extra flags (2bit) | CHECK (8bit)
+//
 // |----------------------|--|--------|
 // 32                    10  8         0
 type baseCheck uint32
@@ -196,24 +198,29 @@ func (da *doubleArray) lookup(path string, params []Param, idx int) (*node, []Pa
 	if next := nextIndex(da.bc[idx].Base(), TerminationCharacter); next < len(da.bc) && da.bc[next].Check() == TerminationCharacter {
 		return da.node[da.bc[next].Base()], params, true
 	}
+
 BACKTRACKING:
 	for j := len(indices) - 1; j >= 0; j-- {
 		i, idx := int(indices[j]>>32), int(indices[j]&0xffffffff)
 		if da.bc[idx].IsSingleParam() {
-			idx := nextIndex(da.bc[idx].Base(), ParamCharacter)
-			if idx >= len(da.bc) {
+			nextIdx := nextIndex(da.bc[idx].Base(), ParamCharacter)
+			if nextIdx >= len(da.bc) {
 				break
 			}
+
 			next := NextSeparator(path, i)
-			params := append(params, Param{Value: path[i:next]})
-			if nd, params, found := da.lookup(path[next:], params, idx); found {
-				return nd, params, true
+			nextParams := params
+			nextParams = append(nextParams, Param{Value: path[i:next]})
+			if nd, nextNextParams, found := da.lookup(path[next:], nextParams, nextIdx); found {
+				return nd, nextNextParams, true
 			}
 		}
+
 		if da.bc[idx].IsWildcardParam() {
-			idx := nextIndex(da.bc[idx].Base(), WildcardCharacter)
-			params := append(params, Param{Value: path[i:]})
-			return da.node[da.bc[idx].Base()], params, true
+			nextIdx := nextIndex(da.bc[idx].Base(), WildcardCharacter)
+			nextParams := params
+			nextParams = append(nextParams, Param{Value: path[i:]})
+			return da.node[da.bc[nextIdx].Base()], nextParams, true
 		}
 	}
 	return nil, nil, false
@@ -325,7 +332,7 @@ func (da *doubleArray) arrange(records []*record, idx, depth int, usedBase map[i
 	}
 	base = da.findBase(siblings, idx, usedBase)
 	if base > MaxSize {
-		return -1, nil, nil, fmt.Errorf("denco: too many elements of internal slice")
+		return -1, nil, nil, errors.New("denco: too many elements of internal slice")
 	}
 	da.setBase(idx, base)
 	return base, siblings, leaf, err
@@ -386,7 +393,7 @@ func makeSiblings(records []*record, depth int) (sib []sibling, leaf *record, er
 		case pc == c:
 			continue
 		default:
-			return nil, nil, fmt.Errorf("denco: BUG: routing table hasn't been sorted")
+			return nil, nil, errors.New("denco: BUG: routing table hasn't been sorted")
 		}
 		if n > 0 {
 			sib[n-1].end = i
@@ -431,7 +438,7 @@ func makeRecords(srcs []Record) (statics, params []*record) {
 	wildcardPrefix := string(SeparatorCharacter) + string(WildcardCharacter)
 	restconfPrefix := string(PathParamCharacter) + string(ParamCharacter)
 	for _, r := range srcs {
-		if strings.Contains(r.Key, paramPrefix) || strings.Contains(r.Key, wildcardPrefix) ||strings.Contains(r.Key, restconfPrefix){
+		if strings.Contains(r.Key, paramPrefix) || strings.Contains(r.Key, wildcardPrefix) || strings.Contains(r.Key, restconfPrefix) {
 			r.Key += termChar
 			params = append(params, &record{Record: r})
 		} else {
diff --git a/vendor/github.com/go-openapi/runtime/middleware/doc.go b/vendor/github.com/go-openapi/runtime/middleware/doc.go
index eaf90606..836a9885 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/doc.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/doc.go
@@ -12,51 +12,52 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-/*Package middleware provides the library with helper functions for serving swagger APIs.
+/*
+Package middleware provides the library with helper functions for serving swagger APIs.
 
 Pseudo middleware handler
 
-  import (
-  	"net/http"
-
-  	"github.com/go-openapi/errors"
-  )
-
-  func newCompleteMiddleware(ctx *Context) http.Handler {
-  	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
-  		// use context to lookup routes
-  		if matched, ok := ctx.RouteInfo(r); ok {
-
-  			if matched.NeedsAuth() {
-  				if _, err := ctx.Authorize(r, matched); err != nil {
-  					ctx.Respond(rw, r, matched.Produces, matched, err)
-  					return
-  				}
-  			}
-
-  			bound, validation := ctx.BindAndValidate(r, matched)
-  			if validation != nil {
-  				ctx.Respond(rw, r, matched.Produces, matched, validation)
-  				return
-  			}
-
-  			result, err := matched.Handler.Handle(bound)
-  			if err != nil {
-  				ctx.Respond(rw, r, matched.Produces, matched, err)
-  				return
-  			}
-
-  			ctx.Respond(rw, r, matched.Produces, matched, result)
-  			return
-  		}
-
-  		// Not found, check if it exists in the other methods first
-  		if others := ctx.AllowedMethods(r); len(others) > 0 {
-  			ctx.Respond(rw, r, ctx.spec.RequiredProduces(), nil, errors.MethodNotAllowed(r.Method, others))
-  			return
-  		}
-  		ctx.Respond(rw, r, ctx.spec.RequiredProduces(), nil, errors.NotFound("path %s was not found", r.URL.Path))
-  	})
-  }
+	import (
+		"net/http"
+
+		"github.com/go-openapi/errors"
+	)
+
+	func newCompleteMiddleware(ctx *Context) http.Handler {
+		return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+			// use context to lookup routes
+			if matched, ok := ctx.RouteInfo(r); ok {
+
+				if matched.NeedsAuth() {
+					if _, err := ctx.Authorize(r, matched); err != nil {
+						ctx.Respond(rw, r, matched.Produces, matched, err)
+						return
+					}
+				}
+
+				bound, validation := ctx.BindAndValidate(r, matched)
+				if validation != nil {
+					ctx.Respond(rw, r, matched.Produces, matched, validation)
+					return
+				}
+
+				result, err := matched.Handler.Handle(bound)
+				if err != nil {
+					ctx.Respond(rw, r, matched.Produces, matched, err)
+					return
+				}
+
+				ctx.Respond(rw, r, matched.Produces, matched, result)
+				return
+			}
+
+			// Not found, check if it exists in the other methods first
+			if others := ctx.AllowedMethods(r); len(others) > 0 {
+				ctx.Respond(rw, r, ctx.spec.RequiredProduces(), nil, errors.MethodNotAllowed(r.Method, others))
+				return
+			}
+			ctx.Respond(rw, r, ctx.spec.RequiredProduces(), nil, errors.NotFound("path %s was not found", r.URL.Path))
+		})
+	}
 */
 package middleware
diff --git a/vendor/github.com/go-openapi/runtime/middleware/go18.go b/vendor/github.com/go-openapi/runtime/middleware/go18.go
deleted file mode 100644
index 75c762c0..00000000
--- a/vendor/github.com/go-openapi/runtime/middleware/go18.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build go1.8
-
-package middleware
-
-import "net/url"
-
-func pathUnescape(path string) (string, error) {
-	return url.PathUnescape(path)
-}
diff --git a/vendor/github.com/go-openapi/runtime/middleware/header/header.go b/vendor/github.com/go-openapi/runtime/middleware/header/header.go
index e069743e..df073c87 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/header/header.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/header/header.go
@@ -195,7 +195,8 @@ func ParseAccept2(header http.Header, key string) (specs []AcceptSpec) {
 }
 
 // ParseAccept parses Accept* headers.
-func ParseAccept(header http.Header, key string) (specs []AcceptSpec) {
+func ParseAccept(header http.Header, key string) []AcceptSpec {
+	var specs []AcceptSpec
 loop:
 	for _, s := range header[key] {
 		for {
@@ -218,6 +219,7 @@ loop:
 					}
 				}
 			}
+
 			specs = append(specs, spec)
 			s = skipSpace(s)
 			if !strings.HasPrefix(s, ",") {
@@ -226,7 +228,8 @@ loop:
 			s = skipSpace(s[1:])
 		}
 	}
-	return
+
+	return specs
 }
 
 func skipSpace(s string) (rest string) {
@@ -306,7 +309,7 @@ func expectTokenOrQuoted(s string) (value string, rest string) {
 			p := make([]byte, len(s)-1)
 			j := copy(p, s[:i])
 			escape := true
-			for i = i + 1; i < len(s); i++ {
+			for i++; i < len(s); i++ {
 				b := s[i]
 				switch {
 				case escape:
diff --git a/vendor/github.com/go-openapi/runtime/middleware/parameter.go b/vendor/github.com/go-openapi/runtime/middleware/parameter.go
index 9aaf6595..9c3353a9 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/parameter.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/parameter.go
@@ -34,6 +34,11 @@ import (
 
 const defaultMaxMemory = 32 << 20
 
+const (
+	typeString = "string"
+	typeArray  = "array"
+)
+
 var textUnmarshalType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem()
 
 func newUntypedParamBinder(param spec.Parameter, spec *spec.Swagger, formats strfmt.Registry) *untypedParamBinder {
@@ -66,7 +71,7 @@ func (p *untypedParamBinder) typeForSchema(tpe, format string, items *spec.Items
 	case "boolean":
 		return reflect.TypeOf(true)
 
-	case "string":
+	case typeString:
 		if tt, ok := p.formats.GetType(format); ok {
 			return tt
 		}
@@ -94,7 +99,7 @@ func (p *untypedParamBinder) typeForSchema(tpe, format string, items *spec.Items
 			return reflect.TypeOf(float64(0))
 		}
 
-	case "array":
+	case typeArray:
 		if items == nil {
 			return nil
 		}
@@ -119,7 +124,7 @@ func (p *untypedParamBinder) allowsMulti() bool {
 
 func (p *untypedParamBinder) readValue(values runtime.Gettable, target reflect.Value) ([]string, bool, bool, error) {
 	name, in, cf, tpe := p.parameter.Name, p.parameter.In, p.parameter.CollectionFormat, p.parameter.Type
-	if tpe == "array" {
+	if tpe == typeArray {
 		if cf == "multi" {
 			if !p.allowsMulti() {
 				return nil, false, false, errors.InvalidCollectionFormat(name, in, cf)
@@ -208,10 +213,11 @@ func (p *untypedParamBinder) Bind(request *http.Request, routeParams RouteParams
 			if ffErr != nil {
 				if p.parameter.Required {
 					return errors.NewParseError(p.Name, p.parameter.In, "", ffErr)
-				} else {
-					return nil
 				}
+
+				return nil
 			}
+
 			target.Set(reflect.ValueOf(runtime.File{Data: file, Header: header}))
 			return nil
 		}
@@ -263,7 +269,7 @@ func (p *untypedParamBinder) Bind(request *http.Request, routeParams RouteParams
 }
 
 func (p *untypedParamBinder) bindValue(data []string, hasKey bool, target reflect.Value) error {
-	if p.parameter.Type == "array" {
+	if p.parameter.Type == typeArray {
 		return p.setSliceFieldValue(target, p.parameter.Default, data, hasKey)
 	}
 	var d string
@@ -273,7 +279,7 @@ func (p *untypedParamBinder) bindValue(data []string, hasKey bool, target reflec
 	return p.setFieldValue(target, p.parameter.Default, d, hasKey)
 }
 
-func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue interface{}, data string, hasKey bool) error {
+func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue interface{}, data string, hasKey bool) error { //nolint:gocyclo
 	tpe := p.parameter.Type
 	if p.parameter.Format != "" {
 		tpe = p.parameter.Format
@@ -317,7 +323,7 @@ func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue in
 		return nil
 	}
 
-	switch target.Kind() {
+	switch target.Kind() { //nolint:exhaustive // we want to check only types that map from a swagger parameter
 	case reflect.Bool:
 		if data == "" {
 			if target.CanSet() {
diff --git a/vendor/github.com/go-openapi/runtime/middleware/pre_go18.go b/vendor/github.com/go-openapi/runtime/middleware/pre_go18.go
deleted file mode 100644
index 03385251..00000000
--- a/vendor/github.com/go-openapi/runtime/middleware/pre_go18.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build !go1.8
-
-package middleware
-
-import "net/url"
-
-func pathUnescape(path string) (string, error) {
-	return url.QueryUnescape(path)
-}
diff --git a/vendor/github.com/go-openapi/runtime/middleware/rapidoc.go b/vendor/github.com/go-openapi/runtime/middleware/rapidoc.go
index 4be330d6..ef75e744 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/rapidoc.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/rapidoc.go
@@ -10,67 +10,57 @@ import (
 
 // RapiDocOpts configures the RapiDoc middlewares
 type RapiDocOpts struct {
-	// BasePath for the UI path, defaults to: /
+	// BasePath for the UI, defaults to: /
 	BasePath string
-	// Path combines with BasePath for the full UI path, defaults to: docs
+
+	// Path combines with BasePath to construct the path to the UI, defaults to: "docs".
 	Path string
-	// SpecURL the url to find the spec for
+
+	// SpecURL is the URL of the spec document.
+	//
+	// Defaults to: /swagger.json
 	SpecURL string
-	// RapiDocURL for the js that generates the rapidoc site, defaults to: https://cdn.jsdelivr.net/npm/rapidoc/bundles/rapidoc.standalone.js
-	RapiDocURL string
+
 	// Title for the documentation site, default to: API documentation
 	Title string
+
+	// Template specifies a custom template to serve the UI
+	Template string
+
+	// RapiDocURL points to the js asset that generates the rapidoc site.
+	//
+	// Defaults to https://unpkg.com/rapidoc/dist/rapidoc-min.js
+	RapiDocURL string
 }
 
-// EnsureDefaults in case some options are missing
 func (r *RapiDocOpts) EnsureDefaults() {
-	if r.BasePath == "" {
-		r.BasePath = "/"
-	}
-	if r.Path == "" {
-		r.Path = "docs"
-	}
-	if r.SpecURL == "" {
-		r.SpecURL = "/swagger.json"
-	}
+	common := toCommonUIOptions(r)
+	common.EnsureDefaults()
+	fromCommonToAnyOptions(common, r)
+
+	// rapidoc-specifics
 	if r.RapiDocURL == "" {
 		r.RapiDocURL = rapidocLatest
 	}
-	if r.Title == "" {
-		r.Title = "API documentation"
+	if r.Template == "" {
+		r.Template = rapidocTemplate
 	}
 }
 
 // RapiDoc creates a middleware to serve a documentation site for a swagger spec.
-// This allows for altering the spec before starting the http listener.
 //
+// This allows for altering the spec before starting the http listener.
 func RapiDoc(opts RapiDocOpts, next http.Handler) http.Handler {
 	opts.EnsureDefaults()
 
 	pth := path.Join(opts.BasePath, opts.Path)
-	tmpl := template.Must(template.New("rapidoc").Parse(rapidocTemplate))
-
-	buf := bytes.NewBuffer(nil)
-	_ = tmpl.Execute(buf, opts)
-	b := buf.Bytes()
-
-	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
-		if r.URL.Path == pth {
-			rw.Header().Set("Content-Type", "text/html; charset=utf-8")
-			rw.WriteHeader(http.StatusOK)
-
-			_, _ = rw.Write(b)
-			return
-		}
+	tmpl := template.Must(template.New("rapidoc").Parse(opts.Template))
+	assets := bytes.NewBuffer(nil)
+	if err := tmpl.Execute(assets, opts); err != nil {
+		panic(fmt.Errorf("cannot execute template: %w", err))
+	}
 
-		if next == nil {
-			rw.Header().Set("Content-Type", "text/plain")
-			rw.WriteHeader(http.StatusNotFound)
-			_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
-			return
-		}
-		next.ServeHTTP(rw, r)
-	})
+	return serveUI(pth, assets.Bytes(), next)
 }
 
 const (
@@ -79,7 +69,7 @@ const (
 <html>
 <head>
   <title>{{ .Title }}</title>
-  <meta charset="utf-8"> <!-- Important: rapi-doc uses utf8 charecters -->
+  <meta charset="utf-8"> <!-- Important: rapi-doc uses utf8 characters -->
   <script type="module" src="{{ .RapiDocURL }}"></script>
 </head>
 <body>
diff --git a/vendor/github.com/go-openapi/runtime/middleware/redoc.go b/vendor/github.com/go-openapi/runtime/middleware/redoc.go
index 019c8542..b96b01e7 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/redoc.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/redoc.go
@@ -10,67 +10,58 @@ import (
 
 // RedocOpts configures the Redoc middlewares
 type RedocOpts struct {
-	// BasePath for the UI path, defaults to: /
+	// BasePath for the UI, defaults to: /
 	BasePath string
-	// Path combines with BasePath for the full UI path, defaults to: docs
+
+	// Path combines with BasePath to construct the path to the UI, defaults to: "docs".
 	Path string
-	// SpecURL the url to find the spec for
+
+	// SpecURL is the URL of the spec document.
+	//
+	// Defaults to: /swagger.json
 	SpecURL string
-	// RedocURL for the js that generates the redoc site, defaults to: https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js
-	RedocURL string
+
 	// Title for the documentation site, default to: API documentation
 	Title string
+
+	// Template specifies a custom template to serve the UI
+	Template string
+
+	// RedocURL points to the js that generates the redoc site.
+	//
+	// Defaults to: https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js
+	RedocURL string
 }
 
 // EnsureDefaults in case some options are missing
 func (r *RedocOpts) EnsureDefaults() {
-	if r.BasePath == "" {
-		r.BasePath = "/"
-	}
-	if r.Path == "" {
-		r.Path = "docs"
-	}
-	if r.SpecURL == "" {
-		r.SpecURL = "/swagger.json"
-	}
+	common := toCommonUIOptions(r)
+	common.EnsureDefaults()
+	fromCommonToAnyOptions(common, r)
+
+	// redoc-specifics
 	if r.RedocURL == "" {
 		r.RedocURL = redocLatest
 	}
-	if r.Title == "" {
-		r.Title = "API documentation"
+	if r.Template == "" {
+		r.Template = redocTemplate
 	}
 }
 
 // Redoc creates a middleware to serve a documentation site for a swagger spec.
-// This allows for altering the spec before starting the http listener.
 //
+// This allows for altering the spec before starting the http listener.
 func Redoc(opts RedocOpts, next http.Handler) http.Handler {
 	opts.EnsureDefaults()
 
 	pth := path.Join(opts.BasePath, opts.Path)
-	tmpl := template.Must(template.New("redoc").Parse(redocTemplate))
-
-	buf := bytes.NewBuffer(nil)
-	_ = tmpl.Execute(buf, opts)
-	b := buf.Bytes()
-
-	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
-		if r.URL.Path == pth {
-			rw.Header().Set("Content-Type", "text/html; charset=utf-8")
-			rw.WriteHeader(http.StatusOK)
-
-			_, _ = rw.Write(b)
-			return
-		}
+	tmpl := template.Must(template.New("redoc").Parse(opts.Template))
+	assets := bytes.NewBuffer(nil)
+	if err := tmpl.Execute(assets, opts); err != nil {
+		panic(fmt.Errorf("cannot execute template: %w", err))
+	}
 
-		if next == nil {
-			rw.Header().Set("Content-Type", "text/plain")
-			rw.WriteHeader(http.StatusNotFound)
-			_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
-			return
-		}
-		next.ServeHTTP(rw, r)
-	})
+	return serveUI(pth, assets.Bytes(), next)
 }
 
 const (
diff --git a/vendor/github.com/go-openapi/runtime/middleware/request.go b/vendor/github.com/go-openapi/runtime/middleware/request.go
index 760c3786..82e14366 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/request.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/request.go
@@ -19,10 +19,10 @@ import (
 	"reflect"
 
 	"github.com/go-openapi/errors"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/runtime/logger"
 	"github.com/go-openapi/spec"
 	"github.com/go-openapi/strfmt"
-
-	"github.com/go-openapi/runtime"
 )
 
 // UntypedRequestBinder binds and validates the data from a http request
@@ -31,6 +31,7 @@ type UntypedRequestBinder struct {
 	Parameters   map[string]spec.Parameter
 	Formats      strfmt.Registry
 	paramBinders map[string]*untypedParamBinder
+	debugLogf    func(string, ...any) // a logging function to debug context and all components using it
 }
 
 // NewUntypedRequestBinder creates a new binder for reading a request.
@@ -44,6 +45,7 @@ func NewUntypedRequestBinder(parameters map[string]spec.Parameter, spec *spec.Sw
 		paramBinders: binders,
 		Spec:         spec,
 		Formats:      formats,
+		debugLogf:    debugLogfFunc(nil),
 	}
 }
 
@@ -52,10 +54,10 @@ func (o *UntypedRequestBinder) Bind(request *http.Request, routeParams RoutePara
 	val := reflect.Indirect(reflect.ValueOf(data))
 	isMap := val.Kind() == reflect.Map
 	var result []error
-	debugLog("binding %d parameters for %s %s", len(o.Parameters), request.Method, request.URL.EscapedPath())
+	o.debugLogf("binding %d parameters for %s %s", len(o.Parameters), request.Method, request.URL.EscapedPath())
 	for fieldName, param := range o.Parameters {
 		binder := o.paramBinders[fieldName]
-		debugLog("binding parameter %s for %s %s", fieldName, request.Method, request.URL.EscapedPath())
+		o.debugLogf("binding parameter %s for %s %s", fieldName, request.Method, request.URL.EscapedPath())
 		var target reflect.Value
 		if !isMap {
 			binder.Name = fieldName
@@ -65,7 +67,7 @@ func (o *UntypedRequestBinder) Bind(request *http.Request, routeParams RoutePara
 		if isMap {
 			tpe := binder.Type()
 			if tpe == nil {
-				if param.Schema.Type.Contains("array") {
+				if param.Schema.Type.Contains(typeArray) {
 					tpe = reflect.TypeOf([]interface{}{})
 				} else {
 					tpe = reflect.TypeOf(map[string]interface{}{})
@@ -102,3 +104,14 @@ func (o *UntypedRequestBinder) Bind(request *http.Request, routeParams RoutePara
 
 	return nil
 }
+
+// SetLogger allows for injecting a logger to catch debug entries.
+//
+// The logger is enabled in DEBUG mode only.
+func (o *UntypedRequestBinder) SetLogger(lg logger.Logger) {
+	o.debugLogf = debugLogfFunc(lg)
+}
+
+func (o *UntypedRequestBinder) setDebugLogf(fn func(string, ...any)) {
+	o.debugLogf = fn
+}
diff --git a/vendor/github.com/go-openapi/runtime/middleware/router.go b/vendor/github.com/go-openapi/runtime/middleware/router.go
index 5052031c..3a6aee90 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/router.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/router.go
@@ -17,10 +17,12 @@ package middleware
 import (
 	"fmt"
 	"net/http"
+	"net/url"
 	fpath "path"
 	"regexp"
 	"strings"
 
+	"github.com/go-openapi/runtime/logger"
 	"github.com/go-openapi/runtime/security"
 	"github.com/go-openapi/swag"
 
@@ -67,10 +69,10 @@ func (r RouteParams) GetOK(name string) ([]string, bool, bool) {
 	return nil, false, false
 }
 
-// NewRouter creates a new context aware router middleware
+// NewRouter creates a new context-aware router middleware
 func NewRouter(ctx *Context, next http.Handler) http.Handler {
 	if ctx.router == nil {
-		ctx.router = DefaultRouter(ctx.spec, ctx.api)
+		ctx.router = DefaultRouter(ctx.spec, ctx.api, WithDefaultRouterLoggerFunc(ctx.debugLogf))
 	}
 
 	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
@@ -103,41 +105,75 @@ type RoutableAPI interface {
 	DefaultConsumes() string
 }
 
-// Router represents a swagger aware router
+// Router represents a swagger-aware router
 type Router interface {
 	Lookup(method, path string) (*MatchedRoute, bool)
 	OtherMethods(method, path string) []string
 }
 
 type defaultRouteBuilder struct {
-	spec     *loads.Document
-	analyzer *analysis.Spec
-	api      RoutableAPI
-	records  map[string][]denco.Record
+	spec      *loads.Document
+	analyzer  *analysis.Spec
+	api       RoutableAPI
+	records   map[string][]denco.Record
+	debugLogf func(string, ...any) // a logging function to debug context and all components using it
 }
 
 type defaultRouter struct {
-	spec    *loads.Document
-	routers map[string]*denco.Router
+	spec      *loads.Document
+	routers   map[string]*denco.Router
+	debugLogf func(string, ...any) // a logging function to debug context and all components using it
 }
 
-func newDefaultRouteBuilder(spec *loads.Document, api RoutableAPI) *defaultRouteBuilder {
+func newDefaultRouteBuilder(spec *loads.Document, api RoutableAPI, opts ...DefaultRouterOpt) *defaultRouteBuilder {
+	var o defaultRouterOpts
+	for _, apply := range opts {
+		apply(&o)
+	}
+	if o.debugLogf == nil {
+		o.debugLogf = debugLogfFunc(nil) // defaults to standard logger
+	}
+
 	return &defaultRouteBuilder{
-		spec:     spec,
-		analyzer: analysis.New(spec.Spec()),
-		api:      api,
-		records:  make(map[string][]denco.Record),
+		spec:      spec,
+		analyzer:  analysis.New(spec.Spec()),
+		api:       api,
+		records:   make(map[string][]denco.Record),
+		debugLogf: o.debugLogf,
 	}
 }
 
-// DefaultRouter creates a default implemenation of the router
-func DefaultRouter(spec *loads.Document, api RoutableAPI) Router {
-	builder := newDefaultRouteBuilder(spec, api)
+// DefaultRouterOpt allows to inject optional behavior to the default router.
+type DefaultRouterOpt func(*defaultRouterOpts)
+
+type defaultRouterOpts struct {
+	debugLogf func(string, ...any)
+}
+
+// WithDefaultRouterLogger sets the debug logger for the default router.
+//
+// This is enabled only in DEBUG mode.
+func WithDefaultRouterLogger(lg logger.Logger) DefaultRouterOpt {
+	return func(o *defaultRouterOpts) {
+		o.debugLogf = debugLogfFunc(lg)
+	}
+}
+
+// WithDefaultRouterLoggerFunc sets a logging debug method for the default router.
+func WithDefaultRouterLoggerFunc(fn func(string, ...any)) DefaultRouterOpt {
+	return func(o *defaultRouterOpts) {
+		o.debugLogf = fn
+	}
+}
+
+// DefaultRouter creates a default implementation of the router
+func DefaultRouter(spec *loads.Document, api RoutableAPI, opts ...DefaultRouterOpt) Router {
+	builder := newDefaultRouteBuilder(spec, api, opts...)
 	if spec != nil {
 		for method, paths := range builder.analyzer.Operations() {
 			for path, operation := range paths {
 				fp := fpath.Join(spec.BasePath(), path)
-				debugLog("adding route %s %s %q", method, fp, operation.ID)
+				builder.debugLogf("adding route %s %s %q", method, fp, operation.ID)
 				builder.AddRoute(method, fp, operation)
 			}
 		}
@@ -319,24 +355,24 @@ func (m *MatchedRoute) NeedsAuth() bool {
 
 func (d *defaultRouter) Lookup(method, path string) (*MatchedRoute, bool) {
 	mth := strings.ToUpper(method)
-	debugLog("looking up route for %s %s", method, path)
+	d.debugLogf("looking up route for %s %s", method, path)
 	if Debug {
 		if len(d.routers) == 0 {
-			debugLog("there are no known routers")
+			d.debugLogf("there are no known routers")
 		}
 		for meth := range d.routers {
-			debugLog("got a router for %s", meth)
+			d.debugLogf("got a router for %s", meth)
 		}
 	}
 	if router, ok := d.routers[mth]; ok {
 		if m, rp, ok := router.Lookup(fpath.Clean(path)); ok && m != nil {
 			if entry, ok := m.(*routeEntry); ok {
-				debugLog("found a route for %s %s with %d parameters", method, path, len(entry.Parameters))
+				d.debugLogf("found a route for %s %s with %d parameters", method, path, len(entry.Parameters))
 				var params RouteParams
 				for _, p := range rp {
-					v, err := pathUnescape(p.Value)
+					v, err := url.PathUnescape(p.Value)
 					if err != nil {
-						debugLog("failed to escape %q: %v", p.Value, err)
+						d.debugLogf("failed to escape %q: %v", p.Value, err)
 						v = p.Value
 					}
 					// a workaround to handle fragment/composing parameters until they are supported in denco router
@@ -356,10 +392,10 @@ func (d *defaultRouter) Lookup(method, path string) (*MatchedRoute, bool) {
 				return &MatchedRoute{routeEntry: *entry, Params: params}, true
 			}
 		} else {
-			debugLog("couldn't find a route by path for %s %s", method, path)
+			d.debugLogf("couldn't find a route by path for %s %s", method, path)
 		}
 	} else {
-		debugLog("couldn't find a route by method for %s %s", method, path)
+		d.debugLogf("couldn't find a route by method for %s %s", method, path)
 	}
 	return nil, false
 }
@@ -378,6 +414,10 @@ func (d *defaultRouter) OtherMethods(method, path string) []string {
 	return methods
 }
 
+func (d *defaultRouter) SetLogger(lg logger.Logger) {
+	d.debugLogf = debugLogfFunc(lg)
+}
+
 // convert swagger parameters per path segment into a denco parameter as multiple parameters per segment are not supported in denco
 var pathConverter = regexp.MustCompile(`{(.+?)}([^/]*)`)
 
@@ -413,7 +453,7 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper
 		bp = bp[:len(bp)-1]
 	}
 
-	debugLog("operation: %#v", *operation)
+	d.debugLogf("operation: %#v", *operation)
 	if handler, ok := d.api.HandlerFor(method, strings.TrimPrefix(path, bp)); ok {
 		consumes := d.analyzer.ConsumesFor(operation)
 		produces := d.analyzer.ProducesFor(operation)
@@ -428,6 +468,8 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper
 			produces = append(produces, defProduces)
 		}
 
+		requestBinder := NewUntypedRequestBinder(parameters, d.spec.Spec(), d.api.Formats())
+		requestBinder.setDebugLogf(d.debugLogf)
 		record := denco.NewRecord(pathConverter.ReplaceAllString(path, ":$1"), &routeEntry{
 			BasePath:       bp,
 			PathPattern:    path,
@@ -439,7 +481,7 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper
 			Producers:      d.api.ProducersFor(normalizeOffers(produces)),
 			Parameters:     parameters,
 			Formats:        d.api.Formats(),
-			Binder:         NewUntypedRequestBinder(parameters, d.spec.Spec(), d.api.Formats()),
+			Binder:         requestBinder,
 			Authenticators: d.buildAuthenticators(operation),
 			Authorizer:     d.api.Authorizer(),
 		})
@@ -449,11 +491,11 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper
 
 func (d *defaultRouteBuilder) buildAuthenticators(operation *spec.Operation) RouteAuthenticators {
 	requirements := d.analyzer.SecurityRequirementsFor(operation)
-	var auths []RouteAuthenticator
+	auths := make([]RouteAuthenticator, 0, len(requirements))
 	for _, reqs := range requirements {
-		var schemes []string
+		schemes := make([]string, 0, len(reqs))
 		scopes := make(map[string][]string, len(reqs))
-		var scopeSlices [][]string
+		scopeSlices := make([][]string, 0, len(reqs))
 		for _, req := range reqs {
 			schemes = append(schemes, req.Name)
 			scopes[req.Name] = req.Scopes
@@ -482,7 +524,8 @@ func (d *defaultRouteBuilder) Build() *defaultRouter {
 		routers[method] = router
 	}
 	return &defaultRouter{
-		spec:    d.spec,
-		routers: routers,
+		spec:      d.spec,
+		routers:   routers,
+		debugLogf: d.debugLogf,
 	}
 }
diff --git a/vendor/github.com/go-openapi/runtime/middleware/spec.go b/vendor/github.com/go-openapi/runtime/middleware/spec.go
index f0291429..87e17e34 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/spec.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/spec.go
@@ -19,30 +19,84 @@ import (
 	"path"
 )
 
-// Spec creates a middleware to serve a swagger spec.
+const (
+	contentTypeHeader = "Content-Type"
+	applicationJSON   = "application/json"
+)
+
+// SpecOption can be applied to the Spec serving middleware
+type SpecOption func(*specOptions)
+
+var defaultSpecOptions = specOptions{
+	Path:     "",
+	Document: "swagger.json",
+}
+
+type specOptions struct {
+	Path     string
+	Document string
+}
+
+func specOptionsWithDefaults(opts []SpecOption) specOptions {
+	o := defaultSpecOptions
+	for _, apply := range opts {
+		apply(&o)
+	}
+
+	return o
+}
+
+// Spec creates a middleware to serve a swagger spec as a JSON document.
+//
 // This allows for altering the spec before starting the http listener.
-// This can be useful if you want to serve the swagger spec from another path than /swagger.json
 //
-func Spec(basePath string, b []byte, next http.Handler) http.Handler {
+// The basePath argument indicates the path of the spec document (defaults to "/").
+// Additional SpecOption can be used to change the name of the document (defaults to "swagger.json").
+func Spec(basePath string, b []byte, next http.Handler, opts ...SpecOption) http.Handler {
 	if basePath == "" {
 		basePath = "/"
 	}
-	pth := path.Join(basePath, "swagger.json")
+	o := specOptionsWithDefaults(opts)
+	pth := path.Join(basePath, o.Path, o.Document)
 
 	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
-		if r.URL.Path == pth {
-			rw.Header().Set("Content-Type", "application/json")
+		if path.Clean(r.URL.Path) == pth {
+			rw.Header().Set(contentTypeHeader, applicationJSON)
 			rw.WriteHeader(http.StatusOK)
-			//#nosec
 			_, _ = rw.Write(b)
+
 			return
 		}
 
-		if next == nil {
-			rw.Header().Set("Content-Type", "application/json")
-			rw.WriteHeader(http.StatusNotFound)
+		if next != nil {
+			next.ServeHTTP(rw, r)
+
 			return
 		}
-		next.ServeHTTP(rw, r)
+
+		rw.Header().Set(contentTypeHeader, applicationJSON)
+		rw.WriteHeader(http.StatusNotFound)
 	})
 }
+
+// WithSpecPath sets the path to be joined to the base path of the Spec middleware.
+//
+// This is empty by default.
+func WithSpecPath(pth string) SpecOption {
+	return func(o *specOptions) {
+		o.Path = pth
+	}
+}
+
+// WithSpecDocument sets the name of the JSON document served as a spec.
+//
+// By default, this is "swagger.json"
+func WithSpecDocument(doc string) SpecOption {
+	return func(o *specOptions) {
+		if doc == "" {
+			return
+		}
+
+		o.Document = doc
+	}
+}
diff --git a/vendor/github.com/go-openapi/runtime/middleware/swaggerui.go b/vendor/github.com/go-openapi/runtime/middleware/swaggerui.go
index b4dea29e..ec3c10cb 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/swaggerui.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/swaggerui.go
@@ -8,40 +8,65 @@ import (
 	"path"
 )
 
-// SwaggerUIOpts configures the Swaggerui middlewares
+// SwaggerUIOpts configures the SwaggerUI middleware
 type SwaggerUIOpts struct {
-	// BasePath for the UI path, defaults to: /
+	// BasePath for the API, defaults to: /
 	BasePath string
-	// Path combines with BasePath for the full UI path, defaults to: docs
+
+	// Path combines with BasePath to construct the path to the UI, defaults to: "docs".
 	Path string
-	// SpecURL the url to find the spec for
+
+	// SpecURL is the URL of the spec document.
+	//
+	// Defaults to: /swagger.json
 	SpecURL string
+
+	// Title for the documentation site, default to: API documentation
+	Title string
+
+	// Template specifies a custom template to serve the UI
+	Template string
+
 	// OAuthCallbackURL the url called after OAuth2 login
 	OAuthCallbackURL string
 
 	// The three components needed to embed swagger-ui
-	SwaggerURL       string
+
+	// SwaggerURL points to the js that generates the SwaggerUI site.
+	//
+	// Defaults to: https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js
+	SwaggerURL string
+
 	SwaggerPresetURL string
 	SwaggerStylesURL string
 
 	Favicon32 string
 	Favicon16 string
-
-	// Title for the documentation site, default to: API documentation
-	Title string
 }
 
 // EnsureDefaults in case some options are missing
 func (r *SwaggerUIOpts) EnsureDefaults() {
-	if r.BasePath == "" {
-		r.BasePath = "/"
-	}
-	if r.Path == "" {
-		r.Path = "docs"
+	r.ensureDefaults()
+
+	if r.Template == "" {
+		r.Template = swaggeruiTemplate
 	}
-	if r.SpecURL == "" {
-		r.SpecURL = "/swagger.json"
+}
+
+func (r *SwaggerUIOpts) EnsureDefaultsOauth2() {
+	r.ensureDefaults()
+
+	if r.Template == "" {
+		r.Template = swaggerOAuthTemplate
 	}
+}
+
+func (r *SwaggerUIOpts) ensureDefaults() {
+	common := toCommonUIOptions(r)
+	common.EnsureDefaults()
+	fromCommonToAnyOptions(common, r)
+
+	// swaggerui-specifics
 	if r.OAuthCallbackURL == "" {
 		r.OAuthCallbackURL = path.Join(r.BasePath, r.Path, "oauth2-callback")
 	}
@@ -60,40 +85,22 @@ func (r *SwaggerUIOpts) EnsureDefaults() {
 	if r.Favicon32 == "" {
 		r.Favicon32 = swaggerFavicon32Latest
 	}
-	if r.Title == "" {
-		r.Title = "API documentation"
-	}
 }
 
 // SwaggerUI creates a middleware to serve a documentation site for a swagger spec.
+//
 // This allows for altering the spec before starting the http listener.
 func SwaggerUI(opts SwaggerUIOpts, next http.Handler) http.Handler {
 	opts.EnsureDefaults()
 
 	pth := path.Join(opts.BasePath, opts.Path)
-	tmpl := template.Must(template.New("swaggerui").Parse(swaggeruiTemplate))
-
-	buf := bytes.NewBuffer(nil)
-	_ = tmpl.Execute(buf, &opts)
-	b := buf.Bytes()
-
-	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
-		if path.Join(r.URL.Path) == pth {
-			rw.Header().Set("Content-Type", "text/html; charset=utf-8")
-			rw.WriteHeader(http.StatusOK)
-
-			_, _ = rw.Write(b)
-			return
-		}
-
-		if next == nil {
-			rw.Header().Set("Content-Type", "text/plain")
-			rw.WriteHeader(http.StatusNotFound)
-			_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
-			return
-		}
-		next.ServeHTTP(rw, r)
-	})
+	tmpl := template.Must(template.New("swaggerui").Parse(opts.Template))
+	assets := bytes.NewBuffer(nil)
+	if err := tmpl.Execute(assets, opts); err != nil {
+		panic(fmt.Errorf("cannot execute template: %w", err))
+	}
+
+	return serveUI(pth, assets.Bytes(), next)
 }
 
 const (
diff --git a/vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go b/vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go
index 576f6003..e81212f7 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/swaggerui_oauth2.go
@@ -4,37 +4,20 @@ import (
 	"bytes"
 	"fmt"
 	"net/http"
-	"path"
 	"text/template"
 )
 
 func SwaggerUIOAuth2Callback(opts SwaggerUIOpts, next http.Handler) http.Handler {
-	opts.EnsureDefaults()
+	opts.EnsureDefaultsOauth2()
 
 	pth := opts.OAuthCallbackURL
-	tmpl := template.Must(template.New("swaggeroauth").Parse(swaggerOAuthTemplate))
+	tmpl := template.Must(template.New("swaggeroauth").Parse(opts.Template))
+	assets := bytes.NewBuffer(nil)
+	if err := tmpl.Execute(assets, opts); err != nil {
+		panic(fmt.Errorf("cannot execute template: %w", err))
+	}
 
-	buf := bytes.NewBuffer(nil)
-	_ = tmpl.Execute(buf, &opts)
-	b := buf.Bytes()
-
-	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
-		if path.Join(r.URL.Path) == pth {
-			rw.Header().Set("Content-Type", "text/html; charset=utf-8")
-			rw.WriteHeader(http.StatusOK)
-
-			_, _ = rw.Write(b)
-			return
-		}
-
-		if next == nil {
-			rw.Header().Set("Content-Type", "text/plain")
-			rw.WriteHeader(http.StatusNotFound)
-			_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
-			return
-		}
-		next.ServeHTTP(rw, r)
-	})
+	return serveUI(pth, assets.Bytes(), next)
 }
 
 const (
diff --git a/vendor/github.com/go-openapi/runtime/middleware/ui_options.go b/vendor/github.com/go-openapi/runtime/middleware/ui_options.go
new file mode 100644
index 00000000..b86efa00
--- /dev/null
+++ b/vendor/github.com/go-openapi/runtime/middleware/ui_options.go
@@ -0,0 +1,173 @@
+package middleware
+
+import (
+	"bytes"
+	"encoding/gob"
+	"fmt"
+	"net/http"
+	"path"
+	"strings"
+)
+
+const (
+	// constants that are common to all UI-serving middlewares
+	defaultDocsPath  = "docs"
+	defaultDocsURL   = "/swagger.json"
+	defaultDocsTitle = "API Documentation"
+)
+
+// uiOptions defines common options for UI serving middlewares.
+type uiOptions struct {
+	// BasePath for the UI, defaults to: /
+	BasePath string
+
+	// Path combines with BasePath to construct the path to the UI, defaults to: "docs".
+	Path string
+
+	// SpecURL is the URL of the spec document.
+	//
+	// Defaults to: /swagger.json
+	SpecURL string
+
+	// Title for the documentation site, default to: API documentation
+	Title string
+
+	// Template specifies a custom template to serve the UI
+	Template string
+}
+
+// toCommonUIOptions converts any UI option type to retain the common options.
+//
+// This uses gob encoding/decoding to convert common fields from one struct to another.
+func toCommonUIOptions(opts interface{}) uiOptions {
+	var buf bytes.Buffer
+	enc := gob.NewEncoder(&buf)
+	dec := gob.NewDecoder(&buf)
+	var o uiOptions
+	err := enc.Encode(opts)
+	if err != nil {
+		panic(err)
+	}
+
+	err = dec.Decode(&o)
+	if err != nil {
+		panic(err)
+	}
+
+	return o
+}
+
+func fromCommonToAnyOptions[T any](source uiOptions, target *T) {
+	var buf bytes.Buffer
+	enc := gob.NewEncoder(&buf)
+	dec := gob.NewDecoder(&buf)
+	err := enc.Encode(source)
+	if err != nil {
+		panic(err)
+	}
+
+	err = dec.Decode(target)
+	if err != nil {
+		panic(err)
+	}
+}
+
+// UIOption can be applied to UI serving middleware, such as Context.APIHandler or
+// Context.APIHandlerSwaggerUI to alter the defaut behavior.
+type UIOption func(*uiOptions)
+
+func uiOptionsWithDefaults(opts []UIOption) uiOptions {
+	var o uiOptions
+	for _, apply := range opts {
+		apply(&o)
+	}
+
+	return o
+}
+
+// WithUIBasePath sets the base path from where to serve the UI assets.
+//
+// By default, Context middleware sets this value to the API base path.
+func WithUIBasePath(base string) UIOption {
+	return func(o *uiOptions) {
+		if !strings.HasPrefix(base, "/") {
+			base = "/" + base
+		}
+		o.BasePath = base
+	}
+}
+
+// WithUIPath sets the path from where to serve the UI assets (i.e. /{basepath}/{path}.
+func WithUIPath(pth string) UIOption {
+	return func(o *uiOptions) {
+		o.Path = pth
+	}
+}
+
+// WithUISpecURL sets the path from where to serve swagger spec document.
+//
+// This may be specified as a full URL or a path.
+//
+// By default, this is "/swagger.json"
+func WithUISpecURL(specURL string) UIOption {
+	return func(o *uiOptions) {
+		o.SpecURL = specURL
+	}
+}
+
+// WithUITitle sets the title of the UI.
+//
+// By default, Context middleware sets this value to the title found in the API spec.
+func WithUITitle(title string) UIOption {
+	return func(o *uiOptions) {
+		o.Title = title
+	}
+}
+
+// WithTemplate allows to set a custom template for the UI.
+//
+// UI middleware will panic if the template does not parse or execute properly.
+func WithTemplate(tpl string) UIOption {
+	return func(o *uiOptions) {
+		o.Template = tpl
+	}
+}
+
+// EnsureDefaults in case some options are missing
+func (r *uiOptions) EnsureDefaults() {
+	if r.BasePath == "" {
+		r.BasePath = "/"
+	}
+	if r.Path == "" {
+		r.Path = defaultDocsPath
+	}
+	if r.SpecURL == "" {
+		r.SpecURL = defaultDocsURL
+	}
+	if r.Title == "" {
+		r.Title = defaultDocsTitle
+	}
+}
+
+// serveUI creates a middleware that serves a templated asset as text/html.
+func serveUI(pth string, assets []byte, next http.Handler) http.Handler {
+	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		if path.Clean(r.URL.Path) == pth {
+			rw.Header().Set(contentTypeHeader, "text/html; charset=utf-8")
+			rw.WriteHeader(http.StatusOK)
+			_, _ = rw.Write(assets)
+
+			return
+		}
+
+		if next != nil {
+			next.ServeHTTP(rw, r)
+
+			return
+		}
+
+		rw.Header().Set(contentTypeHeader, "text/plain")
+		rw.WriteHeader(http.StatusNotFound)
+		_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
+	})
+}
diff --git a/vendor/github.com/go-openapi/runtime/middleware/untyped/api.go b/vendor/github.com/go-openapi/runtime/middleware/untyped/api.go
index 39a85f7d..7b7269bd 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/untyped/api.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/untyped/api.go
@@ -197,30 +197,31 @@ func (d *API) Validate() error {
 
 // validateWith validates the registrations in this API against the provided spec analyzer
 func (d *API) validate() error {
-	var consumes []string
+	consumes := make([]string, 0, len(d.consumers))
 	for k := range d.consumers {
 		consumes = append(consumes, k)
 	}
 
-	var produces []string
+	produces := make([]string, 0, len(d.producers))
 	for k := range d.producers {
 		produces = append(produces, k)
 	}
 
-	var authenticators []string
+	authenticators := make([]string, 0, len(d.authenticators))
 	for k := range d.authenticators {
 		authenticators = append(authenticators, k)
 	}
 
-	var operations []string
+	operations := make([]string, 0, len(d.operations))
 	for m, v := range d.operations {
 		for p := range v {
 			operations = append(operations, fmt.Sprintf("%s %s", strings.ToUpper(m), p))
 		}
 	}
 
-	var definedAuths []string
-	for k := range d.spec.Spec().SecurityDefinitions {
+	secDefinitions := d.spec.Spec().SecurityDefinitions
+	definedAuths := make([]string, 0, len(secDefinitions))
+	for k := range secDefinitions {
 		definedAuths = append(definedAuths, k)
 	}
 
@@ -267,7 +268,7 @@ func (d *API) verify(name string, registrations []string, expectations []string)
 		delete(expected, k)
 	}
 
-	var unregistered []string
+	unregistered := make([]string, 0, len(expected))
 	for k := range expected {
 		unregistered = append(unregistered, k)
 	}
diff --git a/vendor/github.com/go-openapi/runtime/middleware/validation.go b/vendor/github.com/go-openapi/runtime/middleware/validation.go
index 1f0135b5..0a5356c6 100644
--- a/vendor/github.com/go-openapi/runtime/middleware/validation.go
+++ b/vendor/github.com/go-openapi/runtime/middleware/validation.go
@@ -35,7 +35,6 @@ type validation struct {
 
 // ContentType validates the content type of a request
 func validateContentType(allowed []string, actual string) error {
-	debugLog("validating content type for %q against [%s]", actual, strings.Join(allowed, ", "))
 	if len(allowed) == 0 {
 		return nil
 	}
@@ -57,13 +56,13 @@ func validateContentType(allowed []string, actual string) error {
 }
 
 func validateRequest(ctx *Context, request *http.Request, route *MatchedRoute) *validation {
-	debugLog("validating request %s %s", request.Method, request.URL.EscapedPath())
 	validate := &validation{
 		context: ctx,
 		request: request,
 		route:   route,
 		bound:   make(map[string]interface{}),
 	}
+	validate.debugLogf("validating request %s %s", request.Method, request.URL.EscapedPath())
 
 	validate.contentType()
 	if len(validate.result) == 0 {
@@ -76,8 +75,12 @@ func validateRequest(ctx *Context, request *http.Request, route *MatchedRoute) *
 	return validate
 }
 
+func (v *validation) debugLogf(format string, args ...any) {
+	v.context.debugLogf(format, args...)
+}
+
 func (v *validation) parameters() {
-	debugLog("validating request parameters for %s %s", v.request.Method, v.request.URL.EscapedPath())
+	v.debugLogf("validating request parameters for %s %s", v.request.Method, v.request.URL.EscapedPath())
 	if result := v.route.Binder.Bind(v.request, v.route.Params, v.route.Consumer, v.bound); result != nil {
 		if result.Error() == "validation failure list" {
 			for _, e := range result.(*errors.Validation).Value.([]interface{}) {
@@ -91,7 +94,7 @@ func (v *validation) parameters() {
 
 func (v *validation) contentType() {
 	if len(v.result) == 0 && runtime.HasBody(v.request) {
-		debugLog("validating body content type for %s %s", v.request.Method, v.request.URL.EscapedPath())
+		v.debugLogf("validating body content type for %s %s", v.request.Method, v.request.URL.EscapedPath())
 		ct, _, req, err := v.context.ContentType(v.request)
 		if err != nil {
 			v.result = append(v.result, err)
@@ -100,6 +103,7 @@ func (v *validation) contentType() {
 		}
 
 		if len(v.result) == 0 {
+			v.debugLogf("validating content type for %q against [%s]", ct, strings.Join(v.route.Consumes, ", "))
 			if err := validateContentType(v.route.Consumes, ct); err != nil {
 				v.result = append(v.result, err)
 			}
diff --git a/vendor/github.com/go-openapi/runtime/request.go b/vendor/github.com/go-openapi/runtime/request.go
index 078fda17..9e3e1ecb 100644
--- a/vendor/github.com/go-openapi/runtime/request.go
+++ b/vendor/github.com/go-openapi/runtime/request.go
@@ -16,6 +16,8 @@ package runtime
 
 import (
 	"bufio"
+	"context"
+	"errors"
 	"io"
 	"net/http"
 	"strings"
@@ -96,10 +98,16 @@ func (p *peekingReader) Read(d []byte) (int, error) {
 	if p == nil {
 		return 0, io.EOF
 	}
+	if p.underlying == nil {
+		return 0, io.ErrUnexpectedEOF
+	}
 	return p.underlying.Read(d)
 }
 
 func (p *peekingReader) Close() error {
+	if p.underlying == nil {
+		return errors.New("reader already closed")
+	}
 	p.underlying = nil
 	if p.orig != nil {
 		return p.orig.Close()
@@ -107,9 +115,11 @@ func (p *peekingReader) Close() error {
 	return nil
 }
 
-// JSONRequest creates a new http request with json headers set
+// JSONRequest creates a new http request with json headers set.
+//
+// It uses context.Background.
 func JSONRequest(method, urlStr string, body io.Reader) (*http.Request, error) {
-	req, err := http.NewRequest(method, urlStr, body)
+	req, err := http.NewRequestWithContext(context.Background(), method, urlStr, body)
 	if err != nil {
 		return nil, err
 	}
diff --git a/vendor/github.com/go-openapi/runtime/security/authenticator.go b/vendor/github.com/go-openapi/runtime/security/authenticator.go
index c3ffdac7..bb30472b 100644
--- a/vendor/github.com/go-openapi/runtime/security/authenticator.go
+++ b/vendor/github.com/go-openapi/runtime/security/authenticator.go
@@ -25,12 +25,13 @@ import (
 )
 
 const (
-	query  = "query"
-	header = "header"
+	query            = "query"
+	header           = "header"
+	accessTokenParam = "access_token"
 )
 
 // HttpAuthenticator is a function that authenticates a HTTP request
-func HttpAuthenticator(handler func(*http.Request) (bool, interface{}, error)) runtime.Authenticator {
+func HttpAuthenticator(handler func(*http.Request) (bool, interface{}, error)) runtime.Authenticator { //nolint:revive,stylecheck
 	return runtime.AuthenticatorFunc(func(params interface{}) (bool, interface{}, error) {
 		if request, ok := params.(*http.Request); ok {
 			return handler(request)
@@ -158,7 +159,7 @@ func APIKeyAuth(name, in string, authenticate TokenAuthentication) runtime.Authe
 	inl := strings.ToLower(in)
 	if inl != query && inl != header {
 		// panic because this is most likely a typo
-		panic(errors.New(500, "api key auth: in value needs to be either \"query\" or \"header\"."))
+		panic(errors.New(500, "api key auth: in value needs to be either \"query\" or \"header\""))
 	}
 
 	var getToken func(*http.Request) string
@@ -186,7 +187,7 @@ func APIKeyAuthCtx(name, in string, authenticate TokenAuthenticationCtx) runtime
 	inl := strings.ToLower(in)
 	if inl != query && inl != header {
 		// panic because this is most likely a typo
-		panic(errors.New(500, "api key auth: in value needs to be either \"query\" or \"header\"."))
+		panic(errors.New(500, "api key auth: in value needs to be either \"query\" or \"header\""))
 	}
 
 	var getToken func(*http.Request) string
@@ -226,12 +227,12 @@ func BearerAuth(name string, authenticate ScopedTokenAuthentication) runtime.Aut
 		}
 		if token == "" {
 			qs := r.Request.URL.Query()
-			token = qs.Get("access_token")
+			token = qs.Get(accessTokenParam)
 		}
 		//#nosec
 		ct, _, _ := runtime.ContentType(r.Request.Header)
 		if token == "" && (ct == "application/x-www-form-urlencoded" || ct == "multipart/form-data") {
-			token = r.Request.FormValue("access_token")
+			token = r.Request.FormValue(accessTokenParam)
 		}
 
 		if token == "" {
@@ -256,12 +257,12 @@ func BearerAuthCtx(name string, authenticate ScopedTokenAuthenticationCtx) runti
 		}
 		if token == "" {
 			qs := r.Request.URL.Query()
-			token = qs.Get("access_token")
+			token = qs.Get(accessTokenParam)
 		}
 		//#nosec
 		ct, _, _ := runtime.ContentType(r.Request.Header)
 		if token == "" && (ct == "application/x-www-form-urlencoded" || ct == "multipart/form-data") {
-			token = r.Request.FormValue("access_token")
+			token = r.Request.FormValue(accessTokenParam)
 		}
 
 		if token == "" {
diff --git a/vendor/github.com/go-openapi/runtime/yamlpc/yaml.go b/vendor/github.com/go-openapi/runtime/yamlpc/yaml.go
index b30d3771..a1a0a589 100644
--- a/vendor/github.com/go-openapi/runtime/yamlpc/yaml.go
+++ b/vendor/github.com/go-openapi/runtime/yamlpc/yaml.go
@@ -18,8 +18,7 @@ import (
 	"io"
 
 	"github.com/go-openapi/runtime"
-
-	"gopkg.in/yaml.v2"
+	"gopkg.in/yaml.v3"
 )
 
 // YAMLConsumer creates a consumer for yaml data
diff --git a/vendor/github.com/go-openapi/spec/.gitignore b/vendor/github.com/go-openapi/spec/.gitignore
index dd91ed6a..f47cb204 100644
--- a/vendor/github.com/go-openapi/spec/.gitignore
+++ b/vendor/github.com/go-openapi/spec/.gitignore
@@ -1,2 +1 @@
-secrets.yml
-coverage.out
+*.out
diff --git a/vendor/github.com/go-openapi/spec/.golangci.yml b/vendor/github.com/go-openapi/spec/.golangci.yml
index 835d55e7..22f8d21c 100644
--- a/vendor/github.com/go-openapi/spec/.golangci.yml
+++ b/vendor/github.com/go-openapi/spec/.golangci.yml
@@ -11,7 +11,7 @@ linters-settings:
     threshold: 200
   goconst:
     min-len: 2
-    min-occurrences: 2
+    min-occurrences: 3
 
 linters:
   enable-all: true
@@ -40,3 +40,22 @@ linters:
     - tparallel
     - thelper
     - ifshort
+    - exhaustruct
+    - varnamelen
+    - gci
+    - depguard
+    - errchkjson
+    - inamedparam
+    - nonamedreturns
+    - musttag
+    - ireturn
+    - forcetypeassert
+    - cyclop
+    # deprecated linters
+    - deadcode
+    - interfacer
+    - scopelint
+    - varcheck
+    - structcheck
+    - golint
+    - nosnakecase
diff --git a/vendor/github.com/go-openapi/spec/README.md b/vendor/github.com/go-openapi/spec/README.md
index 18782c6d..7fd2810c 100644
--- a/vendor/github.com/go-openapi/spec/README.md
+++ b/vendor/github.com/go-openapi/spec/README.md
@@ -1,8 +1,5 @@
-# OAI object model
+# OpenAPI v2 object model [![Build Status](https://github.com/go-openapi/spec/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/spec/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/spec/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/spec)
 
-[![Build Status](https://travis-ci.org/go-openapi/spec.svg?branch=master)](https://travis-ci.org/go-openapi/spec)
-<!-- [![Build status](https://ci.appveyor.com/api/projects/status/x377t5o9ennm847o/branch/master?svg=true)](https://ci.appveyor.com/project/casualjim/go-openapi/spec/branch/master) -->
-[![codecov](https://codecov.io/gh/go-openapi/spec/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/spec)
 [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
 [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/spec/master/LICENSE)
 [![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/spec.svg)](https://pkg.go.dev/github.com/go-openapi/spec)
@@ -32,3 +29,26 @@ The object model for OpenAPI specification documents.
 > This [discussion thread](https://github.com/go-openapi/spec/issues/21) relates the full story.
 >
 > An early attempt to support Swagger 3 may be found at: https://github.com/go-openapi/spec3
+
+* Does the unmarshaling support YAML?
+
+> Not directly. The exposed types know only how to unmarshal from JSON.
+>
+> In order to load a YAML document as a Swagger spec, you need to use the loaders provided by
+> github.com/go-openapi/loads
+>
+> Take a look at the example there: https://pkg.go.dev/github.com/go-openapi/loads#example-Spec
+>
+> See also https://github.com/go-openapi/spec/issues/164
+
+* How can I validate a spec?
+
+> Validation is provided by [the validate package](http://github.com/go-openapi/validate)
+
+* Why do we have an `ID` field for `Schema` which is not part of the swagger spec?
+
+> We found jsonschema compatibility more important: since `id` in jsonschema influences
+> how `$ref` are resolved.
+> This `id` does not conflict with any property named `id`.
+>
+> See also https://github.com/go-openapi/spec/issues/23
diff --git a/vendor/github.com/go-openapi/spec/appveyor.yml b/vendor/github.com/go-openapi/spec/appveyor.yml
deleted file mode 100644
index 09035939..00000000
--- a/vendor/github.com/go-openapi/spec/appveyor.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-version: "0.1.{build}"
-
-clone_folder: C:\go-openapi\spec
-shallow_clone: true # for startup speed
-pull_requests:
-  do_not_increment_build_number: true
-
-#skip_tags: true
-#skip_branch_with_pr: true
-
-# appveyor.yml
-build: off
-
-environment:
-  GOPATH: c:\gopath
-
-stack: go 1.15
-
-test_script:
-  - go test -v -timeout 20m ./...
-
-deploy: off
-
-notifications:
-  - provider: Slack
-    incoming_webhook: https://hooks.slack.com/services/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
-    auth_token:
-      secure: Sf7kZf7ZGbnwWUMpffHwMu5A0cHkLK2MYY32LNTPj4+/3qC3Ghl7+9v4TSLOqOlCwdRNjOGblAq7s+GDJed6/xgRQl1JtCi1klzZNrYX4q01pgTPvvGcwbBkIYgeMaPeIRcK9OZnud7sRXdttozgTOpytps2U6Js32ip7uj5mHSg2ub0FwoSJwlS6dbezZ8+eDhoha0F/guY99BEwx8Bd+zROrT2TFGsSGOFGN6wFc7moCqTHO/YkWib13a2QNXqOxCCVBy/lt76Wp+JkeFppjHlzs/2lP3EAk13RIUAaesdEUHvIHrzCyNJEd3/+KO2DzsWOYfpktd+KBCvgaYOsoo7ubdT3IROeAegZdCgo/6xgCEsmFc9ZcqCfN5yNx2A+BZ2Vwmpws+bQ1E1+B5HDzzaiLcYfG4X2O210QVGVDLWsv1jqD+uPYeHY2WRfh5ZsIUFvaqgUEnwHwrK44/8REAhQavt1QAj5uJpsRd7CkRVPWRNK+yIky+wgbVUFEchRNmS55E7QWf+W4+4QZkQi7vUTMc9nbTUu2Es9NfvfudOpM2wZbn98fjpb/qq/nRv6Bk+ca+7XD5/IgNLMbWp2ouDdzbiHLCOfDUiHiDJhLfFZx9Bwo7ZwfzeOlbrQX66bx7xRKYmOe4DLrXhNcpbsMa8qbfxlZRCmYbubB/Y8h4=
-    channel: bots
-    on_build_success: false
-    on_build_failure: true
-    on_build_status_changed: true
diff --git a/vendor/github.com/go-openapi/spec/bindata.go b/vendor/github.com/go-openapi/spec/bindata.go
deleted file mode 100644
index afc83850..00000000
--- a/vendor/github.com/go-openapi/spec/bindata.go
+++ /dev/null
@@ -1,297 +0,0 @@
-// Code generated by go-bindata. DO NOT EDIT.
-// sources:
-// schemas/jsonschema-draft-04.json (4.357kB)
-// schemas/v2/schema.json (40.248kB)
-
-package spec
-
-import (
-	"bytes"
-	"compress/gzip"
-	"crypto/sha256"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strings"
-	"time"
-)
-
-func bindataRead(data []byte, name string) ([]byte, error) {
-	gz, err := gzip.NewReader(bytes.NewBuffer(data))
-	if err != nil {
-		return nil, fmt.Errorf("read %q: %v", name, err)
-	}
-
-	var buf bytes.Buffer
-	_, err = io.Copy(&buf, gz)
-	clErr := gz.Close()
-
-	if err != nil {
-		return nil, fmt.Errorf("read %q: %v", name, err)
-	}
-	if clErr != nil {
-		return nil, err
-	}
-
-	return buf.Bytes(), nil
-}
-
-type asset struct {
-	bytes  []byte
-	info   os.FileInfo
-	digest [sha256.Size]byte
-}
-
-type bindataFileInfo struct {
-	name    string
-	size    int64
-	mode    os.FileMode
-	modTime time.Time
-}
-
-func (fi bindataFileInfo) Name() string {
-	return fi.name
-}
-func (fi bindataFileInfo) Size() int64 {
-	return fi.size
-}
-func (fi bindataFileInfo) Mode() os.FileMode {
-	return fi.mode
-}
-func (fi bindataFileInfo) ModTime() time.Time {
-	return fi.modTime
-}
-func (fi bindataFileInfo) IsDir() bool {
-	return false
-}
-func (fi bindataFileInfo) Sys() interface{} {
-	return nil
-}
-
-var _jsonschemaDraft04Json = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x57\x3d\x6f\xdb\x3c\x10\xde\xf3\x2b\x08\x26\x63\xf2\x2a\x2f\xd0\xc9\x5b\xd1\x2e\x01\x5a\x34\x43\x37\x23\x03\x6d\x9d\x6c\x06\x14\xa9\x50\x54\x60\xc3\xd0\x7f\x2f\x28\x4a\x14\x29\x91\x92\x2d\xa7\x8d\x97\x28\xbc\xaf\xe7\x8e\xf7\xc5\xd3\x0d\x42\x08\x61\x9a\xe2\x15\xc2\x7b\xa5\x8a\x55\x92\xbc\x96\x82\x3f\x94\xdb\x3d\xe4\xe4\x3f\x21\x77\x49\x2a\x49\xa6\x1e\x1e\xbf\x24\xe6\xec\x16\xdf\x1b\xa1\x3b\xf3\xff\x02\xc9\x14\xca\xad\xa4\x85\xa2\x82\x6b\xe9\x6f\x42\x02\x32\x2c\x28\x07\x45\x5a\x15\x3d\x77\x46\x39\xd5\xcc\x25\x5e\x21\x83\xb8\x21\x18\xb6\xaf\x52\x92\xa3\x47\x68\x88\xea\x58\x80\x56\x4e\x1a\xf2\xbd\x4f\xcc\x29\x7f\x52\x90\x6b\x7d\xff\x0f\x48\xb4\x3d\x3f\x21\x7c\x27\x21\xd3\x2a\x6e\x31\xaa\x2d\x53\xdd\xf3\xe3\x42\x94\x54\xd1\x77\x78\xe2\x0a\x76\x20\xe3\x20\x68\xcb\x30\x86\x41\xf3\x2a\xc7\x2b\xf4\x78\x8e\xfe\xef\x90\x91\x8a\xa9\xc7\xb1\x1d\xc2\xd8\x2f\x0d\x75\xed\xc1\x4e\x9c\xc8\x25\x43\xac\xa8\xbe\xd7\xcc\xa9\xd1\xa9\x21\xa0\x1a\xbd\x04\x61\x94\x34\x2f\x18\xfc\x3e\x16\x50\x8e\x4d\x03\x6f\x1c\x58\xdb\x48\x23\xbc\x11\x82\x01\xe1\xfa\xd3\x3a\x8e\x30\xaf\x18\x33\x7f\xf3\x8d\x39\x11\x9b\x57\xd8\x2a\xfd\x55\x2a\x49\xf9\x0e\xc7\xec\x37\xd4\x25\xf7\xec\x5c\x66\xc7\xd7\x99\xaa\xcf\x4f\x89\x8a\xd3\xb7\x0a\x3a\xaa\x92\x15\xf4\x30\x6f\x1c\xb0\xd6\x46\xe7\x98\x39\x2d\xa4\x28\x40\x2a\x3a\x88\x9e\x29\xba\x88\x37\x2d\xca\x60\x38\xfa\xba\x5b\x20\xac\xa8\x62\xb0\x4c\xd4\xaf\xda\x45\x0a\xba\x5c\x3b\xb9\xc7\x79\xc5\x14\x2d\x18\x34\x19\x1c\x51\xdb\x25\x4d\xb4\x7e\x06\x14\x38\x6c\x59\x55\xd2\x77\xf8\x69\x59\xfc\x7b\x73\xed\x93\x43\xcb\x32\x6d\x3c\x28\xdc\x1b\x9a\xd3\x62\xab\xc2\x27\xf7\x41\xc9\x08\x2b\x23\x08\xad\x13\x57\x21\x9c\xd3\x72\x0d\x42\x72\xf8\x01\x7c\xa7\xf6\x83\xce\x39\xd7\x82\x3c\x1f\x2f\xd6\x60\x1b\xa2\xdf\x35\x89\x52\x20\xe7\x73\x74\xe0\x66\x26\x64\x4e\xb4\x97\x58\xc2\x0e\x0e\xe1\x60\x92\x34\x6d\xa0\x10\xd6\xb5\x83\x61\x27\xe6\x47\xd3\x89\xbd\x63\xfd\x3b\x8d\x03\x3d\x6c\x42\x2d\x5b\x70\xee\xe8\xdf\x4b\xf4\x66\x4e\xe1\x01\x45\x17\x80\x74\xad\x4f\xc3\xf3\xae\xc6\x1d\xc6\xd7\xc2\xce\xc9\xe1\x29\x30\x86\x2f\x4a\xa6\x4b\x15\x84\x73\xc9\x6f\xfd\x7f\xa5\x6e\x9e\xbd\xf1\xb0\xd4\xdd\x45\x5a\xc2\x3e\x4b\x78\xab\xa8\x84\x74\x4a\x91\x3b\x92\x23\x05\xf2\x1c\x1e\x7b\xf3\x09\xf8\xcf\xab\x24\xb6\x60\xa2\xe8\x4c\x9f\x75\x77\xaa\x8c\xe6\x01\x45\x36\x86\xcf\xc3\x63\x3a\xea\xd4\x8d\x7e\x06\xac\x14\x0a\xe0\x29\xf0\xed\x07\x22\x1a\x65\xda\x44\xae\xa2\x73\x1a\xe6\x90\x69\xa2\x8c\x46\xb2\x2f\xde\x49\x38\x08\xed\xfe\xfd\x41\xaf\x9f\xa9\x55\xd7\xdd\x22\x8d\xfa\x45\x63\xc5\x0f\x80\xf3\xb4\x08\xd6\x79\x30\x9e\x93\xee\x59\xa6\xd0\x4b\xee\x22\xe3\x33\xc1\x3a\x27\x68\x36\x78\x7e\x87\x0a\x06\xd5\x2e\x20\xd3\xaf\x15\xfb\xd8\x3b\x73\x14\xbb\x92\xed\x05\x5d\x2e\x29\x38\x2c\x94\xe4\x42\x45\x5e\xd3\xb5\x7d\xdf\x47\xca\x38\xb4\x5c\xaf\xfb\x7d\xdd\x6d\xf4\xa1\x2d\x77\xdd\x2f\xce\x6d\xc4\x7b\x8b\x4e\x67\xa9\x6f\xfe\x04\x00\x00\xff\xff\xb1\xd1\x27\x78\x05\x11\x00\x00")
-
-func jsonschemaDraft04JsonBytes() ([]byte, error) {
-	return bindataRead(
-		_jsonschemaDraft04Json,
-		"jsonschema-draft-04.json",
-	)
-}
-
-func jsonschemaDraft04Json() (*asset, error) {
-	bytes, err := jsonschemaDraft04JsonBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "jsonschema-draft-04.json", size: 4357, mode: os.FileMode(0640), modTime: time.Unix(1568963823, 0)}
-	a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe1, 0x48, 0x9d, 0xb, 0x47, 0x55, 0xf0, 0x27, 0x93, 0x30, 0x25, 0x91, 0xd3, 0xfc, 0xb8, 0xf0, 0x7b, 0x68, 0x93, 0xa8, 0x2a, 0x94, 0xf2, 0x48, 0x95, 0xf8, 0xe4, 0xed, 0xf1, 0x1b, 0x82, 0xe2}}
-	return a, nil
-}
-
-var _v2SchemaJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5d\x4f\x93\xdb\x36\xb2\xbf\xfb\x53\xa0\x14\x57\xd9\xae\xd8\x92\xe3\xf7\x2e\xcf\x97\xd4\xbc\xd8\x49\x66\x37\x5e\x4f\x79\x26\xbb\x87\x78\x5c\x05\x91\x2d\x09\x09\x09\x30\x00\x38\x33\x5a\xef\x7c\xf7\x2d\xf0\x9f\x08\x02\x20\x41\x8a\xd2\xc8\x0e\x0f\xa9\x78\x28\xa0\xd1\xdd\x68\x34\x7e\xdd\xf8\xf7\xf9\x11\x42\x33\x49\x64\x04\xb3\xd7\x68\x76\x86\xfe\x76\xf9\xfe\x1f\xe8\x32\xd8\x40\x8c\xd1\x8a\x71\x74\x79\x8b\xd7\x6b\xe0\xe8\xd5\xfc\x25\x3a\xbb\x38\x9f\xcf\x9e\xab\x0a\x24\x54\xa5\x37\x52\x26\xaf\x17\x0b\x91\x17\x99\x13\xb6\xb8\x79\xb5\x10\x59\xdd\xf9\xef\x82\xd1\x6f\xf2\xc2\x8f\xf3\x4f\xb5\x1a\xea\xc7\x17\x45\x41\xc6\xd7\x8b\x90\xe3\x95\x7c\xf1\xf2\x7f\x8b\xca\x45\x3d\xb9\x4d\x32\xa6\xd8\xf2\x77\x08\x64\xfe\x8d\xc3\x9f\x29\xe1\xa0\x9a\xff\xed\x11\x42\x08\xcd\x8a\xd6\xb3\x9f\x15\x67\x74\xc5\xca\x7f\x27\x58\x6e\xc4\xec\x11\x42\xd7\x59\x5d\x1c\x86\x44\x12\x46\x71\x74\xc1\x59\x02\x5c\x12\x10\xb3\xd7\x68\x85\x23\x01\x59\x81\x04\x4b\x09\x9c\x6a\xbf\x7e\xce\x49\x7d\xba\x7b\x51\xfd\xa1\x44\xe2\xb0\x52\xac\x7d\xb3\x08\x61\x45\x68\x46\x56\x2c\x6e\x80\x86\x8c\xbf\xbd\x93\x40\x05\x61\x74\x96\x95\xbe\x7f\x84\xd0\x7d\x4e\xde\x42\xb7\xe4\xbe\x46\xbb\x14\x5b\x48\x4e\xe8\xba\x90\x05\xa1\x19\xd0\x34\xae\xc4\xce\xbe\xbc\x9a\xbf\x9c\x15\x7f\x5d\x57\xc5\x42\x10\x01\x27\x89\xe2\x48\x51\xb9\xda\x40\xd5\x87\x37\xc0\x15\x5f\x88\xad\x90\xdc\x10\x81\x42\x16\xa4\x31\x50\x39\x2f\x38\xad\xab\xb0\x53\xd8\xac\x94\x56\x6f\xc3\x84\xf4\x11\xa4\x50\xb3\xfa\xe9\xd3\x6f\x9f\x3e\xdf\x2f\xd0\xeb\x8f\x1f\x3f\x7e\xbc\xfe\xf6\xe9\xf7\xaf\x5f\x7f\xfc\x18\x7e\xfb\xec\xfb\xc7\xb3\x36\x79\x54\x43\xe8\x29\xc5\x31\x20\xc6\x11\x49\x9e\xe5\x12\x41\x66\xa0\xe8\xed\x1d\x8e\x93\x08\x5e\xa3\x27\x3b\xc3\x7c\xa2\x73\xba\xc4\x02\x2e\xb0\xdc\xf4\xe5\x76\xd1\xca\x96\xa2\x8a\x94\xcd\x21\xc9\x6c\xec\x2c\x70\x42\x9e\x34\x74\x9d\x19\x7c\xcd\x20\x9c\xea\x2e\x0a\xfe\x42\x84\xd4\x29\x04\x8c\x8a\xb4\x41\xa2\xc1\xdc\x19\x8a\x88\x90\x4a\x49\xef\xce\xdf\xbd\x45\x4a\x52\x81\x70\x10\x40\x22\x21\x44\xcb\x6d\xc5\xec\x4e\x3c\x1c\x45\xef\x57\x9a\xb5\x7d\xae\xfe\xe5\xe4\x31\x86\x90\xe0\xab\x6d\x02\x3b\x2e\xcb\x11\x90\xd9\xa8\xc6\x77\xc2\x59\x98\x06\xfd\xf9\x2e\x78\x45\x01\xa6\xa8\xa0\x71\x5c\xbe\x33\xa7\xd2\xd9\x5f\x95\xef\xd9\xd5\xac\xfd\xdc\x5d\xbf\x5e\xb8\xd1\x3e\xc7\x31\x48\xe0\x5e\x4c\x14\x65\xdf\xb8\xa8\x71\x10\x09\xa3\xc2\xc7\x02\xcb\xa2\x4e\x5a\x02\x82\x94\x13\xb9\xf5\x30\xe6\xb2\xa4\xb5\xfe\x9b\x3e\x7a\xb2\x55\xd2\xa8\x4a\xbc\x16\xb6\x71\x8e\x39\xc7\xdb\x9d\xe1\x10\x09\x71\xbd\x9c\xb3\x41\x89\xd7\xa5\x89\xdc\x57\xb5\x53\x4a\xfe\x4c\xe1\xbc\xa0\x21\x79\x0a\x1a\x0f\x70\xa7\x5c\x08\x8e\xde\xb0\xc0\x43\x24\xad\x74\x63\x0e\xb1\xd9\x90\xe1\xb0\x2d\x13\xa7\x6d\x78\xfd\x04\x14\x38\x8e\x90\xaa\xce\x63\xac\x3e\x23\xbc\x64\xa9\xb4\xf8\x03\x63\xde\xcd\xbe\x16\x13\x4a\x55\xac\x82\x12\xc6\xac\xd4\x35\xf7\x22\xd4\x3a\xff\x22\x73\x0e\x6e\x51\xa0\x75\x1e\xae\x8f\xe8\x5d\xc7\x59\xe6\xe4\x9a\x18\x8d\xd6\x1c\x53\x84\x4d\xb7\x67\x28\x37\x09\x84\x69\x88\x12\x0e\x01\x11\x80\x32\xa2\xf5\xb9\xaa\xc6\xd9\x73\x53\xab\xfb\xb4\x2e\x20\xc6\x54\x92\xa0\x9a\xf3\x69\x1a\x2f\x81\x77\x37\xae\x53\x1a\xce\x40\xc4\xa8\x82\x1c\xb5\xef\xda\x24\x7d\xb9\x61\x69\x14\xa2\x25\xa0\x90\xac\x56\xc0\x81\x4a\xb4\xe2\x2c\xce\x4a\x64\x7a\x9a\x23\xf4\x13\x91\x3f\xa7\x4b\xf4\x63\x84\x6f\x18\x87\x10\xbd\xc3\xfc\x8f\x90\xdd\x52\x44\x04\xc2\x51\xc4\x6e\x21\x74\x48\x21\x81\xc7\xe2\xfd\xea\x12\xf8\x0d\x09\xf6\xe9\x47\x35\xaf\x67\xc4\x14\xf7\x22\x27\x97\xe1\xe2\x76\x2d\x06\x8c\x4a\x1c\x48\x3f\x73\x2d\x0b\x5b\x29\x45\x24\x00\x2a\x0c\x11\xec\x94\xca\xc2\xa6\xc1\x37\x21\x43\x83\x3b\x5f\x97\xf1\x43\x5e\x53\x73\x19\xa5\x36\xd8\x2d\x05\x2e\x34\x0b\xeb\x39\xfc\x1d\x63\x51\x01\xbd\x3d\xbb\x90\x84\x40\x25\x59\x6d\x09\x5d\xa3\x1c\x37\xe6\x5c\x16\x9a\x40\x09\x70\xc1\xe8\x82\xf1\x35\xa6\xe4\xdf\x99\x5c\x8e\x9e\x4d\x79\xb4\x27\x2f\xbf\x7e\xf8\x05\x25\x8c\x50\xa9\x98\x29\x90\x62\x60\xea\x75\xae\x13\xca\xbf\x2b\x1a\x29\x27\x76\xd6\x20\xc6\x64\x5f\xe6\x32\x1a\x08\x87\x21\x07\x21\xbc\xb4\xe4\xe0\x32\x67\xa6\xcd\xf3\x1e\xcd\xd9\x6b\xb6\x6f\x8e\x27\xa7\xed\xdb\xe7\xbc\xcc\x1a\x07\xce\x6f\x87\x33\xf0\xba\x51\x17\x22\x66\x78\x79\x8e\xce\xe5\x13\x81\x80\x06\x2c\xe5\x78\x0d\xa1\xb2\xb8\x54\xa8\x79\x09\xbd\xbf\x3c\x47\x01\x8b\x13\x2c\xc9\x32\xaa\xaa\x1d\xd5\xee\xab\x36\xbd\x6c\xfd\x54\x6c\xc8\x08\x01\x3c\xbd\xe7\x07\x88\xb0\x24\x37\x79\x90\x28\x4a\x1d\x10\x1a\x92\x1b\x12\xa6\x38\x42\x40\xc3\x4c\x43\x62\x8e\xae\x36\xb0\x45\x71\x2a\xa4\x9a\x23\x79\x59\xb1\xa8\xf2\xa4\x0c\x60\x9f\xcc\x8d\x40\xf5\x80\xca\xa8\x99\xc3\xa7\x85\x1f\x31\x25\xa9\x82\xc5\x6d\xbd\xd8\x36\x76\x7c\x02\x28\x97\xf6\x1d\x74\x3b\x11\x7e\x91\xae\x32\xf8\x6c\xf4\xe6\x7b\x9a\xa5\x1f\x62\xc6\x21\xcf\x9a\xe5\xed\x8b\x02\xf3\x2c\x33\x33\xdf\x00\xca\xc9\x09\xb4\x04\xf5\xa5\x08\xd7\xc3\x02\x18\x66\xf1\xab\x1e\x83\x37\x4c\xcd\x12\xc1\x1d\x50\xf6\xaa\xbd\xfe\xe2\x73\x48\x38\x08\xa0\x32\x9b\x18\x44\x86\x0b\x6a\xc1\xaa\x26\x96\x2d\x96\x3c\xa0\x54\x65\x73\xe3\x08\xb5\x8b\x99\xbd\x82\xbc\x9e\xc2\xe8\x53\x46\x83\x3f\x33\x54\x2b\x5b\xad\x92\x79\xd9\x8f\x5d\x93\x98\xf2\xe6\xc6\x1c\xe6\x9a\x9e\xfc\x43\x82\x31\x66\x8e\x53\x77\xfe\x90\xe7\xf3\xf6\xe9\x62\x23\x3f\x10\x93\x18\xae\x72\x1a\x9d\xf9\x48\xcb\xcc\x5a\x65\xc7\x4a\x04\xf0\xf3\xd5\xd5\x05\x8a\x41\x08\xbc\x86\x86\x43\x51\x6c\xe0\x46\x57\xf6\x44\x40\x0d\xfb\xff\xa2\xc3\x7c\x3d\x39\x84\xdc\x09\x22\x64\x4f\x12\xd9\xba\xaa\xf6\xe3\xbd\x56\xdd\x91\x25\x6a\x14\x9c\x89\x34\x8e\x31\xdf\xee\x15\x7e\x2f\x39\x81\x15\x2a\x28\x95\x66\x51\xf5\xfd\x83\xc5\xfe\x15\x07\xcf\xf7\x08\xee\x1d\x8e\xb6\xc5\x52\xcc\x8c\x5a\x93\x66\xc5\xd8\x79\x38\x46\xd6\xa7\x88\x37\xc9\x2e\xe3\xd2\xa5\x7b\x4b\x3a\xdc\xa1\xdc\x9e\x29\xf1\x8c\x8a\x99\x16\x47\x8d\xd4\x78\x8b\xf6\x1c\xe9\x71\x54\x1b\x69\xa8\x4a\x93\x37\xe5\xb2\x2c\x4f\x0c\x92\xab\xa0\x73\x32\x72\x59\xd3\xf0\x2d\x8d\xed\xca\x37\x16\x19\x9e\xdb\x1c\xab\x17\x49\xc3\x0f\x37\xdc\x88\xb1\xb4\xd4\x42\xcb\x58\x5e\x6a\x52\x0b\x15\x10\x0a\xb0\x04\xe7\xf8\x58\x32\x16\x01\xa6\xcd\x01\xb2\xc2\x69\x24\x35\x38\x6f\x30\x6a\xae\x1b\xb4\x71\xaa\xad\x1d\xa0\xd6\x20\x2d\x8b\x3c\xc6\x82\x62\x27\x34\x6d\x15\x84\x7b\x43\xb1\x35\x78\xa6\x24\x77\x28\xc1\x6e\xfc\xe9\x48\x74\xf4\x15\xe3\xe1\x84\x42\x88\x40\x7a\x26\x49\x3b\x48\xb1\xa4\x19\x8e\x0c\xa7\xb5\x01\x6c\x0c\x97\x61\x8a\xc2\x32\xd8\x8c\x44\x69\x24\xbf\x65\x1d\x74\xd6\xe5\x44\xef\xec\x48\x5e\xb7\x8a\xa3\x29\x8e\x41\x64\xce\x1f\x88\xdc\x00\x47\x4b\x40\x98\x6e\xd1\x0d\x8e\x48\x98\x63\x5c\x21\xb1\x4c\x05\x0a\x58\x98\xc5\x6d\x4f\x0a\x77\x53\x4f\x8b\xc4\x44\x1f\xb2\xdf\x8d\x3b\xea\x9f\xfe\xf6\xf2\xc5\xff\x5d\x7f\xfe\x9f\xfb\x67\x8f\xff\xf3\xe9\x69\xd1\xfe\xb3\xc7\xfd\x3c\xf8\x3f\x71\x94\x82\x23\xd1\x72\x00\xb7\x42\x99\x6c\xc0\x60\x7b\x0f\x79\xea\xa8\x53\x4b\x56\x31\xfa\x0b\x52\x9f\x96\xdb\xcd\x2f\xd7\x67\xcd\x04\x19\x85\xfe\xdb\x02\x9a\x59\x03\xad\x63\x3c\xea\xff\x2e\x18\xfd\x00\xd9\xe2\x56\x60\x59\x93\xb9\xb6\xb2\x3e\x3c\x2c\xab\x0f\xa7\xb2\x89\x43\xc7\xf6\xd5\xce\x2e\xad\xa6\xa9\xed\xa6\xc6\x5a\xb4\xa6\x67\xdf\x8c\x26\x7b\x50\x5a\x91\x08\x2e\x6d\xd4\x3a\xc1\x9d\xf2\xdb\xde\x1e\xb2\x2c\x6c\xa5\x64\xc9\x16\xb4\x90\xaa\x4a\xb7\x0c\xde\x13\xc3\x2a\x9a\x11\x9b\x7a\x1b\x3d\x95\x97\x37\x31\x6b\x69\x7e\x34\xc0\x67\x1f\x66\x19\x49\xef\xf1\x25\xf5\xac\x0e\xea\x0a\x28\x8d\x4d\x7e\xd9\x57\x4b\x49\xe5\xc6\xb3\x25\xfd\xe6\x57\x42\x25\xac\xcd\xcf\x36\x74\x8e\xca\x24\x47\xe7\x80\xa8\x92\x72\xbd\x3d\x84\x2d\x65\xe2\x82\x1a\x9c\xc4\x44\x92\x1b\x10\x79\x8a\xc4\x4a\x2f\x60\x51\x04\x81\xaa\xf0\xa3\x95\x27\xd7\x12\x7b\xa3\x96\x03\x45\x96\xc1\x8a\x07\xc9\xb2\xb0\x95\x52\x8c\xef\x48\x9c\xc6\x7e\x94\xca\xc2\x0e\x07\x12\x44\xa9\x20\x37\xf0\xae\x0f\x49\xa3\x96\x9d\x4b\x42\x7b\x70\x59\x14\xee\xe0\xb2\x0f\x49\xa3\x96\x4b\x97\xbf\x00\x5d\x4b\x4f\xfc\xbb\x2b\xee\x92\xb9\x17\xb5\xaa\xb8\x0b\x97\x17\x9b\x43\xfd\xd6\xc2\xb2\xc2\x2e\x29\xcf\xfd\x87\x4a\x55\xda\x25\x63\x1f\x5a\x65\x69\x2b\x2d\x3d\x67\xe9\x41\xae\x5e\xc1\x6e\x2b\xd4\xdb\x3e\xa8\xd3\x26\xd2\x48\x92\x24\xca\x61\x86\x8f\x8c\xbb\xf2\x8e\x91\xdf\x1f\x06\x19\x33\xf3\x03\x4d\xba\xcd\xe2\x2d\xfb\x69\xe9\x16\x15\x13\xd5\x56\x85\x4e\x3c\x5b\x8a\xbf\x25\x72\x83\xee\x5e\x20\x22\xf2\xc8\xaa\x7b\xdb\x8e\xe4\x29\x58\xca\x38\xb7\x3f\x2e\x59\xb8\xbd\xa8\x16\x16\xf7\xdb\x79\x51\x9f\x5a\xb4\x8d\x87\x3a\x6e\xbc\x3e\xc5\xb4\xcd\x58\xf9\xf5\x3c\xb9\x6f\x49\xaf\x57\xc1\xfa\x1c\x5d\x6d\x88\x8a\x8b\xd3\x28\xcc\xb7\xef\x10\x8a\x4a\x74\xa9\x4a\xa7\x62\xbf\x0d\x76\x23\x6f\x59\xd9\x31\xee\x40\x11\xfb\x28\xec\x8d\x22\x1c\x13\x5a\x64\x94\x23\x16\x60\xbb\xd2\x7c\xa0\x98\xb2\xe5\x6e\xbc\x54\x33\xe0\x3e\xb9\x52\x17\xdb\xb7\x1b\xc8\x12\x20\x8c\x23\xca\x64\x7e\x78\xa3\x62\x5b\x75\x56\xd9\x9e\x2a\x91\x27\xb0\x70\x34\x1f\x90\x89\xb5\x86\x73\x7e\x71\xda\x1e\xfb\x3a\x72\xdc\x5e\x79\x88\xcb\x74\x79\xd9\x64\xe4\xd4\xc2\x9e\xce\xb1\xfe\x85\x5a\xc0\xe9\x0c\x34\x3d\xd0\x43\xce\xa1\x36\x39\xd5\xa1\x4e\xf5\xf8\xb1\xa9\x23\x08\x75\x84\xac\x53\x6c\x3a\xc5\xa6\x53\x6c\x3a\xc5\xa6\x7f\xc5\xd8\xf4\x51\xfd\xff\x25\x4e\xfa\x33\x05\xbe\x9d\x60\xd2\x04\x93\x6a\x5f\x33\x9b\x98\x50\xd2\xe1\x50\x52\xc6\xcc\xdb\x38\x91\xdb\xe6\xaa\xa2\x8f\xa1\x6a\xa6\xd4\xc6\x56\xd6\x8c\x40\x02\x68\x48\xe8\x1a\xe1\x9a\xd9\x2e\xb7\x05\xc3\x34\xda\x2a\xbb\xcd\x12\x36\x98\x22\x50\x4c\xa1\x1b\xc5\xd5\x84\xf0\xbe\x24\x84\xf7\x2f\x22\x37\xef\x94\xd7\x9f\xa0\xde\x04\xf5\x26\xa8\x37\x41\x3d\x64\x40\x3d\xe5\xf2\xde\x60\x89\x27\xb4\x37\xa1\xbd\xda\xd7\xd2\x2c\x26\xc0\x37\x01\x3e\x1b\xef\x5f\x06\xe0\x6b\x7c\x5c\x91\x08\x26\x10\x38\x81\xc0\x09\x04\x76\x4a\x3d\x81\xc0\xbf\x12\x08\x4c\xb0\xdc\x7c\x99\x00\xd0\x75\x70\xb4\xf8\x5a\x7c\xea\xde\x3e\x39\x08\x30\x5a\x27\x35\xed\xb4\x65\xad\x69\x74\x10\x88\x79\xe2\x30\x52\x19\xd6\x04\x21\xa7\x95\xd5\x0e\x03\xf8\xda\x20\xd7\x84\xb4\x26\xa4\x35\x21\xad\x09\x69\x21\x03\x69\x51\x46\xff\xff\x18\x9b\x54\xed\x87\x47\x06\x9d\x4e\x73\x6e\x9a\xb3\xa9\xce\x83\x5e\x4b\xc6\x71\x20\x45\xd7\x72\xf5\x40\x72\x0e\x34\x6c\xf4\x6c\xf3\xba\x5e\x4b\x97\x0e\x52\xb8\xbe\x8b\x79\xa0\x10\x86\xa1\x75\xb0\x6f\xec\xc8\xf4\x3d\x4d\x7b\x86\xc2\x02\x31\x12\x51\xbf\x07\x94\xad\x10\xd6\x2e\x79\xcf\xe9\x1c\xf5\x1e\x31\x23\x5c\x18\xfb\x9c\xfb\x70\xe0\x62\xbd\xf7\xb5\x94\xcf\xf3\xf6\xfa\xc5\x4e\x9c\x85\x76\x1d\xae\x37\xbc\xde\xa3\x41\xcb\x29\xd0\x5e\x70\x67\x50\x93\x6d\x98\xa8\xd3\x67\x0f\x68\xb1\xeb\x38\x47\x07\x10\x1b\xd2\xe2\x18\x68\x6d\x40\xbb\xa3\x40\xba\x21\xf2\x8e\x81\xfb\xf6\x92\x77\x2f\x70\xe8\xdb\xb2\x36\xbf\x30\x91\xc5\x21\xe7\x45\xcc\x34\x0c\x48\x8e\xd0\xf2\x9b\x7c\x3c\xbd\x1c\x04\x3e\x07\xe8\x7c\x2f\x84\x7a\x48\x4d\x1f\xba\xe1\x76\x45\x7b\x60\xe0\x01\xca\xee\x04\xca\x31\xbe\x73\x5f\xa3\x70\x0c\xad\x1f\xa5\xf5\x76\xd5\xbb\xd2\x7e\xfb\x30\x90\xcf\xfa\x67\x7a\xe6\xc3\x37\x42\x19\xe2\xc9\x9c\x61\x4c\xe7\xd1\x77\x55\x86\x6e\x8f\x7b\x85\x42\x33\xa3\xaa\x57\xae\xfd\xd5\xcc\x9c\x56\x68\xe2\xde\x0e\xa8\x2c\xa9\xb0\x7d\xf0\x54\x2d\x80\xf2\x48\x39\x3d\x98\x1a\x6d\x0b\x9d\xba\x53\xfb\xce\xf8\xd1\x7e\xbb\x60\x4f\x06\xf5\xce\xda\xab\xeb\xca\xcb\xd5\xac\x20\xda\x72\x3b\xa2\x4b\x38\xd7\xb5\x89\xbe\x42\xd9\xb9\x73\xc4\x0c\x6d\xb7\xd9\xf8\x8d\xbd\x3e\x9c\xf5\x53\x68\x48\x14\x36\x8f\x09\xc5\x92\xf1\x21\xd1\x09\x07\x1c\xbe\xa7\x91\xf3\x6a\xc8\xc1\x57\xb0\xdd\xc5\xc6\x1d\xad\x76\x1d\xa8\x82\x0e\x4c\x38\xfe\xa5\x8c\xc5\x0a\x40\x5d\xa1\xbb\x98\xd1\xfb\x74\x61\xed\x1a\x98\xaf\x3c\x8c\x1e\xe3\xc2\x92\x29\x74\x3e\x99\xd0\xf9\x41\x50\xd0\x38\x4b\x57\x7e\x5b\x7a\x0e\xe6\xce\x4e\xd7\x19\x35\x57\xbb\x3c\x3c\xd2\x5e\x4f\x4b\x4c\xf7\x0f\x4d\x2b\x91\x5d\x94\xa6\x95\xc8\x69\x25\x72\x5a\x89\x7c\xb8\x95\xc8\x07\x80\x8c\xda\x9c\x64\x7b\xb7\x71\xdf\x57\x12\x4b\x9a\x1f\x72\x0c\x13\x03\xad\x3c\xd5\x4e\xde\x8e\x57\x13\x6d\x34\x86\xcf\x97\xe6\xa4\x68\xc4\xb0\xf6\xc9\xc2\xeb\x8d\x0b\xd7\xcd\xfe\xba\xa6\xf5\x30\xeb\x30\x33\xbe\xc7\x56\x27\xab\x08\xd9\x6d\xbb\x09\xee\x7c\x2d\xcf\xee\x87\x38\xac\xc8\xdd\x90\x9a\x58\x4a\x4e\x96\xa9\x79\x79\xf3\xde\x20\xf0\x96\xe3\x24\x19\xeb\xba\xf2\x53\x19\xab\x12\xaf\x47\xb3\xa0\x3e\xef\x9b\x8d\x6d\x6d\x7b\xde\x3b\x3b\x1a\xc0\x3f\x95\x7e\xed\x78\xfb\x76\xb8\xaf\xb3\xdd\xc5\xeb\x95\xed\x5a\x62\x41\x82\xb3\x54\x6e\x80\x4a\x92\x6f\x36\xbd\x34\xae\xde\x6f\xa4\xc0\xbc\x08\xe3\x84\xfc\x1d\xb6\xe3\xd0\x62\x38\x95\x9b\x57\xe7\x71\x12\x91\x80\xc8\x31\x69\x5e\x60\x21\x6e\x19\x0f\xc7\xa4\x79\x96\x28\x3e\x47\x54\x65\x41\x36\x08\x40\x88\x1f\x58\x08\x56\xaa\xd5\xbf\xaf\xad\x96\xd7\xd6\xcf\x87\xf5\x34\x0f\x71\x93\x6e\x26\xed\x98\x5b\x9f\x4f\xcf\x95\x34\xc6\xd7\x11\xfa\xb0\x81\x22\x1a\xdb\xdf\x8e\xdc\xc3\xb9\xf8\xdd\x5d\x3c\x74\xe6\xea\xb7\x8b\xbf\xf5\x6e\xb3\x46\x2e\x64\xf4\xab\x3c\x4e\xcf\x36\x1d\xfe\xfa\xb8\x36\xba\x8a\xd8\xad\xf6\xc6\x41\x2a\x37\x8c\x17\x0f\xda\xfe\xda\xe7\x65\xbc\x71\x2c\x36\x57\x8a\x47\x12\x4c\xf1\xbd\x77\x6b\xa4\x50\x7e\x77\x7b\x22\x60\x89\xef\xcd\xf5\xb9\x0c\x97\x79\x0d\x2b\x35\x43\xcb\x3d\x24\xf1\x78\xfc\xf8\xcb\x1f\x15\x06\xe2\x78\xd8\x51\x21\xd9\x1f\xf0\xf5\x8f\x86\xa4\x50\xfa\xb1\x47\x43\xa5\xdd\x69\x14\xe8\xa3\xc0\x86\x91\xa7\x81\x50\xb4\x7c\xc0\x81\x80\x77\x7a\x9f\xc6\xc2\xa9\x8c\x05\x33\xb0\x3b\x31\xa4\xf4\xd7\x1b\x26\x55\x97\x7c\x65\xf8\x69\x1a\x84\x8e\x41\x78\xd9\xec\xc5\x11\x16\x1e\x74\x91\xf5\x56\xf5\x57\x49\x47\x5c\x92\xa9\x1e\x99\x36\xf4\xdb\xb1\x0e\xd3\x78\x02\xb0\x9b\x25\xcb\xe9\xe9\x1d\x0d\x44\x01\x42\x08\x91\x64\xd9\xdd\x37\x08\x17\xef\xf9\xe5\x0f\xbd\x46\x91\xf5\xf9\x89\x92\x37\xdd\x89\x59\x44\x1f\x9c\xee\x34\x1e\xbe\x47\x83\x32\x72\x8e\x37\xdf\xac\x69\x38\xef\x75\xb0\xda\xdb\xac\x83\x94\x2f\x39\xa6\x62\x05\x1c\x25\x9c\x49\x16\xb0\xa8\x3c\xc7\x7e\x76\x71\x3e\x6f\xb5\x24\xe7\xe8\xb7\xb9\xc7\x6c\x43\x92\xee\x21\xd4\x17\xa1\x7f\xba\x35\xfe\xae\x39\xbc\xde\xba\x69\xd9\x8e\xe1\x62\xde\x64\x7d\x16\x88\x1b\xed\x29\x11\xfd\x4f\xa9\xff\x99\x90\xc4\xf6\xf4\xf9\x6e\xe9\x28\x23\xd7\xca\xe5\xee\xee\x9f\x63\xb1\x5b\xfb\x10\xd7\x2f\x1d\xf2\xe3\xbf\xb9\xb5\x6f\xa4\x6d\x7d\x25\x79\xfb\x24\x31\xea\x56\xbe\x5d\x53\xcd\x2d\x36\xa3\x6d\xdf\xab\x1c\xb8\x6d\x6f\xc0\x98\xa7\xdd\xaa\x86\x8c\x1d\x39\xa3\x9d\x70\x2b\x9b\x68\xd9\xfd\x33\xfe\xa9\xb6\x4a\x2e\x63\x0f\xcf\x68\x27\xd9\x4c\xb9\x46\x6d\xcb\xbe\xa1\xa8\xd6\x5f\xc6\xd6\x9f\xf1\x4f\xf4\xd4\xb4\x78\xd0\xd6\xf4\x13\x3c\x3b\xac\xd0\xdc\x90\x34\xda\xc9\xb4\x9a\x1a\x8d\xbd\x93\x87\xd4\xe2\x21\x1b\xb3\x2b\xd1\xbe\xe7\x69\xd4\x53\x67\xd5\x40\xa0\xe3\x19\x3f\x6d\x1a\xbc\x0e\x86\x3c\x10\xb4\x3d\x2a\xcd\x78\x32\xe6\xab\xbd\x36\xc9\xf4\x3a\x58\xae\xc3\xf4\x47\xea\xbf\xfb\x47\xff\x0d\x00\x00\xff\xff\xd2\x32\x5a\x28\x38\x9d\x00\x00")
-
-func v2SchemaJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_v2SchemaJson,
-		"v2/schema.json",
-	)
-}
-
-func v2SchemaJson() (*asset, error) {
-	bytes, err := v2SchemaJsonBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "v2/schema.json", size: 40248, mode: os.FileMode(0640), modTime: time.Unix(1568964748, 0)}
-	a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xab, 0x88, 0x5e, 0xf, 0xbf, 0x17, 0x74, 0x0, 0xb2, 0x5a, 0x7f, 0xbc, 0x58, 0xcd, 0xc, 0x25, 0x73, 0xd5, 0x29, 0x1c, 0x7a, 0xd0, 0xce, 0x79, 0xd4, 0x89, 0x31, 0x27, 0x90, 0xf2, 0xff, 0xe6}}
-	return a, nil
-}
-
-// Asset loads and returns the asset for the given name.
-// It returns an error if the asset could not be found or
-// could not be loaded.
-func Asset(name string) ([]byte, error) {
-	canonicalName := strings.Replace(name, "\\", "/", -1)
-	if f, ok := _bindata[canonicalName]; ok {
-		a, err := f()
-		if err != nil {
-			return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
-		}
-		return a.bytes, nil
-	}
-	return nil, fmt.Errorf("Asset %s not found", name)
-}
-
-// AssetString returns the asset contents as a string (instead of a []byte).
-func AssetString(name string) (string, error) {
-	data, err := Asset(name)
-	return string(data), err
-}
-
-// MustAsset is like Asset but panics when Asset would return an error.
-// It simplifies safe initialization of global variables.
-func MustAsset(name string) []byte {
-	a, err := Asset(name)
-	if err != nil {
-		panic("asset: Asset(" + name + "): " + err.Error())
-	}
-
-	return a
-}
-
-// MustAssetString is like AssetString but panics when Asset would return an
-// error. It simplifies safe initialization of global variables.
-func MustAssetString(name string) string {
-	return string(MustAsset(name))
-}
-
-// AssetInfo loads and returns the asset info for the given name.
-// It returns an error if the asset could not be found or
-// could not be loaded.
-func AssetInfo(name string) (os.FileInfo, error) {
-	canonicalName := strings.Replace(name, "\\", "/", -1)
-	if f, ok := _bindata[canonicalName]; ok {
-		a, err := f()
-		if err != nil {
-			return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
-		}
-		return a.info, nil
-	}
-	return nil, fmt.Errorf("AssetInfo %s not found", name)
-}
-
-// AssetDigest returns the digest of the file with the given name. It returns an
-// error if the asset could not be found or the digest could not be loaded.
-func AssetDigest(name string) ([sha256.Size]byte, error) {
-	canonicalName := strings.Replace(name, "\\", "/", -1)
-	if f, ok := _bindata[canonicalName]; ok {
-		a, err := f()
-		if err != nil {
-			return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s can't read by error: %v", name, err)
-		}
-		return a.digest, nil
-	}
-	return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s not found", name)
-}
-
-// Digests returns a map of all known files and their checksums.
-func Digests() (map[string][sha256.Size]byte, error) {
-	mp := make(map[string][sha256.Size]byte, len(_bindata))
-	for name := range _bindata {
-		a, err := _bindata[name]()
-		if err != nil {
-			return nil, err
-		}
-		mp[name] = a.digest
-	}
-	return mp, nil
-}
-
-// AssetNames returns the names of the assets.
-func AssetNames() []string {
-	names := make([]string, 0, len(_bindata))
-	for name := range _bindata {
-		names = append(names, name)
-	}
-	return names
-}
-
-// _bindata is a table, holding each asset generator, mapped to its name.
-var _bindata = map[string]func() (*asset, error){
-	"jsonschema-draft-04.json": jsonschemaDraft04Json,
-
-	"v2/schema.json": v2SchemaJson,
-}
-
-// AssetDir returns the file names below a certain
-// directory embedded in the file by go-bindata.
-// For example if you run go-bindata on data/... and data contains the
-// following hierarchy:
-//     data/
-//       foo.txt
-//       img/
-//         a.png
-//         b.png
-// then AssetDir("data") would return []string{"foo.txt", "img"},
-// AssetDir("data/img") would return []string{"a.png", "b.png"},
-// AssetDir("foo.txt") and AssetDir("notexist") would return an error, and
-// AssetDir("") will return []string{"data"}.
-func AssetDir(name string) ([]string, error) {
-	node := _bintree
-	if len(name) != 0 {
-		canonicalName := strings.Replace(name, "\\", "/", -1)
-		pathList := strings.Split(canonicalName, "/")
-		for _, p := range pathList {
-			node = node.Children[p]
-			if node == nil {
-				return nil, fmt.Errorf("Asset %s not found", name)
-			}
-		}
-	}
-	if node.Func != nil {
-		return nil, fmt.Errorf("Asset %s not found", name)
-	}
-	rv := make([]string, 0, len(node.Children))
-	for childName := range node.Children {
-		rv = append(rv, childName)
-	}
-	return rv, nil
-}
-
-type bintree struct {
-	Func     func() (*asset, error)
-	Children map[string]*bintree
-}
-
-var _bintree = &bintree{nil, map[string]*bintree{
-	"jsonschema-draft-04.json": {jsonschemaDraft04Json, map[string]*bintree{}},
-	"v2": {nil, map[string]*bintree{
-		"schema.json": {v2SchemaJson, map[string]*bintree{}},
-	}},
-}}
-
-// RestoreAsset restores an asset under the given directory.
-func RestoreAsset(dir, name string) error {
-	data, err := Asset(name)
-	if err != nil {
-		return err
-	}
-	info, err := AssetInfo(name)
-	if err != nil {
-		return err
-	}
-	err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
-	if err != nil {
-		return err
-	}
-	err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
-	if err != nil {
-		return err
-	}
-	return os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
-}
-
-// RestoreAssets restores an asset under the given directory recursively.
-func RestoreAssets(dir, name string) error {
-	children, err := AssetDir(name)
-	// File
-	if err != nil {
-		return RestoreAsset(dir, name)
-	}
-	// Dir
-	for _, child := range children {
-		err = RestoreAssets(dir, filepath.Join(name, child))
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func _filePath(dir, name string) string {
-	canonicalName := strings.Replace(name, "\\", "/", -1)
-	return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...)
-}
diff --git a/vendor/github.com/go-openapi/spec/embed.go b/vendor/github.com/go-openapi/spec/embed.go
new file mode 100644
index 00000000..1f428475
--- /dev/null
+++ b/vendor/github.com/go-openapi/spec/embed.go
@@ -0,0 +1,17 @@
+package spec
+
+import (
+	"embed"
+	"path"
+)
+
+//go:embed schemas/*.json schemas/*/*.json
+var assets embed.FS
+
+func jsonschemaDraft04JSONBytes() ([]byte, error) {
+	return assets.ReadFile(path.Join("schemas", "jsonschema-draft-04.json"))
+}
+
+func v2SchemaJSONBytes() ([]byte, error) {
+	return assets.ReadFile(path.Join("schemas", "v2", "schema.json"))
+}
diff --git a/vendor/github.com/go-openapi/spec/expander.go b/vendor/github.com/go-openapi/spec/expander.go
index d4ea889d..b81a5699 100644
--- a/vendor/github.com/go-openapi/spec/expander.go
+++ b/vendor/github.com/go-openapi/spec/expander.go
@@ -27,7 +27,6 @@ import (
 // all relative $ref's will be resolved from there.
 //
 // PathLoader injects a document loading method. By default, this resolves to the function provided by the SpecLoader package variable.
-//
 type ExpandOptions struct {
 	RelativeBase        string                                // the path to the root document to expand. This is a file, not a directory
 	SkipSchemas         bool                                  // do not expand schemas, just paths, parameters and responses
@@ -58,7 +57,7 @@ func ExpandSpec(spec *Swagger, options *ExpandOptions) error {
 	if !options.SkipSchemas {
 		for key, definition := range spec.Definitions {
 			parentRefs := make([]string, 0, 10)
-			parentRefs = append(parentRefs, fmt.Sprintf("#/definitions/%s", key))
+			parentRefs = append(parentRefs, "#/definitions/"+key)
 
 			def, err := expandSchema(definition, parentRefs, resolver, specBasePath)
 			if resolver.shouldStopOnError(err) {
@@ -103,15 +102,21 @@ const rootBase = ".root"
 
 // baseForRoot loads in the cache the root document and produces a fake ".root" base path entry
 // for further $ref resolution
-//
-// Setting the cache is optional and this parameter may safely be left to nil.
 func baseForRoot(root interface{}, cache ResolutionCache) string {
+	// cache the root document to resolve $ref's
+	normalizedBase := normalizeBase(rootBase)
+
 	if root == nil {
-		return ""
+		// ensure that we never leave a nil root: always cache the root base pseudo-document
+		cachedRoot, found := cache.Get(normalizedBase)
+		if found && cachedRoot != nil {
+			// the cache is already preloaded with a root
+			return normalizedBase
+		}
+
+		root = map[string]interface{}{}
 	}
 
-	// cache the root document to resolve $ref's
-	normalizedBase := normalizeBase(rootBase)
 	cache.Set(normalizedBase, root)
 
 	return normalizedBase
@@ -208,7 +213,19 @@ func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, ba
 	}
 
 	if target.Ref.String() != "" {
-		return expandSchemaRef(target, parentRefs, resolver, basePath)
+		if !resolver.options.SkipSchemas {
+			return expandSchemaRef(target, parentRefs, resolver, basePath)
+		}
+
+		// when "expand" with SkipSchema, we just rebase the existing $ref without replacing
+		// the full schema.
+		rebasedRef, err := NewRef(normalizeURI(target.Ref.String(), basePath))
+		if err != nil {
+			return nil, err
+		}
+		target.Ref = denormalizeRef(&rebasedRef, resolver.context.basePath, resolver.context.rootID)
+
+		return &target, nil
 	}
 
 	for k := range target.Definitions {
@@ -520,21 +537,25 @@ func getRefAndSchema(input interface{}) (*Ref, *Schema, error) {
 }
 
 func expandParameterOrResponse(input interface{}, resolver *schemaLoader, basePath string) error {
-	ref, _, err := getRefAndSchema(input)
+	ref, sch, err := getRefAndSchema(input)
 	if err != nil {
 		return err
 	}
 
-	if ref == nil {
+	if ref == nil && sch == nil { // nothing to do
 		return nil
 	}
 
 	parentRefs := make([]string, 0, 10)
-	if err = resolver.deref(input, parentRefs, basePath); resolver.shouldStopOnError(err) {
-		return err
+	if ref != nil {
+		// dereference this $ref
+		if err = resolver.deref(input, parentRefs, basePath); resolver.shouldStopOnError(err) {
+			return err
+		}
+
+		ref, sch, _ = getRefAndSchema(input)
 	}
 
-	ref, sch, _ := getRefAndSchema(input)
 	if ref.String() != "" {
 		transitiveResolver := resolver.transitiveResolver(basePath, *ref)
 		basePath = resolver.updateBasePath(transitiveResolver, basePath)
@@ -546,6 +567,7 @@ func expandParameterOrResponse(input interface{}, resolver *schemaLoader, basePa
 		if ref != nil {
 			*ref = Ref{}
 		}
+
 		return nil
 	}
 
@@ -555,38 +577,29 @@ func expandParameterOrResponse(input interface{}, resolver *schemaLoader, basePa
 			return ern
 		}
 
-		switch {
-		case resolver.isCircular(&rebasedRef, basePath, parentRefs...):
+		if resolver.isCircular(&rebasedRef, basePath, parentRefs...) {
 			// this is a circular $ref: stop expansion
 			if !resolver.options.AbsoluteCircularRef {
 				sch.Ref = denormalizeRef(&rebasedRef, resolver.context.basePath, resolver.context.rootID)
 			} else {
 				sch.Ref = rebasedRef
 			}
-		case !resolver.options.SkipSchemas:
-			// schema expanded to a $ref in another root
-			sch.Ref = rebasedRef
-			debugLog("rebased to: %s", sch.Ref.String())
-		default:
-			// skip schema expansion but rebase $ref to schema
-			sch.Ref = denormalizeRef(&rebasedRef, resolver.context.basePath, resolver.context.rootID)
 		}
 	}
 
+	// $ref expansion or rebasing is performed by expandSchema below
 	if ref != nil {
 		*ref = Ref{}
 	}
 
 	// expand schema
-	if !resolver.options.SkipSchemas {
-		s, err := expandSchema(*sch, parentRefs, resolver, basePath)
-		if resolver.shouldStopOnError(err) {
-			return err
-		}
-		if s == nil {
-			// guard for when continuing on error
-			return nil
-		}
+	// yes, we do it even if options.SkipSchema is true: we have to go down that rabbit hole and rebase nested $ref)
+	s, err := expandSchema(*sch, parentRefs, resolver, basePath)
+	if resolver.shouldStopOnError(err) {
+		return err
+	}
+
+	if s != nil { // guard for when continuing on error
 		*sch = *s
 	}
 
diff --git a/vendor/github.com/go-openapi/spec/info.go b/vendor/github.com/go-openapi/spec/info.go
index c458b49b..582f0fd4 100644
--- a/vendor/github.com/go-openapi/spec/info.go
+++ b/vendor/github.com/go-openapi/spec/info.go
@@ -16,6 +16,7 @@ package spec
 
 import (
 	"encoding/json"
+	"strconv"
 	"strings"
 
 	"github.com/go-openapi/jsonpointer"
@@ -40,6 +41,24 @@ func (e Extensions) GetString(key string) (string, bool) {
 	return "", false
 }
 
+// GetInt gets a int value from the extensions
+func (e Extensions) GetInt(key string) (int, bool) {
+	realKey := strings.ToLower(key)
+
+	if v, ok := e.GetString(realKey); ok {
+		if r, err := strconv.Atoi(v); err == nil {
+			return r, true
+		}
+	}
+
+	if v, ok := e[realKey]; ok {
+		if r, rOk := v.(float64); rOk {
+			return int(r), true
+		}
+	}
+	return -1, false
+}
+
 // GetBool gets a string value from the extensions
 func (e Extensions) GetBool(key string) (bool, bool) {
 	if v, ok := e[strings.ToLower(key)]; ok {
diff --git a/vendor/github.com/go-openapi/spec/normalizer_nonwindows.go b/vendor/github.com/go-openapi/spec/normalizer_nonwindows.go
index 2df07231..f19f1a8f 100644
--- a/vendor/github.com/go-openapi/spec/normalizer_nonwindows.go
+++ b/vendor/github.com/go-openapi/spec/normalizer_nonwindows.go
@@ -40,5 +40,5 @@ func repairURI(in string) (*url.URL, string) {
 	return u, ""
 }
 
-func fixWindowsURI(u *url.URL, in string) {
+func fixWindowsURI(_ *url.URL, _ string) {
 }
diff --git a/vendor/github.com/go-openapi/spec/operation.go b/vendor/github.com/go-openapi/spec/operation.go
index 995ce6ac..a69cca88 100644
--- a/vendor/github.com/go-openapi/spec/operation.go
+++ b/vendor/github.com/go-openapi/spec/operation.go
@@ -217,9 +217,12 @@ func (o *Operation) AddParam(param *Parameter) *Operation {
 
 	for i, p := range o.Parameters {
 		if p.Name == param.Name && p.In == param.In {
-			params := append(o.Parameters[:i], *param)
+			params := make([]Parameter, 0, len(o.Parameters)+1)
+			params = append(params, o.Parameters[:i]...)
+			params = append(params, *param)
 			params = append(params, o.Parameters[i+1:]...)
 			o.Parameters = params
+
 			return o
 		}
 	}
diff --git a/vendor/github.com/go-openapi/spec/parameter.go b/vendor/github.com/go-openapi/spec/parameter.go
index 2b2b89b6..bd4f1cdb 100644
--- a/vendor/github.com/go-openapi/spec/parameter.go
+++ b/vendor/github.com/go-openapi/spec/parameter.go
@@ -84,27 +84,27 @@ type ParamProps struct {
 // Parameter a unique parameter is defined by a combination of a [name](#parameterName) and [location](#parameterIn).
 //
 // There are five possible parameter types.
-// * Path - Used together with [Path Templating](#pathTemplating), where the parameter value is actually part
-//   of the operation's URL. This does not include the host or base path of the API. For example, in `/items/{itemId}`,
-//   the path parameter is `itemId`.
-// * Query - Parameters that are appended to the URL. For example, in `/items?id=###`, the query parameter is `id`.
-// * Header - Custom headers that are expected as part of the request.
-// * Body - The payload that's appended to the HTTP request. Since there can only be one payload, there can only be
-//   _one_ body parameter. The name of the body parameter has no effect on the parameter itself and is used for
-//   documentation purposes only. Since Form parameters are also in the payload, body and form parameters cannot exist
-//   together for the same operation.
-// * Form - Used to describe the payload of an HTTP request when either `application/x-www-form-urlencoded` or
-//   `multipart/form-data` are used as the content type of the request (in Swagger's definition,
-//   the [`consumes`](#operationConsumes) property of an operation). This is the only parameter type that can be used
-//   to send files, thus supporting the `file` type. Since form parameters are sent in the payload, they cannot be
-//   declared together with a body parameter for the same operation. Form parameters have a different format based on
-//   the content-type used (for further details, consult http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4).
-//   * `application/x-www-form-urlencoded` - Similar to the format of Query parameters but as a payload.
-//   For example, `foo=1&bar=swagger` - both `foo` and `bar` are form parameters. This is normally used for simple
-//   parameters that are being transferred.
-//   * `multipart/form-data` - each parameter takes a section in the payload with an internal header.
-//   For example, for the header `Content-Disposition: form-data; name="submit-name"` the name of the parameter is
-//   `submit-name`. This type of form parameters is more commonly used for file transfers.
+//   - Path - Used together with [Path Templating](#pathTemplating), where the parameter value is actually part
+//     of the operation's URL. This does not include the host or base path of the API. For example, in `/items/{itemId}`,
+//     the path parameter is `itemId`.
+//   - Query - Parameters that are appended to the URL. For example, in `/items?id=###`, the query parameter is `id`.
+//   - Header - Custom headers that are expected as part of the request.
+//   - Body - The payload that's appended to the HTTP request. Since there can only be one payload, there can only be
+//     _one_ body parameter. The name of the body parameter has no effect on the parameter itself and is used for
+//     documentation purposes only. Since Form parameters are also in the payload, body and form parameters cannot exist
+//     together for the same operation.
+//   - Form - Used to describe the payload of an HTTP request when either `application/x-www-form-urlencoded` or
+//     `multipart/form-data` are used as the content type of the request (in Swagger's definition,
+//     the [`consumes`](#operationConsumes) property of an operation). This is the only parameter type that can be used
+//     to send files, thus supporting the `file` type. Since form parameters are sent in the payload, they cannot be
+//     declared together with a body parameter for the same operation. Form parameters have a different format based on
+//     the content-type used (for further details, consult http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4).
+//   - `application/x-www-form-urlencoded` - Similar to the format of Query parameters but as a payload.
+//     For example, `foo=1&bar=swagger` - both `foo` and `bar` are form parameters. This is normally used for simple
+//     parameters that are being transferred.
+//   - `multipart/form-data` - each parameter takes a section in the payload with an internal header.
+//     For example, for the header `Content-Disposition: form-data; name="submit-name"` the name of the parameter is
+//     `submit-name`. This type of form parameters is more commonly used for file transfers.
 //
 // For more information: http://goo.gl/8us55a#parameterObject
 type Parameter struct {
diff --git a/vendor/github.com/go-openapi/spec/properties.go b/vendor/github.com/go-openapi/spec/properties.go
index 2af13787..91d2435f 100644
--- a/vendor/github.com/go-openapi/spec/properties.go
+++ b/vendor/github.com/go-openapi/spec/properties.go
@@ -42,8 +42,8 @@ func (items OrderSchemaItems) MarshalJSON() ([]byte, error) {
 func (items OrderSchemaItems) Len() int      { return len(items) }
 func (items OrderSchemaItems) Swap(i, j int) { items[i], items[j] = items[j], items[i] }
 func (items OrderSchemaItems) Less(i, j int) (ret bool) {
-	ii, oki := items[i].Extensions.GetString("x-order")
-	ij, okj := items[j].Extensions.GetString("x-order")
+	ii, oki := items[i].Extensions.GetInt("x-order")
+	ij, okj := items[j].Extensions.GetInt("x-order")
 	if oki {
 		if okj {
 			defer func() {
@@ -56,7 +56,7 @@ func (items OrderSchemaItems) Less(i, j int) (ret bool) {
 					ret = reflect.ValueOf(ii).String() < reflect.ValueOf(ij).String()
 				}
 			}()
-			return reflect.ValueOf(ii).Int() < reflect.ValueOf(ij).Int()
+			return ii < ij
 		}
 		return true
 	} else if okj {
diff --git a/vendor/github.com/go-openapi/spec/responses.go b/vendor/github.com/go-openapi/spec/responses.go
index 4efb6f86..16c3076f 100644
--- a/vendor/github.com/go-openapi/spec/responses.go
+++ b/vendor/github.com/go-openapi/spec/responses.go
@@ -19,6 +19,7 @@ import (
 	"fmt"
 	"reflect"
 	"strconv"
+	"strings"
 
 	"github.com/go-openapi/swag"
 )
@@ -62,6 +63,7 @@ func (r *Responses) UnmarshalJSON(data []byte) error {
 	if err := json.Unmarshal(data, &r.ResponsesProps); err != nil {
 		return err
 	}
+
 	if err := json.Unmarshal(data, &r.VendorExtensible); err != nil {
 		return err
 	}
@@ -107,20 +109,31 @@ func (r ResponsesProps) MarshalJSON() ([]byte, error) {
 
 // UnmarshalJSON unmarshals responses from JSON
 func (r *ResponsesProps) UnmarshalJSON(data []byte) error {
-	var res map[string]Response
+	var res map[string]json.RawMessage
 	if err := json.Unmarshal(data, &res); err != nil {
-		return nil
+		return err
 	}
+
 	if v, ok := res["default"]; ok {
-		r.Default = &v
+		var defaultRes Response
+		if err := json.Unmarshal(v, &defaultRes); err != nil {
+			return err
+		}
+		r.Default = &defaultRes
 		delete(res, "default")
 	}
 	for k, v := range res {
-		if nk, err := strconv.Atoi(k); err == nil {
-			if r.StatusCodeResponses == nil {
-				r.StatusCodeResponses = map[int]Response{}
+		if !strings.HasPrefix(k, "x-") {
+			var statusCodeResp Response
+			if err := json.Unmarshal(v, &statusCodeResp); err != nil {
+				return err
+			}
+			if nk, err := strconv.Atoi(k); err == nil {
+				if r.StatusCodeResponses == nil {
+					r.StatusCodeResponses = map[int]Response{}
+				}
+				r.StatusCodeResponses[nk] = statusCodeResp
 			}
-			r.StatusCodeResponses[nk] = v
 		}
 	}
 	return nil
diff --git a/vendor/github.com/go-openapi/spec/schema_loader.go b/vendor/github.com/go-openapi/spec/schema_loader.go
index b81175af..0059b99a 100644
--- a/vendor/github.com/go-openapi/spec/schema_loader.go
+++ b/vendor/github.com/go-openapi/spec/schema_loader.go
@@ -168,14 +168,7 @@ func (r *schemaLoader) load(refURL *url.URL) (interface{}, url.URL, bool, error)
 	normalized := normalizeBase(pth)
 	debugLog("loading doc from: %s", normalized)
 
-	unescaped, err := url.PathUnescape(normalized)
-	if err != nil {
-		return nil, url.URL{}, false, err
-	}
-
-	u := url.URL{Path: unescaped}
-
-	data, fromCache := r.cache.Get(u.RequestURI())
+	data, fromCache := r.cache.Get(normalized)
 	if fromCache {
 		return data, toFetch, fromCache, nil
 	}
diff --git a/vendor/github.com/go-openapi/spec/schemas/jsonschema-draft-04.json b/vendor/github.com/go-openapi/spec/schemas/jsonschema-draft-04.json
new file mode 100644
index 00000000..bcbb8474
--- /dev/null
+++ b/vendor/github.com/go-openapi/spec/schemas/jsonschema-draft-04.json
@@ -0,0 +1,149 @@
+{
+    "id": "http://json-schema.org/draft-04/schema#",
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "description": "Core schema meta-schema",
+    "definitions": {
+        "schemaArray": {
+            "type": "array",
+            "minItems": 1,
+            "items": { "$ref": "#" }
+        },
+        "positiveInteger": {
+            "type": "integer",
+            "minimum": 0
+        },
+        "positiveIntegerDefault0": {
+            "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
+        },
+        "simpleTypes": {
+            "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
+        },
+        "stringArray": {
+            "type": "array",
+            "items": { "type": "string" },
+            "minItems": 1,
+            "uniqueItems": true
+        }
+    },
+    "type": "object",
+    "properties": {
+        "id": {
+            "type": "string"
+        },
+        "$schema": {
+            "type": "string"
+        },
+        "title": {
+            "type": "string"
+        },
+        "description": {
+            "type": "string"
+        },
+        "default": {},
+        "multipleOf": {
+            "type": "number",
+            "minimum": 0,
+            "exclusiveMinimum": true
+        },
+        "maximum": {
+            "type": "number"
+        },
+        "exclusiveMaximum": {
+            "type": "boolean",
+            "default": false
+        },
+        "minimum": {
+            "type": "number"
+        },
+        "exclusiveMinimum": {
+            "type": "boolean",
+            "default": false
+        },
+        "maxLength": { "$ref": "#/definitions/positiveInteger" },
+        "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
+        "pattern": {
+            "type": "string",
+            "format": "regex"
+        },
+        "additionalItems": {
+            "anyOf": [
+                { "type": "boolean" },
+                { "$ref": "#" }
+            ],
+            "default": {}
+        },
+        "items": {
+            "anyOf": [
+                { "$ref": "#" },
+                { "$ref": "#/definitions/schemaArray" }
+            ],
+            "default": {}
+        },
+        "maxItems": { "$ref": "#/definitions/positiveInteger" },
+        "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
+        "uniqueItems": {
+            "type": "boolean",
+            "default": false
+        },
+        "maxProperties": { "$ref": "#/definitions/positiveInteger" },
+        "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
+        "required": { "$ref": "#/definitions/stringArray" },
+        "additionalProperties": {
+            "anyOf": [
+                { "type": "boolean" },
+                { "$ref": "#" }
+            ],
+            "default": {}
+        },
+        "definitions": {
+            "type": "object",
+            "additionalProperties": { "$ref": "#" },
+            "default": {}
+        },
+        "properties": {
+            "type": "object",
+            "additionalProperties": { "$ref": "#" },
+            "default": {}
+        },
+        "patternProperties": {
+            "type": "object",
+            "additionalProperties": { "$ref": "#" },
+            "default": {}
+        },
+        "dependencies": {
+            "type": "object",
+            "additionalProperties": {
+                "anyOf": [
+                    { "$ref": "#" },
+                    { "$ref": "#/definitions/stringArray" }
+                ]
+            }
+        },
+        "enum": {
+            "type": "array",
+            "minItems": 1,
+            "uniqueItems": true
+        },
+        "type": {
+            "anyOf": [
+                { "$ref": "#/definitions/simpleTypes" },
+                {
+                    "type": "array",
+                    "items": { "$ref": "#/definitions/simpleTypes" },
+                    "minItems": 1,
+                    "uniqueItems": true
+                }
+            ]
+        },
+        "format": { "type": "string" },
+        "allOf": { "$ref": "#/definitions/schemaArray" },
+        "anyOf": { "$ref": "#/definitions/schemaArray" },
+        "oneOf": { "$ref": "#/definitions/schemaArray" },
+        "not": { "$ref": "#" }
+    },
+    "dependencies": {
+        "exclusiveMaximum": [ "maximum" ],
+        "exclusiveMinimum": [ "minimum" ]
+    },
+    "default": {}
+}
diff --git a/vendor/github.com/go-openapi/spec/schemas/v2/schema.json b/vendor/github.com/go-openapi/spec/schemas/v2/schema.json
new file mode 100644
index 00000000..ebe10ed3
--- /dev/null
+++ b/vendor/github.com/go-openapi/spec/schemas/v2/schema.json
@@ -0,0 +1,1607 @@
+{
+  "title": "A JSON Schema for Swagger 2.0 API.",
+  "id": "http://swagger.io/v2/schema.json#",
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "type": "object",
+  "required": [
+    "swagger",
+    "info",
+    "paths"
+  ],
+  "additionalProperties": false,
+  "patternProperties": {
+    "^x-": {
+      "$ref": "#/definitions/vendorExtension"
+    }
+  },
+  "properties": {
+    "swagger": {
+      "type": "string",
+      "enum": [
+        "2.0"
+      ],
+      "description": "The Swagger version of this document."
+    },
+    "info": {
+      "$ref": "#/definitions/info"
+    },
+    "host": {
+      "type": "string",
+      "pattern": "^[^{}/ :\\\\]+(?::\\d+)?$",
+      "description": "The host (name or ip) of the API. Example: 'swagger.io'"
+    },
+    "basePath": {
+      "type": "string",
+      "pattern": "^/",
+      "description": "The base path to the API. Example: '/api'."
+    },
+    "schemes": {
+      "$ref": "#/definitions/schemesList"
+    },
+    "consumes": {
+      "description": "A list of MIME types accepted by the API.",
+      "allOf": [
+        {
+          "$ref": "#/definitions/mediaTypeList"
+        }
+      ]
+    },
+    "produces": {
+      "description": "A list of MIME types the API can produce.",
+      "allOf": [
+        {
+          "$ref": "#/definitions/mediaTypeList"
+        }
+      ]
+    },
+    "paths": {
+      "$ref": "#/definitions/paths"
+    },
+    "definitions": {
+      "$ref": "#/definitions/definitions"
+    },
+    "parameters": {
+      "$ref": "#/definitions/parameterDefinitions"
+    },
+    "responses": {
+      "$ref": "#/definitions/responseDefinitions"
+    },
+    "security": {
+      "$ref": "#/definitions/security"
+    },
+    "securityDefinitions": {
+      "$ref": "#/definitions/securityDefinitions"
+    },
+    "tags": {
+      "type": "array",
+      "items": {
+        "$ref": "#/definitions/tag"
+      },
+      "uniqueItems": true
+    },
+    "externalDocs": {
+      "$ref": "#/definitions/externalDocs"
+    }
+  },
+  "definitions": {
+    "info": {
+      "type": "object",
+      "description": "General information about the API.",
+      "required": [
+        "version",
+        "title"
+      ],
+      "additionalProperties": false,
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      },
+      "properties": {
+        "title": {
+          "type": "string",
+          "description": "A unique and precise title of the API."
+        },
+        "version": {
+          "type": "string",
+          "description": "A semantic version number of the API."
+        },
+        "description": {
+          "type": "string",
+          "description": "A longer description of the API. Should be different from the title.  GitHub Flavored Markdown is allowed."
+        },
+        "termsOfService": {
+          "type": "string",
+          "description": "The terms of service for the API."
+        },
+        "contact": {
+          "$ref": "#/definitions/contact"
+        },
+        "license": {
+          "$ref": "#/definitions/license"
+        }
+      }
+    },
+    "contact": {
+      "type": "object",
+      "description": "Contact information for the owners of the API.",
+      "additionalProperties": false,
+      "properties": {
+        "name": {
+          "type": "string",
+          "description": "The identifying name of the contact person/organization."
+        },
+        "url": {
+          "type": "string",
+          "description": "The URL pointing to the contact information.",
+          "format": "uri"
+        },
+        "email": {
+          "type": "string",
+          "description": "The email address of the contact person/organization.",
+          "format": "email"
+        }
+      },
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "license": {
+      "type": "object",
+      "required": [
+        "name"
+      ],
+      "additionalProperties": false,
+      "properties": {
+        "name": {
+          "type": "string",
+          "description": "The name of the license type. It's encouraged to use an OSI compatible license."
+        },
+        "url": {
+          "type": "string",
+          "description": "The URL pointing to the license.",
+          "format": "uri"
+        }
+      },
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "paths": {
+      "type": "object",
+      "description": "Relative paths to the individual endpoints. They must be relative to the 'basePath'.",
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        },
+        "^/": {
+          "$ref": "#/definitions/pathItem"
+        }
+      },
+      "additionalProperties": false
+    },
+    "definitions": {
+      "type": "object",
+      "additionalProperties": {
+        "$ref": "#/definitions/schema"
+      },
+      "description": "One or more JSON objects describing the schemas being consumed and produced by the API."
+    },
+    "parameterDefinitions": {
+      "type": "object",
+      "additionalProperties": {
+        "$ref": "#/definitions/parameter"
+      },
+      "description": "One or more JSON representations for parameters"
+    },
+    "responseDefinitions": {
+      "type": "object",
+      "additionalProperties": {
+        "$ref": "#/definitions/response"
+      },
+      "description": "One or more JSON representations for responses"
+    },
+    "externalDocs": {
+      "type": "object",
+      "additionalProperties": false,
+      "description": "information about external documentation",
+      "required": [
+        "url"
+      ],
+      "properties": {
+        "description": {
+          "type": "string"
+        },
+        "url": {
+          "type": "string",
+          "format": "uri"
+        }
+      },
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "examples": {
+      "type": "object",
+      "additionalProperties": true
+    },
+    "mimeType": {
+      "type": "string",
+      "description": "The MIME type of the HTTP message."
+    },
+    "operation": {
+      "type": "object",
+      "required": [
+        "responses"
+      ],
+      "additionalProperties": false,
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      },
+      "properties": {
+        "tags": {
+          "type": "array",
+          "items": {
+            "type": "string"
+          },
+          "uniqueItems": true
+        },
+        "summary": {
+          "type": "string",
+          "description": "A brief summary of the operation."
+        },
+        "description": {
+          "type": "string",
+          "description": "A longer description of the operation, GitHub Flavored Markdown is allowed."
+        },
+        "externalDocs": {
+          "$ref": "#/definitions/externalDocs"
+        },
+        "operationId": {
+          "type": "string",
+          "description": "A unique identifier of the operation."
+        },
+        "produces": {
+          "description": "A list of MIME types the API can produce.",
+          "allOf": [
+            {
+              "$ref": "#/definitions/mediaTypeList"
+            }
+          ]
+        },
+        "consumes": {
+          "description": "A list of MIME types the API can consume.",
+          "allOf": [
+            {
+              "$ref": "#/definitions/mediaTypeList"
+            }
+          ]
+        },
+        "parameters": {
+          "$ref": "#/definitions/parametersList"
+        },
+        "responses": {
+          "$ref": "#/definitions/responses"
+        },
+        "schemes": {
+          "$ref": "#/definitions/schemesList"
+        },
+        "deprecated": {
+          "type": "boolean",
+          "default": false
+        },
+        "security": {
+          "$ref": "#/definitions/security"
+        }
+      }
+    },
+    "pathItem": {
+      "type": "object",
+      "additionalProperties": false,
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      },
+      "properties": {
+        "$ref": {
+          "type": "string"
+        },
+        "get": {
+          "$ref": "#/definitions/operation"
+        },
+        "put": {
+          "$ref": "#/definitions/operation"
+        },
+        "post": {
+          "$ref": "#/definitions/operation"
+        },
+        "delete": {
+          "$ref": "#/definitions/operation"
+        },
+        "options": {
+          "$ref": "#/definitions/operation"
+        },
+        "head": {
+          "$ref": "#/definitions/operation"
+        },
+        "patch": {
+          "$ref": "#/definitions/operation"
+        },
+        "parameters": {
+          "$ref": "#/definitions/parametersList"
+        }
+      }
+    },
+    "responses": {
+      "type": "object",
+      "description": "Response objects names can either be any valid HTTP status code or 'default'.",
+      "minProperties": 1,
+      "additionalProperties": false,
+      "patternProperties": {
+        "^([0-9]{3})$|^(default)$": {
+          "$ref": "#/definitions/responseValue"
+        },
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      },
+      "not": {
+        "type": "object",
+        "additionalProperties": false,
+        "patternProperties": {
+          "^x-": {
+            "$ref": "#/definitions/vendorExtension"
+          }
+        }
+      }
+    },
+    "responseValue": {
+      "oneOf": [
+        {
+          "$ref": "#/definitions/response"
+        },
+        {
+          "$ref": "#/definitions/jsonReference"
+        }
+      ]
+    },
+    "response": {
+      "type": "object",
+      "required": [
+        "description"
+      ],
+      "properties": {
+        "description": {
+          "type": "string"
+        },
+        "schema": {
+          "oneOf": [
+            {
+              "$ref": "#/definitions/schema"
+            },
+            {
+              "$ref": "#/definitions/fileSchema"
+            }
+          ]
+        },
+        "headers": {
+          "$ref": "#/definitions/headers"
+        },
+        "examples": {
+          "$ref": "#/definitions/examples"
+        }
+      },
+      "additionalProperties": false,
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "headers": {
+      "type": "object",
+      "additionalProperties": {
+        "$ref": "#/definitions/header"
+      }
+    },
+    "header": {
+      "type": "object",
+      "additionalProperties": false,
+      "required": [
+        "type"
+      ],
+      "properties": {
+        "type": {
+          "type": "string",
+          "enum": [
+            "string",
+            "number",
+            "integer",
+            "boolean",
+            "array"
+          ]
+        },
+        "format": {
+          "type": "string"
+        },
+        "items": {
+          "$ref": "#/definitions/primitivesItems"
+        },
+        "collectionFormat": {
+          "$ref": "#/definitions/collectionFormat"
+        },
+        "default": {
+          "$ref": "#/definitions/default"
+        },
+        "maximum": {
+          "$ref": "#/definitions/maximum"
+        },
+        "exclusiveMaximum": {
+          "$ref": "#/definitions/exclusiveMaximum"
+        },
+        "minimum": {
+          "$ref": "#/definitions/minimum"
+        },
+        "exclusiveMinimum": {
+          "$ref": "#/definitions/exclusiveMinimum"
+        },
+        "maxLength": {
+          "$ref": "#/definitions/maxLength"
+        },
+        "minLength": {
+          "$ref": "#/definitions/minLength"
+        },
+        "pattern": {
+          "$ref": "#/definitions/pattern"
+        },
+        "maxItems": {
+          "$ref": "#/definitions/maxItems"
+        },
+        "minItems": {
+          "$ref": "#/definitions/minItems"
+        },
+        "uniqueItems": {
+          "$ref": "#/definitions/uniqueItems"
+        },
+        "enum": {
+          "$ref": "#/definitions/enum"
+        },
+        "multipleOf": {
+          "$ref": "#/definitions/multipleOf"
+        },
+        "description": {
+          "type": "string"
+        }
+      },
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "vendorExtension": {
+      "description": "Any property starting with x- is valid.",
+      "additionalProperties": true,
+      "additionalItems": true
+    },
+    "bodyParameter": {
+      "type": "object",
+      "required": [
+        "name",
+        "in",
+        "schema"
+      ],
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      },
+      "properties": {
+        "description": {
+          "type": "string",
+          "description": "A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed."
+        },
+        "name": {
+          "type": "string",
+          "description": "The name of the parameter."
+        },
+        "in": {
+          "type": "string",
+          "description": "Determines the location of the parameter.",
+          "enum": [
+            "body"
+          ]
+        },
+        "required": {
+          "type": "boolean",
+          "description": "Determines whether or not this parameter is required or optional.",
+          "default": false
+        },
+        "schema": {
+          "$ref": "#/definitions/schema"
+        }
+      },
+      "additionalProperties": false
+    },
+    "headerParameterSubSchema": {
+      "additionalProperties": false,
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      },
+      "properties": {
+        "required": {
+          "type": "boolean",
+          "description": "Determines whether or not this parameter is required or optional.",
+          "default": false
+        },
+        "in": {
+          "type": "string",
+          "description": "Determines the location of the parameter.",
+          "enum": [
+            "header"
+          ]
+        },
+        "description": {
+          "type": "string",
+          "description": "A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed."
+        },
+        "name": {
+          "type": "string",
+          "description": "The name of the parameter."
+        },
+        "type": {
+          "type": "string",
+          "enum": [
+            "string",
+            "number",
+            "boolean",
+            "integer",
+            "array"
+          ]
+        },
+        "format": {
+          "type": "string"
+        },
+        "items": {
+          "$ref": "#/definitions/primitivesItems"
+        },
+        "collectionFormat": {
+          "$ref": "#/definitions/collectionFormat"
+        },
+        "default": {
+          "$ref": "#/definitions/default"
+        },
+        "maximum": {
+          "$ref": "#/definitions/maximum"
+        },
+        "exclusiveMaximum": {
+          "$ref": "#/definitions/exclusiveMaximum"
+        },
+        "minimum": {
+          "$ref": "#/definitions/minimum"
+        },
+        "exclusiveMinimum": {
+          "$ref": "#/definitions/exclusiveMinimum"
+        },
+        "maxLength": {
+          "$ref": "#/definitions/maxLength"
+        },
+        "minLength": {
+          "$ref": "#/definitions/minLength"
+        },
+        "pattern": {
+          "$ref": "#/definitions/pattern"
+        },
+        "maxItems": {
+          "$ref": "#/definitions/maxItems"
+        },
+        "minItems": {
+          "$ref": "#/definitions/minItems"
+        },
+        "uniqueItems": {
+          "$ref": "#/definitions/uniqueItems"
+        },
+        "enum": {
+          "$ref": "#/definitions/enum"
+        },
+        "multipleOf": {
+          "$ref": "#/definitions/multipleOf"
+        }
+      }
+    },
+    "queryParameterSubSchema": {
+      "additionalProperties": false,
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      },
+      "properties": {
+        "required": {
+          "type": "boolean",
+          "description": "Determines whether or not this parameter is required or optional.",
+          "default": false
+        },
+        "in": {
+          "type": "string",
+          "description": "Determines the location of the parameter.",
+          "enum": [
+            "query"
+          ]
+        },
+        "description": {
+          "type": "string",
+          "description": "A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed."
+        },
+        "name": {
+          "type": "string",
+          "description": "The name of the parameter."
+        },
+        "allowEmptyValue": {
+          "type": "boolean",
+          "default": false,
+          "description": "allows sending a parameter by name only or with an empty value."
+        },
+        "type": {
+          "type": "string",
+          "enum": [
+            "string",
+            "number",
+            "boolean",
+            "integer",
+            "array"
+          ]
+        },
+        "format": {
+          "type": "string"
+        },
+        "items": {
+          "$ref": "#/definitions/primitivesItems"
+        },
+        "collectionFormat": {
+          "$ref": "#/definitions/collectionFormatWithMulti"
+        },
+        "default": {
+          "$ref": "#/definitions/default"
+        },
+        "maximum": {
+          "$ref": "#/definitions/maximum"
+        },
+        "exclusiveMaximum": {
+          "$ref": "#/definitions/exclusiveMaximum"
+        },
+        "minimum": {
+          "$ref": "#/definitions/minimum"
+        },
+        "exclusiveMinimum": {
+          "$ref": "#/definitions/exclusiveMinimum"
+        },
+        "maxLength": {
+          "$ref": "#/definitions/maxLength"
+        },
+        "minLength": {
+          "$ref": "#/definitions/minLength"
+        },
+        "pattern": {
+          "$ref": "#/definitions/pattern"
+        },
+        "maxItems": {
+          "$ref": "#/definitions/maxItems"
+        },
+        "minItems": {
+          "$ref": "#/definitions/minItems"
+        },
+        "uniqueItems": {
+          "$ref": "#/definitions/uniqueItems"
+        },
+        "enum": {
+          "$ref": "#/definitions/enum"
+        },
+        "multipleOf": {
+          "$ref": "#/definitions/multipleOf"
+        }
+      }
+    },
+    "formDataParameterSubSchema": {
+      "additionalProperties": false,
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      },
+      "properties": {
+        "required": {
+          "type": "boolean",
+          "description": "Determines whether or not this parameter is required or optional.",
+          "default": false
+        },
+        "in": {
+          "type": "string",
+          "description": "Determines the location of the parameter.",
+          "enum": [
+            "formData"
+          ]
+        },
+        "description": {
+          "type": "string",
+          "description": "A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed."
+        },
+        "name": {
+          "type": "string",
+          "description": "The name of the parameter."
+        },
+        "allowEmptyValue": {
+          "type": "boolean",
+          "default": false,
+          "description": "allows sending a parameter by name only or with an empty value."
+        },
+        "type": {
+          "type": "string",
+          "enum": [
+            "string",
+            "number",
+            "boolean",
+            "integer",
+            "array",
+            "file"
+          ]
+        },
+        "format": {
+          "type": "string"
+        },
+        "items": {
+          "$ref": "#/definitions/primitivesItems"
+        },
+        "collectionFormat": {
+          "$ref": "#/definitions/collectionFormatWithMulti"
+        },
+        "default": {
+          "$ref": "#/definitions/default"
+        },
+        "maximum": {
+          "$ref": "#/definitions/maximum"
+        },
+        "exclusiveMaximum": {
+          "$ref": "#/definitions/exclusiveMaximum"
+        },
+        "minimum": {
+          "$ref": "#/definitions/minimum"
+        },
+        "exclusiveMinimum": {
+          "$ref": "#/definitions/exclusiveMinimum"
+        },
+        "maxLength": {
+          "$ref": "#/definitions/maxLength"
+        },
+        "minLength": {
+          "$ref": "#/definitions/minLength"
+        },
+        "pattern": {
+          "$ref": "#/definitions/pattern"
+        },
+        "maxItems": {
+          "$ref": "#/definitions/maxItems"
+        },
+        "minItems": {
+          "$ref": "#/definitions/minItems"
+        },
+        "uniqueItems": {
+          "$ref": "#/definitions/uniqueItems"
+        },
+        "enum": {
+          "$ref": "#/definitions/enum"
+        },
+        "multipleOf": {
+          "$ref": "#/definitions/multipleOf"
+        }
+      }
+    },
+    "pathParameterSubSchema": {
+      "additionalProperties": false,
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      },
+      "required": [
+        "required"
+      ],
+      "properties": {
+        "required": {
+          "type": "boolean",
+          "enum": [
+            true
+          ],
+          "description": "Determines whether or not this parameter is required or optional."
+        },
+        "in": {
+          "type": "string",
+          "description": "Determines the location of the parameter.",
+          "enum": [
+            "path"
+          ]
+        },
+        "description": {
+          "type": "string",
+          "description": "A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed."
+        },
+        "name": {
+          "type": "string",
+          "description": "The name of the parameter."
+        },
+        "type": {
+          "type": "string",
+          "enum": [
+            "string",
+            "number",
+            "boolean",
+            "integer",
+            "array"
+          ]
+        },
+        "format": {
+          "type": "string"
+        },
+        "items": {
+          "$ref": "#/definitions/primitivesItems"
+        },
+        "collectionFormat": {
+          "$ref": "#/definitions/collectionFormat"
+        },
+        "default": {
+          "$ref": "#/definitions/default"
+        },
+        "maximum": {
+          "$ref": "#/definitions/maximum"
+        },
+        "exclusiveMaximum": {
+          "$ref": "#/definitions/exclusiveMaximum"
+        },
+        "minimum": {
+          "$ref": "#/definitions/minimum"
+        },
+        "exclusiveMinimum": {
+          "$ref": "#/definitions/exclusiveMinimum"
+        },
+        "maxLength": {
+          "$ref": "#/definitions/maxLength"
+        },
+        "minLength": {
+          "$ref": "#/definitions/minLength"
+        },
+        "pattern": {
+          "$ref": "#/definitions/pattern"
+        },
+        "maxItems": {
+          "$ref": "#/definitions/maxItems"
+        },
+        "minItems": {
+          "$ref": "#/definitions/minItems"
+        },
+        "uniqueItems": {
+          "$ref": "#/definitions/uniqueItems"
+        },
+        "enum": {
+          "$ref": "#/definitions/enum"
+        },
+        "multipleOf": {
+          "$ref": "#/definitions/multipleOf"
+        }
+      }
+    },
+    "nonBodyParameter": {
+      "type": "object",
+      "required": [
+        "name",
+        "in",
+        "type"
+      ],
+      "oneOf": [
+        {
+          "$ref": "#/definitions/headerParameterSubSchema"
+        },
+        {
+          "$ref": "#/definitions/formDataParameterSubSchema"
+        },
+        {
+          "$ref": "#/definitions/queryParameterSubSchema"
+        },
+        {
+          "$ref": "#/definitions/pathParameterSubSchema"
+        }
+      ]
+    },
+    "parameter": {
+      "oneOf": [
+        {
+          "$ref": "#/definitions/bodyParameter"
+        },
+        {
+          "$ref": "#/definitions/nonBodyParameter"
+        }
+      ]
+    },
+    "schema": {
+      "type": "object",
+      "description": "A deterministic version of a JSON Schema object.",
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      },
+      "properties": {
+        "$ref": {
+          "type": "string"
+        },
+        "format": {
+          "type": "string"
+        },
+        "title": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/title"
+        },
+        "description": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/description"
+        },
+        "default": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/default"
+        },
+        "multipleOf": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/multipleOf"
+        },
+        "maximum": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/maximum"
+        },
+        "exclusiveMaximum": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum"
+        },
+        "minimum": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/minimum"
+        },
+        "exclusiveMinimum": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum"
+        },
+        "maxLength": {
+          "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
+        },
+        "minLength": {
+          "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
+        },
+        "pattern": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/pattern"
+        },
+        "maxItems": {
+          "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
+        },
+        "minItems": {
+          "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
+        },
+        "uniqueItems": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/uniqueItems"
+        },
+        "maxProperties": {
+          "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
+        },
+        "minProperties": {
+          "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
+        },
+        "required": {
+          "$ref": "http://json-schema.org/draft-04/schema#/definitions/stringArray"
+        },
+        "enum": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/enum"
+        },
+        "additionalProperties": {
+          "anyOf": [
+            {
+              "$ref": "#/definitions/schema"
+            },
+            {
+              "type": "boolean"
+            }
+          ],
+          "default": {}
+        },
+        "type": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/type"
+        },
+        "items": {
+          "anyOf": [
+            {
+              "$ref": "#/definitions/schema"
+            },
+            {
+              "type": "array",
+              "minItems": 1,
+              "items": {
+                "$ref": "#/definitions/schema"
+              }
+            }
+          ],
+          "default": {}
+        },
+        "allOf": {
+          "type": "array",
+          "minItems": 1,
+          "items": {
+            "$ref": "#/definitions/schema"
+          }
+        },
+        "properties": {
+          "type": "object",
+          "additionalProperties": {
+            "$ref": "#/definitions/schema"
+          },
+          "default": {}
+        },
+        "discriminator": {
+          "type": "string"
+        },
+        "readOnly": {
+          "type": "boolean",
+          "default": false
+        },
+        "xml": {
+          "$ref": "#/definitions/xml"
+        },
+        "externalDocs": {
+          "$ref": "#/definitions/externalDocs"
+        },
+        "example": {}
+      },
+      "additionalProperties": false
+    },
+    "fileSchema": {
+      "type": "object",
+      "description": "A deterministic version of a JSON Schema object.",
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      },
+      "required": [
+        "type"
+      ],
+      "properties": {
+        "format": {
+          "type": "string"
+        },
+        "title": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/title"
+        },
+        "description": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/description"
+        },
+        "default": {
+          "$ref": "http://json-schema.org/draft-04/schema#/properties/default"
+        },
+        "required": {
+          "$ref": "http://json-schema.org/draft-04/schema#/definitions/stringArray"
+        },
+        "type": {
+          "type": "string",
+          "enum": [
+            "file"
+          ]
+        },
+        "readOnly": {
+          "type": "boolean",
+          "default": false
+        },
+        "externalDocs": {
+          "$ref": "#/definitions/externalDocs"
+        },
+        "example": {}
+      },
+      "additionalProperties": false
+    },
+    "primitivesItems": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "type": {
+          "type": "string",
+          "enum": [
+            "string",
+            "number",
+            "integer",
+            "boolean",
+            "array"
+          ]
+        },
+        "format": {
+          "type": "string"
+        },
+        "items": {
+          "$ref": "#/definitions/primitivesItems"
+        },
+        "collectionFormat": {
+          "$ref": "#/definitions/collectionFormat"
+        },
+        "default": {
+          "$ref": "#/definitions/default"
+        },
+        "maximum": {
+          "$ref": "#/definitions/maximum"
+        },
+        "exclusiveMaximum": {
+          "$ref": "#/definitions/exclusiveMaximum"
+        },
+        "minimum": {
+          "$ref": "#/definitions/minimum"
+        },
+        "exclusiveMinimum": {
+          "$ref": "#/definitions/exclusiveMinimum"
+        },
+        "maxLength": {
+          "$ref": "#/definitions/maxLength"
+        },
+        "minLength": {
+          "$ref": "#/definitions/minLength"
+        },
+        "pattern": {
+          "$ref": "#/definitions/pattern"
+        },
+        "maxItems": {
+          "$ref": "#/definitions/maxItems"
+        },
+        "minItems": {
+          "$ref": "#/definitions/minItems"
+        },
+        "uniqueItems": {
+          "$ref": "#/definitions/uniqueItems"
+        },
+        "enum": {
+          "$ref": "#/definitions/enum"
+        },
+        "multipleOf": {
+          "$ref": "#/definitions/multipleOf"
+        }
+      },
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "security": {
+      "type": "array",
+      "items": {
+        "$ref": "#/definitions/securityRequirement"
+      },
+      "uniqueItems": true
+    },
+    "securityRequirement": {
+      "type": "object",
+      "additionalProperties": {
+        "type": "array",
+        "items": {
+          "type": "string"
+        },
+        "uniqueItems": true
+      }
+    },
+    "xml": {
+      "type": "object",
+      "additionalProperties": false,
+      "properties": {
+        "name": {
+          "type": "string"
+        },
+        "namespace": {
+          "type": "string"
+        },
+        "prefix": {
+          "type": "string"
+        },
+        "attribute": {
+          "type": "boolean",
+          "default": false
+        },
+        "wrapped": {
+          "type": "boolean",
+          "default": false
+        }
+      },
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "tag": {
+      "type": "object",
+      "additionalProperties": false,
+      "required": [
+        "name"
+      ],
+      "properties": {
+        "name": {
+          "type": "string"
+        },
+        "description": {
+          "type": "string"
+        },
+        "externalDocs": {
+          "$ref": "#/definitions/externalDocs"
+        }
+      },
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "securityDefinitions": {
+      "type": "object",
+      "additionalProperties": {
+        "oneOf": [
+          {
+            "$ref": "#/definitions/basicAuthenticationSecurity"
+          },
+          {
+            "$ref": "#/definitions/apiKeySecurity"
+          },
+          {
+            "$ref": "#/definitions/oauth2ImplicitSecurity"
+          },
+          {
+            "$ref": "#/definitions/oauth2PasswordSecurity"
+          },
+          {
+            "$ref": "#/definitions/oauth2ApplicationSecurity"
+          },
+          {
+            "$ref": "#/definitions/oauth2AccessCodeSecurity"
+          }
+        ]
+      }
+    },
+    "basicAuthenticationSecurity": {
+      "type": "object",
+      "additionalProperties": false,
+      "required": [
+        "type"
+      ],
+      "properties": {
+        "type": {
+          "type": "string",
+          "enum": [
+            "basic"
+          ]
+        },
+        "description": {
+          "type": "string"
+        }
+      },
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "apiKeySecurity": {
+      "type": "object",
+      "additionalProperties": false,
+      "required": [
+        "type",
+        "name",
+        "in"
+      ],
+      "properties": {
+        "type": {
+          "type": "string",
+          "enum": [
+            "apiKey"
+          ]
+        },
+        "name": {
+          "type": "string"
+        },
+        "in": {
+          "type": "string",
+          "enum": [
+            "header",
+            "query"
+          ]
+        },
+        "description": {
+          "type": "string"
+        }
+      },
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "oauth2ImplicitSecurity": {
+      "type": "object",
+      "additionalProperties": false,
+      "required": [
+        "type",
+        "flow",
+        "authorizationUrl"
+      ],
+      "properties": {
+        "type": {
+          "type": "string",
+          "enum": [
+            "oauth2"
+          ]
+        },
+        "flow": {
+          "type": "string",
+          "enum": [
+            "implicit"
+          ]
+        },
+        "scopes": {
+          "$ref": "#/definitions/oauth2Scopes"
+        },
+        "authorizationUrl": {
+          "type": "string",
+          "format": "uri"
+        },
+        "description": {
+          "type": "string"
+        }
+      },
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "oauth2PasswordSecurity": {
+      "type": "object",
+      "additionalProperties": false,
+      "required": [
+        "type",
+        "flow",
+        "tokenUrl"
+      ],
+      "properties": {
+        "type": {
+          "type": "string",
+          "enum": [
+            "oauth2"
+          ]
+        },
+        "flow": {
+          "type": "string",
+          "enum": [
+            "password"
+          ]
+        },
+        "scopes": {
+          "$ref": "#/definitions/oauth2Scopes"
+        },
+        "tokenUrl": {
+          "type": "string",
+          "format": "uri"
+        },
+        "description": {
+          "type": "string"
+        }
+      },
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "oauth2ApplicationSecurity": {
+      "type": "object",
+      "additionalProperties": false,
+      "required": [
+        "type",
+        "flow",
+        "tokenUrl"
+      ],
+      "properties": {
+        "type": {
+          "type": "string",
+          "enum": [
+            "oauth2"
+          ]
+        },
+        "flow": {
+          "type": "string",
+          "enum": [
+            "application"
+          ]
+        },
+        "scopes": {
+          "$ref": "#/definitions/oauth2Scopes"
+        },
+        "tokenUrl": {
+          "type": "string",
+          "format": "uri"
+        },
+        "description": {
+          "type": "string"
+        }
+      },
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "oauth2AccessCodeSecurity": {
+      "type": "object",
+      "additionalProperties": false,
+      "required": [
+        "type",
+        "flow",
+        "authorizationUrl",
+        "tokenUrl"
+      ],
+      "properties": {
+        "type": {
+          "type": "string",
+          "enum": [
+            "oauth2"
+          ]
+        },
+        "flow": {
+          "type": "string",
+          "enum": [
+            "accessCode"
+          ]
+        },
+        "scopes": {
+          "$ref": "#/definitions/oauth2Scopes"
+        },
+        "authorizationUrl": {
+          "type": "string",
+          "format": "uri"
+        },
+        "tokenUrl": {
+          "type": "string",
+          "format": "uri"
+        },
+        "description": {
+          "type": "string"
+        }
+      },
+      "patternProperties": {
+        "^x-": {
+          "$ref": "#/definitions/vendorExtension"
+        }
+      }
+    },
+    "oauth2Scopes": {
+      "type": "object",
+      "additionalProperties": {
+        "type": "string"
+      }
+    },
+    "mediaTypeList": {
+      "type": "array",
+      "items": {
+        "$ref": "#/definitions/mimeType"
+      },
+      "uniqueItems": true
+    },
+    "parametersList": {
+      "type": "array",
+      "description": "The parameters needed to send a valid API call.",
+      "additionalItems": false,
+      "items": {
+        "oneOf": [
+          {
+            "$ref": "#/definitions/parameter"
+          },
+          {
+            "$ref": "#/definitions/jsonReference"
+          }
+        ]
+      },
+      "uniqueItems": true
+    },
+    "schemesList": {
+      "type": "array",
+      "description": "The transfer protocol of the API.",
+      "items": {
+        "type": "string",
+        "enum": [
+          "http",
+          "https",
+          "ws",
+          "wss"
+        ]
+      },
+      "uniqueItems": true
+    },
+    "collectionFormat": {
+      "type": "string",
+      "enum": [
+        "csv",
+        "ssv",
+        "tsv",
+        "pipes"
+      ],
+      "default": "csv"
+    },
+    "collectionFormatWithMulti": {
+      "type": "string",
+      "enum": [
+        "csv",
+        "ssv",
+        "tsv",
+        "pipes",
+        "multi"
+      ],
+      "default": "csv"
+    },
+    "title": {
+      "$ref": "http://json-schema.org/draft-04/schema#/properties/title"
+    },
+    "description": {
+      "$ref": "http://json-schema.org/draft-04/schema#/properties/description"
+    },
+    "default": {
+      "$ref": "http://json-schema.org/draft-04/schema#/properties/default"
+    },
+    "multipleOf": {
+      "$ref": "http://json-schema.org/draft-04/schema#/properties/multipleOf"
+    },
+    "maximum": {
+      "$ref": "http://json-schema.org/draft-04/schema#/properties/maximum"
+    },
+    "exclusiveMaximum": {
+      "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum"
+    },
+    "minimum": {
+      "$ref": "http://json-schema.org/draft-04/schema#/properties/minimum"
+    },
+    "exclusiveMinimum": {
+      "$ref": "http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum"
+    },
+    "maxLength": {
+      "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
+    },
+    "minLength": {
+      "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
+    },
+    "pattern": {
+      "$ref": "http://json-schema.org/draft-04/schema#/properties/pattern"
+    },
+    "maxItems": {
+      "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveInteger"
+    },
+    "minItems": {
+      "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
+    },
+    "uniqueItems": {
+      "$ref": "http://json-schema.org/draft-04/schema#/properties/uniqueItems"
+    },
+    "enum": {
+      "$ref": "http://json-schema.org/draft-04/schema#/properties/enum"
+    },
+    "jsonReference": {
+      "type": "object",
+      "required": [
+        "$ref"
+      ],
+      "additionalProperties": false,
+      "properties": {
+        "$ref": {
+          "type": "string"
+        }
+      }
+    }
+  }
+}
diff --git a/vendor/github.com/go-openapi/spec/spec.go b/vendor/github.com/go-openapi/spec/spec.go
index 7d38b6e6..876aa127 100644
--- a/vendor/github.com/go-openapi/spec/spec.go
+++ b/vendor/github.com/go-openapi/spec/spec.go
@@ -26,7 +26,7 @@ import (
 const (
 	// SwaggerSchemaURL the url for the swagger 2.0 schema to validate specs
 	SwaggerSchemaURL = "http://swagger.io/v2/schema.json#"
-	// JSONSchemaURL the url for the json schema schema
+	// JSONSchemaURL the url for the json schema
 	JSONSchemaURL = "http://json-schema.org/draft-04/schema#"
 )
 
@@ -41,7 +41,7 @@ func MustLoadJSONSchemaDraft04() *Schema {
 
 // JSONSchemaDraft04 loads the json schema document for json shema draft04
 func JSONSchemaDraft04() (*Schema, error) {
-	b, err := Asset("jsonschema-draft-04.json")
+	b, err := jsonschemaDraft04JSONBytes()
 	if err != nil {
 		return nil, err
 	}
@@ -65,7 +65,7 @@ func MustLoadSwagger20Schema() *Schema {
 // Swagger20Schema loads the swagger 2.0 schema from the embedded assets
 func Swagger20Schema() (*Schema, error) {
 
-	b, err := Asset("v2/schema.json")
+	b, err := v2SchemaJSONBytes()
 	if err != nil {
 		return nil, err
 	}
diff --git a/vendor/github.com/go-openapi/spec/swagger.go b/vendor/github.com/go-openapi/spec/swagger.go
index 44722ffd..1590fd17 100644
--- a/vendor/github.com/go-openapi/spec/swagger.go
+++ b/vendor/github.com/go-openapi/spec/swagger.go
@@ -253,7 +253,7 @@ func (s SchemaOrBool) MarshalJSON() ([]byte, error) {
 // UnmarshalJSON converts this bool or schema object from a JSON structure
 func (s *SchemaOrBool) UnmarshalJSON(data []byte) error {
 	var nw SchemaOrBool
-	if len(data) >= 4 {
+	if len(data) > 0 {
 		if data[0] == '{' {
 			var sch Schema
 			if err := json.Unmarshal(data, &sch); err != nil {
@@ -261,7 +261,7 @@ func (s *SchemaOrBool) UnmarshalJSON(data []byte) error {
 			}
 			nw.Schema = &sch
 		}
-		nw.Allows = !(data[0] == 'f' && data[1] == 'a' && data[2] == 'l' && data[3] == 's' && data[4] == 'e')
+		nw.Allows = !bytes.Equal(data, []byte("false"))
 	}
 	*s = nw
 	return nil
diff --git a/vendor/github.com/go-openapi/spec/url_go18.go b/vendor/github.com/go-openapi/spec/url_go18.go
deleted file mode 100644
index 60b78515..00000000
--- a/vendor/github.com/go-openapi/spec/url_go18.go
+++ /dev/null
@@ -1,8 +0,0 @@
-//go:build !go1.19
-// +build !go1.19
-
-package spec
-
-import "net/url"
-
-var parseURL = url.Parse
diff --git a/vendor/github.com/go-openapi/spec/url_go19.go b/vendor/github.com/go-openapi/spec/url_go19.go
index 392e3e63..5bdfe40b 100644
--- a/vendor/github.com/go-openapi/spec/url_go19.go
+++ b/vendor/github.com/go-openapi/spec/url_go19.go
@@ -1,6 +1,3 @@
-//go:build go1.19
-// +build go1.19
-
 package spec
 
 import "net/url"
diff --git a/vendor/github.com/go-openapi/strfmt/.golangci.yml b/vendor/github.com/go-openapi/strfmt/.golangci.yml
index be4899cb..22f8d21c 100644
--- a/vendor/github.com/go-openapi/strfmt/.golangci.yml
+++ b/vendor/github.com/go-openapi/strfmt/.golangci.yml
@@ -4,56 +4,58 @@ linters-settings:
   golint:
     min-confidence: 0
   gocyclo:
-    min-complexity: 31
+    min-complexity: 45
   maligned:
     suggest-new: true
   dupl:
-    threshold: 100
+    threshold: 200
   goconst:
     min-len: 2
-    min-occurrences: 4
+    min-occurrences: 3
 
 linters:
-  enable:
-    - revive
-    - goimports
-    - gosec
+  enable-all: true
+  disable:
+    - maligned
     - unparam
-    - unconvert
-    - predeclared
-    - prealloc
-    - misspell
-
-  # disable:
-  #   - maligned
-  #   - lll
-  #   - gochecknoinits
-  #   - gochecknoglobals
-  #   - godox
-  #   - gocognit
-  #   - whitespace
-  #   - wsl
-  #   - funlen
-  #   - wrapcheck
-  #   - testpackage
-  #   - nlreturn
-  #   - gofumpt
-  #   - goerr113
-  #   - gci
-  #   - gomnd
-  #   - godot
-  #   - exhaustivestruct
-  #   - paralleltest
-  #   - varnamelen
-  #   - ireturn
-  #   - exhaustruct
-  #   #- thelper
-
-issues:
-  exclude-rules:
-    - path: bson.go
-      text: "should be .*ObjectID"
-      linters:
-        - golint
-        - stylecheck
-
+    - lll
+    - gochecknoinits
+    - gochecknoglobals
+    - funlen
+    - godox
+    - gocognit
+    - whitespace
+    - wsl
+    - wrapcheck
+    - testpackage
+    - nlreturn
+    - gomnd
+    - exhaustivestruct
+    - goerr113
+    - errorlint
+    - nestif
+    - godot
+    - gofumpt
+    - paralleltest
+    - tparallel
+    - thelper
+    - ifshort
+    - exhaustruct
+    - varnamelen
+    - gci
+    - depguard
+    - errchkjson
+    - inamedparam
+    - nonamedreturns
+    - musttag
+    - ireturn
+    - forcetypeassert
+    - cyclop
+    # deprecated linters
+    - deadcode
+    - interfacer
+    - scopelint
+    - varcheck
+    - structcheck
+    - golint
+    - nosnakecase
diff --git a/vendor/github.com/go-openapi/strfmt/README.md b/vendor/github.com/go-openapi/strfmt/README.md
index 0cf89d77..f6b39c6c 100644
--- a/vendor/github.com/go-openapi/strfmt/README.md
+++ b/vendor/github.com/go-openapi/strfmt/README.md
@@ -1,8 +1,7 @@
-# Strfmt [![Build Status](https://travis-ci.org/go-openapi/strfmt.svg?branch=master)](https://travis-ci.org/go-openapi/strfmt) [![codecov](https://codecov.io/gh/go-openapi/strfmt/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/strfmt) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
-
+# Strfmt [![Build Status](https://github.com/go-openapi/strfmt/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/strfmt/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/strfmt/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/strfmt)
+[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
 [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/strfmt/master/LICENSE)
 [![GoDoc](https://godoc.org/github.com/go-openapi/strfmt?status.svg)](http://godoc.org/github.com/go-openapi/strfmt)
-[![GolangCI](https://golangci.com/badges/github.com/go-openapi/strfmt.svg)](https://golangci.com)
 [![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/strfmt)](https://goreportcard.com/report/github.com/go-openapi/strfmt)
 
 This package exposes a registry of data types to support string formats in the go-openapi toolkit.
diff --git a/vendor/github.com/go-openapi/strfmt/bson.go b/vendor/github.com/go-openapi/strfmt/bson.go
index a8a3604a..cfa9a526 100644
--- a/vendor/github.com/go-openapi/strfmt/bson.go
+++ b/vendor/github.com/go-openapi/strfmt/bson.go
@@ -39,10 +39,10 @@ func IsBSONObjectID(str string) bool {
 // ObjectId represents a BSON object ID (alias to go.mongodb.org/mongo-driver/bson/primitive.ObjectID)
 //
 // swagger:strfmt bsonobjectid
-type ObjectId bsonprim.ObjectID //nolint:revive
+type ObjectId bsonprim.ObjectID //nolint:revive,stylecheck
 
 // NewObjectId creates a ObjectId from a Hex String
-func NewObjectId(hex string) ObjectId { //nolint:revive
+func NewObjectId(hex string) ObjectId { //nolint:revive,stylecheck
 	oid, err := bsonprim.ObjectIDFromHex(hex)
 	if err != nil {
 		panic(err)
@@ -135,7 +135,7 @@ func (id *ObjectId) UnmarshalBSON(data []byte) error {
 // BSON document if the error is nil.
 func (id ObjectId) MarshalBSONValue() (bsontype.Type, []byte, error) {
 	oid := bsonprim.ObjectID(id)
-	return bsontype.ObjectID, oid[:], nil
+	return bson.TypeObjectID, oid[:], nil
 }
 
 // UnmarshalBSONValue is an interface implemented by types that can unmarshal a
diff --git a/vendor/github.com/go-openapi/strfmt/default.go b/vendor/github.com/go-openapi/strfmt/default.go
index a89a4de3..28137140 100644
--- a/vendor/github.com/go-openapi/strfmt/default.go
+++ b/vendor/github.com/go-openapi/strfmt/default.go
@@ -25,6 +25,7 @@ import (
 	"strings"
 
 	"github.com/asaskevich/govalidator"
+	"github.com/google/uuid"
 	"go.mongodb.org/mongo-driver/bson"
 )
 
@@ -57,24 +58,35 @@ const (
 	//   - long top-level domain names (e.g. example.london) are permitted
 	//   - symbol unicode points are permitted (e.g. emoji) (not for top-level domain)
 	HostnamePattern = `^([a-zA-Z0-9\p{S}\p{L}]((-?[a-zA-Z0-9\p{S}\p{L}]{0,62})?)|([a-zA-Z0-9\p{S}\p{L}](([a-zA-Z0-9-\p{S}\p{L}]{0,61}[a-zA-Z0-9\p{S}\p{L}])?)(\.)){1,}([a-zA-Z\p{L}]){2,63})$`
+
+	// json null type
+	jsonNull = "null"
+)
+
+const (
 	// UUIDPattern Regex for UUID that allows uppercase
-	UUIDPattern = `(?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$`
+	//
+	// Deprecated: strfmt no longer uses regular expressions to validate UUIDs.
+	UUIDPattern = `(?i)(^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$)|(^[0-9a-f]{32}$)`
+
 	// UUID3Pattern Regex for UUID3 that allows uppercase
-	UUID3Pattern = `(?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$`
+	//
+	// Deprecated: strfmt no longer uses regular expressions to validate UUIDs.
+	UUID3Pattern = `(?i)(^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$)|(^[0-9a-f]{12}3[0-9a-f]{3}?[0-9a-f]{16}$)`
+
 	// UUID4Pattern Regex for UUID4 that allows uppercase
-	UUID4Pattern = `(?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$`
+	//
+	// Deprecated: strfmt no longer uses regular expressions to validate UUIDs.
+	UUID4Pattern = `(?i)(^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$)|(^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$)`
+
 	// UUID5Pattern Regex for UUID5 that allows uppercase
-	UUID5Pattern = `(?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$`
-	// json null type
-	jsonNull = "null"
+	//
+	// Deprecated: strfmt no longer uses regular expressions to validate UUIDs.
+	UUID5Pattern = `(?i)(^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$)|(^[0-9a-f]{12}5[0-9a-f]{3}[89ab][0-9a-f]{15}$)`
 )
 
 var (
 	rxHostname = regexp.MustCompile(HostnamePattern)
-	rxUUID     = regexp.MustCompile(UUIDPattern)
-	rxUUID3    = regexp.MustCompile(UUID3Pattern)
-	rxUUID4    = regexp.MustCompile(UUID4Pattern)
-	rxUUID5    = regexp.MustCompile(UUID5Pattern)
 )
 
 // IsHostname returns true when the string is a valid hostname
@@ -99,24 +111,28 @@ func IsHostname(str string) bool {
 	return valid
 }
 
-// IsUUID returns true is the string matches a UUID, upper case is allowed
+// IsUUID returns true is the string matches a UUID (in any version, including v6 and v7), upper case is allowed
 func IsUUID(str string) bool {
-	return rxUUID.MatchString(str)
+	_, err := uuid.Parse(str)
+	return err == nil
 }
 
-// IsUUID3 returns true is the string matches a UUID, upper case is allowed
+// IsUUID3 returns true is the string matches a UUID v3, upper case is allowed
 func IsUUID3(str string) bool {
-	return rxUUID3.MatchString(str)
+	id, err := uuid.Parse(str)
+	return err == nil && id.Version() == uuid.Version(3)
 }
 
-// IsUUID4 returns true is the string matches a UUID, upper case is allowed
+// IsUUID4 returns true is the string matches a UUID v4, upper case is allowed
 func IsUUID4(str string) bool {
-	return rxUUID4.MatchString(str)
+	id, err := uuid.Parse(str)
+	return err == nil && id.Version() == uuid.Version(4)
 }
 
-// IsUUID5 returns true is the string matches a UUID, upper case is allowed
+// IsUUID5 returns true is the string matches a UUID v5, upper case is allowed
 func IsUUID5(str string) bool {
-	return rxUUID5.MatchString(str)
+	id, err := uuid.Parse(str)
+	return err == nil && id.Version() == uuid.Version(5)
 }
 
 // IsEmail validates an email address.
diff --git a/vendor/github.com/go-openapi/strfmt/format.go b/vendor/github.com/go-openapi/strfmt/format.go
index ad3b3c35..888e107c 100644
--- a/vendor/github.com/go-openapi/strfmt/format.go
+++ b/vendor/github.com/go-openapi/strfmt/format.go
@@ -16,6 +16,7 @@ package strfmt
 
 import (
 	"encoding"
+	stderrors "errors"
 	"fmt"
 	"reflect"
 	"strings"
@@ -94,7 +95,7 @@ func NewSeededFormats(seeds []knownFormat, normalizer NameNormalizer) Registry {
 }
 
 // MapStructureHookFunc is a decode hook function for mapstructure
-func (f *defaultFormats) MapStructureHookFunc() mapstructure.DecodeHookFunc { //nolint:gocyclo,cyclop
+func (f *defaultFormats) MapStructureHookFunc() mapstructure.DecodeHookFunc {
 	return func(from reflect.Type, to reflect.Type, obj interface{}) (interface{}, error) {
 		if from.Kind() != reflect.String {
 			return obj, nil
@@ -117,7 +118,7 @@ func (f *defaultFormats) MapStructureHookFunc() mapstructure.DecodeHookFunc { //
 				case "datetime":
 					input := data
 					if len(input) == 0 {
-						return nil, fmt.Errorf("empty string is an invalid datetime format")
+						return nil, stderrors.New("empty string is an invalid datetime format")
 					}
 					return ParseDateTime(input)
 				case "duration":
diff --git a/vendor/github.com/go-openapi/strfmt/time.go b/vendor/github.com/go-openapi/strfmt/time.go
index 9bef4c3b..f08ba4da 100644
--- a/vendor/github.com/go-openapi/strfmt/time.go
+++ b/vendor/github.com/go-openapi/strfmt/time.go
@@ -76,6 +76,8 @@ const (
 	ISO8601TimeWithReducedPrecisionLocaltime = "2006-01-02T15:04"
 	// ISO8601TimeUniversalSortableDateTimePattern represents a ISO8601 universal sortable date time pattern.
 	ISO8601TimeUniversalSortableDateTimePattern = "2006-01-02 15:04:05"
+	// short form of ISO8601TimeUniversalSortableDateTimePattern
+	ISO8601TimeUniversalSortableDateTimePatternShortForm = "2006-01-02"
 	// DateTimePattern pattern to match for the date-time format from http://tools.ietf.org/html/rfc3339#section-5.6
 	DateTimePattern = `^([0-9]{2}):([0-9]{2}):([0-9]{2})(.[0-9]+)?(z|([+-][0-9]{2}:[0-9]{2}))$`
 )
@@ -84,7 +86,7 @@ var (
 	rxDateTime = regexp.MustCompile(DateTimePattern)
 
 	// DateTimeFormats is the collection of formats used by ParseDateTime()
-	DateTimeFormats = []string{RFC3339Micro, RFC3339MicroNoColon, RFC3339Millis, RFC3339MillisNoColon, time.RFC3339, time.RFC3339Nano, ISO8601LocalTime, ISO8601TimeWithReducedPrecision, ISO8601TimeWithReducedPrecisionLocaltime, ISO8601TimeUniversalSortableDateTimePattern}
+	DateTimeFormats = []string{RFC3339Micro, RFC3339MicroNoColon, RFC3339Millis, RFC3339MillisNoColon, time.RFC3339, time.RFC3339Nano, ISO8601LocalTime, ISO8601TimeWithReducedPrecision, ISO8601TimeWithReducedPrecisionLocaltime, ISO8601TimeUniversalSortableDateTimePattern, ISO8601TimeUniversalSortableDateTimePatternShortForm}
 
 	// MarshalFormat sets the time resolution format used for marshaling time (set to milliseconds)
 	MarshalFormat = RFC3339Millis
@@ -245,7 +247,7 @@ func (t DateTime) MarshalBSONValue() (bsontype.Type, []byte, error) {
 	buf := make([]byte, 8)
 	binary.LittleEndian.PutUint64(buf, uint64(i64))
 
-	return bsontype.DateTime, buf, nil
+	return bson.TypeDateTime, buf, nil
 }
 
 // UnmarshalBSONValue is an interface implemented by types that can unmarshal a
@@ -253,7 +255,7 @@ func (t DateTime) MarshalBSONValue() (bsontype.Type, []byte, error) {
 // assumed to be valid. UnmarshalBSONValue must copy the BSON value bytes if it
 // wishes to retain the data after returning.
 func (t *DateTime) UnmarshalBSONValue(tpe bsontype.Type, data []byte) error {
-	if tpe == bsontype.Null {
+	if tpe == bson.TypeNull {
 		*t = DateTime{}
 		return nil
 	}
diff --git a/vendor/github.com/go-openapi/swag/.gitignore b/vendor/github.com/go-openapi/swag/.gitignore
index d69b53ac..c4b1b64f 100644
--- a/vendor/github.com/go-openapi/swag/.gitignore
+++ b/vendor/github.com/go-openapi/swag/.gitignore
@@ -2,3 +2,4 @@ secrets.yml
 vendor
 Godeps
 .idea
+*.out
diff --git a/vendor/github.com/go-openapi/swag/.golangci.yml b/vendor/github.com/go-openapi/swag/.golangci.yml
index bf503e40..80e2be00 100644
--- a/vendor/github.com/go-openapi/swag/.golangci.yml
+++ b/vendor/github.com/go-openapi/swag/.golangci.yml
@@ -4,14 +4,14 @@ linters-settings:
   golint:
     min-confidence: 0
   gocyclo:
-    min-complexity: 25
+    min-complexity: 45
   maligned:
     suggest-new: true
   dupl:
-    threshold: 100
+    threshold: 200
   goconst:
     min-len: 3
-    min-occurrences: 2
+    min-occurrences: 3
 
 linters:
   enable-all: true
@@ -20,35 +20,41 @@ linters:
     - lll
     - gochecknoinits
     - gochecknoglobals
-    - nlreturn
-    - testpackage
+    - funlen
+    - godox
+    - gocognit
+    - whitespace
+    - wsl
     - wrapcheck
+    - testpackage
+    - nlreturn
     - gomnd
-    - exhaustive
     - exhaustivestruct
     - goerr113
-    - wsl
-    - whitespace
-    - gofumpt
-    - godot
+    - errorlint
     - nestif
-    - godox
-    - funlen
-    - gci
-    - gocognit
+    - godot
+    - gofumpt
     - paralleltest
+    - tparallel
     - thelper
     - ifshort
-    - gomoddirectives
-    - cyclop
-    - forcetypeassert
-    - ireturn
-    - tagliatelle
-    - varnamelen
-    - goimports
-    - tenv
-    - golint
     - exhaustruct
-    - nilnil
+    - varnamelen
+    - gci
+    - depguard
+    - errchkjson
+    - inamedparam
     - nonamedreturns
+    - musttag
+    - ireturn
+    - forcetypeassert
+    - cyclop
+    # deprecated linters
+    - deadcode
+    - interfacer
+    - scopelint
+    - varcheck
+    - structcheck
+    - golint
     - nosnakecase
diff --git a/vendor/github.com/go-openapi/swag/BENCHMARK.md b/vendor/github.com/go-openapi/swag/BENCHMARK.md
new file mode 100644
index 00000000..e7f28ed6
--- /dev/null
+++ b/vendor/github.com/go-openapi/swag/BENCHMARK.md
@@ -0,0 +1,52 @@
+# Benchmarks
+
+## Name mangling utilities
+
+```bash
+go test -bench XXX -run XXX -benchtime 30s
+```
+
+### Benchmarks at b3e7a5386f996177e4808f11acb2aa93a0f660df
+
+```
+goos: linux
+goarch: amd64
+pkg: github.com/go-openapi/swag
+cpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
+BenchmarkToXXXName/ToGoName-4         	  862623	     44101 ns/op	   10450 B/op	     732 allocs/op
+BenchmarkToXXXName/ToVarName-4        	  853656	     40728 ns/op	   10468 B/op	     734 allocs/op
+BenchmarkToXXXName/ToFileName-4       	 1268312	     27813 ns/op	    9785 B/op	     617 allocs/op
+BenchmarkToXXXName/ToCommandName-4    	 1276322	     27903 ns/op	    9785 B/op	     617 allocs/op
+BenchmarkToXXXName/ToHumanNameLower-4 	  895334	     40354 ns/op	   10472 B/op	     731 allocs/op
+BenchmarkToXXXName/ToHumanNameTitle-4 	  882441	     40678 ns/op	   10566 B/op	     749 allocs/op
+```
+
+### Benchmarks after PR #79
+
+~ x10 performance improvement and ~ /100 memory allocations.
+
+```
+goos: linux
+goarch: amd64
+pkg: github.com/go-openapi/swag
+cpu: Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
+BenchmarkToXXXName/ToGoName-4         	 9595830	      3991 ns/op	      42 B/op	       5 allocs/op
+BenchmarkToXXXName/ToVarName-4        	 9194276	      3984 ns/op	      62 B/op	       7 allocs/op
+BenchmarkToXXXName/ToFileName-4       	17002711	      2123 ns/op	     147 B/op	       7 allocs/op
+BenchmarkToXXXName/ToCommandName-4    	16772926	      2111 ns/op	     147 B/op	       7 allocs/op
+BenchmarkToXXXName/ToHumanNameLower-4 	 9788331	      3749 ns/op	      92 B/op	       6 allocs/op
+BenchmarkToXXXName/ToHumanNameTitle-4 	 9188260	      3941 ns/op	     104 B/op	       6 allocs/op
+```
+
+```
+goos: linux
+goarch: amd64
+pkg: github.com/go-openapi/swag
+cpu: AMD Ryzen 7 5800X 8-Core Processor             
+BenchmarkToXXXName/ToGoName-16         	18527378	      1972 ns/op	      42 B/op	       5 allocs/op
+BenchmarkToXXXName/ToVarName-16        	15552692	      2093 ns/op	      62 B/op	       7 allocs/op
+BenchmarkToXXXName/ToFileName-16       	32161176	      1117 ns/op	     147 B/op	       7 allocs/op
+BenchmarkToXXXName/ToCommandName-16    	32256634	      1137 ns/op	     147 B/op	       7 allocs/op
+BenchmarkToXXXName/ToHumanNameLower-16 	18599661	      1946 ns/op	      92 B/op	       6 allocs/op
+BenchmarkToXXXName/ToHumanNameTitle-16 	17581353	      2054 ns/op	     105 B/op	       6 allocs/op
+```
diff --git a/vendor/github.com/go-openapi/swag/README.md b/vendor/github.com/go-openapi/swag/README.md
index 217f6fa5..a7292229 100644
--- a/vendor/github.com/go-openapi/swag/README.md
+++ b/vendor/github.com/go-openapi/swag/README.md
@@ -1,7 +1,8 @@
-# Swag [![Build Status](https://travis-ci.org/go-openapi/swag.svg?branch=master)](https://travis-ci.org/go-openapi/swag) [![codecov](https://codecov.io/gh/go-openapi/swag/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/swag) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
+# Swag [![Build Status](https://github.com/go-openapi/swag/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/swag/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/swag/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/swag)
 
+[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
 [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE)
-[![GoDoc](https://godoc.org/github.com/go-openapi/swag?status.svg)](http://godoc.org/github.com/go-openapi/swag)
+[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/swag.svg)](https://pkg.go.dev/github.com/go-openapi/swag)
 [![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/swag)](https://goreportcard.com/report/github.com/go-openapi/swag)
 
 Contains a bunch of helper functions for go-openapi and go-swagger projects.
@@ -18,4 +19,5 @@ You may also use it standalone for your projects.
 
 This repo has only few dependencies outside of the standard library:
 
-* YAML utilities depend on gopkg.in/yaml.v2
+* YAML utilities depend on `gopkg.in/yaml.v3`
+* `github.com/mailru/easyjson v0.7.7`
diff --git a/vendor/github.com/go-openapi/swag/initialism_index.go b/vendor/github.com/go-openapi/swag/initialism_index.go
new file mode 100644
index 00000000..20a359bb
--- /dev/null
+++ b/vendor/github.com/go-openapi/swag/initialism_index.go
@@ -0,0 +1,202 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 swag
+
+import (
+	"sort"
+	"strings"
+	"sync"
+)
+
+var (
+	// commonInitialisms are common acronyms that are kept as whole uppercased words.
+	commonInitialisms *indexOfInitialisms
+
+	// initialisms is a slice of sorted initialisms
+	initialisms []string
+
+	// a copy of initialisms pre-baked as []rune
+	initialismsRunes      [][]rune
+	initialismsUpperCased [][]rune
+
+	isInitialism func(string) bool
+
+	maxAllocMatches int
+)
+
+func init() {
+	// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
+	configuredInitialisms := map[string]bool{
+		"ACL":   true,
+		"API":   true,
+		"ASCII": true,
+		"CPU":   true,
+		"CSS":   true,
+		"DNS":   true,
+		"EOF":   true,
+		"GUID":  true,
+		"HTML":  true,
+		"HTTPS": true,
+		"HTTP":  true,
+		"ID":    true,
+		"IP":    true,
+		"IPv4":  true,
+		"IPv6":  true,
+		"JSON":  true,
+		"LHS":   true,
+		"OAI":   true,
+		"QPS":   true,
+		"RAM":   true,
+		"RHS":   true,
+		"RPC":   true,
+		"SLA":   true,
+		"SMTP":  true,
+		"SQL":   true,
+		"SSH":   true,
+		"TCP":   true,
+		"TLS":   true,
+		"TTL":   true,
+		"UDP":   true,
+		"UI":    true,
+		"UID":   true,
+		"UUID":  true,
+		"URI":   true,
+		"URL":   true,
+		"UTF8":  true,
+		"VM":    true,
+		"XML":   true,
+		"XMPP":  true,
+		"XSRF":  true,
+		"XSS":   true,
+	}
+
+	// a thread-safe index of initialisms
+	commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
+	initialisms = commonInitialisms.sorted()
+	initialismsRunes = asRunes(initialisms)
+	initialismsUpperCased = asUpperCased(initialisms)
+	maxAllocMatches = maxAllocHeuristic(initialismsRunes)
+
+	// a test function
+	isInitialism = commonInitialisms.isInitialism
+}
+
+func asRunes(in []string) [][]rune {
+	out := make([][]rune, len(in))
+	for i, initialism := range in {
+		out[i] = []rune(initialism)
+	}
+
+	return out
+}
+
+func asUpperCased(in []string) [][]rune {
+	out := make([][]rune, len(in))
+
+	for i, initialism := range in {
+		out[i] = []rune(upper(trim(initialism)))
+	}
+
+	return out
+}
+
+func maxAllocHeuristic(in [][]rune) int {
+	heuristic := make(map[rune]int)
+	for _, initialism := range in {
+		heuristic[initialism[0]]++
+	}
+
+	var maxAlloc int
+	for _, val := range heuristic {
+		if val > maxAlloc {
+			maxAlloc = val
+		}
+	}
+
+	return maxAlloc
+}
+
+// AddInitialisms add additional initialisms
+func AddInitialisms(words ...string) {
+	for _, word := range words {
+		// commonInitialisms[upper(word)] = true
+		commonInitialisms.add(upper(word))
+	}
+	// sort again
+	initialisms = commonInitialisms.sorted()
+	initialismsRunes = asRunes(initialisms)
+	initialismsUpperCased = asUpperCased(initialisms)
+}
+
+// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
+// Since go1.9, this may be implemented with sync.Map.
+type indexOfInitialisms struct {
+	sortMutex *sync.Mutex
+	index     *sync.Map
+}
+
+func newIndexOfInitialisms() *indexOfInitialisms {
+	return &indexOfInitialisms{
+		sortMutex: new(sync.Mutex),
+		index:     new(sync.Map),
+	}
+}
+
+func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
+	m.sortMutex.Lock()
+	defer m.sortMutex.Unlock()
+	for k, v := range initial {
+		m.index.Store(k, v)
+	}
+	return m
+}
+
+func (m *indexOfInitialisms) isInitialism(key string) bool {
+	_, ok := m.index.Load(key)
+	return ok
+}
+
+func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
+	m.index.Store(key, true)
+	return m
+}
+
+func (m *indexOfInitialisms) sorted() (result []string) {
+	m.sortMutex.Lock()
+	defer m.sortMutex.Unlock()
+	m.index.Range(func(key, _ interface{}) bool {
+		k := key.(string)
+		result = append(result, k)
+		return true
+	})
+	sort.Sort(sort.Reverse(byInitialism(result)))
+	return
+}
+
+type byInitialism []string
+
+func (s byInitialism) Len() int {
+	return len(s)
+}
+func (s byInitialism) Swap(i, j int) {
+	s[i], s[j] = s[j], s[i]
+}
+func (s byInitialism) Less(i, j int) bool {
+	if len(s[i]) != len(s[j]) {
+		return len(s[i]) < len(s[j])
+	}
+
+	return strings.Compare(s[i], s[j]) > 0
+}
diff --git a/vendor/github.com/go-openapi/swag/loading.go b/vendor/github.com/go-openapi/swag/loading.go
index 00038c37..783442fd 100644
--- a/vendor/github.com/go-openapi/swag/loading.go
+++ b/vendor/github.com/go-openapi/swag/loading.go
@@ -21,6 +21,7 @@ import (
 	"net/http"
 	"net/url"
 	"os"
+	"path"
 	"path/filepath"
 	"runtime"
 	"strings"
@@ -40,43 +41,97 @@ var LoadHTTPBasicAuthPassword = ""
 var LoadHTTPCustomHeaders = map[string]string{}
 
 // LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in
-func LoadFromFileOrHTTP(path string) ([]byte, error) {
-	return LoadStrategy(path, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path)
+func LoadFromFileOrHTTP(pth string) ([]byte, error) {
+	return LoadStrategy(pth, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(pth)
 }
 
 // LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in
 // timeout arg allows for per request overriding of the request timeout
-func LoadFromFileOrHTTPWithTimeout(path string, timeout time.Duration) ([]byte, error) {
-	return LoadStrategy(path, os.ReadFile, loadHTTPBytes(timeout))(path)
+func LoadFromFileOrHTTPWithTimeout(pth string, timeout time.Duration) ([]byte, error) {
+	return LoadStrategy(pth, os.ReadFile, loadHTTPBytes(timeout))(pth)
 }
 
-// LoadStrategy returns a loader function for a given path or uri
-func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) {
-	if strings.HasPrefix(path, "http") {
+// LoadStrategy returns a loader function for a given path or URI.
+//
+// The load strategy returns the remote load for any path starting with `http`.
+// So this works for any URI with a scheme `http` or `https`.
+//
+// The fallback strategy is to call the local loader.
+//
+// The local loader takes a local file system path (absolute or relative) as argument,
+// or alternatively a `file://...` URI, **without host** (see also below for windows).
+//
+// There are a few liberalities, initially intended to be tolerant regarding the URI syntax,
+// especially on windows.
+//
+// Before the local loader is called, the given path is transformed:
+//   - percent-encoded characters are unescaped
+//   - simple paths (e.g. `./folder/file`) are passed as-is
+//   - on windows, occurrences of `/` are replaced by `\`, so providing a relative path such a `folder/file` works too.
+//
+// For paths provided as URIs with the "file" scheme, please note that:
+//   - `file://` is simply stripped.
+//     This means that the host part of the URI is not parsed at all.
+//     For example, `file:///folder/file" becomes "/folder/file`,
+//     but `file://localhost/folder/file` becomes `localhost/folder/file` on unix systems.
+//     Similarly, `file://./folder/file` yields `./folder/file`.
+//   - on windows, `file://...` can take a host so as to specify an UNC share location.
+//
+// Reminder about windows-specifics:
+// - `file://host/folder/file` becomes an UNC path like `\\host\folder\file` (no port specification is supported)
+// - `file:///c:/folder/file` becomes `C:\folder\file`
+// - `file://c:/folder/file` is tolerated (without leading `/`) and becomes `c:\folder\file`
+func LoadStrategy(pth string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) {
+	if strings.HasPrefix(pth, "http") {
 		return remote
 	}
-	return func(pth string) ([]byte, error) {
-		upth, err := pathUnescape(pth)
+
+	return func(p string) ([]byte, error) {
+		upth, err := url.PathUnescape(p)
 		if err != nil {
 			return nil, err
 		}
 
-		if strings.HasPrefix(pth, `file://`) {
-			if runtime.GOOS == "windows" {
-				// support for canonical file URIs on windows.
-				// Zero tolerance here for dodgy URIs.
-				u, _ := url.Parse(upth)
-				if u.Host != "" {
-					// assume UNC name (volume share)
-					// file://host/share/folder\... ==> \\host\share\path\folder
-					// NOTE: UNC port not yet supported
-					upth = strings.Join([]string{`\`, u.Host, u.Path}, `\`)
-				} else {
-					// file:///c:/folder/... ==> just remove the leading slash
-					upth = strings.TrimPrefix(upth, `file:///`)
-				}
-			} else {
-				upth = strings.TrimPrefix(upth, `file://`)
+		if !strings.HasPrefix(p, `file://`) {
+			// regular file path provided: just normalize slashes
+			return local(filepath.FromSlash(upth))
+		}
+
+		if runtime.GOOS != "windows" {
+			// crude processing: this leaves full URIs with a host with a (mostly) unexpected result
+			upth = strings.TrimPrefix(upth, `file://`)
+
+			return local(filepath.FromSlash(upth))
+		}
+
+		// windows-only pre-processing of file://... URIs
+
+		// support for canonical file URIs on windows.
+		u, err := url.Parse(filepath.ToSlash(upth))
+		if err != nil {
+			return nil, err
+		}
+
+		if u.Host != "" {
+			// assume UNC name (volume share)
+			// NOTE: UNC port not yet supported
+
+			// when the "host" segment is a drive letter:
+			// file://C:/folder/... => C:\folder
+			upth = path.Clean(strings.Join([]string{u.Host, u.Path}, `/`))
+			if !strings.HasSuffix(u.Host, ":") && u.Host[0] != '.' {
+				// tolerance: if we have a leading dot, this can't be a host
+				// file://host/share/folder\... ==> \\host\share\path\folder
+				upth = "//" + upth
+			}
+		} else {
+			// no host, let's figure out if this is a drive letter
+			upth = strings.TrimPrefix(upth, `file://`)
+			first, _, _ := strings.Cut(strings.TrimPrefix(u.Path, "/"), "/")
+			if strings.HasSuffix(first, ":") {
+				// drive letter in the first segment:
+				// file:///c:/folder/... ==> strip the leading slash
+				upth = strings.TrimPrefix(upth, `/`)
 			}
 		}
 
diff --git a/vendor/github.com/go-openapi/swag/name_lexem.go b/vendor/github.com/go-openapi/swag/name_lexem.go
index aa7f6a9b..8bb64ac3 100644
--- a/vendor/github.com/go-openapi/swag/name_lexem.go
+++ b/vendor/github.com/go-openapi/swag/name_lexem.go
@@ -14,74 +14,80 @@
 
 package swag
 
-import "unicode"
+import (
+	"unicode"
+	"unicode/utf8"
+)
 
 type (
-	nameLexem interface {
-		GetUnsafeGoName() string
-		GetOriginal() string
-		IsInitialism() bool
-	}
+	lexemKind uint8
 
-	initialismNameLexem struct {
+	nameLexem struct {
 		original          string
 		matchedInitialism string
+		kind              lexemKind
 	}
+)
 
-	casualNameLexem struct {
-		original string
-	}
+const (
+	lexemKindCasualName lexemKind = iota
+	lexemKindInitialismName
 )
 
-func newInitialismNameLexem(original, matchedInitialism string) *initialismNameLexem {
-	return &initialismNameLexem{
+func newInitialismNameLexem(original, matchedInitialism string) nameLexem {
+	return nameLexem{
+		kind:              lexemKindInitialismName,
 		original:          original,
 		matchedInitialism: matchedInitialism,
 	}
 }
 
-func newCasualNameLexem(original string) *casualNameLexem {
-	return &casualNameLexem{
+func newCasualNameLexem(original string) nameLexem {
+	return nameLexem{
+		kind:     lexemKindCasualName,
 		original: original,
 	}
 }
 
-func (l *initialismNameLexem) GetUnsafeGoName() string {
-	return l.matchedInitialism
-}
+func (l nameLexem) GetUnsafeGoName() string {
+	if l.kind == lexemKindInitialismName {
+		return l.matchedInitialism
+	}
+
+	var (
+		first rune
+		rest  string
+	)
 
-func (l *casualNameLexem) GetUnsafeGoName() string {
-	var first rune
-	var rest string
 	for i, orig := range l.original {
 		if i == 0 {
 			first = orig
 			continue
 		}
+
 		if i > 0 {
 			rest = l.original[i:]
 			break
 		}
 	}
+
 	if len(l.original) > 1 {
-		return string(unicode.ToUpper(first)) + lower(rest)
+		b := poolOfBuffers.BorrowBuffer(utf8.UTFMax + len(rest))
+		defer func() {
+			poolOfBuffers.RedeemBuffer(b)
+		}()
+		b.WriteRune(unicode.ToUpper(first))
+		b.WriteString(lower(rest))
+		return b.String()
 	}
 
 	return l.original
 }
 
-func (l *initialismNameLexem) GetOriginal() string {
+func (l nameLexem) GetOriginal() string {
 	return l.original
 }
 
-func (l *casualNameLexem) GetOriginal() string {
-	return l.original
-}
-
-func (l *initialismNameLexem) IsInitialism() bool {
-	return true
-}
-
-func (l *casualNameLexem) IsInitialism() bool {
-	return false
+func (l nameLexem) IsInitialism() bool {
+	return l.kind == lexemKindInitialismName
 }
diff --git a/vendor/github.com/go-openapi/swag/post_go18.go b/vendor/github.com/go-openapi/swag/post_go18.go
deleted file mode 100644
index f5228b82..00000000
--- a/vendor/github.com/go-openapi/swag/post_go18.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2015 go-swagger maintainers
-//
-// 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 go1.8
-// +build go1.8
-
-package swag
-
-import "net/url"
-
-func pathUnescape(path string) (string, error) {
-	return url.PathUnescape(path)
-}
diff --git a/vendor/github.com/go-openapi/swag/post_go19.go b/vendor/github.com/go-openapi/swag/post_go19.go
deleted file mode 100644
index 7c7da9c0..00000000
--- a/vendor/github.com/go-openapi/swag/post_go19.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2015 go-swagger maintainers
-//
-// 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 go1.9
-// +build go1.9
-
-package swag
-
-import (
-	"sort"
-	"sync"
-)
-
-// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
-// Since go1.9, this may be implemented with sync.Map.
-type indexOfInitialisms struct {
-	sortMutex *sync.Mutex
-	index     *sync.Map
-}
-
-func newIndexOfInitialisms() *indexOfInitialisms {
-	return &indexOfInitialisms{
-		sortMutex: new(sync.Mutex),
-		index:     new(sync.Map),
-	}
-}
-
-func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
-	m.sortMutex.Lock()
-	defer m.sortMutex.Unlock()
-	for k, v := range initial {
-		m.index.Store(k, v)
-	}
-	return m
-}
-
-func (m *indexOfInitialisms) isInitialism(key string) bool {
-	_, ok := m.index.Load(key)
-	return ok
-}
-
-func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
-	m.index.Store(key, true)
-	return m
-}
-
-func (m *indexOfInitialisms) sorted() (result []string) {
-	m.sortMutex.Lock()
-	defer m.sortMutex.Unlock()
-	m.index.Range(func(key, value interface{}) bool {
-		k := key.(string)
-		result = append(result, k)
-		return true
-	})
-	sort.Sort(sort.Reverse(byInitialism(result)))
-	return
-}
diff --git a/vendor/github.com/go-openapi/swag/pre_go18.go b/vendor/github.com/go-openapi/swag/pre_go18.go
deleted file mode 100644
index 2757d9b9..00000000
--- a/vendor/github.com/go-openapi/swag/pre_go18.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2015 go-swagger maintainers
-//
-// 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 !go1.8
-// +build !go1.8
-
-package swag
-
-import "net/url"
-
-func pathUnescape(path string) (string, error) {
-	return url.QueryUnescape(path)
-}
diff --git a/vendor/github.com/go-openapi/swag/pre_go19.go b/vendor/github.com/go-openapi/swag/pre_go19.go
deleted file mode 100644
index 0565db37..00000000
--- a/vendor/github.com/go-openapi/swag/pre_go19.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2015 go-swagger maintainers
-//
-// 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 !go1.9
-// +build !go1.9
-
-package swag
-
-import (
-	"sort"
-	"sync"
-)
-
-// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
-// Before go1.9, this may be implemented with a mutex on the map.
-type indexOfInitialisms struct {
-	getMutex *sync.Mutex
-	index    map[string]bool
-}
-
-func newIndexOfInitialisms() *indexOfInitialisms {
-	return &indexOfInitialisms{
-		getMutex: new(sync.Mutex),
-		index:    make(map[string]bool, 50),
-	}
-}
-
-func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
-	m.getMutex.Lock()
-	defer m.getMutex.Unlock()
-	for k, v := range initial {
-		m.index[k] = v
-	}
-	return m
-}
-
-func (m *indexOfInitialisms) isInitialism(key string) bool {
-	m.getMutex.Lock()
-	defer m.getMutex.Unlock()
-	_, ok := m.index[key]
-	return ok
-}
-
-func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
-	m.getMutex.Lock()
-	defer m.getMutex.Unlock()
-	m.index[key] = true
-	return m
-}
-
-func (m *indexOfInitialisms) sorted() (result []string) {
-	m.getMutex.Lock()
-	defer m.getMutex.Unlock()
-	for k := range m.index {
-		result = append(result, k)
-	}
-	sort.Sort(sort.Reverse(byInitialism(result)))
-	return
-}
diff --git a/vendor/github.com/go-openapi/swag/split.go b/vendor/github.com/go-openapi/swag/split.go
index a1825fb7..274727a8 100644
--- a/vendor/github.com/go-openapi/swag/split.go
+++ b/vendor/github.com/go-openapi/swag/split.go
@@ -15,124 +15,269 @@
 package swag
 
 import (
+	"bytes"
+	"sync"
 	"unicode"
+	"unicode/utf8"
 )
 
-var nameReplaceTable = map[rune]string{
-	'@': "At ",
-	'&': "And ",
-	'|': "Pipe ",
-	'$': "Dollar ",
-	'!': "Bang ",
-	'-': "",
-	'_': "",
-}
-
 type (
 	splitter struct {
-		postSplitInitialismCheck bool
 		initialisms              []string
+		initialismsRunes         [][]rune
+		initialismsUpperCased    [][]rune // initialisms cached in their trimmed, upper-cased version
+		postSplitInitialismCheck bool
+	}
+
+	splitterOption func(*splitter)
+
+	initialismMatch struct {
+		body       []rune
+		start, end int
+		complete   bool
+	}
+	initialismMatches []initialismMatch
+)
+
+type (
+	// memory pools of temporary objects.
+	//
+	// These are used to recycle temporarily allocated objects
+	// and relieve the GC from undue pressure.
+
+	matchesPool struct {
+		*sync.Pool
 	}
 
-	splitterOption func(*splitter) *splitter
+	buffersPool struct {
+		*sync.Pool
+	}
+
+	lexemsPool struct {
+		*sync.Pool
+	}
+
+	splittersPool struct {
+		*sync.Pool
+	}
 )
 
-// split calls the splitter; splitter provides more control and post options
+var (
+	// poolOfMatches holds temporary slices for recycling during the initialism match process
+	poolOfMatches = matchesPool{
+		Pool: &sync.Pool{
+			New: func() any {
+				s := make(initialismMatches, 0, maxAllocMatches)
+
+				return &s
+			},
+		},
+	}
+
+	poolOfBuffers = buffersPool{
+		Pool: &sync.Pool{
+			New: func() any {
+				return new(bytes.Buffer)
+			},
+		},
+	}
+
+	poolOfLexems = lexemsPool{
+		Pool: &sync.Pool{
+			New: func() any {
+				s := make([]nameLexem, 0, maxAllocMatches)
+
+				return &s
+			},
+		},
+	}
+
+	poolOfSplitters = splittersPool{
+		Pool: &sync.Pool{
+			New: func() any {
+				s := newSplitter()
+
+				return &s
+			},
+		},
+	}
+)
+
+// nameReplaceTable finds a word representation for special characters.
+func nameReplaceTable(r rune) (string, bool) {
+	switch r {
+	case '@':
+		return "At ", true
+	case '&':
+		return "And ", true
+	case '|':
+		return "Pipe ", true
+	case '$':
+		return "Dollar ", true
+	case '!':
+		return "Bang ", true
+	case '-':
+		return "", true
+	case '_':
+		return "", true
+	default:
+		return "", false
+	}
+}
+
+// split calls the splitter.
+//
+// Use newSplitter for more control and options
 func split(str string) []string {
-	lexems := newSplitter().split(str)
-	result := make([]string, 0, len(lexems))
+	s := poolOfSplitters.BorrowSplitter()
+	lexems := s.split(str)
+	result := make([]string, 0, len(*lexems))
 
-	for _, lexem := range lexems {
+	for _, lexem := range *lexems {
 		result = append(result, lexem.GetOriginal())
 	}
+	poolOfLexems.RedeemLexems(lexems)
+	poolOfSplitters.RedeemSplitter(s)
 
 	return result
 
 }
 
-func (s *splitter) split(str string) []nameLexem {
-	return s.toNameLexems(str)
-}
-
-func newSplitter(options ...splitterOption) *splitter {
-	splitter := &splitter{
+func newSplitter(options ...splitterOption) splitter {
+	s := splitter{
 		postSplitInitialismCheck: false,
 		initialisms:              initialisms,
+		initialismsRunes:         initialismsRunes,
+		initialismsUpperCased:    initialismsUpperCased,
 	}
 
 	for _, option := range options {
-		splitter = option(splitter)
+		option(&s)
 	}
 
-	return splitter
+	return s
 }
 
 // withPostSplitInitialismCheck allows to catch initialisms after main split process
-func withPostSplitInitialismCheck(s *splitter) *splitter {
+func withPostSplitInitialismCheck(s *splitter) {
 	s.postSplitInitialismCheck = true
+}
+
+func (p matchesPool) BorrowMatches() *initialismMatches {
+	s := p.Get().(*initialismMatches)
+	*s = (*s)[:0] // reset slice, keep allocated capacity
+
 	return s
 }
 
-type (
-	initialismMatch struct {
-		start, end int
-		body       []rune
-		complete   bool
+func (p buffersPool) BorrowBuffer(size int) *bytes.Buffer {
+	s := p.Get().(*bytes.Buffer)
+	s.Reset()
+
+	if s.Cap() < size {
+		s.Grow(size)
 	}
-	initialismMatches []*initialismMatch
-)
 
-func (s *splitter) toNameLexems(name string) []nameLexem {
+	return s
+}
+
+func (p lexemsPool) BorrowLexems() *[]nameLexem {
+	s := p.Get().(*[]nameLexem)
+	*s = (*s)[:0] // reset slice, keep allocated capacity
+
+	return s
+}
+
+func (p splittersPool) BorrowSplitter(options ...splitterOption) *splitter {
+	s := p.Get().(*splitter)
+	s.postSplitInitialismCheck = false // reset options
+	for _, apply := range options {
+		apply(s)
+	}
+
+	return s
+}
+
+func (p matchesPool) RedeemMatches(s *initialismMatches) {
+	p.Put(s)
+}
+
+func (p buffersPool) RedeemBuffer(s *bytes.Buffer) {
+	p.Put(s)
+}
+
+func (p lexemsPool) RedeemLexems(s *[]nameLexem) {
+	p.Put(s)
+}
+
+func (p splittersPool) RedeemSplitter(s *splitter) {
+	p.Put(s)
+}
+
+func (m initialismMatch) isZero() bool {
+	return m.start == 0 && m.end == 0
+}
+
+func (s splitter) split(name string) *[]nameLexem {
 	nameRunes := []rune(name)
 	matches := s.gatherInitialismMatches(nameRunes)
+	if matches == nil {
+		return poolOfLexems.BorrowLexems()
+	}
+
 	return s.mapMatchesToNameLexems(nameRunes, matches)
 }
 
-func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches {
-	matches := make(initialismMatches, 0)
+func (s splitter) gatherInitialismMatches(nameRunes []rune) *initialismMatches {
+	var matches *initialismMatches
 
 	for currentRunePosition, currentRune := range nameRunes {
-		newMatches := make(initialismMatches, 0, len(matches))
+		// recycle these allocations as we loop over runes
+		// with such recycling, only 2 slices should be allocated per call
+		// instead of o(n).
+		newMatches := poolOfMatches.BorrowMatches()
 
 		// check current initialism matches
-		for _, match := range matches {
-			if keepCompleteMatch := match.complete; keepCompleteMatch {
-				newMatches = append(newMatches, match)
-				continue
-			}
+		if matches != nil { // skip first iteration
+			for _, match := range *matches {
+				if keepCompleteMatch := match.complete; keepCompleteMatch {
+					*newMatches = append(*newMatches, match)
+					continue
+				}
 
-			// drop failed match
-			currentMatchRune := match.body[currentRunePosition-match.start]
-			if !s.initialismRuneEqual(currentMatchRune, currentRune) {
-				continue
-			}
+				// drop failed match
+				currentMatchRune := match.body[currentRunePosition-match.start]
+				if currentMatchRune != currentRune {
+					continue
+				}
 
-			// try to complete ongoing match
-			if currentRunePosition-match.start == len(match.body)-1 {
-				// we are close; the next step is to check the symbol ahead
-				// if it is a small letter, then it is not the end of match
-				// but beginning of the next word
-
-				if currentRunePosition < len(nameRunes)-1 {
-					nextRune := nameRunes[currentRunePosition+1]
-					if newWord := unicode.IsLower(nextRune); newWord {
-						// oh ok, it was the start of a new word
-						continue
+				// try to complete ongoing match
+				if currentRunePosition-match.start == len(match.body)-1 {
+					// we are close; the next step is to check the symbol ahead
+					// if it is a small letter, then it is not the end of match
+					// but beginning of the next word
+
+					if currentRunePosition < len(nameRunes)-1 {
+						nextRune := nameRunes[currentRunePosition+1]
+						if newWord := unicode.IsLower(nextRune); newWord {
+							// oh ok, it was the start of a new word
+							continue
+						}
 					}
+
+					match.complete = true
+					match.end = currentRunePosition
 				}
 
-				match.complete = true
-				match.end = currentRunePosition
+				*newMatches = append(*newMatches, match)
 			}
-
-			newMatches = append(newMatches, match)
 		}
 
 		// check for new initialism matches
-		for _, initialism := range s.initialisms {
-			initialismRunes := []rune(initialism)
-			if s.initialismRuneEqual(initialismRunes[0], currentRune) {
-				newMatches = append(newMatches, &initialismMatch{
+		for i := range s.initialisms {
+			initialismRunes := s.initialismsRunes[i]
+			if initialismRunes[0] == currentRune {
+				*newMatches = append(*newMatches, initialismMatch{
 					start:    currentRunePosition,
 					body:     initialismRunes,
 					complete: false,
@@ -140,24 +285,28 @@ func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches {
 			}
 		}
 
+		if matches != nil {
+			poolOfMatches.RedeemMatches(matches)
+		}
 		matches = newMatches
 	}
 
+	// up to the caller to redeem this last slice
 	return matches
 }
 
-func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMatches) []nameLexem {
-	nameLexems := make([]nameLexem, 0)
+func (s splitter) mapMatchesToNameLexems(nameRunes []rune, matches *initialismMatches) *[]nameLexem {
+	nameLexems := poolOfLexems.BorrowLexems()
 
-	var lastAcceptedMatch *initialismMatch
-	for _, match := range matches {
+	var lastAcceptedMatch initialismMatch
+	for _, match := range *matches {
 		if !match.complete {
 			continue
 		}
 
-		if firstMatch := lastAcceptedMatch == nil; firstMatch {
-			nameLexems = append(nameLexems, s.breakCasualString(nameRunes[:match.start])...)
-			nameLexems = append(nameLexems, s.breakInitialism(string(match.body)))
+		if firstMatch := lastAcceptedMatch.isZero(); firstMatch {
+			s.appendBrokenDownCasualString(nameLexems, nameRunes[:match.start])
+			*nameLexems = append(*nameLexems, s.breakInitialism(string(match.body)))
 
 			lastAcceptedMatch = match
 
@@ -169,63 +318,66 @@ func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMa
 		}
 
 		middle := nameRunes[lastAcceptedMatch.end+1 : match.start]
-		nameLexems = append(nameLexems, s.breakCasualString(middle)...)
-		nameLexems = append(nameLexems, s.breakInitialism(string(match.body)))
+		s.appendBrokenDownCasualString(nameLexems, middle)
+		*nameLexems = append(*nameLexems, s.breakInitialism(string(match.body)))
 
 		lastAcceptedMatch = match
 	}
 
 	// we have not found any accepted matches
-	if lastAcceptedMatch == nil {
-		return s.breakCasualString(nameRunes)
-	}
-
-	if lastAcceptedMatch.end+1 != len(nameRunes) {
+	if lastAcceptedMatch.isZero() {
+		*nameLexems = (*nameLexems)[:0]
+		s.appendBrokenDownCasualString(nameLexems, nameRunes)
+	} else if lastAcceptedMatch.end+1 != len(nameRunes) {
 		rest := nameRunes[lastAcceptedMatch.end+1:]
-		nameLexems = append(nameLexems, s.breakCasualString(rest)...)
+		s.appendBrokenDownCasualString(nameLexems, rest)
 	}
 
-	return nameLexems
-}
+	poolOfMatches.RedeemMatches(matches)
 
-func (s *splitter) initialismRuneEqual(a, b rune) bool {
-	return a == b
+	return nameLexems
 }
 
-func (s *splitter) breakInitialism(original string) nameLexem {
+func (s splitter) breakInitialism(original string) nameLexem {
 	return newInitialismNameLexem(original, original)
 }
 
-func (s *splitter) breakCasualString(str []rune) []nameLexem {
-	segments := make([]nameLexem, 0)
-	currentSegment := ""
+func (s splitter) appendBrokenDownCasualString(segments *[]nameLexem, str []rune) {
+	currentSegment := poolOfBuffers.BorrowBuffer(len(str)) // unlike strings.Builder, bytes.Buffer initial storage can reused
+	defer func() {
+		poolOfBuffers.RedeemBuffer(currentSegment)
+	}()
 
 	addCasualNameLexem := func(original string) {
-		segments = append(segments, newCasualNameLexem(original))
+		*segments = append(*segments, newCasualNameLexem(original))
 	}
 
 	addInitialismNameLexem := func(original, match string) {
-		segments = append(segments, newInitialismNameLexem(original, match))
+		*segments = append(*segments, newInitialismNameLexem(original, match))
 	}
 
-	addNameLexem := func(original string) {
-		if s.postSplitInitialismCheck {
-			for _, initialism := range s.initialisms {
-				if upper(initialism) == upper(original) {
-					addInitialismNameLexem(original, initialism)
+	var addNameLexem func(string)
+	if s.postSplitInitialismCheck {
+		addNameLexem = func(original string) {
+			for i := range s.initialisms {
+				if isEqualFoldIgnoreSpace(s.initialismsUpperCased[i], original) {
+					addInitialismNameLexem(original, s.initialisms[i])
+
 					return
 				}
 			}
-		}
 
-		addCasualNameLexem(original)
+			addCasualNameLexem(original)
+		}
+	} else {
+		addNameLexem = addCasualNameLexem
 	}
 
-	for _, rn := range string(str) {
-		if replace, found := nameReplaceTable[rn]; found {
-			if currentSegment != "" {
-				addNameLexem(currentSegment)
-				currentSegment = ""
+	for _, rn := range str {
+		if replace, found := nameReplaceTable(rn); found {
+			if currentSegment.Len() > 0 {
+				addNameLexem(currentSegment.String())
+				currentSegment.Reset()
 			}
 
 			if replace != "" {
@@ -236,27 +388,121 @@ func (s *splitter) breakCasualString(str []rune) []nameLexem {
 		}
 
 		if !unicode.In(rn, unicode.L, unicode.M, unicode.N, unicode.Pc) {
-			if currentSegment != "" {
-				addNameLexem(currentSegment)
-				currentSegment = ""
+			if currentSegment.Len() > 0 {
+				addNameLexem(currentSegment.String())
+				currentSegment.Reset()
 			}
 
 			continue
 		}
 
 		if unicode.IsUpper(rn) {
-			if currentSegment != "" {
-				addNameLexem(currentSegment)
+			if currentSegment.Len() > 0 {
+				addNameLexem(currentSegment.String())
 			}
-			currentSegment = ""
+			currentSegment.Reset()
 		}
 
-		currentSegment += string(rn)
+		currentSegment.WriteRune(rn)
+	}
+
+	if currentSegment.Len() > 0 {
+		addNameLexem(currentSegment.String())
 	}
+}
+
+// isEqualFoldIgnoreSpace is the same as strings.EqualFold, but
+// it ignores leading and trailing blank spaces in the compared
+// string.
+//
+// base is assumed to be composed of upper-cased runes, and be already
+// trimmed.
+//
+// This code is heavily inspired from strings.EqualFold.
+func isEqualFoldIgnoreSpace(base []rune, str string) bool {
+	var i, baseIndex int
+	// equivalent to b := []byte(str), but without data copy
+	b := hackStringBytes(str)
+
+	for i < len(b) {
+		if c := b[i]; c < utf8.RuneSelf {
+			// fast path for ASCII
+			if c != ' ' && c != '\t' {
+				break
+			}
+			i++
+
+			continue
+		}
+
+		// unicode case
+		r, size := utf8.DecodeRune(b[i:])
+		if !unicode.IsSpace(r) {
+			break
+		}
+		i += size
+	}
+
+	if i >= len(b) {
+		return len(base) == 0
+	}
+
+	for _, baseRune := range base {
+		if i >= len(b) {
+			break
+		}
+
+		if c := b[i]; c < utf8.RuneSelf {
+			// single byte rune case (ASCII)
+			if baseRune >= utf8.RuneSelf {
+				return false
+			}
+
+			baseChar := byte(baseRune)
+			if c != baseChar &&
+				!('a' <= c && c <= 'z' && c-'a'+'A' == baseChar) {
+				return false
+			}
+
+			baseIndex++
+			i++
+
+			continue
+		}
+
+		// unicode case
+		r, size := utf8.DecodeRune(b[i:])
+		if unicode.ToUpper(r) != baseRune {
+			return false
+		}
+		baseIndex++
+		i += size
+	}
+
+	if baseIndex != len(base) {
+		return false
+	}
+
+	// all passed: now we should only have blanks
+	for i < len(b) {
+		if c := b[i]; c < utf8.RuneSelf {
+			// fast path for ASCII
+			if c != ' ' && c != '\t' {
+				return false
+			}
+			i++
+
+			continue
+		}
+
+		// unicode case
+		r, size := utf8.DecodeRune(b[i:])
+		if !unicode.IsSpace(r) {
+			return false
+		}
 
-	if currentSegment != "" {
-		addNameLexem(currentSegment)
+		i += size
 	}
 
-	return segments
+	return true
 }
diff --git a/vendor/github.com/go-openapi/swag/string_bytes.go b/vendor/github.com/go-openapi/swag/string_bytes.go
new file mode 100644
index 00000000..90745d5c
--- /dev/null
+++ b/vendor/github.com/go-openapi/swag/string_bytes.go
@@ -0,0 +1,8 @@
+package swag
+
+import "unsafe"
+
+// hackStringBytes returns the (unsafe) underlying bytes slice of a string.
+func hackStringBytes(str string) []byte {
+	return unsafe.Slice(unsafe.StringData(str), len(str))
+}
diff --git a/vendor/github.com/go-openapi/swag/util.go b/vendor/github.com/go-openapi/swag/util.go
index d971fbe3..5051401c 100644
--- a/vendor/github.com/go-openapi/swag/util.go
+++ b/vendor/github.com/go-openapi/swag/util.go
@@ -18,76 +18,25 @@ import (
 	"reflect"
 	"strings"
 	"unicode"
+	"unicode/utf8"
 )
 
-// commonInitialisms are common acronyms that are kept as whole uppercased words.
-var commonInitialisms *indexOfInitialisms
-
-// initialisms is a slice of sorted initialisms
-var initialisms []string
-
-var isInitialism func(string) bool
-
 // GoNamePrefixFunc sets an optional rule to prefix go names
 // which do not start with a letter.
 //
+// The prefix function is assumed to return a string that starts with an upper case letter.
+//
 // e.g. to help convert "123" into "{prefix}123"
 //
 // The default is to prefix with "X"
 var GoNamePrefixFunc func(string) string
 
-func init() {
-	// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
-	var configuredInitialisms = map[string]bool{
-		"ACL":   true,
-		"API":   true,
-		"ASCII": true,
-		"CPU":   true,
-		"CSS":   true,
-		"DNS":   true,
-		"EOF":   true,
-		"GUID":  true,
-		"HTML":  true,
-		"HTTPS": true,
-		"HTTP":  true,
-		"ID":    true,
-		"IP":    true,
-		"IPv4":  true,
-		"IPv6":  true,
-		"JSON":  true,
-		"LHS":   true,
-		"OAI":   true,
-		"QPS":   true,
-		"RAM":   true,
-		"RHS":   true,
-		"RPC":   true,
-		"SLA":   true,
-		"SMTP":  true,
-		"SQL":   true,
-		"SSH":   true,
-		"TCP":   true,
-		"TLS":   true,
-		"TTL":   true,
-		"UDP":   true,
-		"UI":    true,
-		"UID":   true,
-		"UUID":  true,
-		"URI":   true,
-		"URL":   true,
-		"UTF8":  true,
-		"VM":    true,
-		"XML":   true,
-		"XMPP":  true,
-		"XSRF":  true,
-		"XSS":   true,
+func prefixFunc(name, in string) string {
+	if GoNamePrefixFunc == nil {
+		return "X" + in
 	}
 
-	// a thread-safe index of initialisms
-	commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
-	initialisms = commonInitialisms.sorted()
-
-	// a test function
-	isInitialism = commonInitialisms.isInitialism
+	return GoNamePrefixFunc(name) + in
 }
 
 const (
@@ -156,25 +105,9 @@ func SplitByFormat(data, format string) []string {
 	return result
 }
 
-type byInitialism []string
-
-func (s byInitialism) Len() int {
-	return len(s)
-}
-func (s byInitialism) Swap(i, j int) {
-	s[i], s[j] = s[j], s[i]
-}
-func (s byInitialism) Less(i, j int) bool {
-	if len(s[i]) != len(s[j]) {
-		return len(s[i]) < len(s[j])
-	}
-
-	return strings.Compare(s[i], s[j]) > 0
-}
-
 // Removes leading whitespaces
 func trim(str string) string {
-	return strings.Trim(str, " ")
+	return strings.TrimSpace(str)
 }
 
 // Shortcut to strings.ToUpper()
@@ -188,15 +121,20 @@ func lower(str string) string {
 }
 
 // Camelize an uppercased word
-func Camelize(word string) (camelized string) {
+func Camelize(word string) string {
+	camelized := poolOfBuffers.BorrowBuffer(len(word))
+	defer func() {
+		poolOfBuffers.RedeemBuffer(camelized)
+	}()
+
 	for pos, ru := range []rune(word) {
 		if pos > 0 {
-			camelized += string(unicode.ToLower(ru))
+			camelized.WriteRune(unicode.ToLower(ru))
 		} else {
-			camelized += string(unicode.ToUpper(ru))
+			camelized.WriteRune(unicode.ToUpper(ru))
 		}
 	}
-	return
+	return camelized.String()
 }
 
 // ToFileName lowercases and underscores a go type name
@@ -224,33 +162,40 @@ func ToCommandName(name string) string {
 
 // ToHumanNameLower represents a code name as a human series of words
 func ToHumanNameLower(name string) string {
-	in := newSplitter(withPostSplitInitialismCheck).split(name)
-	out := make([]string, 0, len(in))
+	s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
+	in := s.split(name)
+	poolOfSplitters.RedeemSplitter(s)
+	out := make([]string, 0, len(*in))
 
-	for _, w := range in {
+	for _, w := range *in {
 		if !w.IsInitialism() {
 			out = append(out, lower(w.GetOriginal()))
 		} else {
-			out = append(out, w.GetOriginal())
+			out = append(out, trim(w.GetOriginal()))
 		}
 	}
+	poolOfLexems.RedeemLexems(in)
 
 	return strings.Join(out, " ")
 }
 
 // ToHumanNameTitle represents a code name as a human series of words with the first letters titleized
 func ToHumanNameTitle(name string) string {
-	in := newSplitter(withPostSplitInitialismCheck).split(name)
+	s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
+	in := s.split(name)
+	poolOfSplitters.RedeemSplitter(s)
 
-	out := make([]string, 0, len(in))
-	for _, w := range in {
-		original := w.GetOriginal()
+	out := make([]string, 0, len(*in))
+	for _, w := range *in {
+		original := trim(w.GetOriginal())
 		if !w.IsInitialism() {
 			out = append(out, Camelize(original))
 		} else {
 			out = append(out, original)
 		}
 	}
+	poolOfLexems.RedeemLexems(in)
+
 	return strings.Join(out, " ")
 }
 
@@ -264,7 +209,7 @@ func ToJSONName(name string) string {
 			out = append(out, lower(w))
 			continue
 		}
-		out = append(out, Camelize(w))
+		out = append(out, Camelize(trim(w)))
 	}
 	return strings.Join(out, "")
 }
@@ -283,35 +228,70 @@ func ToVarName(name string) string {
 
 // ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes
 func ToGoName(name string) string {
-	lexems := newSplitter(withPostSplitInitialismCheck).split(name)
+	s := poolOfSplitters.BorrowSplitter(withPostSplitInitialismCheck)
+	lexems := s.split(name)
+	poolOfSplitters.RedeemSplitter(s)
+	defer func() {
+		poolOfLexems.RedeemLexems(lexems)
+	}()
+	lexemes := *lexems
+
+	if len(lexemes) == 0 {
+		return ""
+	}
+
+	result := poolOfBuffers.BorrowBuffer(len(name))
+	defer func() {
+		poolOfBuffers.RedeemBuffer(result)
+	}()
+
+	// check if not starting with a letter, upper case
+	firstPart := lexemes[0].GetUnsafeGoName()
+	if lexemes[0].IsInitialism() {
+		firstPart = upper(firstPart)
+	}
+
+	if c := firstPart[0]; c < utf8.RuneSelf {
+		// ASCII
+		switch {
+		case 'A' <= c && c <= 'Z':
+			result.WriteString(firstPart)
+		case 'a' <= c && c <= 'z':
+			result.WriteByte(c - 'a' + 'A')
+			result.WriteString(firstPart[1:])
+		default:
+			result.WriteString(prefixFunc(name, firstPart))
+			// NOTE: no longer check if prefixFunc returns a string that starts with uppercase:
+			// assume this is always the case
+		}
+	} else {
+		// unicode
+		firstRune, _ := utf8.DecodeRuneInString(firstPart)
+		switch {
+		case !unicode.IsLetter(firstRune):
+			result.WriteString(prefixFunc(name, firstPart))
+		case !unicode.IsUpper(firstRune):
+			result.WriteString(prefixFunc(name, firstPart))
+			/*
+				result.WriteRune(unicode.ToUpper(firstRune))
+				result.WriteString(firstPart[offset:])
+			*/
+		default:
+			result.WriteString(firstPart)
+		}
+	}
 
-	result := ""
-	for _, lexem := range lexems {
+	for _, lexem := range lexemes[1:] {
 		goName := lexem.GetUnsafeGoName()
 
 		// to support old behavior
 		if lexem.IsInitialism() {
 			goName = upper(goName)
 		}
-		result += goName
+		result.WriteString(goName)
 	}
 
-	if len(result) > 0 {
-		// Only prefix with X when the first character isn't an ascii letter
-		first := []rune(result)[0]
-		if !unicode.IsLetter(first) || (first > unicode.MaxASCII && !unicode.IsUpper(first)) {
-			if GoNamePrefixFunc == nil {
-				return "X" + result
-			}
-			result = GoNamePrefixFunc(name) + result
-		}
-		first = []rune(result)[0]
-		if unicode.IsLetter(first) && !unicode.IsUpper(first) {
-			result = string(append([]rune{unicode.ToUpper(first)}, []rune(result)[1:]...))
-		}
-	}
-
-	return result
+	return result.String()
 }
 
 // ContainsStrings searches a slice of strings for a case-sensitive match
@@ -343,7 +323,7 @@ type zeroable interface {
 func IsZero(data interface{}) bool {
 	v := reflect.ValueOf(data)
 	// check for nil data
-	switch v.Kind() {
+	switch v.Kind() { //nolint:exhaustive
 	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
 		if v.IsNil() {
 			return true
@@ -356,7 +336,7 @@ func IsZero(data interface{}) bool {
 	}
 
 	// continue with slightly more complex reflection
-	switch v.Kind() {
+	switch v.Kind() { //nolint:exhaustive
 	case reflect.String:
 		return v.Len() == 0
 	case reflect.Bool:
@@ -376,16 +356,6 @@ func IsZero(data interface{}) bool {
 	}
 }
 
-// AddInitialisms add additional initialisms
-func AddInitialisms(words ...string) {
-	for _, word := range words {
-		// commonInitialisms[upper(word)] = true
-		commonInitialisms.add(upper(word))
-	}
-	// sort again
-	initialisms = commonInitialisms.sorted()
-}
-
 // CommandLineOptionsGroup represents a group of user-defined command line options
 type CommandLineOptionsGroup struct {
 	ShortDescription string
diff --git a/vendor/github.com/go-openapi/swag/yaml.go b/vendor/github.com/go-openapi/swag/yaml.go
index f09ee609..f59e0259 100644
--- a/vendor/github.com/go-openapi/swag/yaml.go
+++ b/vendor/github.com/go-openapi/swag/yaml.go
@@ -16,8 +16,11 @@ package swag
 
 import (
 	"encoding/json"
+	"errors"
 	"fmt"
 	"path/filepath"
+	"reflect"
+	"sort"
 	"strconv"
 
 	"github.com/mailru/easyjson/jlexer"
@@ -48,7 +51,7 @@ func BytesToYAMLDoc(data []byte) (interface{}, error) {
 		return nil, err
 	}
 	if document.Kind != yaml.DocumentNode || len(document.Content) != 1 || document.Content[0].Kind != yaml.MappingNode {
-		return nil, fmt.Errorf("only YAML documents that are objects are supported")
+		return nil, errors.New("only YAML documents that are objects are supported")
 	}
 	return &document, nil
 }
@@ -147,7 +150,7 @@ func yamlScalar(node *yaml.Node) (interface{}, error) {
 	case yamlTimestamp:
 		return node.Value, nil
 	case yamlNull:
-		return nil, nil
+		return nil, nil //nolint:nilnil
 	default:
 		return nil, fmt.Errorf("YAML tag %q is not supported", node.LongTag())
 	}
@@ -245,7 +248,27 @@ func (s JSONMapSlice) MarshalYAML() (interface{}, error) {
 	return yaml.Marshal(&n)
 }
 
+func isNil(input interface{}) bool {
+	if input == nil {
+		return true
+	}
+	kind := reflect.TypeOf(input).Kind()
+	switch kind { //nolint:exhaustive
+	case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan:
+		return reflect.ValueOf(input).IsNil()
+	default:
+		return false
+	}
+}
+
 func json2yaml(item interface{}) (*yaml.Node, error) {
+	if isNil(item) {
+		return &yaml.Node{
+			Kind:  yaml.ScalarNode,
+			Value: "null",
+		}, nil
+	}
+
 	switch val := item.(type) {
 	case JSONMapSlice:
 		var n yaml.Node
@@ -265,7 +288,14 @@ func json2yaml(item interface{}) (*yaml.Node, error) {
 	case map[string]interface{}:
 		var n yaml.Node
 		n.Kind = yaml.MappingNode
-		for k, v := range val {
+		keys := make([]string, 0, len(val))
+		for k := range val {
+			keys = append(keys, k)
+		}
+		sort.Strings(keys)
+
+		for _, k := range keys {
+			v := val[k]
 			childNode, err := json2yaml(v)
 			if err != nil {
 				return nil, err
@@ -318,8 +348,9 @@ func json2yaml(item interface{}) (*yaml.Node, error) {
 			Tag:   yamlBoolScalar,
 			Value: strconv.FormatBool(val),
 		}, nil
+	default:
+		return nil, fmt.Errorf("unhandled type: %T", val)
 	}
-	return nil, nil
 }
 
 // JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice
diff --git a/vendor/github.com/go-openapi/validate/.golangci.yml b/vendor/github.com/go-openapi/validate/.golangci.yml
index 81818ca6..22f8d21c 100644
--- a/vendor/github.com/go-openapi/validate/.golangci.yml
+++ b/vendor/github.com/go-openapi/validate/.golangci.yml
@@ -1,12 +1,14 @@
 linters-settings:
   govet:
     check-shadowing: true
+  golint:
+    min-confidence: 0
   gocyclo:
-    min-complexity: 50
+    min-complexity: 45
   maligned:
     suggest-new: true
   dupl:
-    threshold: 100
+    threshold: 200
   goconst:
     min-len: 2
     min-occurrences: 3
@@ -15,36 +17,45 @@ linters:
   enable-all: true
   disable:
     - maligned
+    - unparam
     - lll
+    - gochecknoinits
+    - gochecknoglobals
+    - funlen
     - godox
     - gocognit
     - whitespace
     - wsl
-    - funlen
-    - gochecknoglobals
-    - gochecknoinits
-    - scopelint
     - wrapcheck
-    - exhaustivestruct
-    - exhaustive
-    - nlreturn
     - testpackage
-    - gci
-    - gofumpt
-    - goerr113
+    - nlreturn
     - gomnd
-    - tparallel
+    - exhaustivestruct
+    - goerr113
+    - errorlint
     - nestif
     - godot
-    - tparallel
+    - gofumpt
     - paralleltest
-    - cyclop # because we have gocyclo already
-    # TODO: review the linters below. We disabled them to make the CI pass first.
-    - ireturn
+    - tparallel
+    - thelper
+    - ifshort
+    - exhaustruct
     - varnamelen
+    - gci
+    - depguard
+    - errchkjson
+    - inamedparam
+    - nonamedreturns
+    - musttag
+    - ireturn
     - forcetypeassert
-    - thelper
-    # Disable deprecated linters.
-    # They will be removed from golangci-lint in future.
+    - cyclop
+    # deprecated linters
+    - deadcode
     - interfacer
-    - golint
\ No newline at end of file
+    - scopelint
+    - varcheck
+    - structcheck
+    - golint
+    - nosnakecase
diff --git a/vendor/github.com/go-openapi/validate/BENCHMARK.md b/vendor/github.com/go-openapi/validate/BENCHMARK.md
new file mode 100644
index 00000000..79cf6a07
--- /dev/null
+++ b/vendor/github.com/go-openapi/validate/BENCHMARK.md
@@ -0,0 +1,31 @@
+# Benchmark
+
+Validating the Kubernetes Swagger API
+
+## v0.22.6: 60,000,000 allocs
+```
+goos: linux
+goarch: amd64
+pkg: github.com/go-openapi/validate
+cpu: AMD Ryzen 7 5800X 8-Core Processor
+Benchmark_KubernetesSpec/validating_kubernetes_API-16         	       1	8549863982 ns/op	7067424936 B/op	59583275 allocs/op
+```
+
+## After refact PR: minor but noticable improvements: 25,000,000 allocs
+```
+go test -bench Spec
+goos: linux
+goarch: amd64
+pkg: github.com/go-openapi/validate
+cpu: AMD Ryzen 7 5800X 8-Core Processor
+Benchmark_KubernetesSpec/validating_kubernetes_API-16         	       1	4064535557 ns/op	3379715592 B/op	25320330 allocs/op
+```
+
+## After reduce GC pressure PR: 17,000,000 allocs
+```
+goos: linux
+goarch: amd64
+pkg: github.com/go-openapi/validate
+cpu: AMD Ryzen 7 5800X 8-Core Processor             
+Benchmark_KubernetesSpec/validating_kubernetes_API-16         	       1	3758414145 ns/op	2593881496 B/op	17111373 allocs/op
+```
diff --git a/vendor/github.com/go-openapi/validate/README.md b/vendor/github.com/go-openapi/validate/README.md
index ea2d68cb..e8e1bb21 100644
--- a/vendor/github.com/go-openapi/validate/README.md
+++ b/vendor/github.com/go-openapi/validate/README.md
@@ -1,7 +1,5 @@
-# Validation helpers
-[![Build Status](https://travis-ci.org/go-openapi/validate.svg?branch=master)](https://travis-ci.org/go-openapi/validate)
-[![Build status](https://ci.appveyor.com/api/projects/status/d6epy6vipueyh5fs/branch/master?svg=true)](https://ci.appveyor.com/project/fredbi/validate/branch/master)
-[![codecov](https://codecov.io/gh/go-openapi/validate/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/validate)
+# Validation helpers [![Build Status](https://github.com/go-openapi/validate/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/validate/actions?query=workflow%3A"go+test") [![codecov](https://codecov.io/gh/go-openapi/validate/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/validate)
+
 [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
 [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/validate/master/LICENSE)
 [![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/validate.svg)](https://pkg.go.dev/github.com/go-openapi/validate)
@@ -24,7 +22,7 @@ Reference can be found here: https://github.com/OAI/OpenAPI-Specification/blob/m
   * Minimum, Maximum, MultipleOf
   * FormatOf
 
-[Documentation](https://godoc.org/github.com/go-openapi/validate)
+[Documentation](https://pkg.go.dev/github.com/go-openapi/validate)
 
 ## FAQ
 
diff --git a/vendor/github.com/go-openapi/validate/appveyor.yml b/vendor/github.com/go-openapi/validate/appveyor.yml
deleted file mode 100644
index 89e5bccb..00000000
--- a/vendor/github.com/go-openapi/validate/appveyor.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-version: "0.1.{build}"
-
-clone_folder: C:\go-openapi\validate
-shallow_clone: true # for startup speed
-pull_requests:
-  do_not_increment_build_number: true
-
-#skip_tags: true
-#skip_branch_with_pr: true
-
-# appveyor.yml
-build: off
-
-environment:
-  GOPATH: c:\gopath
-
-stack: go 1.15
-
-test_script:
-  - go test -v -timeout 20m -args -enable-long ./...
-
-deploy: off
-
-notifications:
-  - provider: Slack
-    incoming_webhook: https://hooks.slack.com/services/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
-    auth_token:
-      secure: Sf7kZf7ZGbnwWUMpffHwMu5A0cHkLK2MYY32LNTPj4+/3qC3Ghl7+9v4TSLOqOlCwdRNjOGblAq7s+GDJed6/xgRQl1JtCi1klzZNrYX4q01pgTPvvGcwbBkIYgeMaPeIRcK9OZnud7sRXdttozgTOpytps2U6Js32ip7uj5mHSg2ub0FwoSJwlS6dbezZ8+eDhoha0F/guY99BEwx8Bd+zROrT2TFGsSGOFGN6wFc7moCqTHO/YkWib13a2QNXqOxCCVBy/lt76Wp+JkeFppjHlzs/2lP3EAk13RIUAaesdEUHvIHrzCyNJEd3/+KO2DzsWOYfpktd+KBCvgaYOsoo7ubdT3IROeAegZdCgo/6xgCEsmFc9ZcqCfN5yNx2A+BZ2Vwmpws+bQ1E1+B5HDzzaiLcYfG4X2O210QVGVDLWsv1jqD+uPYeHY2WRfh5ZsIUFvaqgUEnwHwrK44/8REAhQavt1QAj5uJpsRd7CkRVPWRNK+yIky+wgbVUFEchRNmS55E7QWf+W4+4QZkQi7vUTMc9nbTUu2Es9NfvfudOpM2wZbn98fjpb/qq/nRv6Bk+ca+7XD5/IgNLMbWp2ouDdzbiHLCOfDUiHiDJhLfFZx9Bwo7ZwfzeOlbrQX66bx7xRKYmOe4DLrXhNcpbsMa8qbfxlZRCmYbubB/Y8h4=
-    channel: bots
-    on_build_success: false
-    on_build_failure: true
-    on_build_status_changed: true
diff --git a/vendor/github.com/go-openapi/validate/default_validator.go b/vendor/github.com/go-openapi/validate/default_validator.go
index bd14c2a2..e0dd9383 100644
--- a/vendor/github.com/go-openapi/validate/default_validator.go
+++ b/vendor/github.com/go-openapi/validate/default_validator.go
@@ -25,48 +25,55 @@ import (
 // According to Swagger spec, default values MUST validate their schema.
 type defaultValidator struct {
 	SpecValidator  *SpecValidator
-	visitedSchemas map[string]bool
+	visitedSchemas map[string]struct{}
+	schemaOptions  *SchemaValidatorOptions
 }
 
 // resetVisited resets the internal state of visited schemas
 func (d *defaultValidator) resetVisited() {
-	d.visitedSchemas = map[string]bool{}
+	if d.visitedSchemas == nil {
+		d.visitedSchemas = make(map[string]struct{})
+
+		return
+	}
+
+	// TODO(go1.21): clear(ex.visitedSchemas)
+	for k := range d.visitedSchemas {
+		delete(d.visitedSchemas, k)
+	}
 }
 
-func isVisited(path string, visitedSchemas map[string]bool) bool {
-	found := visitedSchemas[path]
-	if !found {
-		// search for overlapping paths
-		frags := strings.Split(path, ".")
-		if len(frags) < 2 {
-			// shortcut exit on smaller paths
-			return found
+func isVisited(path string, visitedSchemas map[string]struct{}) bool {
+	_, found := visitedSchemas[path]
+	if found {
+		return true
+	}
+
+	// search for overlapping paths
+	var (
+		parent string
+		suffix string
+	)
+	for i := len(path) - 2; i >= 0; i-- {
+		r := path[i]
+		if r != '.' {
+			continue
 		}
-		last := len(frags) - 1
-		var currentFragStr, parent string
-		for i := range frags {
-			if i == 0 {
-				currentFragStr = frags[last]
-			} else {
-				currentFragStr = strings.Join([]string{frags[last-i], currentFragStr}, ".")
-			}
-			if i < last {
-				parent = strings.Join(frags[0:last-i], ".")
-			} else {
-				parent = ""
-			}
-			if strings.HasSuffix(parent, currentFragStr) {
-				found = true
-				break
-			}
+
+		parent = path[0:i]
+		suffix = path[i+1:]
+
+		if strings.HasSuffix(parent, suffix) {
+			return true
 		}
 	}
-	return found
+
+	return false
 }
 
 // beingVisited asserts a schema is being visited
 func (d *defaultValidator) beingVisited(path string) {
-	d.visitedSchemas[path] = true
+	d.visitedSchemas[path] = struct{}{}
 }
 
 // isVisited tells if a path has already been visited
@@ -75,8 +82,9 @@ func (d *defaultValidator) isVisited(path string) bool {
 }
 
 // Validate validates the default values declared in the swagger spec
-func (d *defaultValidator) Validate() (errs *Result) {
-	errs = new(Result)
+func (d *defaultValidator) Validate() *Result {
+	errs := pools.poolOfResults.BorrowResult() // will redeem when merged
+
 	if d == nil || d.SpecValidator == nil {
 		return errs
 	}
@@ -89,7 +97,7 @@ func (d *defaultValidator) validateDefaultValueValidAgainstSchema() *Result {
 	// every default value that is specified must validate against the schema for that property
 	// headers, items, parameters, schema
 
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult() // will redeem when merged
 	s := d.SpecValidator
 
 	for method, pathItem := range s.expandedAnalyzer().Operations() {
@@ -107,10 +115,12 @@ func (d *defaultValidator) validateDefaultValueValidAgainstSchema() *Result {
 				// default values provided must validate against their inline definition (no explicit schema)
 				if param.Default != nil && param.Schema == nil {
 					// check param default value is valid
-					red := NewParamValidator(&param, s.KnownFormats).Validate(param.Default) //#nosec
+					red := newParamValidator(&param, s.KnownFormats, d.schemaOptions).Validate(param.Default) //#nosec
 					if red.HasErrorsOrWarnings() {
 						res.AddErrors(defaultValueDoesNotValidateMsg(param.Name, param.In))
 						res.Merge(red)
+					} else if red.wantsRedeemOnMerge {
+						pools.poolOfResults.RedeemResult(red)
 					}
 				}
 
@@ -120,6 +130,8 @@ func (d *defaultValidator) validateDefaultValueValidAgainstSchema() *Result {
 					if red.HasErrorsOrWarnings() {
 						res.AddErrors(defaultValueItemsDoesNotValidateMsg(param.Name, param.In))
 						res.Merge(red)
+					} else if red.wantsRedeemOnMerge {
+						pools.poolOfResults.RedeemResult(red)
 					}
 				}
 
@@ -129,6 +141,8 @@ func (d *defaultValidator) validateDefaultValueValidAgainstSchema() *Result {
 					if red.HasErrorsOrWarnings() {
 						res.AddErrors(defaultValueDoesNotValidateMsg(param.Name, param.In))
 						res.Merge(red)
+					} else if red.wantsRedeemOnMerge {
+						pools.poolOfResults.RedeemResult(red)
 					}
 				}
 			}
@@ -154,7 +168,7 @@ func (d *defaultValidator) validateDefaultValueValidAgainstSchema() *Result {
 		// reset explored schemas to get depth-first recursive-proof exploration
 		d.resetVisited()
 		for nm, sch := range s.spec.Spec().Definitions {
-			res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("definitions.%s", nm), "body", &sch)) //#nosec
+			res.Merge(d.validateDefaultValueSchemaAgainstSchema("definitions."+nm, "body", &sch)) //#nosec
 		}
 	}
 	return res
@@ -170,17 +184,18 @@ func (d *defaultValidator) validateDefaultInResponse(resp *spec.Response, respon
 
 	responseName, responseCodeAsStr := responseHelp.responseMsgVariants(responseType, responseCode)
 
-	// nolint: dupl
 	if response.Headers != nil { // Safeguard
 		for nm, h := range response.Headers {
 			// reset explored schemas to get depth-first recursive-proof exploration
 			d.resetVisited()
 
 			if h.Default != nil {
-				red := NewHeaderValidator(nm, &h, s.KnownFormats).Validate(h.Default) //#nosec
+				red := newHeaderValidator(nm, &h, s.KnownFormats, d.schemaOptions).Validate(h.Default) //#nosec
 				if red.HasErrorsOrWarnings() {
 					res.AddErrors(defaultValueHeaderDoesNotValidateMsg(operationID, nm, responseName))
 					res.Merge(red)
+				} else if red.wantsRedeemOnMerge {
+					pools.poolOfResults.RedeemResult(red)
 				}
 			}
 
@@ -190,6 +205,8 @@ func (d *defaultValidator) validateDefaultInResponse(resp *spec.Response, respon
 				if red.HasErrorsOrWarnings() {
 					res.AddErrors(defaultValueHeaderItemsDoesNotValidateMsg(operationID, nm, responseName))
 					res.Merge(red)
+				} else if red.wantsRedeemOnMerge {
+					pools.poolOfResults.RedeemResult(red)
 				}
 			}
 
@@ -209,6 +226,8 @@ func (d *defaultValidator) validateDefaultInResponse(resp *spec.Response, respon
 			// Additional message to make sure the context of the error is not lost
 			res.AddErrors(defaultValueInDoesNotValidateMsg(operationID, responseName))
 			res.Merge(red)
+		} else if red.wantsRedeemOnMerge {
+			pools.poolOfResults.RedeemResult(red)
 		}
 	}
 	return res
@@ -220,11 +239,13 @@ func (d *defaultValidator) validateDefaultValueSchemaAgainstSchema(path, in stri
 		return nil
 	}
 	d.beingVisited(path)
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 	s := d.SpecValidator
 
 	if schema.Default != nil {
-		res.Merge(NewSchemaValidator(schema, s.spec.Spec(), path+".default", s.KnownFormats, SwaggerSchema(true)).Validate(schema.Default))
+		res.Merge(
+			newSchemaValidator(schema, s.spec.Spec(), path+".default", s.KnownFormats, d.schemaOptions).Validate(schema.Default),
+		)
 	}
 	if schema.Items != nil {
 		if schema.Items.Schema != nil {
@@ -242,7 +263,7 @@ func (d *defaultValidator) validateDefaultValueSchemaAgainstSchema(path, in stri
 	}
 	if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
 		// NOTE: we keep validating values, even though additionalItems is not supported by Swagger 2.0 (and 3.0 as well)
-		res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.additionalItems", path), in, schema.AdditionalItems.Schema))
+		res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+".additionalItems", in, schema.AdditionalItems.Schema))
 	}
 	for propName, prop := range schema.Properties {
 		res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+"."+propName, in, &prop)) //#nosec
@@ -251,7 +272,7 @@ func (d *defaultValidator) validateDefaultValueSchemaAgainstSchema(path, in stri
 		res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+"."+propName, in, &prop)) //#nosec
 	}
 	if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
-		res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.additionalProperties", path), in, schema.AdditionalProperties.Schema))
+		res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+".additionalProperties", in, schema.AdditionalProperties.Schema))
 	}
 	if schema.AllOf != nil {
 		for i, aoSch := range schema.AllOf {
@@ -262,13 +283,15 @@ func (d *defaultValidator) validateDefaultValueSchemaAgainstSchema(path, in stri
 }
 
 // TODO: Temporary duplicated code. Need to refactor with examples
-// nolint: dupl
+
 func (d *defaultValidator) validateDefaultValueItemsAgainstSchema(path, in string, root interface{}, items *spec.Items) *Result {
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 	s := d.SpecValidator
 	if items != nil {
 		if items.Default != nil {
-			res.Merge(newItemsValidator(path, in, items, root, s.KnownFormats).Validate(0, items.Default))
+			res.Merge(
+				newItemsValidator(path, in, items, root, s.KnownFormats, d.schemaOptions).Validate(0, items.Default),
+			)
 		}
 		if items.Items != nil {
 			res.Merge(d.validateDefaultValueItemsAgainstSchema(path+"[0].default", in, root, items.Items))
diff --git a/vendor/github.com/go-openapi/validate/doc.go b/vendor/github.com/go-openapi/validate/doc.go
index f5ca9a5d..d2b901ea 100644
--- a/vendor/github.com/go-openapi/validate/doc.go
+++ b/vendor/github.com/go-openapi/validate/doc.go
@@ -19,7 +19,7 @@ as well as tools to validate data against their schema.
 This package follows Swagger 2.0. specification (aka OpenAPI 2.0). Reference
 can be found here: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md.
 
-Validating a specification
+# Validating a specification
 
 Validates a spec document (from JSON or YAML) against the JSON schema for swagger,
 then checks a number of extra rules that can't be expressed in JSON schema.
@@ -30,34 +30,36 @@ Entry points:
   - SpecValidator.Validate()
 
 Reported as errors:
-  [x] definition can't declare a property that's already defined by one of its ancestors
-  [x] definition's ancestor can't be a descendant of the same model
-  [x] path uniqueness: each api path should be non-verbatim (account for path param names) unique per method
-  [x] each security reference should contain only unique scopes
-  [x] each security scope in a security definition should be unique
-  [x] parameters in path must be unique
-  [x] each path parameter must correspond to a parameter placeholder and vice versa
-  [x] each referenceable definition must have references
-  [x] each definition property listed in the required array must be defined in the properties of the model
-  [x] each parameter should have a unique `name` and `type` combination
-  [x] each operation should have only 1 parameter of type body
-  [x] each reference must point to a valid object
-  [x] every default value that is specified must validate against the schema for that property
-  [x] items property is required for all schemas/definitions of type `array`
-  [x] path parameters must be declared a required
-  [x] headers must not contain $ref
-  [x] schema and property examples provided must validate against their respective object's schema
-  [x] examples provided must validate their schema
+
+	[x] definition can't declare a property that's already defined by one of its ancestors
+	[x] definition's ancestor can't be a descendant of the same model
+	[x] path uniqueness: each api path should be non-verbatim (account for path param names) unique per method. Validation can be laxed by disabling StrictPathParamUniqueness.
+	[x] each security reference should contain only unique scopes
+	[x] each security scope in a security definition should be unique
+	[x] parameters in path must be unique
+	[x] each path parameter must correspond to a parameter placeholder and vice versa
+	[x] each referenceable definition must have references
+	[x] each definition property listed in the required array must be defined in the properties of the model
+	[x] each parameter should have a unique `name` and `type` combination
+	[x] each operation should have only 1 parameter of type body
+	[x] each reference must point to a valid object
+	[x] every default value that is specified must validate against the schema for that property
+	[x] items property is required for all schemas/definitions of type `array`
+	[x] path parameters must be declared a required
+	[x] headers must not contain $ref
+	[x] schema and property examples provided must validate against their respective object's schema
+	[x] examples provided must validate their schema
 
 Reported as warnings:
-  [x] path parameters should not contain any of [{,},\w]
-  [x] empty path
-  [x] unused definitions
-  [x] unsupported validation of examples on non-JSON media types
-  [x] examples in response without schema
-  [x] readOnly properties should not be required
 
-Validating a schema
+	[x] path parameters should not contain any of [{,},\w]
+	[x] empty path
+	[x] unused definitions
+	[x] unsupported validation of examples on non-JSON media types
+	[x] examples in response without schema
+	[x] readOnly properties should not be required
+
+# Validating a schema
 
 The schema validation toolkit validates data against JSON-schema-draft 04 schema.
 
@@ -70,16 +72,16 @@ Entry points:
   - AgainstSchema()
   - ...
 
-Known limitations
+# Known limitations
 
 With the current version of this package, the following aspects of swagger are not yet supported:
-  [ ] errors and warnings are not reported with key/line number in spec
-  [ ] default values and examples on responses only support application/json producer type
-  [ ] invalid numeric constraints (such as Minimum, etc..) are not checked except for default and example values
-  [ ] rules for collectionFormat are not implemented
-  [ ] no validation rule for polymorphism support (discriminator) [not done here]
-  [ ] valid js ECMA regexp not supported by Go regexp engine are considered invalid
-  [ ] arbitrary large numbers are not supported: max is math.MaxFloat64
 
+	[ ] errors and warnings are not reported with key/line number in spec
+	[ ] default values and examples on responses only support application/json producer type
+	[ ] invalid numeric constraints (such as Minimum, etc..) are not checked except for default and example values
+	[ ] rules for collectionFormat are not implemented
+	[ ] no validation rule for polymorphism support (discriminator) [not done here]
+	[ ] valid js ECMA regexp not supported by Go regexp engine are considered invalid
+	[ ] arbitrary large numbers are not supported: max is math.MaxFloat64
 */
 package validate
diff --git a/vendor/github.com/go-openapi/validate/example_validator.go b/vendor/github.com/go-openapi/validate/example_validator.go
index c8bffd78..d0895697 100644
--- a/vendor/github.com/go-openapi/validate/example_validator.go
+++ b/vendor/github.com/go-openapi/validate/example_validator.go
@@ -23,17 +23,27 @@ import (
 // ExampleValidator validates example values defined in a spec
 type exampleValidator struct {
 	SpecValidator  *SpecValidator
-	visitedSchemas map[string]bool
+	visitedSchemas map[string]struct{}
+	schemaOptions  *SchemaValidatorOptions
 }
 
 // resetVisited resets the internal state of visited schemas
 func (ex *exampleValidator) resetVisited() {
-	ex.visitedSchemas = map[string]bool{}
+	if ex.visitedSchemas == nil {
+		ex.visitedSchemas = make(map[string]struct{})
+
+		return
+	}
+
+	// TODO(go1.21): clear(ex.visitedSchemas)
+	for k := range ex.visitedSchemas {
+		delete(ex.visitedSchemas, k)
+	}
 }
 
 // beingVisited asserts a schema is being visited
 func (ex *exampleValidator) beingVisited(path string) {
-	ex.visitedSchemas[path] = true
+	ex.visitedSchemas[path] = struct{}{}
 }
 
 // isVisited tells if a path has already been visited
@@ -48,9 +58,9 @@ func (ex *exampleValidator) isVisited(path string) bool {
 //   - schemas
 //   - individual property
 //   - responses
-//
-func (ex *exampleValidator) Validate() (errs *Result) {
-	errs = new(Result)
+func (ex *exampleValidator) Validate() *Result {
+	errs := pools.poolOfResults.BorrowResult()
+
 	if ex == nil || ex.SpecValidator == nil {
 		return errs
 	}
@@ -65,7 +75,7 @@ func (ex *exampleValidator) validateExampleValueValidAgainstSchema() *Result {
 	// in: schemas, properties, object, items
 	// not in: headers, parameters without schema
 
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 	s := ex.SpecValidator
 
 	for method, pathItem := range s.expandedAnalyzer().Operations() {
@@ -83,10 +93,12 @@ func (ex *exampleValidator) validateExampleValueValidAgainstSchema() *Result {
 				// default values provided must validate against their inline definition (no explicit schema)
 				if param.Example != nil && param.Schema == nil {
 					// check param default value is valid
-					red := NewParamValidator(&param, s.KnownFormats).Validate(param.Example) //#nosec
+					red := newParamValidator(&param, s.KnownFormats, ex.schemaOptions).Validate(param.Example) //#nosec
 					if red.HasErrorsOrWarnings() {
 						res.AddWarnings(exampleValueDoesNotValidateMsg(param.Name, param.In))
 						res.MergeAsWarnings(red)
+					} else if red.wantsRedeemOnMerge {
+						pools.poolOfResults.RedeemResult(red)
 					}
 				}
 
@@ -96,6 +108,8 @@ func (ex *exampleValidator) validateExampleValueValidAgainstSchema() *Result {
 					if red.HasErrorsOrWarnings() {
 						res.AddWarnings(exampleValueItemsDoesNotValidateMsg(param.Name, param.In))
 						res.Merge(red)
+					} else if red.wantsRedeemOnMerge {
+						pools.poolOfResults.RedeemResult(red)
 					}
 				}
 
@@ -105,6 +119,8 @@ func (ex *exampleValidator) validateExampleValueValidAgainstSchema() *Result {
 					if red.HasErrorsOrWarnings() {
 						res.AddWarnings(exampleValueDoesNotValidateMsg(param.Name, param.In))
 						res.Merge(red)
+					} else if red.wantsRedeemOnMerge {
+						pools.poolOfResults.RedeemResult(red)
 					}
 				}
 			}
@@ -130,7 +146,7 @@ func (ex *exampleValidator) validateExampleValueValidAgainstSchema() *Result {
 		// reset explored schemas to get depth-first recursive-proof exploration
 		ex.resetVisited()
 		for nm, sch := range s.spec.Spec().Definitions {
-			res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("definitions.%s", nm), "body", &sch)) //#nosec
+			res.Merge(ex.validateExampleValueSchemaAgainstSchema("definitions."+nm, "body", &sch)) //#nosec
 		}
 	}
 	return res
@@ -146,17 +162,18 @@ func (ex *exampleValidator) validateExampleInResponse(resp *spec.Response, respo
 
 	responseName, responseCodeAsStr := responseHelp.responseMsgVariants(responseType, responseCode)
 
-	// nolint: dupl
 	if response.Headers != nil { // Safeguard
 		for nm, h := range response.Headers {
 			// reset explored schemas to get depth-first recursive-proof exploration
 			ex.resetVisited()
 
 			if h.Example != nil {
-				red := NewHeaderValidator(nm, &h, s.KnownFormats).Validate(h.Example) //#nosec
+				red := newHeaderValidator(nm, &h, s.KnownFormats, ex.schemaOptions).Validate(h.Example) //#nosec
 				if red.HasErrorsOrWarnings() {
 					res.AddWarnings(exampleValueHeaderDoesNotValidateMsg(operationID, nm, responseName))
 					res.MergeAsWarnings(red)
+				} else if red.wantsRedeemOnMerge {
+					pools.poolOfResults.RedeemResult(red)
 				}
 			}
 
@@ -166,6 +183,8 @@ func (ex *exampleValidator) validateExampleInResponse(resp *spec.Response, respo
 				if red.HasErrorsOrWarnings() {
 					res.AddWarnings(exampleValueHeaderItemsDoesNotValidateMsg(operationID, nm, responseName))
 					res.MergeAsWarnings(red)
+				} else if red.wantsRedeemOnMerge {
+					pools.poolOfResults.RedeemResult(red)
 				}
 			}
 
@@ -185,13 +204,17 @@ func (ex *exampleValidator) validateExampleInResponse(resp *spec.Response, respo
 			// Additional message to make sure the context of the error is not lost
 			res.AddWarnings(exampleValueInDoesNotValidateMsg(operationID, responseName))
 			res.Merge(red)
+		} else if red.wantsRedeemOnMerge {
+			pools.poolOfResults.RedeemResult(red)
 		}
 	}
 
 	if response.Examples != nil {
 		if response.Schema != nil {
 			if example, ok := response.Examples["application/json"]; ok {
-				res.MergeAsWarnings(NewSchemaValidator(response.Schema, s.spec.Spec(), path+".examples", s.KnownFormats, SwaggerSchema(true)).Validate(example))
+				res.MergeAsWarnings(
+					newSchemaValidator(response.Schema, s.spec.Spec(), path+".examples", s.KnownFormats, s.schemaOptions).Validate(example),
+				)
 			} else {
 				// TODO: validate other media types too
 				res.AddWarnings(examplesMimeNotSupportedMsg(operationID, responseName))
@@ -210,10 +233,12 @@ func (ex *exampleValidator) validateExampleValueSchemaAgainstSchema(path, in str
 	}
 	ex.beingVisited(path)
 	s := ex.SpecValidator
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 
 	if schema.Example != nil {
-		res.MergeAsWarnings(NewSchemaValidator(schema, s.spec.Spec(), path+".example", s.KnownFormats, SwaggerSchema(true)).Validate(schema.Example))
+		res.MergeAsWarnings(
+			newSchemaValidator(schema, s.spec.Spec(), path+".example", s.KnownFormats, ex.schemaOptions).Validate(schema.Example),
+		)
 	}
 	if schema.Items != nil {
 		if schema.Items.Schema != nil {
@@ -231,7 +256,7 @@ func (ex *exampleValidator) validateExampleValueSchemaAgainstSchema(path, in str
 	}
 	if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
 		// NOTE: we keep validating values, even though additionalItems is unsupported in Swagger 2.0 (and 3.0 as well)
-		res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.additionalItems", path), in, schema.AdditionalItems.Schema))
+		res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+".additionalItems", in, schema.AdditionalItems.Schema))
 	}
 	for propName, prop := range schema.Properties {
 		res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+"."+propName, in, &prop)) //#nosec
@@ -240,7 +265,7 @@ func (ex *exampleValidator) validateExampleValueSchemaAgainstSchema(path, in str
 		res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+"."+propName, in, &prop)) //#nosec
 	}
 	if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
-		res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.additionalProperties", path), in, schema.AdditionalProperties.Schema))
+		res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+".additionalProperties", in, schema.AdditionalProperties.Schema))
 	}
 	if schema.AllOf != nil {
 		for i, aoSch := range schema.AllOf {
@@ -251,13 +276,16 @@ func (ex *exampleValidator) validateExampleValueSchemaAgainstSchema(path, in str
 }
 
 // TODO: Temporary duplicated code. Need to refactor with examples
-// nolint: dupl
+//
+
 func (ex *exampleValidator) validateExampleValueItemsAgainstSchema(path, in string, root interface{}, items *spec.Items) *Result {
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 	s := ex.SpecValidator
 	if items != nil {
 		if items.Example != nil {
-			res.MergeAsWarnings(newItemsValidator(path, in, items, root, s.KnownFormats).Validate(0, items.Example))
+			res.MergeAsWarnings(
+				newItemsValidator(path, in, items, root, s.KnownFormats, ex.schemaOptions).Validate(0, items.Example),
+			)
 		}
 		if items.Items != nil {
 			res.Merge(ex.validateExampleValueItemsAgainstSchema(path+"[0].example", in, root, items.Items))
@@ -266,5 +294,6 @@ func (ex *exampleValidator) validateExampleValueItemsAgainstSchema(path, in stri
 			res.AddErrors(invalidPatternInMsg(path, in, items.Pattern))
 		}
 	}
+
 	return res
 }
diff --git a/vendor/github.com/go-openapi/validate/formats.go b/vendor/github.com/go-openapi/validate/formats.go
index 0ad996cb..f4e35521 100644
--- a/vendor/github.com/go-openapi/validate/formats.go
+++ b/vendor/github.com/go-openapi/validate/formats.go
@@ -22,10 +22,32 @@ import (
 )
 
 type formatValidator struct {
-	Format       string
 	Path         string
 	In           string
+	Format       string
 	KnownFormats strfmt.Registry
+	Options      *SchemaValidatorOptions
+}
+
+func newFormatValidator(path, in, format string, formats strfmt.Registry, opts *SchemaValidatorOptions) *formatValidator {
+	if opts == nil {
+		opts = new(SchemaValidatorOptions)
+	}
+
+	var f *formatValidator
+	if opts.recycleValidators {
+		f = pools.poolOfFormatValidators.BorrowValidator()
+	} else {
+		f = new(formatValidator)
+	}
+
+	f.Path = path
+	f.In = in
+	f.Format = format
+	f.KnownFormats = formats
+	f.Options = opts
+
+	return f
 }
 
 func (f *formatValidator) SetPath(path string) {
@@ -33,37 +55,45 @@ func (f *formatValidator) SetPath(path string) {
 }
 
 func (f *formatValidator) Applies(source interface{}, kind reflect.Kind) bool {
-	doit := func() bool {
-		if source == nil {
-			return false
-		}
-		switch source := source.(type) {
-		case *spec.Items:
-			return kind == reflect.String && f.KnownFormats.ContainsName(source.Format)
-		case *spec.Parameter:
-			return kind == reflect.String && f.KnownFormats.ContainsName(source.Format)
-		case *spec.Schema:
-			return kind == reflect.String && f.KnownFormats.ContainsName(source.Format)
-		case *spec.Header:
-			return kind == reflect.String && f.KnownFormats.ContainsName(source.Format)
-		}
+	if source == nil || f.KnownFormats == nil {
+		return false
+	}
+
+	switch source := source.(type) {
+	case *spec.Items:
+		return kind == reflect.String && f.KnownFormats.ContainsName(source.Format)
+	case *spec.Parameter:
+		return kind == reflect.String && f.KnownFormats.ContainsName(source.Format)
+	case *spec.Schema:
+		return kind == reflect.String && f.KnownFormats.ContainsName(source.Format)
+	case *spec.Header:
+		return kind == reflect.String && f.KnownFormats.ContainsName(source.Format)
+	default:
 		return false
 	}
-	r := doit()
-	debugLog("format validator for %q applies %t for %T (kind: %v)\n", f.Path, r, source, kind)
-	return r
 }
 
 func (f *formatValidator) Validate(val interface{}) *Result {
-	result := new(Result)
-	debugLog("validating \"%v\" against format: %s", val, f.Format)
+	if f.Options.recycleValidators {
+		defer func() {
+			f.redeem()
+		}()
+	}
+
+	var result *Result
+	if f.Options.recycleResult {
+		result = pools.poolOfResults.BorrowResult()
+	} else {
+		result = new(Result)
+	}
 
 	if err := FormatOf(f.Path, f.In, f.Format, val.(string), f.KnownFormats); err != nil {
 		result.AddErrors(err)
 	}
 
-	if result.HasErrors() {
-		return result
-	}
-	return nil
+	return result
+}
+
+func (f *formatValidator) redeem() {
+	pools.poolOfFormatValidators.RedeemValidator(f)
 }
diff --git a/vendor/github.com/go-openapi/validate/helpers.go b/vendor/github.com/go-openapi/validate/helpers.go
index 48ebfab5..757e403d 100644
--- a/vendor/github.com/go-openapi/validate/helpers.go
+++ b/vendor/github.com/go-openapi/validate/helpers.go
@@ -101,9 +101,17 @@ type errorHelper struct {
 	// A collection of unexported helpers for error construction
 }
 
-func (h *errorHelper) sErr(err errors.Error) *Result {
+func (h *errorHelper) sErr(err errors.Error, recycle bool) *Result {
 	// Builds a Result from standard errors.Error
-	return &Result{Errors: []error{err}}
+	var result *Result
+	if recycle {
+		result = pools.poolOfResults.BorrowResult()
+	} else {
+		result = new(Result)
+	}
+	result.Errors = []error{err}
+
+	return result
 }
 
 func (h *errorHelper) addPointerError(res *Result, err error, ref string, fromPath string) *Result {
@@ -157,7 +165,7 @@ func (h *valueHelper) asInt64(val interface{}) int64 {
 	// Number conversion function for int64, without error checking
 	// (implements an implicit type upgrade).
 	v := reflect.ValueOf(val)
-	switch v.Kind() {
+	switch v.Kind() { //nolint:exhaustive
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 		return v.Int()
 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
@@ -174,7 +182,7 @@ func (h *valueHelper) asUint64(val interface{}) uint64 {
 	// Number conversion function for uint64, without error checking
 	// (implements an implicit type upgrade).
 	v := reflect.ValueOf(val)
-	switch v.Kind() {
+	switch v.Kind() { //nolint:exhaustive
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 		return uint64(v.Int())
 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
@@ -192,7 +200,7 @@ func (h *valueHelper) asFloat64(val interface{}) float64 {
 	// Number conversion function for float64, without error checking
 	// (implements an implicit type upgrade).
 	v := reflect.ValueOf(val)
-	switch v.Kind() {
+	switch v.Kind() { //nolint:exhaustive
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 		return float64(v.Int())
 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
@@ -225,7 +233,7 @@ func (h *paramHelper) safeExpandedParamsFor(path, method, operationID string, re
 		operation.Parameters = resolvedParams
 
 		for _, ppr := range s.expandedAnalyzer().SafeParamsFor(method, path,
-			func(p spec.Parameter, err error) bool {
+			func(_ spec.Parameter, err error) bool {
 				// since params have already been expanded, there are few causes for error
 				res.AddErrors(someParametersBrokenMsg(path, method, operationID))
 				// original error from analyzer
@@ -250,7 +258,7 @@ func (h *paramHelper) resolveParam(path, method, operationID string, param *spec
 
 	}
 	if err != nil { // Safeguard
-		// NOTE: we may enter enter here when the whole parameter is an unresolved $ref
+		// NOTE: we may enter here when the whole parameter is an unresolved $ref
 		refPath := strings.Join([]string{"\"" + path + "\"", method}, ".")
 		errorHelp.addPointerError(res, err, param.Ref.String(), refPath)
 		return nil, res
@@ -306,6 +314,7 @@ func (r *responseHelper) expandResponseRef(
 		errorHelp.addPointerError(res, err, response.Ref.String(), path)
 		return nil, res
 	}
+
 	return response, res
 }
 
diff --git a/vendor/github.com/go-openapi/validate/object_validator.go b/vendor/github.com/go-openapi/validate/object_validator.go
index 7bb12615..dff73fa9 100644
--- a/vendor/github.com/go-openapi/validate/object_validator.go
+++ b/vendor/github.com/go-openapi/validate/object_validator.go
@@ -15,8 +15,8 @@
 package validate
 
 import (
+	"fmt"
 	"reflect"
-	"regexp"
 	"strings"
 
 	"github.com/go-openapi/errors"
@@ -35,62 +35,116 @@ type objectValidator struct {
 	PatternProperties    map[string]spec.Schema
 	Root                 interface{}
 	KnownFormats         strfmt.Registry
-	Options              SchemaValidatorOptions
+	Options              *SchemaValidatorOptions
+	splitPath            []string
+}
+
+func newObjectValidator(path, in string,
+	maxProperties, minProperties *int64, required []string, properties spec.SchemaProperties,
+	additionalProperties *spec.SchemaOrBool, patternProperties spec.SchemaProperties,
+	root interface{}, formats strfmt.Registry, opts *SchemaValidatorOptions) *objectValidator {
+	if opts == nil {
+		opts = new(SchemaValidatorOptions)
+	}
+
+	var v *objectValidator
+	if opts.recycleValidators {
+		v = pools.poolOfObjectValidators.BorrowValidator()
+	} else {
+		v = new(objectValidator)
+	}
+
+	v.Path = path
+	v.In = in
+	v.MaxProperties = maxProperties
+	v.MinProperties = minProperties
+	v.Required = required
+	v.Properties = properties
+	v.AdditionalProperties = additionalProperties
+	v.PatternProperties = patternProperties
+	v.Root = root
+	v.KnownFormats = formats
+	v.Options = opts
+	v.splitPath = strings.Split(v.Path, ".")
+
+	return v
 }
 
 func (o *objectValidator) SetPath(path string) {
 	o.Path = path
+	o.splitPath = strings.Split(path, ".")
 }
 
 func (o *objectValidator) Applies(source interface{}, kind reflect.Kind) bool {
 	// TODO: this should also work for structs
 	// there is a problem in the type validator where it will be unhappy about null values
 	// so that requires more testing
-	r := reflect.TypeOf(source) == specSchemaType && (kind == reflect.Map || kind == reflect.Struct)
-	debugLog("object validator for %q applies %t for %T (kind: %v)\n", o.Path, r, source, kind)
-	return r
+	_, isSchema := source.(*spec.Schema)
+	return isSchema && (kind == reflect.Map || kind == reflect.Struct)
 }
 
 func (o *objectValidator) isProperties() bool {
-	p := strings.Split(o.Path, ".")
+	p := o.splitPath
 	return len(p) > 1 && p[len(p)-1] == jsonProperties && p[len(p)-2] != jsonProperties
 }
 
 func (o *objectValidator) isDefault() bool {
-	p := strings.Split(o.Path, ".")
+	p := o.splitPath
 	return len(p) > 1 && p[len(p)-1] == jsonDefault && p[len(p)-2] != jsonDefault
 }
 
 func (o *objectValidator) isExample() bool {
-	p := strings.Split(o.Path, ".")
+	p := o.splitPath
 	return len(p) > 1 && (p[len(p)-1] == swaggerExample || p[len(p)-1] == swaggerExamples) && p[len(p)-2] != swaggerExample
 }
 
 func (o *objectValidator) checkArrayMustHaveItems(res *Result, val map[string]interface{}) {
 	// for swagger 2.0 schemas, there is an additional constraint to have array items defined explicitly.
 	// with pure jsonschema draft 4, one may have arrays with undefined items (i.e. any type).
-	if t, typeFound := val[jsonType]; typeFound {
-		if tpe, ok := t.(string); ok && tpe == arrayType {
-			if item, itemsKeyFound := val[jsonItems]; !itemsKeyFound {
-				res.AddErrors(errors.Required(jsonItems, o.Path, item))
-			}
-		}
+	if val == nil {
+		return
+	}
+
+	t, typeFound := val[jsonType]
+	if !typeFound {
+		return
+	}
+
+	tpe, isString := t.(string)
+	if !isString || tpe != arrayType {
+		return
+	}
+
+	item, itemsKeyFound := val[jsonItems]
+	if itemsKeyFound {
+		return
 	}
+
+	res.AddErrors(errors.Required(jsonItems, o.Path, item))
 }
 
 func (o *objectValidator) checkItemsMustBeTypeArray(res *Result, val map[string]interface{}) {
-	if !o.isProperties() && !o.isDefault() && !o.isExample() {
-		if _, itemsKeyFound := val[jsonItems]; itemsKeyFound {
-			t, typeFound := val[jsonType]
-			if typeFound {
-				if tpe, ok := t.(string); !ok || tpe != arrayType {
-					res.AddErrors(errors.InvalidType(o.Path, o.In, arrayType, nil))
-				}
-			} else {
-				// there is no type
-				res.AddErrors(errors.Required(jsonType, o.Path, t))
-			}
-		}
+	if val == nil {
+		return
+	}
+
+	if o.isProperties() || o.isDefault() || o.isExample() {
+		return
+	}
+
+	_, itemsKeyFound := val[jsonItems]
+	if !itemsKeyFound {
+		return
+	}
+
+	t, typeFound := val[jsonType]
+	if !typeFound {
+		// there is no type
+		res.AddErrors(errors.Required(jsonType, o.Path, t))
+	}
+
+	if tpe, isString := t.(string); !isString || tpe != arrayType {
+		res.AddErrors(errors.InvalidType(o.Path, o.In, arrayType, nil))
 	}
 }
 
@@ -104,176 +158,274 @@ func (o *objectValidator) precheck(res *Result, val map[string]interface{}) {
 }
 
 func (o *objectValidator) Validate(data interface{}) *Result {
-	val := data.(map[string]interface{})
-	// TODO: guard against nil data
+	if o.Options.recycleValidators {
+		defer func() {
+			o.redeem()
+		}()
+	}
+
+	var val map[string]interface{}
+	if data != nil {
+		var ok bool
+		val, ok = data.(map[string]interface{})
+		if !ok {
+			return errorHelp.sErr(invalidObjectMsg(o.Path, o.In), o.Options.recycleResult)
+		}
+	}
 	numKeys := int64(len(val))
 
 	if o.MinProperties != nil && numKeys < *o.MinProperties {
-		return errorHelp.sErr(errors.TooFewProperties(o.Path, o.In, *o.MinProperties))
+		return errorHelp.sErr(errors.TooFewProperties(o.Path, o.In, *o.MinProperties), o.Options.recycleResult)
 	}
 	if o.MaxProperties != nil && numKeys > *o.MaxProperties {
-		return errorHelp.sErr(errors.TooManyProperties(o.Path, o.In, *o.MaxProperties))
+		return errorHelp.sErr(errors.TooManyProperties(o.Path, o.In, *o.MaxProperties), o.Options.recycleResult)
 	}
 
-	res := new(Result)
+	var res *Result
+	if o.Options.recycleResult {
+		res = pools.poolOfResults.BorrowResult()
+	} else {
+		res = new(Result)
+	}
 
 	o.precheck(res, val)
 
 	// check validity of field names
 	if o.AdditionalProperties != nil && !o.AdditionalProperties.Allows {
 		// Case: additionalProperties: false
-		for k := range val {
-			_, regularProperty := o.Properties[k]
-			matched := false
-
-			for pk := range o.PatternProperties {
-				if matches, _ := regexp.MatchString(pk, k); matches {
-					matched = true
-					break
-				}
+		o.validateNoAdditionalProperties(val, res)
+	} else {
+		// Cases: empty additionalProperties (implying: true), or additionalProperties: true, or additionalProperties: { <<schema>> }
+		o.validateAdditionalProperties(val, res)
+	}
+
+	o.validatePropertiesSchema(val, res)
+
+	// Check patternProperties
+	// TODO: it looks like we have done that twice in many cases
+	for key, value := range val {
+		_, regularProperty := o.Properties[key]
+		matched, _, patterns := o.validatePatternProperty(key, value, res) // applies to regular properties as well
+		if regularProperty || !matched {
+			continue
+		}
+
+		for _, pName := range patterns {
+			if v, ok := o.PatternProperties[pName]; ok {
+				r := newSchemaValidator(&v, o.Root, o.Path+"."+key, o.KnownFormats, o.Options).Validate(value)
+				res.mergeForField(data.(map[string]interface{}), key, r)
 			}
+		}
+	}
 
-			if !regularProperty && k != "$schema" && k != "id" && !matched {
-				// Special properties "$schema" and "id" are ignored
-				res.AddErrors(errors.PropertyNotAllowed(o.Path, o.In, k))
-
-				// BUG(fredbi): This section should move to a part dedicated to spec validation as
-				// it will conflict with regular schemas where a property "headers" is defined.
-
-				//
-				// Croaks a more explicit message on top of the standard one
-				// on some recognized cases.
-				//
-				// NOTE: edge cases with invalid type assertion are simply ignored here.
-				// NOTE: prefix your messages here by "IMPORTANT!" so there are not filtered
-				// by higher level callers (the IMPORTANT! tag will be eventually
-				// removed).
-				if k == "headers" && val[k] != nil {
-					// $ref is forbidden in header
-					if headers, mapOk := val[k].(map[string]interface{}); mapOk {
-						for headerKey, headerBody := range headers {
-							if headerBody != nil {
-								if headerSchema, mapOfMapOk := headerBody.(map[string]interface{}); mapOfMapOk {
-									if _, found := headerSchema["$ref"]; found {
-										var msg string
-										if refString, stringOk := headerSchema["$ref"].(string); stringOk {
-											msg = strings.Join([]string{", one may not use $ref=\":", refString, "\""}, "")
-										}
-										res.AddErrors(refNotAllowedInHeaderMsg(o.Path, headerKey, msg))
-									}
-								}
-							}
-						}
-					}
-					/*
-						case "$ref":
-							if val[k] != nil {
-								// TODO: check context of that ref: warn about siblings, check against invalid context
-							}
-					*/
-				}
+	return res
+}
+
+func (o *objectValidator) validateNoAdditionalProperties(val map[string]interface{}, res *Result) {
+	for k := range val {
+		if k == "$schema" || k == "id" {
+			// special properties "$schema" and "id" are ignored
+			continue
+		}
+
+		_, regularProperty := o.Properties[k]
+		if regularProperty {
+			continue
+		}
+
+		matched := false
+		for pk := range o.PatternProperties {
+			re, err := compileRegexp(pk)
+			if err != nil {
+				continue
+			}
+			if matches := re.MatchString(k); matches {
+				matched = true
+				break
 			}
 		}
-	} else {
-		// Cases: no additionalProperties (implying: true), or additionalProperties: true, or additionalProperties: { <<schema>> }
-		for key, value := range val {
-			_, regularProperty := o.Properties[key]
-
-			// Validates property against "patternProperties" if applicable
-			// BUG(fredbi): succeededOnce is always false
-
-			// NOTE: how about regular properties which do not match patternProperties?
-			matched, succeededOnce, _ := o.validatePatternProperty(key, value, res)
-
-			if !(regularProperty || matched || succeededOnce) {
-
-				// Cases: properties which are not regular properties and have not been matched by the PatternProperties validator
-				if o.AdditionalProperties != nil && o.AdditionalProperties.Schema != nil {
-					// AdditionalProperties as Schema
-					r := NewSchemaValidator(o.AdditionalProperties.Schema, o.Root, o.Path+"."+key, o.KnownFormats, o.Options.Options()...).Validate(value)
-					res.mergeForField(data.(map[string]interface{}), key, r)
-				} else if regularProperty && !(matched || succeededOnce) {
-					// TODO: this is dead code since regularProperty=false here
-					res.AddErrors(errors.FailedAllPatternProperties(o.Path, o.In, key))
-				}
+		if matched {
+			continue
+		}
+
+		res.AddErrors(errors.PropertyNotAllowed(o.Path, o.In, k))
+
+		// BUG(fredbi): This section should move to a part dedicated to spec validation as
+		// it will conflict with regular schemas where a property "headers" is defined.
+
+		//
+		// Croaks a more explicit message on top of the standard one
+		// on some recognized cases.
+		//
+		// NOTE: edge cases with invalid type assertion are simply ignored here.
+		// NOTE: prefix your messages here by "IMPORTANT!" so there are not filtered
+		// by higher level callers (the IMPORTANT! tag will be eventually
+		// removed).
+		if k != "headers" || val[k] == nil {
+			continue
+		}
+
+		// $ref is forbidden in header
+		headers, mapOk := val[k].(map[string]interface{})
+		if !mapOk {
+			continue
+		}
+
+		for headerKey, headerBody := range headers {
+			if headerBody == nil {
+				continue
+			}
+
+			headerSchema, mapOfMapOk := headerBody.(map[string]interface{})
+			if !mapOfMapOk {
+				continue
+			}
+
+			_, found := headerSchema["$ref"]
+			if !found {
+				continue
+			}
+
+			refString, stringOk := headerSchema["$ref"].(string)
+			if !stringOk {
+				continue
 			}
+
+			msg := strings.Join([]string{", one may not use $ref=\":", refString, "\""}, "")
+			res.AddErrors(refNotAllowedInHeaderMsg(o.Path, headerKey, msg))
+			/*
+				case "$ref":
+					if val[k] != nil {
+						// TODO: check context of that ref: warn about siblings, check against invalid context
+					}
+			*/
+		}
+	}
+}
+
+func (o *objectValidator) validateAdditionalProperties(val map[string]interface{}, res *Result) {
+	for key, value := range val {
+		_, regularProperty := o.Properties[key]
+		if regularProperty {
+			continue
+		}
+
+		// Validates property against "patternProperties" if applicable
+		// BUG(fredbi): succeededOnce is always false
+
+		// NOTE: how about regular properties which do not match patternProperties?
+		matched, succeededOnce, _ := o.validatePatternProperty(key, value, res)
+		if matched || succeededOnce {
+			continue
+		}
+
+		if o.AdditionalProperties == nil || o.AdditionalProperties.Schema == nil {
+			continue
 		}
-		// Valid cases: additionalProperties: true or undefined
+
+		// Cases: properties which are not regular properties and have not been matched by the PatternProperties validator
+		// AdditionalProperties as Schema
+		r := newSchemaValidator(o.AdditionalProperties.Schema, o.Root, o.Path+"."+key, o.KnownFormats, o.Options).Validate(value)
+		res.mergeForField(val, key, r)
 	}
+	// Valid cases: additionalProperties: true or undefined
+}
 
-	createdFromDefaults := map[string]bool{}
+func (o *objectValidator) validatePropertiesSchema(val map[string]interface{}, res *Result) {
+	createdFromDefaults := map[string]struct{}{}
 
 	// Property types:
 	// - regular Property
+	pSchema := pools.poolOfSchemas.BorrowSchema() // recycle a spec.Schema object which lifespan extends only to the validation of properties
+	defer func() {
+		pools.poolOfSchemas.RedeemSchema(pSchema)
+	}()
+
 	for pName := range o.Properties {
-		pSchema := o.Properties[pName] // one instance per iteration
-		rName := pName
-		if o.Path != "" {
+		*pSchema = o.Properties[pName]
+		var rName string
+		if o.Path == "" {
+			rName = pName
+		} else {
 			rName = o.Path + "." + pName
 		}
 
 		// Recursively validates each property against its schema
-		if v, ok := val[pName]; ok {
-			r := NewSchemaValidator(&pSchema, o.Root, rName, o.KnownFormats, o.Options.Options()...).Validate(v)
-			res.mergeForField(data.(map[string]interface{}), pName, r)
-		} else if pSchema.Default != nil {
-			// If a default value is defined, creates the property from defaults
-			// NOTE: JSON schema does not enforce default values to be valid against schema. Swagger does.
-			createdFromDefaults[pName] = true
-			res.addPropertySchemata(data.(map[string]interface{}), pName, &pSchema)
+		v, ok := val[pName]
+		if ok {
+			r := newSchemaValidator(pSchema, o.Root, rName, o.KnownFormats, o.Options).Validate(v)
+			res.mergeForField(val, pName, r)
+
+			continue
 		}
-	}
 
-	// Check required properties
-	if len(o.Required) > 0 {
-		for _, k := range o.Required {
-			if v, ok := val[k]; !ok && !createdFromDefaults[k] {
-				res.AddErrors(errors.Required(o.Path+"."+k, o.In, v))
-				continue
+		if pSchema.Default != nil {
+			// if a default value is defined, creates the property from defaults
+			// NOTE: JSON schema does not enforce default values to be valid against schema. Swagger does.
+			createdFromDefaults[pName] = struct{}{}
+			if !o.Options.skipSchemataResult {
+				res.addPropertySchemata(val, pName, pSchema) // this shallow-clones the content of the pSchema pointer
 			}
 		}
 	}
 
-	// Check patternProperties
-	// TODO: it looks like we have done that twice in many cases
-	for key, value := range val {
-		_, regularProperty := o.Properties[key]
-		matched, _ /*succeededOnce*/, patterns := o.validatePatternProperty(key, value, res)
-		if !regularProperty && (matched /*|| succeededOnce*/) {
-			for _, pName := range patterns {
-				if v, ok := o.PatternProperties[pName]; ok {
-					r := NewSchemaValidator(&v, o.Root, o.Path+"."+key, o.KnownFormats, o.Options.Options()...).Validate(value)
-					res.mergeForField(data.(map[string]interface{}), key, r)
-				}
-			}
+	if len(o.Required) == 0 {
+		return
+	}
+
+	// Check required properties
+	for _, k := range o.Required {
+		v, ok := val[k]
+		if ok {
+			continue
+		}
+		_, isCreatedFromDefaults := createdFromDefaults[k]
+		if isCreatedFromDefaults {
+			continue
 		}
+
+		res.AddErrors(errors.Required(fmt.Sprintf("%s.%s", o.Path, k), o.In, v))
 	}
-	return res
 }
 
 // TODO: succeededOnce is not used anywhere
 func (o *objectValidator) validatePatternProperty(key string, value interface{}, result *Result) (bool, bool, []string) {
+	if len(o.PatternProperties) == 0 {
+		return false, false, nil
+	}
+
 	matched := false
 	succeededOnce := false
-	var patterns []string
+	patterns := make([]string, 0, len(o.PatternProperties))
 
-	for k, schema := range o.PatternProperties {
-		sch := schema
-		if match, _ := regexp.MatchString(k, key); match {
-			patterns = append(patterns, k)
-			matched = true
-			validator := NewSchemaValidator(&sch, o.Root, o.Path+"."+key, o.KnownFormats, o.Options.Options()...)
+	schema := pools.poolOfSchemas.BorrowSchema()
+	defer func() {
+		pools.poolOfSchemas.RedeemSchema(schema)
+	}()
 
-			res := validator.Validate(value)
-			result.Merge(res)
+	for k := range o.PatternProperties {
+		re, err := compileRegexp(k)
+		if err != nil {
+			continue
 		}
-	}
 
-	// BUG(fredbi): can't get to here. Should remove dead code (commented out).
+		match := re.MatchString(key)
+		if !match {
+			continue
+		}
 
-	// if succeededOnce {
-	//	result.Inc()
-	// }
+		*schema = o.PatternProperties[k]
+		patterns = append(patterns, k)
+		matched = true
+		validator := newSchemaValidator(schema, o.Root, fmt.Sprintf("%s.%s", o.Path, key), o.KnownFormats, o.Options)
+
+		res := validator.Validate(value)
+		result.Merge(res)
+	}
 
 	return matched, succeededOnce, patterns
 }
+
+func (o *objectValidator) redeem() {
+	pools.poolOfObjectValidators.RedeemValidator(o)
+}
diff --git a/vendor/github.com/go-openapi/validate/options.go b/vendor/github.com/go-openapi/validate/options.go
index deeec2f2..cfe9b066 100644
--- a/vendor/github.com/go-openapi/validate/options.go
+++ b/vendor/github.com/go-openapi/validate/options.go
@@ -21,10 +21,29 @@ import "sync"
 // NOTE: other options might be needed, for example a go-swagger specific mode.
 type Opts struct {
 	ContinueOnErrors bool // true: continue reporting errors, even if spec is invalid
+
+	// StrictPathParamUniqueness enables a strict validation of paths that include
+	// path parameters. When true, it will enforce that for each method, the path
+	// is unique, regardless of path parameters such that GET:/petstore/{id} and
+	// GET:/petstore/{pet} anre considered duplicate paths.
+	//
+	// Consider disabling if path parameters can include slashes such as
+	// GET:/v1/{shelve} and GET:/v1/{book}, where the IDs are "shelve/*" and
+	// /"shelve/*/book/*" respectively.
+	StrictPathParamUniqueness bool
+	SkipSchemataResult        bool
 }
 
 var (
-	defaultOpts      = Opts{ContinueOnErrors: false} // default is to stop validation on errors
+	defaultOpts = Opts{
+		// default is to stop validation on errors
+		ContinueOnErrors: false,
+
+		// StrictPathParamUniqueness is defaulted to true. This maintains existing
+		// behavior.
+		StrictPathParamUniqueness: true,
+	}
+
 	defaultOptsMutex = &sync.Mutex{}
 )
 
diff --git a/vendor/github.com/go-openapi/validate/pools.go b/vendor/github.com/go-openapi/validate/pools.go
new file mode 100644
index 00000000..3ddce4dc
--- /dev/null
+++ b/vendor/github.com/go-openapi/validate/pools.go
@@ -0,0 +1,366 @@
+//go:build !validatedebug
+
+package validate
+
+import (
+	"sync"
+
+	"github.com/go-openapi/spec"
+)
+
+var pools allPools
+
+func init() {
+	resetPools()
+}
+
+func resetPools() {
+	// NOTE: for testing purpose, we might want to reset pools after calling Validate twice.
+	// The pool is corrupted in that case: calling Put twice inserts a duplicate in the pool
+	// and further calls to Get are mishandled.
+
+	pools = allPools{
+		poolOfSchemaValidators: schemaValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &SchemaValidator{}
+
+					return s
+				},
+			},
+		},
+		poolOfObjectValidators: objectValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &objectValidator{}
+
+					return s
+				},
+			},
+		},
+		poolOfSliceValidators: sliceValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &schemaSliceValidator{}
+
+					return s
+				},
+			},
+		},
+		poolOfItemsValidators: itemsValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &itemsValidator{}
+
+					return s
+				},
+			},
+		},
+		poolOfBasicCommonValidators: basicCommonValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &basicCommonValidator{}
+
+					return s
+				},
+			},
+		},
+		poolOfHeaderValidators: headerValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &HeaderValidator{}
+
+					return s
+				},
+			},
+		},
+		poolOfParamValidators: paramValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &ParamValidator{}
+
+					return s
+				},
+			},
+		},
+		poolOfBasicSliceValidators: basicSliceValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &basicSliceValidator{}
+
+					return s
+				},
+			},
+		},
+		poolOfNumberValidators: numberValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &numberValidator{}
+
+					return s
+				},
+			},
+		},
+		poolOfStringValidators: stringValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &stringValidator{}
+
+					return s
+				},
+			},
+		},
+		poolOfSchemaPropsValidators: schemaPropsValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &schemaPropsValidator{}
+
+					return s
+				},
+			},
+		},
+		poolOfFormatValidators: formatValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &formatValidator{}
+
+					return s
+				},
+			},
+		},
+		poolOfTypeValidators: typeValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &typeValidator{}
+
+					return s
+				},
+			},
+		},
+		poolOfSchemas: schemasPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &spec.Schema{}
+
+					return s
+				},
+			},
+		},
+		poolOfResults: resultsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &Result{}
+
+					return s
+				},
+			},
+		},
+	}
+}
+
+type (
+	allPools struct {
+		// memory pools for all validator objects.
+		//
+		// Each pool can be borrowed from and redeemed to.
+		poolOfSchemaValidators      schemaValidatorsPool
+		poolOfObjectValidators      objectValidatorsPool
+		poolOfSliceValidators       sliceValidatorsPool
+		poolOfItemsValidators       itemsValidatorsPool
+		poolOfBasicCommonValidators basicCommonValidatorsPool
+		poolOfHeaderValidators      headerValidatorsPool
+		poolOfParamValidators       paramValidatorsPool
+		poolOfBasicSliceValidators  basicSliceValidatorsPool
+		poolOfNumberValidators      numberValidatorsPool
+		poolOfStringValidators      stringValidatorsPool
+		poolOfSchemaPropsValidators schemaPropsValidatorsPool
+		poolOfFormatValidators      formatValidatorsPool
+		poolOfTypeValidators        typeValidatorsPool
+		poolOfSchemas               schemasPool
+		poolOfResults               resultsPool
+	}
+
+	schemaValidatorsPool struct {
+		*sync.Pool
+	}
+
+	objectValidatorsPool struct {
+		*sync.Pool
+	}
+
+	sliceValidatorsPool struct {
+		*sync.Pool
+	}
+
+	itemsValidatorsPool struct {
+		*sync.Pool
+	}
+
+	basicCommonValidatorsPool struct {
+		*sync.Pool
+	}
+
+	headerValidatorsPool struct {
+		*sync.Pool
+	}
+
+	paramValidatorsPool struct {
+		*sync.Pool
+	}
+
+	basicSliceValidatorsPool struct {
+		*sync.Pool
+	}
+
+	numberValidatorsPool struct {
+		*sync.Pool
+	}
+
+	stringValidatorsPool struct {
+		*sync.Pool
+	}
+
+	schemaPropsValidatorsPool struct {
+		*sync.Pool
+	}
+
+	formatValidatorsPool struct {
+		*sync.Pool
+	}
+
+	typeValidatorsPool struct {
+		*sync.Pool
+	}
+
+	schemasPool struct {
+		*sync.Pool
+	}
+
+	resultsPool struct {
+		*sync.Pool
+	}
+)
+
+func (p schemaValidatorsPool) BorrowValidator() *SchemaValidator {
+	return p.Get().(*SchemaValidator)
+}
+
+func (p schemaValidatorsPool) RedeemValidator(s *SchemaValidator) {
+	// NOTE: s might be nil. In that case, Put is a noop.
+	p.Put(s)
+}
+
+func (p objectValidatorsPool) BorrowValidator() *objectValidator {
+	return p.Get().(*objectValidator)
+}
+
+func (p objectValidatorsPool) RedeemValidator(s *objectValidator) {
+	p.Put(s)
+}
+
+func (p sliceValidatorsPool) BorrowValidator() *schemaSliceValidator {
+	return p.Get().(*schemaSliceValidator)
+}
+
+func (p sliceValidatorsPool) RedeemValidator(s *schemaSliceValidator) {
+	p.Put(s)
+}
+
+func (p itemsValidatorsPool) BorrowValidator() *itemsValidator {
+	return p.Get().(*itemsValidator)
+}
+
+func (p itemsValidatorsPool) RedeemValidator(s *itemsValidator) {
+	p.Put(s)
+}
+
+func (p basicCommonValidatorsPool) BorrowValidator() *basicCommonValidator {
+	return p.Get().(*basicCommonValidator)
+}
+
+func (p basicCommonValidatorsPool) RedeemValidator(s *basicCommonValidator) {
+	p.Put(s)
+}
+
+func (p headerValidatorsPool) BorrowValidator() *HeaderValidator {
+	return p.Get().(*HeaderValidator)
+}
+
+func (p headerValidatorsPool) RedeemValidator(s *HeaderValidator) {
+	p.Put(s)
+}
+
+func (p paramValidatorsPool) BorrowValidator() *ParamValidator {
+	return p.Get().(*ParamValidator)
+}
+
+func (p paramValidatorsPool) RedeemValidator(s *ParamValidator) {
+	p.Put(s)
+}
+
+func (p basicSliceValidatorsPool) BorrowValidator() *basicSliceValidator {
+	return p.Get().(*basicSliceValidator)
+}
+
+func (p basicSliceValidatorsPool) RedeemValidator(s *basicSliceValidator) {
+	p.Put(s)
+}
+
+func (p numberValidatorsPool) BorrowValidator() *numberValidator {
+	return p.Get().(*numberValidator)
+}
+
+func (p numberValidatorsPool) RedeemValidator(s *numberValidator) {
+	p.Put(s)
+}
+
+func (p stringValidatorsPool) BorrowValidator() *stringValidator {
+	return p.Get().(*stringValidator)
+}
+
+func (p stringValidatorsPool) RedeemValidator(s *stringValidator) {
+	p.Put(s)
+}
+
+func (p schemaPropsValidatorsPool) BorrowValidator() *schemaPropsValidator {
+	return p.Get().(*schemaPropsValidator)
+}
+
+func (p schemaPropsValidatorsPool) RedeemValidator(s *schemaPropsValidator) {
+	p.Put(s)
+}
+
+func (p formatValidatorsPool) BorrowValidator() *formatValidator {
+	return p.Get().(*formatValidator)
+}
+
+func (p formatValidatorsPool) RedeemValidator(s *formatValidator) {
+	p.Put(s)
+}
+
+func (p typeValidatorsPool) BorrowValidator() *typeValidator {
+	return p.Get().(*typeValidator)
+}
+
+func (p typeValidatorsPool) RedeemValidator(s *typeValidator) {
+	p.Put(s)
+}
+
+func (p schemasPool) BorrowSchema() *spec.Schema {
+	return p.Get().(*spec.Schema)
+}
+
+func (p schemasPool) RedeemSchema(s *spec.Schema) {
+	p.Put(s)
+}
+
+func (p resultsPool) BorrowResult() *Result {
+	return p.Get().(*Result).cleared()
+}
+
+func (p resultsPool) RedeemResult(s *Result) {
+	if s == emptyResult {
+		return
+	}
+	p.Put(s)
+}
diff --git a/vendor/github.com/go-openapi/validate/pools_debug.go b/vendor/github.com/go-openapi/validate/pools_debug.go
new file mode 100644
index 00000000..12949f02
--- /dev/null
+++ b/vendor/github.com/go-openapi/validate/pools_debug.go
@@ -0,0 +1,1012 @@
+//go:build validatedebug
+
+package validate
+
+import (
+	"fmt"
+	"runtime"
+	"sync"
+	"testing"
+
+	"github.com/go-openapi/spec"
+)
+
+// This version of the pools is to be used for debugging and testing, with build tag "validatedebug".
+//
+// In this mode, the pools are tracked for allocation and redemption of borrowed objects, so we can
+// verify a few behaviors of the validators. The debug pools panic when an invalid usage pattern is detected.
+
+var pools allPools
+
+func init() {
+	resetPools()
+}
+
+func resetPools() {
+	// NOTE: for testing purpose, we might want to reset pools after calling Validate twice.
+	// The pool is corrupted in that case: calling Put twice inserts a duplicate in the pool
+	// and further calls to Get are mishandled.
+
+	pools = allPools{
+		poolOfSchemaValidators: schemaValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &SchemaValidator{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*SchemaValidator]status),
+			allocMap:  make(map[*SchemaValidator]string),
+			redeemMap: make(map[*SchemaValidator]string),
+		},
+		poolOfObjectValidators: objectValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &objectValidator{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*objectValidator]status),
+			allocMap:  make(map[*objectValidator]string),
+			redeemMap: make(map[*objectValidator]string),
+		},
+		poolOfSliceValidators: sliceValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &schemaSliceValidator{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*schemaSliceValidator]status),
+			allocMap:  make(map[*schemaSliceValidator]string),
+			redeemMap: make(map[*schemaSliceValidator]string),
+		},
+		poolOfItemsValidators: itemsValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &itemsValidator{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*itemsValidator]status),
+			allocMap:  make(map[*itemsValidator]string),
+			redeemMap: make(map[*itemsValidator]string),
+		},
+		poolOfBasicCommonValidators: basicCommonValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &basicCommonValidator{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*basicCommonValidator]status),
+			allocMap:  make(map[*basicCommonValidator]string),
+			redeemMap: make(map[*basicCommonValidator]string),
+		},
+		poolOfHeaderValidators: headerValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &HeaderValidator{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*HeaderValidator]status),
+			allocMap:  make(map[*HeaderValidator]string),
+			redeemMap: make(map[*HeaderValidator]string),
+		},
+		poolOfParamValidators: paramValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &ParamValidator{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*ParamValidator]status),
+			allocMap:  make(map[*ParamValidator]string),
+			redeemMap: make(map[*ParamValidator]string),
+		},
+		poolOfBasicSliceValidators: basicSliceValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &basicSliceValidator{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*basicSliceValidator]status),
+			allocMap:  make(map[*basicSliceValidator]string),
+			redeemMap: make(map[*basicSliceValidator]string),
+		},
+		poolOfNumberValidators: numberValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &numberValidator{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*numberValidator]status),
+			allocMap:  make(map[*numberValidator]string),
+			redeemMap: make(map[*numberValidator]string),
+		},
+		poolOfStringValidators: stringValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &stringValidator{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*stringValidator]status),
+			allocMap:  make(map[*stringValidator]string),
+			redeemMap: make(map[*stringValidator]string),
+		},
+		poolOfSchemaPropsValidators: schemaPropsValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &schemaPropsValidator{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*schemaPropsValidator]status),
+			allocMap:  make(map[*schemaPropsValidator]string),
+			redeemMap: make(map[*schemaPropsValidator]string),
+		},
+		poolOfFormatValidators: formatValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &formatValidator{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*formatValidator]status),
+			allocMap:  make(map[*formatValidator]string),
+			redeemMap: make(map[*formatValidator]string),
+		},
+		poolOfTypeValidators: typeValidatorsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &typeValidator{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*typeValidator]status),
+			allocMap:  make(map[*typeValidator]string),
+			redeemMap: make(map[*typeValidator]string),
+		},
+		poolOfSchemas: schemasPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &spec.Schema{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*spec.Schema]status),
+			allocMap:  make(map[*spec.Schema]string),
+			redeemMap: make(map[*spec.Schema]string),
+		},
+		poolOfResults: resultsPool{
+			Pool: &sync.Pool{
+				New: func() any {
+					s := &Result{}
+
+					return s
+				},
+			},
+			debugMap:  make(map[*Result]status),
+			allocMap:  make(map[*Result]string),
+			redeemMap: make(map[*Result]string),
+		},
+	}
+}
+
+const (
+	statusFresh status = iota + 1
+	statusRecycled
+	statusRedeemed
+)
+
+func (s status) String() string {
+	switch s {
+	case statusFresh:
+		return "fresh"
+	case statusRecycled:
+		return "recycled"
+	case statusRedeemed:
+		return "redeemed"
+	default:
+		panic(fmt.Errorf("invalid status: %d", s))
+	}
+}
+
+type (
+	// Debug
+	status uint8
+
+	allPools struct {
+		// memory pools for all validator objects.
+		//
+		// Each pool can be borrowed from and redeemed to.
+		poolOfSchemaValidators      schemaValidatorsPool
+		poolOfObjectValidators      objectValidatorsPool
+		poolOfSliceValidators       sliceValidatorsPool
+		poolOfItemsValidators       itemsValidatorsPool
+		poolOfBasicCommonValidators basicCommonValidatorsPool
+		poolOfHeaderValidators      headerValidatorsPool
+		poolOfParamValidators       paramValidatorsPool
+		poolOfBasicSliceValidators  basicSliceValidatorsPool
+		poolOfNumberValidators      numberValidatorsPool
+		poolOfStringValidators      stringValidatorsPool
+		poolOfSchemaPropsValidators schemaPropsValidatorsPool
+		poolOfFormatValidators      formatValidatorsPool
+		poolOfTypeValidators        typeValidatorsPool
+		poolOfSchemas               schemasPool
+		poolOfResults               resultsPool
+	}
+
+	schemaValidatorsPool struct {
+		*sync.Pool
+		debugMap  map[*SchemaValidator]status
+		allocMap  map[*SchemaValidator]string
+		redeemMap map[*SchemaValidator]string
+		mx        sync.Mutex
+	}
+
+	objectValidatorsPool struct {
+		*sync.Pool
+		debugMap  map[*objectValidator]status
+		allocMap  map[*objectValidator]string
+		redeemMap map[*objectValidator]string
+		mx        sync.Mutex
+	}
+
+	sliceValidatorsPool struct {
+		*sync.Pool
+		debugMap  map[*schemaSliceValidator]status
+		allocMap  map[*schemaSliceValidator]string
+		redeemMap map[*schemaSliceValidator]string
+		mx        sync.Mutex
+	}
+
+	itemsValidatorsPool struct {
+		*sync.Pool
+		debugMap  map[*itemsValidator]status
+		allocMap  map[*itemsValidator]string
+		redeemMap map[*itemsValidator]string
+		mx        sync.Mutex
+	}
+
+	basicCommonValidatorsPool struct {
+		*sync.Pool
+		debugMap  map[*basicCommonValidator]status
+		allocMap  map[*basicCommonValidator]string
+		redeemMap map[*basicCommonValidator]string
+		mx        sync.Mutex
+	}
+
+	headerValidatorsPool struct {
+		*sync.Pool
+		debugMap  map[*HeaderValidator]status
+		allocMap  map[*HeaderValidator]string
+		redeemMap map[*HeaderValidator]string
+		mx        sync.Mutex
+	}
+
+	paramValidatorsPool struct {
+		*sync.Pool
+		debugMap  map[*ParamValidator]status
+		allocMap  map[*ParamValidator]string
+		redeemMap map[*ParamValidator]string
+		mx        sync.Mutex
+	}
+
+	basicSliceValidatorsPool struct {
+		*sync.Pool
+		debugMap  map[*basicSliceValidator]status
+		allocMap  map[*basicSliceValidator]string
+		redeemMap map[*basicSliceValidator]string
+		mx        sync.Mutex
+	}
+
+	numberValidatorsPool struct {
+		*sync.Pool
+		debugMap  map[*numberValidator]status
+		allocMap  map[*numberValidator]string
+		redeemMap map[*numberValidator]string
+		mx        sync.Mutex
+	}
+
+	stringValidatorsPool struct {
+		*sync.Pool
+		debugMap  map[*stringValidator]status
+		allocMap  map[*stringValidator]string
+		redeemMap map[*stringValidator]string
+		mx        sync.Mutex
+	}
+
+	schemaPropsValidatorsPool struct {
+		*sync.Pool
+		debugMap  map[*schemaPropsValidator]status
+		allocMap  map[*schemaPropsValidator]string
+		redeemMap map[*schemaPropsValidator]string
+		mx        sync.Mutex
+	}
+
+	formatValidatorsPool struct {
+		*sync.Pool
+		debugMap  map[*formatValidator]status
+		allocMap  map[*formatValidator]string
+		redeemMap map[*formatValidator]string
+		mx        sync.Mutex
+	}
+
+	typeValidatorsPool struct {
+		*sync.Pool
+		debugMap  map[*typeValidator]status
+		allocMap  map[*typeValidator]string
+		redeemMap map[*typeValidator]string
+		mx        sync.Mutex
+	}
+
+	schemasPool struct {
+		*sync.Pool
+		debugMap  map[*spec.Schema]status
+		allocMap  map[*spec.Schema]string
+		redeemMap map[*spec.Schema]string
+		mx        sync.Mutex
+	}
+
+	resultsPool struct {
+		*sync.Pool
+		debugMap  map[*Result]status
+		allocMap  map[*Result]string
+		redeemMap map[*Result]string
+		mx        sync.Mutex
+	}
+)
+
+func (p *schemaValidatorsPool) BorrowValidator() *SchemaValidator {
+	s := p.Get().(*SchemaValidator)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled schema should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *schemaValidatorsPool) RedeemValidator(s *SchemaValidator) {
+	// NOTE: s might be nil. In that case, Put is a noop.
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed schema should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed schema should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *objectValidatorsPool) BorrowValidator() *objectValidator {
+	s := p.Get().(*objectValidator)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled object should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *objectValidatorsPool) RedeemValidator(s *objectValidator) {
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed object should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed object should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *sliceValidatorsPool) BorrowValidator() *schemaSliceValidator {
+	s := p.Get().(*schemaSliceValidator)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled schemaSliceValidator should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *sliceValidatorsPool) RedeemValidator(s *schemaSliceValidator) {
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed schemaSliceValidator should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed schemaSliceValidator should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *itemsValidatorsPool) BorrowValidator() *itemsValidator {
+	s := p.Get().(*itemsValidator)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled itemsValidator should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *itemsValidatorsPool) RedeemValidator(s *itemsValidator) {
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed itemsValidator should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed itemsValidator should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *basicCommonValidatorsPool) BorrowValidator() *basicCommonValidator {
+	s := p.Get().(*basicCommonValidator)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled basicCommonValidator should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *basicCommonValidatorsPool) RedeemValidator(s *basicCommonValidator) {
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed basicCommonValidator should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed basicCommonValidator should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *headerValidatorsPool) BorrowValidator() *HeaderValidator {
+	s := p.Get().(*HeaderValidator)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled HeaderValidator should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *headerValidatorsPool) RedeemValidator(s *HeaderValidator) {
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed header should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed header should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *paramValidatorsPool) BorrowValidator() *ParamValidator {
+	s := p.Get().(*ParamValidator)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled param should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *paramValidatorsPool) RedeemValidator(s *ParamValidator) {
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed param should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed param should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *basicSliceValidatorsPool) BorrowValidator() *basicSliceValidator {
+	s := p.Get().(*basicSliceValidator)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled basicSliceValidator should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *basicSliceValidatorsPool) RedeemValidator(s *basicSliceValidator) {
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed basicSliceValidator should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed basicSliceValidator should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *numberValidatorsPool) BorrowValidator() *numberValidator {
+	s := p.Get().(*numberValidator)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled number should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *numberValidatorsPool) RedeemValidator(s *numberValidator) {
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed number should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed number should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *stringValidatorsPool) BorrowValidator() *stringValidator {
+	s := p.Get().(*stringValidator)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled string should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *stringValidatorsPool) RedeemValidator(s *stringValidator) {
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed string should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed string should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *schemaPropsValidatorsPool) BorrowValidator() *schemaPropsValidator {
+	s := p.Get().(*schemaPropsValidator)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled param should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *schemaPropsValidatorsPool) RedeemValidator(s *schemaPropsValidator) {
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed schemaProps should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed schemaProps should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *formatValidatorsPool) BorrowValidator() *formatValidator {
+	s := p.Get().(*formatValidator)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled format should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *formatValidatorsPool) RedeemValidator(s *formatValidator) {
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed format should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed format should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *typeValidatorsPool) BorrowValidator() *typeValidator {
+	s := p.Get().(*typeValidator)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled type should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *typeValidatorsPool) RedeemValidator(s *typeValidator) {
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed type should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic(fmt.Errorf("redeemed type should have been allocated from a fresh or recycled pointer. Got status %s, already redeamed at: %s", x, p.redeemMap[s]))
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *schemasPool) BorrowSchema() *spec.Schema {
+	s := p.Get().(*spec.Schema)
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled spec.Schema should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *schemasPool) RedeemSchema(s *spec.Schema) {
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed spec.Schema should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed spec.Schema should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *resultsPool) BorrowResult() *Result {
+	s := p.Get().(*Result).cleared()
+
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		p.debugMap[s] = statusFresh
+	} else {
+		if x != statusRedeemed {
+			panic("recycled result should have been redeemed")
+		}
+		p.debugMap[s] = statusRecycled
+	}
+	p.allocMap[s] = caller()
+
+	return s
+}
+
+func (p *resultsPool) RedeemResult(s *Result) {
+	if s == emptyResult {
+		if len(s.Errors) > 0 || len(s.Warnings) > 0 {
+			panic("empty result should not mutate")
+		}
+		return
+	}
+	p.mx.Lock()
+	defer p.mx.Unlock()
+	x, ok := p.debugMap[s]
+	if !ok {
+		panic("redeemed Result should have been allocated")
+	}
+	if x != statusRecycled && x != statusFresh {
+		panic("redeemed Result should have been allocated from a fresh or recycled pointer")
+	}
+	p.debugMap[s] = statusRedeemed
+	p.redeemMap[s] = caller()
+	p.Put(s)
+}
+
+func (p *allPools) allIsRedeemed(t testing.TB) bool {
+	outcome := true
+	for k, v := range p.poolOfSchemaValidators.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("schemaValidator should be redeemed. Allocated by: %s", p.poolOfSchemaValidators.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfObjectValidators.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("objectValidator should be redeemed. Allocated by: %s", p.poolOfObjectValidators.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfSliceValidators.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("sliceValidator should be redeemed. Allocated by: %s", p.poolOfSliceValidators.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfItemsValidators.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("itemsValidator should be redeemed. Allocated by: %s", p.poolOfItemsValidators.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfBasicCommonValidators.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("basicCommonValidator should be redeemed. Allocated by: %s", p.poolOfBasicCommonValidators.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfHeaderValidators.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("headerValidator should be redeemed. Allocated by: %s", p.poolOfHeaderValidators.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfParamValidators.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("paramValidator should be redeemed. Allocated by: %s", p.poolOfParamValidators.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfBasicSliceValidators.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("basicSliceValidator should be redeemed. Allocated by: %s", p.poolOfBasicSliceValidators.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfNumberValidators.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("numberValidator should be redeemed. Allocated by: %s", p.poolOfNumberValidators.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfStringValidators.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("stringValidator should be redeemed. Allocated by: %s", p.poolOfStringValidators.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfSchemaPropsValidators.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("schemaPropsValidator should be redeemed. Allocated by: %s", p.poolOfSchemaPropsValidators.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfFormatValidators.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("formatValidator should be redeemed. Allocated by: %s", p.poolOfFormatValidators.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfTypeValidators.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("typeValidator should be redeemed. Allocated by: %s", p.poolOfTypeValidators.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfSchemas.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("schemas should be redeemed. Allocated by: %s", p.poolOfSchemas.allocMap[k])
+		outcome = false
+	}
+	for k, v := range p.poolOfResults.debugMap {
+		if v == statusRedeemed {
+			continue
+		}
+		t.Logf("result should be redeemed. Allocated by: %s", p.poolOfResults.allocMap[k])
+		outcome = false
+	}
+
+	return outcome
+}
+
+func caller() string {
+	pc, _, _, _ := runtime.Caller(3) //nolint:dogsled
+	from, line := runtime.FuncForPC(pc).FileLine(pc)
+
+	return fmt.Sprintf("%s:%d", from, line)
+}
diff --git a/vendor/github.com/go-openapi/validate/result.go b/vendor/github.com/go-openapi/validate/result.go
index 8f5f935e..c80804a9 100644
--- a/vendor/github.com/go-openapi/validate/result.go
+++ b/vendor/github.com/go-openapi/validate/result.go
@@ -15,7 +15,7 @@
 package validate
 
 import (
-	"fmt"
+	stderrors "errors"
 	"reflect"
 	"strings"
 
@@ -23,6 +23,8 @@ import (
 	"github.com/go-openapi/spec"
 )
 
+var emptyResult = &Result{MatchCount: 1}
+
 // Result represents a validation result set, composed of
 // errors and warnings.
 //
@@ -50,8 +52,10 @@ type Result struct {
 	// Schemata for slice items
 	itemSchemata []itemSchemata
 
-	cachedFieldSchemta map[FieldKey][]*spec.Schema
-	cachedItemSchemata map[ItemKey][]*spec.Schema
+	cachedFieldSchemata map[FieldKey][]*spec.Schema
+	cachedItemSchemata  map[ItemKey][]*spec.Schema
+
+	wantsRedeemOnMerge bool
 }
 
 // FieldKey is a pair of an object and a field, usable as a key for a map.
@@ -116,6 +120,9 @@ func (r *Result) Merge(others ...*Result) *Result {
 		}
 		r.mergeWithoutRootSchemata(other)
 		r.rootObjectSchemata.Append(other.rootObjectSchemata)
+		if other.wantsRedeemOnMerge {
+			pools.poolOfResults.RedeemResult(other)
+		}
 	}
 	return r
 }
@@ -132,10 +139,9 @@ func (r *Result) RootObjectSchemata() []*spec.Schema {
 }
 
 // FieldSchemata returns the schemata which apply to fields in objects.
-// nolint: dupl
 func (r *Result) FieldSchemata() map[FieldKey][]*spec.Schema {
-	if r.cachedFieldSchemta != nil {
-		return r.cachedFieldSchemta
+	if r.cachedFieldSchemata != nil {
+		return r.cachedFieldSchemata
 	}
 
 	ret := make(map[FieldKey][]*spec.Schema, len(r.fieldSchemata))
@@ -147,12 +153,12 @@ func (r *Result) FieldSchemata() map[FieldKey][]*spec.Schema {
 			ret[key] = append(ret[key], fs.schemata.multiple...)
 		}
 	}
-	r.cachedFieldSchemta = ret
+	r.cachedFieldSchemata = ret
+
 	return ret
 }
 
 // ItemSchemata returns the schemata which apply to items in slices.
-// nolint: dupl
 func (r *Result) ItemSchemata() map[ItemKey][]*spec.Schema {
 	if r.cachedItemSchemata != nil {
 		return r.cachedItemSchemata
@@ -172,12 +178,13 @@ func (r *Result) ItemSchemata() map[ItemKey][]*spec.Schema {
 }
 
 func (r *Result) resetCaches() {
-	r.cachedFieldSchemta = nil
+	r.cachedFieldSchemata = nil
 	r.cachedItemSchemata = nil
 }
 
 // mergeForField merges other into r, assigning other's root schemata to the given Object and field name.
-// nolint: unparam
+//
+//nolint:unparam
 func (r *Result) mergeForField(obj map[string]interface{}, field string, other *Result) *Result {
 	if other == nil {
 		return r
@@ -188,18 +195,23 @@ func (r *Result) mergeForField(obj map[string]interface{}, field string, other *
 		if r.fieldSchemata == nil {
 			r.fieldSchemata = make([]fieldSchemata, len(obj))
 		}
+		// clone other schemata, as other is about to be redeemed to the pool
 		r.fieldSchemata = append(r.fieldSchemata, fieldSchemata{
 			obj:      obj,
 			field:    field,
-			schemata: other.rootObjectSchemata,
+			schemata: other.rootObjectSchemata.Clone(),
 		})
 	}
+	if other.wantsRedeemOnMerge {
+		pools.poolOfResults.RedeemResult(other)
+	}
 
 	return r
 }
 
 // mergeForSlice merges other into r, assigning other's root schemata to the given slice and index.
-// nolint: unparam
+//
+//nolint:unparam
 func (r *Result) mergeForSlice(slice reflect.Value, i int, other *Result) *Result {
 	if other == nil {
 		return r
@@ -210,29 +222,38 @@ func (r *Result) mergeForSlice(slice reflect.Value, i int, other *Result) *Resul
 		if r.itemSchemata == nil {
 			r.itemSchemata = make([]itemSchemata, slice.Len())
 		}
+		// clone other schemata, as other is about to be redeemed to the pool
 		r.itemSchemata = append(r.itemSchemata, itemSchemata{
 			slice:    slice,
 			index:    i,
-			schemata: other.rootObjectSchemata,
+			schemata: other.rootObjectSchemata.Clone(),
 		})
 	}
 
+	if other.wantsRedeemOnMerge {
+		pools.poolOfResults.RedeemResult(other)
+	}
+
 	return r
 }
 
 // addRootObjectSchemata adds the given schemata for the root object of the result.
-// The slice schemata might be reused. I.e. do not modify it after being added to a result.
+//
+// Since the slice schemata might be reused, it is shallow-cloned before saving it into the result.
 func (r *Result) addRootObjectSchemata(s *spec.Schema) {
-	r.rootObjectSchemata.Append(schemata{one: s})
+	clone := *s
+	r.rootObjectSchemata.Append(schemata{one: &clone})
 }
 
 // addPropertySchemata adds the given schemata for the object and field.
-// The slice schemata might be reused. I.e. do not modify it after being added to a result.
+//
+// Since the slice schemata might be reused, it is shallow-cloned before saving it into the result.
 func (r *Result) addPropertySchemata(obj map[string]interface{}, fld string, schema *spec.Schema) {
 	if r.fieldSchemata == nil {
 		r.fieldSchemata = make([]fieldSchemata, 0, len(obj))
 	}
-	r.fieldSchemata = append(r.fieldSchemata, fieldSchemata{obj: obj, field: fld, schemata: schemata{one: schema}})
+	clone := *schema
+	r.fieldSchemata = append(r.fieldSchemata, fieldSchemata{obj: obj, field: fld, schemata: schemata{one: &clone}})
 }
 
 /*
@@ -255,17 +276,21 @@ func (r *Result) mergeWithoutRootSchemata(other *Result) {
 
 	if other.fieldSchemata != nil {
 		if r.fieldSchemata == nil {
-			r.fieldSchemata = other.fieldSchemata
-		} else {
-			r.fieldSchemata = append(r.fieldSchemata, other.fieldSchemata...)
+			r.fieldSchemata = make([]fieldSchemata, 0, len(other.fieldSchemata))
+		}
+		for _, field := range other.fieldSchemata {
+			field.schemata = field.schemata.Clone()
+			r.fieldSchemata = append(r.fieldSchemata, field)
 		}
 	}
 
 	if other.itemSchemata != nil {
 		if r.itemSchemata == nil {
-			r.itemSchemata = other.itemSchemata
-		} else {
-			r.itemSchemata = append(r.itemSchemata, other.itemSchemata...)
+			r.itemSchemata = make([]itemSchemata, 0, len(other.itemSchemata))
+		}
+		for _, field := range other.itemSchemata {
+			field.schemata = field.schemata.Clone()
+			r.itemSchemata = append(r.itemSchemata, field)
 		}
 	}
 }
@@ -280,6 +305,9 @@ func (r *Result) MergeAsErrors(others ...*Result) *Result {
 			r.AddErrors(other.Errors...)
 			r.AddErrors(other.Warnings...)
 			r.MatchCount += other.MatchCount
+			if other.wantsRedeemOnMerge {
+				pools.poolOfResults.RedeemResult(other)
+			}
 		}
 	}
 	return r
@@ -295,6 +323,9 @@ func (r *Result) MergeAsWarnings(others ...*Result) *Result {
 			r.AddWarnings(other.Errors...)
 			r.AddWarnings(other.Warnings...)
 			r.MatchCount += other.MatchCount
+			if other.wantsRedeemOnMerge {
+				pools.poolOfResults.RedeemResult(other)
+			}
 		}
 	}
 	return r
@@ -356,16 +387,21 @@ func (r *Result) keepRelevantErrors() *Result {
 	strippedErrors := []error{}
 	for _, e := range r.Errors {
 		if strings.HasPrefix(e.Error(), "IMPORTANT!") {
-			strippedErrors = append(strippedErrors, fmt.Errorf(strings.TrimPrefix(e.Error(), "IMPORTANT!")))
+			strippedErrors = append(strippedErrors, stderrors.New(strings.TrimPrefix(e.Error(), "IMPORTANT!")))
 		}
 	}
 	strippedWarnings := []error{}
 	for _, e := range r.Warnings {
 		if strings.HasPrefix(e.Error(), "IMPORTANT!") {
-			strippedWarnings = append(strippedWarnings, fmt.Errorf(strings.TrimPrefix(e.Error(), "IMPORTANT!")))
+			strippedWarnings = append(strippedWarnings, stderrors.New(strings.TrimPrefix(e.Error(), "IMPORTANT!")))
 		}
 	}
-	strippedResult := new(Result)
+	var strippedResult *Result
+	if r.wantsRedeemOnMerge {
+		strippedResult = pools.poolOfResults.BorrowResult()
+	} else {
+		strippedResult = new(Result)
+	}
 	strippedResult.Errors = strippedErrors
 	strippedResult.Warnings = strippedWarnings
 	return strippedResult
@@ -427,6 +463,27 @@ func (r *Result) AsError() error {
 	return errors.CompositeValidationError(r.Errors...)
 }
 
+func (r *Result) cleared() *Result {
+	// clear the Result to be reusable. Keep allocated capacity.
+	r.Errors = r.Errors[:0]
+	r.Warnings = r.Warnings[:0]
+	r.MatchCount = 0
+	r.data = nil
+	r.rootObjectSchemata.one = nil
+	r.rootObjectSchemata.multiple = r.rootObjectSchemata.multiple[:0]
+	r.fieldSchemata = r.fieldSchemata[:0]
+	r.itemSchemata = r.itemSchemata[:0]
+	for k := range r.cachedFieldSchemata {
+		delete(r.cachedFieldSchemata, k)
+	}
+	for k := range r.cachedItemSchemata {
+		delete(r.cachedItemSchemata, k)
+	}
+	r.wantsRedeemOnMerge = true // mark this result as eligible for redeem when merged into another
+
+	return r
+}
+
 // schemata is an arbitrary number of schemata. It does a distinction between zero,
 // one and many schemata to avoid slice allocations.
 type schemata struct {
@@ -453,7 +510,7 @@ func (s *schemata) Slice() []*spec.Schema {
 	return s.multiple
 }
 
-// appendSchemata appends the schemata in other to s. It mutated s in-place.
+// appendSchemata appends the schemata in other to s. It mutates s in-place.
 func (s *schemata) Append(other schemata) {
 	if other.one == nil && len(other.multiple) == 0 {
 		return
@@ -484,3 +541,23 @@ func (s *schemata) Append(other schemata) {
 		}
 	}
 }
+
+func (s schemata) Clone() schemata {
+	var clone schemata
+
+	if s.one != nil {
+		clone.one = new(spec.Schema)
+		*clone.one = *s.one
+	}
+
+	if len(s.multiple) > 0 {
+		clone.multiple = make([]*spec.Schema, len(s.multiple))
+		for idx := 0; idx < len(s.multiple); idx++ {
+			sp := new(spec.Schema)
+			*sp = *s.multiple[idx]
+			clone.multiple[idx] = sp
+		}
+	}
+
+	return clone
+}
diff --git a/vendor/github.com/go-openapi/validate/schema.go b/vendor/github.com/go-openapi/validate/schema.go
index b817eb0e..db65264f 100644
--- a/vendor/github.com/go-openapi/validate/schema.go
+++ b/vendor/github.com/go-openapi/validate/schema.go
@@ -24,32 +24,32 @@ import (
 	"github.com/go-openapi/swag"
 )
 
-var (
-	specSchemaType    = reflect.TypeOf(&spec.Schema{})
-	specParameterType = reflect.TypeOf(&spec.Parameter{})
-	specHeaderType    = reflect.TypeOf(&spec.Header{})
-	// specItemsType     = reflect.TypeOf(&spec.Items{})
-)
-
 // SchemaValidator validates data against a JSON schema
 type SchemaValidator struct {
 	Path         string
 	in           string
 	Schema       *spec.Schema
-	validators   []valueValidator
+	validators   [8]valueValidator
 	Root         interface{}
 	KnownFormats strfmt.Registry
-	Options      SchemaValidatorOptions
+	Options      *SchemaValidatorOptions
 }
 
 // AgainstSchema validates the specified data against the provided schema, using a registry of supported formats.
 //
 // When no pre-parsed *spec.Schema structure is provided, it uses a JSON schema as default. See example.
 func AgainstSchema(schema *spec.Schema, data interface{}, formats strfmt.Registry, options ...Option) error {
-	res := NewSchemaValidator(schema, nil, "", formats, options...).Validate(data)
+	res := NewSchemaValidator(schema, nil, "", formats,
+		append(options, WithRecycleValidators(true), withRecycleResults(true))...,
+	).Validate(data)
+	defer func() {
+		pools.poolOfResults.RedeemResult(res)
+	}()
+
 	if res.HasErrors() {
 		return errors.CompositeValidationError(res.Errors...)
 	}
+
 	return nil
 }
 
@@ -57,6 +57,15 @@ func AgainstSchema(schema *spec.Schema, data interface{}, formats strfmt.Registr
 //
 // Panics if the provided schema is invalid.
 func NewSchemaValidator(schema *spec.Schema, rootSchema interface{}, root string, formats strfmt.Registry, options ...Option) *SchemaValidator {
+	opts := new(SchemaValidatorOptions)
+	for _, o := range options {
+		o(opts)
+	}
+
+	return newSchemaValidator(schema, rootSchema, root, formats, opts)
+}
+
+func newSchemaValidator(schema *spec.Schema, rootSchema interface{}, root string, formats strfmt.Registry, opts *SchemaValidatorOptions) *SchemaValidator {
 	if schema == nil {
 		return nil
 	}
@@ -72,17 +81,26 @@ func NewSchemaValidator(schema *spec.Schema, rootSchema interface{}, root string
 			panic(msg)
 		}
 	}
-	s := SchemaValidator{
-		Path:         root,
-		in:           "body",
-		Schema:       schema,
-		Root:         rootSchema,
-		KnownFormats: formats,
-		Options:      SchemaValidatorOptions{}}
-	for _, o := range options {
-		o(&s.Options)
+
+	if opts == nil {
+		opts = new(SchemaValidatorOptions)
 	}
-	s.validators = []valueValidator{
+
+	var s *SchemaValidator
+	if opts.recycleValidators {
+		s = pools.poolOfSchemaValidators.BorrowValidator()
+	} else {
+		s = new(SchemaValidator)
+	}
+
+	s.Path = root
+	s.in = "body"
+	s.Schema = schema
+	s.Root = rootSchema
+	s.Options = opts
+	s.KnownFormats = formats
+
+	s.validators = [8]valueValidator{
 		s.typeValidator(),
 		s.schemaPropsValidator(),
 		s.stringValidator(),
@@ -92,7 +110,8 @@ func NewSchemaValidator(schema *spec.Schema, rootSchema interface{}, root string
 		s.commonValidator(),
 		s.objectValidator(),
 	}
-	return &s
+
+	return s
 }
 
 // SetPath sets the path for this schema valdiator
@@ -101,24 +120,46 @@ func (s *SchemaValidator) SetPath(path string) {
 }
 
 // Applies returns true when this schema validator applies
-func (s *SchemaValidator) Applies(source interface{}, kind reflect.Kind) bool {
+func (s *SchemaValidator) Applies(source interface{}, _ reflect.Kind) bool {
 	_, ok := source.(*spec.Schema)
 	return ok
 }
 
 // Validate validates the data against the schema
 func (s *SchemaValidator) Validate(data interface{}) *Result {
-	result := &Result{data: data}
 	if s == nil {
-		return result
+		return emptyResult
 	}
-	if s.Schema != nil {
+
+	if s.Options.recycleValidators {
+		defer func() {
+			s.redeemChildren()
+			s.redeem() // one-time use validator
+		}()
+	}
+
+	var result *Result
+	if s.Options.recycleResult {
+		result = pools.poolOfResults.BorrowResult()
+		result.data = data
+	} else {
+		result = &Result{data: data}
+	}
+
+	if s.Schema != nil && !s.Options.skipSchemataResult {
 		result.addRootObjectSchemata(s.Schema)
 	}
 
 	if data == nil {
+		// early exit with minimal validation
 		result.Merge(s.validators[0].Validate(data)) // type validator
 		result.Merge(s.validators[6].Validate(data)) // common validator
+
+		if s.Options.recycleValidators {
+			s.validators[0] = nil
+			s.validators[6] = nil
+		}
+
 		return result
 	}
 
@@ -147,6 +188,7 @@ func (s *SchemaValidator) Validate(data interface{}) *Result {
 			if erri != nil {
 				result.AddErrors(invalidTypeConversionMsg(s.Path, erri))
 				result.Inc()
+
 				return result
 			}
 			d = in
@@ -155,6 +197,7 @@ func (s *SchemaValidator) Validate(data interface{}) *Result {
 			if errf != nil {
 				result.AddErrors(invalidTypeConversionMsg(s.Path, errf))
 				result.Inc()
+
 				return result
 			}
 			d = nf
@@ -164,14 +207,26 @@ func (s *SchemaValidator) Validate(data interface{}) *Result {
 		kind = tpe.Kind()
 	}
 
-	for _, v := range s.validators {
+	for idx, v := range s.validators {
 		if !v.Applies(s.Schema, kind) {
-			debugLog("%T does not apply for %v", v, kind)
+			if s.Options.recycleValidators {
+				// Validate won't be called, so relinquish this validator
+				if redeemableChildren, ok := v.(interface{ redeemChildren() }); ok {
+					redeemableChildren.redeemChildren()
+				}
+				if redeemable, ok := v.(interface{ redeem() }); ok {
+					redeemable.redeem()
+				}
+				s.validators[idx] = nil // prevents further (unsafe) usage
+			}
+
 			continue
 		}
 
-		err := v.Validate(d)
-		result.Merge(err)
+		result.Merge(v.Validate(d))
+		if s.Options.recycleValidators {
+			s.validators[idx] = nil // prevents further (unsafe) usage
+		}
 		result.Inc()
 	}
 	result.Inc()
@@ -180,81 +235,120 @@ func (s *SchemaValidator) Validate(data interface{}) *Result {
 }
 
 func (s *SchemaValidator) typeValidator() valueValidator {
-	return &typeValidator{Type: s.Schema.Type, Nullable: s.Schema.Nullable, Format: s.Schema.Format, In: s.in, Path: s.Path}
+	return newTypeValidator(
+		s.Path,
+		s.in,
+		s.Schema.Type,
+		s.Schema.Nullable,
+		s.Schema.Format,
+		s.Options,
+	)
 }
 
 func (s *SchemaValidator) commonValidator() valueValidator {
-	return &basicCommonValidator{
-		Path: s.Path,
-		In:   s.in,
-		Enum: s.Schema.Enum,
-	}
+	return newBasicCommonValidator(
+		s.Path,
+		s.in,
+		s.Schema.Default,
+		s.Schema.Enum,
+		s.Options,
+	)
 }
 
 func (s *SchemaValidator) sliceValidator() valueValidator {
-	return &schemaSliceValidator{
-		Path:            s.Path,
-		In:              s.in,
-		MaxItems:        s.Schema.MaxItems,
-		MinItems:        s.Schema.MinItems,
-		UniqueItems:     s.Schema.UniqueItems,
-		AdditionalItems: s.Schema.AdditionalItems,
-		Items:           s.Schema.Items,
-		Root:            s.Root,
-		KnownFormats:    s.KnownFormats,
-		Options:         s.Options,
-	}
+	return newSliceValidator(
+		s.Path,
+		s.in,
+		s.Schema.MaxItems,
+		s.Schema.MinItems,
+		s.Schema.UniqueItems,
+		s.Schema.AdditionalItems,
+		s.Schema.Items,
+		s.Root,
+		s.KnownFormats,
+		s.Options,
+	)
 }
 
 func (s *SchemaValidator) numberValidator() valueValidator {
-	return &numberValidator{
-		Path:             s.Path,
-		In:               s.in,
-		Default:          s.Schema.Default,
-		MultipleOf:       s.Schema.MultipleOf,
-		Maximum:          s.Schema.Maximum,
-		ExclusiveMaximum: s.Schema.ExclusiveMaximum,
-		Minimum:          s.Schema.Minimum,
-		ExclusiveMinimum: s.Schema.ExclusiveMinimum,
-	}
+	return newNumberValidator(
+		s.Path,
+		s.in,
+		s.Schema.Default,
+		s.Schema.MultipleOf,
+		s.Schema.Maximum,
+		s.Schema.ExclusiveMaximum,
+		s.Schema.Minimum,
+		s.Schema.ExclusiveMinimum,
+		"",
+		"",
+		s.Options,
+	)
 }
 
 func (s *SchemaValidator) stringValidator() valueValidator {
-	return &stringValidator{
-		Path:      s.Path,
-		In:        s.in,
-		MaxLength: s.Schema.MaxLength,
-		MinLength: s.Schema.MinLength,
-		Pattern:   s.Schema.Pattern,
-	}
+	return newStringValidator(
+		s.Path,
+		s.in,
+		nil,
+		false,
+		false,
+		s.Schema.MaxLength,
+		s.Schema.MinLength,
+		s.Schema.Pattern,
+		s.Options,
+	)
 }
 
 func (s *SchemaValidator) formatValidator() valueValidator {
-	return &formatValidator{
-		Path:         s.Path,
-		In:           s.in,
-		Format:       s.Schema.Format,
-		KnownFormats: s.KnownFormats,
-	}
+	return newFormatValidator(
+		s.Path,
+		s.in,
+		s.Schema.Format,
+		s.KnownFormats,
+		s.Options,
+	)
 }
 
 func (s *SchemaValidator) schemaPropsValidator() valueValidator {
 	sch := s.Schema
-	return newSchemaPropsValidator(s.Path, s.in, sch.AllOf, sch.OneOf, sch.AnyOf, sch.Not, sch.Dependencies, s.Root, s.KnownFormats, s.Options.Options()...)
+	return newSchemaPropsValidator(
+		s.Path, s.in, sch.AllOf, sch.OneOf, sch.AnyOf, sch.Not, sch.Dependencies, s.Root, s.KnownFormats,
+		s.Options,
+	)
 }
 
 func (s *SchemaValidator) objectValidator() valueValidator {
-	return &objectValidator{
-		Path:                 s.Path,
-		In:                   s.in,
-		MaxProperties:        s.Schema.MaxProperties,
-		MinProperties:        s.Schema.MinProperties,
-		Required:             s.Schema.Required,
-		Properties:           s.Schema.Properties,
-		AdditionalProperties: s.Schema.AdditionalProperties,
-		PatternProperties:    s.Schema.PatternProperties,
-		Root:                 s.Root,
-		KnownFormats:         s.KnownFormats,
-		Options:              s.Options,
+	return newObjectValidator(
+		s.Path,
+		s.in,
+		s.Schema.MaxProperties,
+		s.Schema.MinProperties,
+		s.Schema.Required,
+		s.Schema.Properties,
+		s.Schema.AdditionalProperties,
+		s.Schema.PatternProperties,
+		s.Root,
+		s.KnownFormats,
+		s.Options,
+	)
+}
+
+func (s *SchemaValidator) redeem() {
+	pools.poolOfSchemaValidators.RedeemValidator(s)
+}
+
+func (s *SchemaValidator) redeemChildren() {
+	for i, validator := range s.validators {
+		if validator == nil {
+			continue
+		}
+		if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok {
+			redeemableChildren.redeemChildren()
+		}
+		if redeemable, ok := validator.(interface{ redeem() }); ok {
+			redeemable.redeem()
+		}
+		s.validators[i] = nil // free up allocated children if not in pool
 	}
 }
diff --git a/vendor/github.com/go-openapi/validate/schema_option.go b/vendor/github.com/go-openapi/validate/schema_option.go
index 4b4879de..65eeebea 100644
--- a/vendor/github.com/go-openapi/validate/schema_option.go
+++ b/vendor/github.com/go-openapi/validate/schema_option.go
@@ -18,6 +18,9 @@ package validate
 type SchemaValidatorOptions struct {
 	EnableObjectArrayTypeCheck    bool
 	EnableArrayMustHaveItemsCheck bool
+	recycleValidators             bool
+	recycleResult                 bool
+	skipSchemataResult            bool
 }
 
 // Option sets optional rules for schema validation
@@ -45,10 +48,36 @@ func SwaggerSchema(enable bool) Option {
 	}
 }
 
-// Options returns current options
+// WithRecycleValidators saves memory allocations and makes validators
+// available for a single use of Validate() only.
+//
+// When a validator is recycled, called MUST not call the Validate() method twice.
+func WithRecycleValidators(enable bool) Option {
+	return func(svo *SchemaValidatorOptions) {
+		svo.recycleValidators = enable
+	}
+}
+
+func withRecycleResults(enable bool) Option {
+	return func(svo *SchemaValidatorOptions) {
+		svo.recycleResult = enable
+	}
+}
+
+// WithSkipSchemataResult skips the deep audit payload stored in validation Result
+func WithSkipSchemataResult(enable bool) Option {
+	return func(svo *SchemaValidatorOptions) {
+		svo.skipSchemataResult = enable
+	}
+}
+
+// Options returns the current set of options
 func (svo SchemaValidatorOptions) Options() []Option {
 	return []Option{
 		EnableObjectArrayTypeCheck(svo.EnableObjectArrayTypeCheck),
 		EnableArrayMustHaveItemsCheck(svo.EnableArrayMustHaveItemsCheck),
+		WithRecycleValidators(svo.recycleValidators),
+		withRecycleResults(svo.recycleResult),
+		WithSkipSchemataResult(svo.skipSchemataResult),
 	}
 }
diff --git a/vendor/github.com/go-openapi/validate/schema_props.go b/vendor/github.com/go-openapi/validate/schema_props.go
index 9bac3d29..1ca37924 100644
--- a/vendor/github.com/go-openapi/validate/schema_props.go
+++ b/vendor/github.com/go-openapi/validate/schema_props.go
@@ -30,211 +30,327 @@ type schemaPropsValidator struct {
 	AnyOf           []spec.Schema
 	Not             *spec.Schema
 	Dependencies    spec.Dependencies
-	anyOfValidators []SchemaValidator
-	allOfValidators []SchemaValidator
-	oneOfValidators []SchemaValidator
+	anyOfValidators []*SchemaValidator
+	allOfValidators []*SchemaValidator
+	oneOfValidators []*SchemaValidator
 	notValidator    *SchemaValidator
 	Root            interface{}
 	KnownFormats    strfmt.Registry
-	Options         SchemaValidatorOptions
+	Options         *SchemaValidatorOptions
 }
 
 func (s *schemaPropsValidator) SetPath(path string) {
 	s.Path = path
 }
 
-func newSchemaPropsValidator(path string, in string, allOf, oneOf, anyOf []spec.Schema, not *spec.Schema, deps spec.Dependencies, root interface{}, formats strfmt.Registry, options ...Option) *schemaPropsValidator {
-	anyValidators := make([]SchemaValidator, 0, len(anyOf))
-	for _, v := range anyOf {
-		v := v
-		anyValidators = append(anyValidators, *NewSchemaValidator(&v, root, path, formats, options...))
+func newSchemaPropsValidator(
+	path string, in string, allOf, oneOf, anyOf []spec.Schema, not *spec.Schema, deps spec.Dependencies, root interface{}, formats strfmt.Registry,
+	opts *SchemaValidatorOptions) *schemaPropsValidator {
+	if opts == nil {
+		opts = new(SchemaValidatorOptions)
 	}
-	allValidators := make([]SchemaValidator, 0, len(allOf))
-	for _, v := range allOf {
-		v := v
-		allValidators = append(allValidators, *NewSchemaValidator(&v, root, path, formats, options...))
+
+	anyValidators := make([]*SchemaValidator, 0, len(anyOf))
+	for i := range anyOf {
+		anyValidators = append(anyValidators, newSchemaValidator(&anyOf[i], root, path, formats, opts))
+	}
+	allValidators := make([]*SchemaValidator, 0, len(allOf))
+	for i := range allOf {
+		allValidators = append(allValidators, newSchemaValidator(&allOf[i], root, path, formats, opts))
 	}
-	oneValidators := make([]SchemaValidator, 0, len(oneOf))
-	for _, v := range oneOf {
-		v := v
-		oneValidators = append(oneValidators, *NewSchemaValidator(&v, root, path, formats, options...))
+	oneValidators := make([]*SchemaValidator, 0, len(oneOf))
+	for i := range oneOf {
+		oneValidators = append(oneValidators, newSchemaValidator(&oneOf[i], root, path, formats, opts))
 	}
 
 	var notValidator *SchemaValidator
 	if not != nil {
-		notValidator = NewSchemaValidator(not, root, path, formats, options...)
-	}
-
-	schOptions := &SchemaValidatorOptions{}
-	for _, o := range options {
-		o(schOptions)
-	}
-	return &schemaPropsValidator{
-		Path:            path,
-		In:              in,
-		AllOf:           allOf,
-		OneOf:           oneOf,
-		AnyOf:           anyOf,
-		Not:             not,
-		Dependencies:    deps,
-		anyOfValidators: anyValidators,
-		allOfValidators: allValidators,
-		oneOfValidators: oneValidators,
-		notValidator:    notValidator,
-		Root:            root,
-		KnownFormats:    formats,
-		Options:         *schOptions,
+		notValidator = newSchemaValidator(not, root, path, formats, opts)
+	}
+
+	var s *schemaPropsValidator
+	if opts.recycleValidators {
+		s = pools.poolOfSchemaPropsValidators.BorrowValidator()
+	} else {
+		s = new(schemaPropsValidator)
 	}
+
+	s.Path = path
+	s.In = in
+	s.AllOf = allOf
+	s.OneOf = oneOf
+	s.AnyOf = anyOf
+	s.Not = not
+	s.Dependencies = deps
+	s.anyOfValidators = anyValidators
+	s.allOfValidators = allValidators
+	s.oneOfValidators = oneValidators
+	s.notValidator = notValidator
+	s.Root = root
+	s.KnownFormats = formats
+	s.Options = opts
+
+	return s
 }
 
-func (s *schemaPropsValidator) Applies(source interface{}, kind reflect.Kind) bool {
-	r := reflect.TypeOf(source) == specSchemaType
-	debugLog("schema props validator for %q applies %t for %T (kind: %v)\n", s.Path, r, source, kind)
-	return r
+func (s *schemaPropsValidator) Applies(source interface{}, _ reflect.Kind) bool {
+	_, isSchema := source.(*spec.Schema)
+	return isSchema
 }
 
 func (s *schemaPropsValidator) Validate(data interface{}) *Result {
-	mainResult := new(Result)
+	var mainResult *Result
+	if s.Options.recycleResult {
+		mainResult = pools.poolOfResults.BorrowResult()
+	} else {
+		mainResult = new(Result)
+	}
 
 	// Intermediary error results
 
 	// IMPORTANT! messages from underlying validators
-	keepResultAnyOf := new(Result)
-	keepResultOneOf := new(Result)
-	keepResultAllOf := new(Result)
+	var keepResultAnyOf, keepResultOneOf, keepResultAllOf *Result
+
+	if s.Options.recycleValidators {
+		defer func() {
+			s.redeemChildren()
+			s.redeem()
+
+			// results are redeemed when merged
+		}()
+	}
 
-	// Validates at least one in anyOf schemas
-	var firstSuccess *Result
 	if len(s.anyOfValidators) > 0 {
-		var bestFailures *Result
-		succeededOnce := false
-		for _, anyOfSchema := range s.anyOfValidators {
-			result := anyOfSchema.Validate(data)
-			// We keep inner IMPORTANT! errors no matter what MatchCount tells us
-			keepResultAnyOf.Merge(result.keepRelevantErrors())
-			if result.IsValid() {
-				bestFailures = nil
-				succeededOnce = true
-				if firstSuccess == nil {
-					firstSuccess = result
-				}
-				keepResultAnyOf = new(Result)
-				break
-			}
-			// MatchCount is used to select errors from the schema with most positive checks
-			if bestFailures == nil || result.MatchCount > bestFailures.MatchCount {
-				bestFailures = result
+		keepResultAnyOf = pools.poolOfResults.BorrowResult()
+		s.validateAnyOf(data, mainResult, keepResultAnyOf)
+	}
+
+	if len(s.oneOfValidators) > 0 {
+		keepResultOneOf = pools.poolOfResults.BorrowResult()
+		s.validateOneOf(data, mainResult, keepResultOneOf)
+	}
+
+	if len(s.allOfValidators) > 0 {
+		keepResultAllOf = pools.poolOfResults.BorrowResult()
+		s.validateAllOf(data, mainResult, keepResultAllOf)
+	}
+
+	if s.notValidator != nil {
+		s.validateNot(data, mainResult)
+	}
+
+	if s.Dependencies != nil && len(s.Dependencies) > 0 && reflect.TypeOf(data).Kind() == reflect.Map {
+		s.validateDependencies(data, mainResult)
+	}
+
+	mainResult.Inc()
+
+	// In the end we retain best failures for schema validation
+	// plus, if any, composite errors which may explain special cases (tagged as IMPORTANT!).
+	return mainResult.Merge(keepResultAllOf, keepResultOneOf, keepResultAnyOf)
+}
+
+func (s *schemaPropsValidator) validateAnyOf(data interface{}, mainResult, keepResultAnyOf *Result) {
+	// Validates at least one in anyOf schemas
+	var bestFailures *Result
+
+	for i, anyOfSchema := range s.anyOfValidators {
+		result := anyOfSchema.Validate(data)
+		if s.Options.recycleValidators {
+			s.anyOfValidators[i] = nil
+		}
+		// We keep inner IMPORTANT! errors no matter what MatchCount tells us
+		keepResultAnyOf.Merge(result.keepRelevantErrors()) // merges (and redeems) a new instance of Result
+
+		if result.IsValid() {
+			if bestFailures != nil && bestFailures.wantsRedeemOnMerge {
+				pools.poolOfResults.RedeemResult(bestFailures)
 			}
+
+			_ = keepResultAnyOf.cleared()
+			mainResult.Merge(result)
+
+			return
 		}
 
-		if !succeededOnce {
-			mainResult.AddErrors(mustValidateAtLeastOneSchemaMsg(s.Path))
+		// MatchCount is used to select errors from the schema with most positive checks
+		if bestFailures == nil || result.MatchCount > bestFailures.MatchCount {
+			if bestFailures != nil && bestFailures.wantsRedeemOnMerge {
+				pools.poolOfResults.RedeemResult(bestFailures)
+			}
+			bestFailures = result
+
+			continue
 		}
-		if bestFailures != nil {
-			mainResult.Merge(bestFailures)
-		} else if firstSuccess != nil {
-			mainResult.Merge(firstSuccess)
+
+		if result.wantsRedeemOnMerge {
+			pools.poolOfResults.RedeemResult(result) // this result is ditched
 		}
 	}
 
+	mainResult.AddErrors(mustValidateAtLeastOneSchemaMsg(s.Path))
+	mainResult.Merge(bestFailures)
+}
+
+func (s *schemaPropsValidator) validateOneOf(data interface{}, mainResult, keepResultOneOf *Result) {
 	// Validates exactly one in oneOf schemas
-	if len(s.oneOfValidators) > 0 {
-		var bestFailures *Result
-		var firstSuccess *Result
-		validated := 0
-
-		for _, oneOfSchema := range s.oneOfValidators {
-			result := oneOfSchema.Validate(data)
-			// We keep inner IMPORTANT! errors no matter what MatchCount tells us
-			keepResultOneOf.Merge(result.keepRelevantErrors())
-			if result.IsValid() {
-				validated++
-				bestFailures = nil
-				if firstSuccess == nil {
-					firstSuccess = result
-				}
-				keepResultOneOf = new(Result)
-				continue
-			}
-			// MatchCount is used to select errors from the schema with most positive checks
-			if validated == 0 && (bestFailures == nil || result.MatchCount > bestFailures.MatchCount) {
-				bestFailures = result
-			}
+	var (
+		firstSuccess, bestFailures *Result
+		validated                  int
+	)
+
+	for i, oneOfSchema := range s.oneOfValidators {
+		result := oneOfSchema.Validate(data)
+		if s.Options.recycleValidators {
+			s.oneOfValidators[i] = nil
 		}
 
-		if validated != 1 {
-			var additionalMsg string
-			if validated == 0 {
-				additionalMsg = "Found none valid"
-			} else {
-				additionalMsg = fmt.Sprintf("Found %d valid alternatives", validated)
-			}
+		// We keep inner IMPORTANT! errors no matter what MatchCount tells us
+		keepResultOneOf.Merge(result.keepRelevantErrors()) // merges (and redeems) a new instance of Result
 
-			mainResult.AddErrors(mustValidateOnlyOneSchemaMsg(s.Path, additionalMsg))
-			if bestFailures != nil {
-				mainResult.Merge(bestFailures)
-			}
-		} else if firstSuccess != nil {
-			mainResult.Merge(firstSuccess)
-		}
-	}
+		if result.IsValid() {
+			validated++
+			_ = keepResultOneOf.cleared()
 
-	// Validates all of allOf schemas
-	if len(s.allOfValidators) > 0 {
-		validated := 0
-
-		for _, allOfSchema := range s.allOfValidators {
-			result := allOfSchema.Validate(data)
-			// We keep inner IMPORTANT! errors no matter what MatchCount tells us
-			keepResultAllOf.Merge(result.keepRelevantErrors())
-			// keepResultAllOf.Merge(result)
-			if result.IsValid() {
-				validated++
+			if firstSuccess == nil {
+				firstSuccess = result
+			} else if result.wantsRedeemOnMerge {
+				pools.poolOfResults.RedeemResult(result) // this result is ditched
 			}
-			mainResult.Merge(result)
+
+			continue
 		}
 
-		if validated != len(s.allOfValidators) {
-			additionalMsg := ""
-			if validated == 0 {
-				additionalMsg = ". None validated"
+		// MatchCount is used to select errors from the schema with most positive checks
+		if validated == 0 && (bestFailures == nil || result.MatchCount > bestFailures.MatchCount) {
+			if bestFailures != nil && bestFailures.wantsRedeemOnMerge {
+				pools.poolOfResults.RedeemResult(bestFailures)
 			}
+			bestFailures = result
+		} else if result.wantsRedeemOnMerge {
+			pools.poolOfResults.RedeemResult(result) // this result is ditched
+		}
+	}
 
-			mainResult.AddErrors(mustValidateAllSchemasMsg(s.Path, additionalMsg))
+	switch validated {
+	case 0:
+		mainResult.AddErrors(mustValidateOnlyOneSchemaMsg(s.Path, "Found none valid"))
+		mainResult.Merge(bestFailures)
+		// firstSucess necessarily nil
+	case 1:
+		mainResult.Merge(firstSuccess)
+		if bestFailures != nil && bestFailures.wantsRedeemOnMerge {
+			pools.poolOfResults.RedeemResult(bestFailures)
+		}
+	default:
+		mainResult.AddErrors(mustValidateOnlyOneSchemaMsg(s.Path, fmt.Sprintf("Found %d valid alternatives", validated)))
+		mainResult.Merge(bestFailures)
+		if firstSuccess != nil && firstSuccess.wantsRedeemOnMerge {
+			pools.poolOfResults.RedeemResult(firstSuccess)
 		}
 	}
+}
 
-	if s.notValidator != nil {
-		result := s.notValidator.Validate(data)
+func (s *schemaPropsValidator) validateAllOf(data interface{}, mainResult, keepResultAllOf *Result) {
+	// Validates all of allOf schemas
+	var validated int
+
+	for i, allOfSchema := range s.allOfValidators {
+		result := allOfSchema.Validate(data)
+		if s.Options.recycleValidators {
+			s.allOfValidators[i] = nil
+		}
 		// We keep inner IMPORTANT! errors no matter what MatchCount tells us
+		keepResultAllOf.Merge(result.keepRelevantErrors())
 		if result.IsValid() {
-			mainResult.AddErrors(mustNotValidatechemaMsg(s.Path))
+			validated++
 		}
+		mainResult.Merge(result)
 	}
 
-	if s.Dependencies != nil && len(s.Dependencies) > 0 && reflect.TypeOf(data).Kind() == reflect.Map {
-		val := data.(map[string]interface{})
-		for key := range val {
-			if dep, ok := s.Dependencies[key]; ok {
+	switch validated {
+	case 0:
+		mainResult.AddErrors(mustValidateAllSchemasMsg(s.Path, ". None validated"))
+	case len(s.allOfValidators):
+	default:
+		mainResult.AddErrors(mustValidateAllSchemasMsg(s.Path, ""))
+	}
+}
 
-				if dep.Schema != nil {
-					mainResult.Merge(NewSchemaValidator(dep.Schema, s.Root, s.Path+"."+key, s.KnownFormats, s.Options.Options()...).Validate(data))
-					continue
-				}
+func (s *schemaPropsValidator) validateNot(data interface{}, mainResult *Result) {
+	result := s.notValidator.Validate(data)
+	if s.Options.recycleValidators {
+		s.notValidator = nil
+	}
+	// We keep inner IMPORTANT! errors no matter what MatchCount tells us
+	if result.IsValid() {
+		mainResult.AddErrors(mustNotValidatechemaMsg(s.Path))
+	}
+	if result.wantsRedeemOnMerge {
+		pools.poolOfResults.RedeemResult(result) // this result is ditched
+	}
+}
+
+func (s *schemaPropsValidator) validateDependencies(data interface{}, mainResult *Result) {
+	val := data.(map[string]interface{})
+	for key := range val {
+		dep, ok := s.Dependencies[key]
+		if !ok {
+			continue
+		}
+
+		if dep.Schema != nil {
+			mainResult.Merge(
+				newSchemaValidator(dep.Schema, s.Root, s.Path+"."+key, s.KnownFormats, s.Options).Validate(data),
+			)
+			continue
+		}
 
-				if len(dep.Property) > 0 {
-					for _, depKey := range dep.Property {
-						if _, ok := val[depKey]; !ok {
-							mainResult.AddErrors(hasADependencyMsg(s.Path, depKey))
-						}
-					}
+		if len(dep.Property) > 0 {
+			for _, depKey := range dep.Property {
+				if _, ok := val[depKey]; !ok {
+					mainResult.AddErrors(hasADependencyMsg(s.Path, depKey))
 				}
 			}
 		}
 	}
+}
 
-	mainResult.Inc()
-	// In the end we retain best failures for schema validation
-	// plus, if any, composite errors which may explain special cases (tagged as IMPORTANT!).
-	return mainResult.Merge(keepResultAllOf, keepResultOneOf, keepResultAnyOf)
+func (s *schemaPropsValidator) redeem() {
+	pools.poolOfSchemaPropsValidators.RedeemValidator(s)
+}
+
+func (s *schemaPropsValidator) redeemChildren() {
+	for _, v := range s.anyOfValidators {
+		if v == nil {
+			continue
+		}
+		v.redeemChildren()
+		v.redeem()
+	}
+	s.anyOfValidators = nil
+
+	for _, v := range s.allOfValidators {
+		if v == nil {
+			continue
+		}
+		v.redeemChildren()
+		v.redeem()
+	}
+	s.allOfValidators = nil
+
+	for _, v := range s.oneOfValidators {
+		if v == nil {
+			continue
+		}
+		v.redeemChildren()
+		v.redeem()
+	}
+	s.oneOfValidators = nil
+
+	if s.notValidator != nil {
+		s.notValidator.redeemChildren()
+		s.notValidator.redeem()
+		s.notValidator = nil
+	}
 }
diff --git a/vendor/github.com/go-openapi/validate/slice_validator.go b/vendor/github.com/go-openapi/validate/slice_validator.go
index aa429f51..13bb0208 100644
--- a/vendor/github.com/go-openapi/validate/slice_validator.go
+++ b/vendor/github.com/go-openapi/validate/slice_validator.go
@@ -32,7 +32,36 @@ type schemaSliceValidator struct {
 	Items           *spec.SchemaOrArray
 	Root            interface{}
 	KnownFormats    strfmt.Registry
-	Options         SchemaValidatorOptions
+	Options         *SchemaValidatorOptions
+}
+
+func newSliceValidator(path, in string,
+	maxItems, minItems *int64, uniqueItems bool,
+	additionalItems *spec.SchemaOrBool, items *spec.SchemaOrArray,
+	root interface{}, formats strfmt.Registry, opts *SchemaValidatorOptions) *schemaSliceValidator {
+	if opts == nil {
+		opts = new(SchemaValidatorOptions)
+	}
+
+	var v *schemaSliceValidator
+	if opts.recycleValidators {
+		v = pools.poolOfSliceValidators.BorrowValidator()
+	} else {
+		v = new(schemaSliceValidator)
+	}
+
+	v.Path = path
+	v.In = in
+	v.MaxItems = maxItems
+	v.MinItems = minItems
+	v.UniqueItems = uniqueItems
+	v.AdditionalItems = additionalItems
+	v.Items = items
+	v.Root = root
+	v.KnownFormats = formats
+	v.Options = opts
+
+	return v
 }
 
 func (s *schemaSliceValidator) SetPath(path string) {
@@ -46,7 +75,18 @@ func (s *schemaSliceValidator) Applies(source interface{}, kind reflect.Kind) bo
 }
 
 func (s *schemaSliceValidator) Validate(data interface{}) *Result {
-	result := new(Result)
+	if s.Options.recycleValidators {
+		defer func() {
+			s.redeem()
+		}()
+	}
+
+	var result *Result
+	if s.Options.recycleResult {
+		result = pools.poolOfResults.BorrowResult()
+	} else {
+		result = new(Result)
+	}
 	if data == nil {
 		return result
 	}
@@ -54,8 +94,8 @@ func (s *schemaSliceValidator) Validate(data interface{}) *Result {
 	size := val.Len()
 
 	if s.Items != nil && s.Items.Schema != nil {
-		validator := NewSchemaValidator(s.Items.Schema, s.Root, s.Path, s.KnownFormats, s.Options.Options()...)
 		for i := 0; i < size; i++ {
+			validator := newSchemaValidator(s.Items.Schema, s.Root, s.Path, s.KnownFormats, s.Options)
 			validator.SetPath(fmt.Sprintf("%s.%d", s.Path, i))
 			value := val.Index(i)
 			result.mergeForSlice(val, i, validator.Validate(value.Interface()))
@@ -66,10 +106,11 @@ func (s *schemaSliceValidator) Validate(data interface{}) *Result {
 	if s.Items != nil && len(s.Items.Schemas) > 0 {
 		itemsSize = len(s.Items.Schemas)
 		for i := 0; i < itemsSize; i++ {
-			validator := NewSchemaValidator(&s.Items.Schemas[i], s.Root, fmt.Sprintf("%s.%d", s.Path, i), s.KnownFormats, s.Options.Options()...)
-			if val.Len() <= i {
+			if size <= i {
 				break
 			}
+
+			validator := newSchemaValidator(&s.Items.Schemas[i], s.Root, fmt.Sprintf("%s.%d", s.Path, i), s.KnownFormats, s.Options)
 			result.mergeForSlice(val, i, validator.Validate(val.Index(i).Interface()))
 		}
 	}
@@ -79,7 +120,7 @@ func (s *schemaSliceValidator) Validate(data interface{}) *Result {
 		}
 		if s.AdditionalItems.Schema != nil {
 			for i := itemsSize; i < size-itemsSize+1; i++ {
-				validator := NewSchemaValidator(s.AdditionalItems.Schema, s.Root, fmt.Sprintf("%s.%d", s.Path, i), s.KnownFormats, s.Options.Options()...)
+				validator := newSchemaValidator(s.AdditionalItems.Schema, s.Root, fmt.Sprintf("%s.%d", s.Path, i), s.KnownFormats, s.Options)
 				result.mergeForSlice(val, i, validator.Validate(val.Index(i).Interface()))
 			}
 		}
@@ -103,3 +144,7 @@ func (s *schemaSliceValidator) Validate(data interface{}) *Result {
 	result.Inc()
 	return result
 }
+
+func (s *schemaSliceValidator) redeem() {
+	pools.poolOfSliceValidators.RedeemValidator(s)
+}
diff --git a/vendor/github.com/go-openapi/validate/spec.go b/vendor/github.com/go-openapi/validate/spec.go
index dff01f00..96545256 100644
--- a/vendor/github.com/go-openapi/validate/spec.go
+++ b/vendor/github.com/go-openapi/validate/spec.go
@@ -15,6 +15,8 @@
 package validate
 
 import (
+	"bytes"
+	"encoding/gob"
 	"encoding/json"
 	"fmt"
 	"sort"
@@ -26,23 +28,23 @@ import (
 	"github.com/go-openapi/loads"
 	"github.com/go-openapi/spec"
 	"github.com/go-openapi/strfmt"
+	"github.com/go-openapi/swag"
 )
 
 // Spec validates an OpenAPI 2.0 specification document.
 //
 // Returns an error flattening in a single standard error, all validation messages.
 //
-//  - TODO: $ref should not have siblings
-//  - TODO: make sure documentation reflects all checks and warnings
-//  - TODO: check on discriminators
-//  - TODO: explicit message on unsupported keywords (better than "forbidden property"...)
-//  - TODO: full list of unresolved refs
-//  - TODO: validate numeric constraints (issue#581): this should be handled like defaults and examples
-//  - TODO: option to determine if we validate for go-swagger or in a more general context
-//  - TODO: check on required properties to support anyOf, allOf, oneOf
+//   - TODO: $ref should not have siblings
+//   - TODO: make sure documentation reflects all checks and warnings
+//   - TODO: check on discriminators
+//   - TODO: explicit message on unsupported keywords (better than "forbidden property"...)
+//   - TODO: full list of unresolved refs
+//   - TODO: validate numeric constraints (issue#581): this should be handled like defaults and examples
+//   - TODO: option to determine if we validate for go-swagger or in a more general context
+//   - TODO: check on required properties to support anyOf, allOf, oneOf
 //
 // NOTE: SecurityScopes are maps: no need to check uniqueness
-//
 func Spec(doc *loads.Document, formats strfmt.Registry) error {
 	errs, _ /*warns*/ := NewSpecValidator(doc.Schema(), formats).Validate(doc)
 	if errs.HasErrors() {
@@ -53,25 +55,38 @@ func Spec(doc *loads.Document, formats strfmt.Registry) error {
 
 // SpecValidator validates a swagger 2.0 spec
 type SpecValidator struct {
-	schema       *spec.Schema // swagger 2.0 schema
-	spec         *loads.Document
-	analyzer     *analysis.Spec
-	expanded     *loads.Document
-	KnownFormats strfmt.Registry
-	Options      Opts // validation options
+	schema        *spec.Schema // swagger 2.0 schema
+	spec          *loads.Document
+	analyzer      *analysis.Spec
+	expanded      *loads.Document
+	KnownFormats  strfmt.Registry
+	Options       Opts // validation options
+	schemaOptions *SchemaValidatorOptions
 }
 
 // NewSpecValidator creates a new swagger spec validator instance
 func NewSpecValidator(schema *spec.Schema, formats strfmt.Registry) *SpecValidator {
+	// schema options that apply to all called validators
+	schemaOptions := new(SchemaValidatorOptions)
+	for _, o := range []Option{
+		SwaggerSchema(true),
+		WithRecycleValidators(true),
+		// withRecycleResults(true),
+	} {
+		o(schemaOptions)
+	}
+
 	return &SpecValidator{
-		schema:       schema,
-		KnownFormats: formats,
-		Options:      defaultOpts,
+		schema:        schema,
+		KnownFormats:  formats,
+		Options:       defaultOpts,
+		schemaOptions: schemaOptions,
 	}
 }
 
 // Validate validates the swagger spec
 func (s *SpecValidator) Validate(data interface{}) (*Result, *Result) {
+	s.schemaOptions.skipSchemataResult = s.Options.SkipSchemataResult
 	var sd *loads.Document
 	errs, warnings := new(Result), new(Result)
 
@@ -85,11 +100,8 @@ func (s *SpecValidator) Validate(data interface{}) (*Result, *Result) {
 	s.spec = sd
 	s.analyzer = analysis.New(sd.Spec())
 
-	// Swagger schema validator
-	schv := NewSchemaValidator(s.schema, nil, "", s.KnownFormats, SwaggerSchema(true))
-	var obj interface{}
-
 	// Raw spec unmarshalling errors
+	var obj interface{}
 	if err := json.Unmarshal(sd.Raw(), &obj); err != nil {
 		// NOTE: under normal conditions, the *load.Document has been already unmarshalled
 		// So this one is just a paranoid check on the behavior of the spec package
@@ -103,6 +115,8 @@ func (s *SpecValidator) Validate(data interface{}) (*Result, *Result) {
 		warnings.AddErrors(errs.Warnings...)
 	}()
 
+	// Swagger schema validator
+	schv := newSchemaValidator(s.schema, nil, "", s.KnownFormats, s.schemaOptions)
 	errs.Merge(schv.Validate(obj)) // error -
 	// There may be a point in continuing to try and determine more accurate errors
 	if !s.Options.ContinueOnErrors && errs.HasErrors() {
@@ -130,13 +144,13 @@ func (s *SpecValidator) Validate(data interface{}) (*Result, *Result) {
 	}
 
 	// Values provided as default MUST validate their schema
-	df := &defaultValidator{SpecValidator: s}
+	df := &defaultValidator{SpecValidator: s, schemaOptions: s.schemaOptions}
 	errs.Merge(df.Validate())
 
 	// Values provided as examples MUST validate their schema
 	// Value provided as examples in a response without schema generate a warning
 	// Known limitations: examples in responses for mime type not application/json are ignored (warning)
-	ex := &exampleValidator{SpecValidator: s}
+	ex := &exampleValidator{SpecValidator: s, schemaOptions: s.schemaOptions}
 	errs.Merge(ex.Validate())
 
 	errs.Merge(s.validateNonEmptyPathParamNames())
@@ -148,22 +162,27 @@ func (s *SpecValidator) Validate(data interface{}) (*Result, *Result) {
 }
 
 func (s *SpecValidator) validateNonEmptyPathParamNames() *Result {
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 	if s.spec.Spec().Paths == nil {
 		// There is no Paths object: error
 		res.AddErrors(noValidPathMsg())
-	} else {
-		if s.spec.Spec().Paths.Paths == nil {
-			// Paths may be empty: warning
-			res.AddWarnings(noValidPathMsg())
-		} else {
-			for k := range s.spec.Spec().Paths.Paths {
-				if strings.Contains(k, "{}") {
-					res.AddErrors(emptyPathParameterMsg(k))
-				}
-			}
+
+		return res
+	}
+
+	if s.spec.Spec().Paths.Paths == nil {
+		// Paths may be empty: warning
+		res.AddWarnings(noValidPathMsg())
+
+		return res
+	}
+
+	for k := range s.spec.Spec().Paths.Paths {
+		if strings.Contains(k, "{}") {
+			res.AddErrors(emptyPathParameterMsg(k))
 		}
 	}
+
 	return res
 }
 
@@ -177,7 +196,7 @@ func (s *SpecValidator) validateDuplicateOperationIDs() *Result {
 		// fallback on possible incomplete picture because of previous errors
 		analyzer = s.analyzer
 	}
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 	known := make(map[string]int)
 	for _, v := range analyzer.OperationIDs() {
 		if v != "" {
@@ -199,7 +218,7 @@ type dupProp struct {
 
 func (s *SpecValidator) validateDuplicatePropertyNames() *Result {
 	// definition can't declare a property that's already defined by one of its ancestors
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 	for k, sch := range s.spec.Spec().Definitions {
 		if len(sch.AllOf) == 0 {
 			continue
@@ -248,7 +267,7 @@ func (s *SpecValidator) validateSchemaPropertyNames(nm string, sch spec.Schema,
 
 	schn := nm
 	schc := &sch
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 
 	for schc.Ref.String() != "" {
 		// gather property names
@@ -285,7 +304,7 @@ func (s *SpecValidator) validateSchemaPropertyNames(nm string, sch spec.Schema,
 }
 
 func (s *SpecValidator) validateCircularAncestry(nm string, sch spec.Schema, knowns map[string]struct{}) ([]string, *Result) {
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 
 	if sch.Ref.String() == "" && len(sch.AllOf) == 0 { // Safeguard. We should not be able to actually get there
 		return nil, res
@@ -335,7 +354,7 @@ func (s *SpecValidator) validateCircularAncestry(nm string, sch spec.Schema, kno
 
 func (s *SpecValidator) validateItems() *Result {
 	// validate parameter, items, schema and response objects for presence of item if type is array
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 
 	for method, pi := range s.analyzer.Operations() {
 		for path, op := range pi {
@@ -394,7 +413,7 @@ func (s *SpecValidator) validateItems() *Result {
 
 // Verifies constraints on array type
 func (s *SpecValidator) validateSchemaItems(schema spec.Schema, prefix, opID string) *Result {
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 	if !schema.Type.Contains(arrayType) {
 		return res
 	}
@@ -418,7 +437,7 @@ func (s *SpecValidator) validateSchemaItems(schema spec.Schema, prefix, opID str
 func (s *SpecValidator) validatePathParamPresence(path string, fromPath, fromOperation []string) *Result {
 	// Each defined operation path parameters must correspond to a named element in the API's path pattern.
 	// (For example, you cannot have a path parameter named id for the following path /pets/{petId} but you must have a path parameter named petId.)
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 	for _, l := range fromPath {
 		var matched bool
 		for _, r := range fromOperation {
@@ -456,7 +475,6 @@ func (s *SpecValidator) validateReferenced() *Result {
 	return &res
 }
 
-// nolint: dupl
 func (s *SpecValidator) validateReferencedParameters() *Result {
 	// Each referenceable definition should have references.
 	params := s.spec.Spec().Parameters
@@ -475,14 +493,13 @@ func (s *SpecValidator) validateReferencedParameters() *Result {
 	if len(expected) == 0 {
 		return nil
 	}
-	result := new(Result)
+	result := pools.poolOfResults.BorrowResult()
 	for k := range expected {
 		result.AddWarnings(unusedParamMsg(k))
 	}
 	return result
 }
 
-// nolint: dupl
 func (s *SpecValidator) validateReferencedResponses() *Result {
 	// Each referenceable definition should have references.
 	responses := s.spec.Spec().Responses
@@ -501,14 +518,13 @@ func (s *SpecValidator) validateReferencedResponses() *Result {
 	if len(expected) == 0 {
 		return nil
 	}
-	result := new(Result)
+	result := pools.poolOfResults.BorrowResult()
 	for k := range expected {
 		result.AddWarnings(unusedResponseMsg(k))
 	}
 	return result
 }
 
-// nolint: dupl
 func (s *SpecValidator) validateReferencedDefinitions() *Result {
 	// Each referenceable definition must have references.
 	defs := s.spec.Spec().Definitions
@@ -537,7 +553,7 @@ func (s *SpecValidator) validateReferencedDefinitions() *Result {
 
 func (s *SpecValidator) validateRequiredDefinitions() *Result {
 	// Each property listed in the required array must be defined in the properties of the model
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 
 DEFINITIONS:
 	for d, schema := range s.spec.Spec().Definitions {
@@ -556,7 +572,7 @@ DEFINITIONS:
 
 func (s *SpecValidator) validateRequiredProperties(path, in string, v *spec.Schema) *Result {
 	// Takes care of recursive property definitions, which may be nested in additionalProperties schemas
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 	propertyMatch := false
 	patternMatch := false
 	additionalPropertiesMatch := false
@@ -615,40 +631,42 @@ func (s *SpecValidator) validateRequiredProperties(path, in string, v *spec.Sche
 func (s *SpecValidator) validateParameters() *Result {
 	// - for each method, path is unique, regardless of path parameters
 	//   e.g. GET:/petstore/{id}, GET:/petstore/{pet}, GET:/petstore are
-	//   considered duplicate paths
+	//   considered duplicate paths, if StrictPathParamUniqueness is enabled.
 	// - each parameter should have a unique `name` and `type` combination
 	// - each operation should have only 1 parameter of type body
 	// - there must be at most 1 parameter in body
 	// - parameters with pattern property must specify valid patterns
 	// - $ref in parameters must resolve
 	// - path param must be required
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 	rexGarbledPathSegment := mustCompileRegexp(`.*[{}\s]+.*`)
 	for method, pi := range s.expandedAnalyzer().Operations() {
 		methodPaths := make(map[string]map[string]string)
 		for path, op := range pi {
-			pathToAdd := pathHelp.stripParametersInPath(path)
+			if s.Options.StrictPathParamUniqueness {
+				pathToAdd := pathHelp.stripParametersInPath(path)
 
-			// Warn on garbled path afer param stripping
-			if rexGarbledPathSegment.MatchString(pathToAdd) {
-				res.AddWarnings(pathStrippedParamGarbledMsg(pathToAdd))
-			}
+				// Warn on garbled path afer param stripping
+				if rexGarbledPathSegment.MatchString(pathToAdd) {
+					res.AddWarnings(pathStrippedParamGarbledMsg(pathToAdd))
+				}
 
-			// Check uniqueness of stripped paths
-			if _, found := methodPaths[method][pathToAdd]; found {
+				// Check uniqueness of stripped paths
+				if _, found := methodPaths[method][pathToAdd]; found {
 
-				// Sort names for stable, testable output
-				if strings.Compare(path, methodPaths[method][pathToAdd]) < 0 {
-					res.AddErrors(pathOverlapMsg(path, methodPaths[method][pathToAdd]))
+					// Sort names for stable, testable output
+					if strings.Compare(path, methodPaths[method][pathToAdd]) < 0 {
+						res.AddErrors(pathOverlapMsg(path, methodPaths[method][pathToAdd]))
+					} else {
+						res.AddErrors(pathOverlapMsg(methodPaths[method][pathToAdd], path))
+					}
 				} else {
-					res.AddErrors(pathOverlapMsg(methodPaths[method][pathToAdd], path))
-				}
-			} else {
-				if _, found := methodPaths[method]; !found {
-					methodPaths[method] = map[string]string{}
-				}
-				methodPaths[method][pathToAdd] = path // Original non stripped path
+					if _, found := methodPaths[method]; !found {
+						methodPaths[method] = map[string]string{}
+					}
+					methodPaths[method][pathToAdd] = path // Original non stripped path
 
+				}
 			}
 
 			var bodyParams []string
@@ -659,7 +677,23 @@ func (s *SpecValidator) validateParameters() *Result {
 			// TODO: should be done after param expansion
 			res.Merge(s.checkUniqueParams(path, method, op))
 
+			// pick the root schema from the swagger specification which describes a parameter
+			origSchema, ok := s.schema.Definitions["parameter"]
+			if !ok {
+				panic("unexpected swagger schema: missing #/definitions/parameter")
+			}
+			// clone it once to avoid expanding a global schema (e.g. swagger spec)
+			paramSchema, err := deepCloneSchema(origSchema)
+			if err != nil {
+				panic(fmt.Errorf("can't clone schema: %v", err))
+			}
+
 			for _, pr := range paramHelp.safeExpandedParamsFor(path, method, op.ID, res, s) {
+				// An expanded parameter must validate the Parameter schema (an unexpanded $ref always passes high-level schema validation)
+				schv := newSchemaValidator(&paramSchema, s.schema, fmt.Sprintf("%s.%s.parameters.%s", path, method, pr.Name), s.KnownFormats, s.schemaOptions)
+				obj := swag.ToDynamicJSON(pr)
+				res.Merge(schv.Validate(obj))
+
 				// Validate pattern regexp for parameters with a Pattern property
 				if _, err := compileRegexp(pr.Pattern); err != nil {
 					res.AddErrors(invalidPatternInParamMsg(op.ID, pr.Name, pr.Pattern))
@@ -741,7 +775,7 @@ func (s *SpecValidator) validateParameters() *Result {
 
 func (s *SpecValidator) validateReferencesValid() *Result {
 	// each reference must point to a valid object
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 	for _, r := range s.analyzer.AllRefs() {
 		if !r.IsValidURI(s.spec.SpecFilePath()) { // Safeguard - spec should always yield a valid URI
 			res.AddErrors(invalidRefMsg(r.String()))
@@ -767,7 +801,7 @@ func (s *SpecValidator) checkUniqueParams(path, method string, op *spec.Operatio
 	// However, there are some issues with such a factorization:
 	// - analysis does not seem to fully expand params
 	// - param keys may be altered by x-go-name
-	res := new(Result)
+	res := pools.poolOfResults.BorrowResult()
 	pnames := make(map[string]struct{})
 
 	if op.Parameters != nil { // Safeguard
@@ -802,3 +836,17 @@ func (s *SpecValidator) expandedAnalyzer() *analysis.Spec {
 	}
 	return s.analyzer
 }
+
+func deepCloneSchema(src spec.Schema) (spec.Schema, error) {
+	var b bytes.Buffer
+	if err := gob.NewEncoder(&b).Encode(src); err != nil {
+		return spec.Schema{}, err
+	}
+
+	var dst spec.Schema
+	if err := gob.NewDecoder(&b).Decode(&dst); err != nil {
+		return spec.Schema{}, err
+	}
+
+	return dst, nil
+}
diff --git a/vendor/github.com/go-openapi/validate/spec_messages.go b/vendor/github.com/go-openapi/validate/spec_messages.go
index b3757add..6d1f0f81 100644
--- a/vendor/github.com/go-openapi/validate/spec_messages.go
+++ b/vendor/github.com/go-openapi/validate/spec_messages.go
@@ -187,6 +187,8 @@ const (
 
 	// UnusedResponseWarning ...
 	UnusedResponseWarning = "response %q is not used anywhere"
+
+	InvalidObject = "expected an object in %q.%s"
 )
 
 // Additional error codes
@@ -347,11 +349,15 @@ func invalidParameterDefinitionAsSchemaMsg(path, method, operationID string) err
 func parameterValidationTypeMismatchMsg(param, path, typ string) errors.Error {
 	return errors.New(errors.CompositeErrorCode, ParamValidationTypeMismatch, param, path, typ)
 }
+func invalidObjectMsg(path, in string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, InvalidObject, path, in)
+}
 
 // disabled
-// func invalidResponseDefinitionAsSchemaMsg(path, method string) errors.Error {
-//	return errors.New(errors.CompositeErrorCode, InvalidResponseDefinitionAsSchemaError, path, method)
-// }
+//
+//	func invalidResponseDefinitionAsSchemaMsg(path, method string) errors.Error {
+//		return errors.New(errors.CompositeErrorCode, InvalidResponseDefinitionAsSchemaError, path, method)
+//	}
 func someParametersBrokenMsg(path, method, operationID string) errors.Error {
 	return errors.New(errors.CompositeErrorCode, SomeParametersBrokenError, path, method, operationID)
 }
diff --git a/vendor/github.com/go-openapi/validate/type.go b/vendor/github.com/go-openapi/validate/type.go
index 87646758..f87abb3d 100644
--- a/vendor/github.com/go-openapi/validate/type.go
+++ b/vendor/github.com/go-openapi/validate/type.go
@@ -25,11 +25,34 @@ import (
 )
 
 type typeValidator struct {
+	Path     string
+	In       string
 	Type     spec.StringOrArray
 	Nullable bool
 	Format   string
-	In       string
-	Path     string
+	Options  *SchemaValidatorOptions
+}
+
+func newTypeValidator(path, in string, typ spec.StringOrArray, nullable bool, format string, opts *SchemaValidatorOptions) *typeValidator {
+	if opts == nil {
+		opts = new(SchemaValidatorOptions)
+	}
+
+	var t *typeValidator
+	if opts.recycleValidators {
+		t = pools.poolOfTypeValidators.BorrowValidator()
+	} else {
+		t = new(typeValidator)
+	}
+
+	t.Path = path
+	t.In = in
+	t.Type = typ
+	t.Nullable = nullable
+	t.Format = format
+	t.Options = opts
+
+	return t
 }
 
 func (t *typeValidator) schemaInfoForType(data interface{}) (string, string) {
@@ -90,7 +113,7 @@ func (t *typeValidator) schemaInfoForType(data interface{}) (string, string) {
 	default:
 		val := reflect.ValueOf(data)
 		tpe := val.Type()
-		switch tpe.Kind() {
+		switch tpe.Kind() { //nolint:exhaustive
 		case reflect.Bool:
 			return booleanType, ""
 		case reflect.String:
@@ -125,23 +148,33 @@ func (t *typeValidator) SetPath(path string) {
 	t.Path = path
 }
 
-func (t *typeValidator) Applies(source interface{}, kind reflect.Kind) bool {
+func (t *typeValidator) Applies(source interface{}, _ reflect.Kind) bool {
 	// typeValidator applies to Schema, Parameter and Header objects
-	stpe := reflect.TypeOf(source)
-	r := (len(t.Type) > 0 || t.Format != "") && (stpe == specSchemaType || stpe == specParameterType || stpe == specHeaderType)
-	debugLog("type validator for %q applies %t for %T (kind: %v)\n", t.Path, r, source, kind)
-	return r
+	switch source.(type) {
+	case *spec.Schema:
+	case *spec.Parameter:
+	case *spec.Header:
+	default:
+		return false
+	}
+
+	return (len(t.Type) > 0 || t.Format != "")
 }
 
 func (t *typeValidator) Validate(data interface{}) *Result {
-	result := new(Result)
-	result.Inc()
+	if t.Options.recycleValidators {
+		defer func() {
+			t.redeem()
+		}()
+	}
+
 	if data == nil {
 		// nil or zero value for the passed structure require Type: null
 		if len(t.Type) > 0 && !t.Type.Contains(nullType) && !t.Nullable { // TODO: if a property is not required it also passes this
-			return errorHelp.sErr(errors.InvalidType(t.Path, t.In, strings.Join(t.Type, ","), nullType))
+			return errorHelp.sErr(errors.InvalidType(t.Path, t.In, strings.Join(t.Type, ","), nullType), t.Options.recycleResult)
 		}
-		return result
+
+		return emptyResult
 	}
 
 	// check if the type matches, should be used in every validator chain as first item
@@ -151,8 +184,6 @@ func (t *typeValidator) Validate(data interface{}) *Result {
 	// infer schema type (JSON) and format from passed data type
 	schType, format := t.schemaInfoForType(data)
 
-	debugLog("path: %s, schType: %s,  format: %s, expType: %s, expFmt: %s, kind: %s", t.Path, schType, format, t.Type, t.Format, val.Kind().String())
-
 	// check numerical types
 	// TODO: check unsigned ints
 	// TODO: check json.Number (see schema.go)
@@ -163,15 +194,20 @@ func (t *typeValidator) Validate(data interface{}) *Result {
 
 	if kind != reflect.String && kind != reflect.Slice && t.Format != "" && !(t.Type.Contains(schType) || format == t.Format || isFloatInt || isIntFloat || isLowerInt || isLowerFloat) {
 		// TODO: test case
-		return errorHelp.sErr(errors.InvalidType(t.Path, t.In, t.Format, format))
+		return errorHelp.sErr(errors.InvalidType(t.Path, t.In, t.Format, format), t.Options.recycleResult)
 	}
 
 	if !(t.Type.Contains(numberType) || t.Type.Contains(integerType)) && t.Format != "" && (kind == reflect.String || kind == reflect.Slice) {
-		return result
+		return emptyResult
 	}
 
 	if !(t.Type.Contains(schType) || isFloatInt || isIntFloat) {
-		return errorHelp.sErr(errors.InvalidType(t.Path, t.In, strings.Join(t.Type, ","), schType))
+		return errorHelp.sErr(errors.InvalidType(t.Path, t.In, strings.Join(t.Type, ","), schType), t.Options.recycleResult)
 	}
-	return result
+
+	return emptyResult
+}
+
+func (t *typeValidator) redeem() {
+	pools.poolOfTypeValidators.RedeemValidator(t)
 }
diff --git a/vendor/github.com/go-openapi/validate/validator.go b/vendor/github.com/go-openapi/validate/validator.go
index 38cdb9bb..c083aecc 100644
--- a/vendor/github.com/go-openapi/validate/validator.go
+++ b/vendor/github.com/go-openapi/validate/validator.go
@@ -39,20 +39,31 @@ type itemsValidator struct {
 	root         interface{}
 	path         string
 	in           string
-	validators   []valueValidator
+	validators   [6]valueValidator
 	KnownFormats strfmt.Registry
+	Options      *SchemaValidatorOptions
 }
 
-func newItemsValidator(path, in string, items *spec.Items, root interface{}, formats strfmt.Registry) *itemsValidator {
-	iv := &itemsValidator{path: path, in: in, items: items, root: root, KnownFormats: formats}
-	iv.validators = []valueValidator{
-		&typeValidator{
-			Type:     spec.StringOrArray([]string{items.Type}),
-			Nullable: items.Nullable,
-			Format:   items.Format,
-			In:       in,
-			Path:     path,
-		},
+func newItemsValidator(path, in string, items *spec.Items, root interface{}, formats strfmt.Registry, opts *SchemaValidatorOptions) *itemsValidator {
+	if opts == nil {
+		opts = new(SchemaValidatorOptions)
+	}
+
+	var iv *itemsValidator
+	if opts.recycleValidators {
+		iv = pools.poolOfItemsValidators.BorrowValidator()
+	} else {
+		iv = new(itemsValidator)
+	}
+
+	iv.path = path
+	iv.in = in
+	iv.items = items
+	iv.root = root
+	iv.KnownFormats = formats
+	iv.Options = opts
+	iv.validators = [6]valueValidator{
+		iv.typeValidator(),
 		iv.stringValidator(),
 		iv.formatValidator(),
 		iv.numberValidator(),
@@ -63,77 +74,152 @@ func newItemsValidator(path, in string, items *spec.Items, root interface{}, for
 }
 
 func (i *itemsValidator) Validate(index int, data interface{}) *Result {
+	if i.Options.recycleValidators {
+		defer func() {
+			i.redeemChildren()
+			i.redeem()
+		}()
+	}
+
 	tpe := reflect.TypeOf(data)
 	kind := tpe.Kind()
-	mainResult := new(Result)
+	var result *Result
+	if i.Options.recycleResult {
+		result = pools.poolOfResults.BorrowResult()
+	} else {
+		result = new(Result)
+	}
+
 	path := fmt.Sprintf("%s.%d", i.path, index)
 
-	for _, validator := range i.validators {
+	for idx, validator := range i.validators {
+		if !validator.Applies(i.root, kind) {
+			if i.Options.recycleValidators {
+				// Validate won't be called, so relinquish this validator
+				if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok {
+					redeemableChildren.redeemChildren()
+				}
+				if redeemable, ok := validator.(interface{ redeem() }); ok {
+					redeemable.redeem()
+				}
+				i.validators[idx] = nil // prevents further (unsafe) usage
+			}
+
+			continue
+		}
+
 		validator.SetPath(path)
-		if validator.Applies(i.root, kind) {
-			result := validator.Validate(data)
-			mainResult.Merge(result)
-			mainResult.Inc()
-			if result != nil && result.HasErrors() {
-				return mainResult
+		err := validator.Validate(data)
+		if i.Options.recycleValidators {
+			i.validators[idx] = nil // prevents further (unsafe) usage
+		}
+		if err != nil {
+			result.Inc()
+			if err.HasErrors() {
+				result.Merge(err)
+
+				break
 			}
+
+			result.Merge(err)
 		}
 	}
-	return mainResult
+
+	return result
+}
+
+func (i *itemsValidator) typeValidator() valueValidator {
+	return newTypeValidator(
+		i.path,
+		i.in,
+		spec.StringOrArray([]string{i.items.Type}),
+		i.items.Nullable,
+		i.items.Format,
+		i.Options,
+	)
 }
 
 func (i *itemsValidator) commonValidator() valueValidator {
-	return &basicCommonValidator{
-		In:      i.in,
-		Default: i.items.Default,
-		Enum:    i.items.Enum,
-	}
+	return newBasicCommonValidator(
+		"",
+		i.in,
+		i.items.Default,
+		i.items.Enum,
+		i.Options,
+	)
 }
 
 func (i *itemsValidator) sliceValidator() valueValidator {
-	return &basicSliceValidator{
-		In:           i.in,
-		Default:      i.items.Default,
-		MaxItems:     i.items.MaxItems,
-		MinItems:     i.items.MinItems,
-		UniqueItems:  i.items.UniqueItems,
-		Source:       i.root,
-		Items:        i.items.Items,
-		KnownFormats: i.KnownFormats,
-	}
+	return newBasicSliceValidator(
+		"",
+		i.in,
+		i.items.Default,
+		i.items.MaxItems,
+		i.items.MinItems,
+		i.items.UniqueItems,
+		i.items.Items,
+		i.root,
+		i.KnownFormats,
+		i.Options,
+	)
 }
 
 func (i *itemsValidator) numberValidator() valueValidator {
-	return &numberValidator{
-		In:               i.in,
-		Default:          i.items.Default,
-		MultipleOf:       i.items.MultipleOf,
-		Maximum:          i.items.Maximum,
-		ExclusiveMaximum: i.items.ExclusiveMaximum,
-		Minimum:          i.items.Minimum,
-		ExclusiveMinimum: i.items.ExclusiveMinimum,
-		Type:             i.items.Type,
-		Format:           i.items.Format,
-	}
+	return newNumberValidator(
+		"",
+		i.in,
+		i.items.Default,
+		i.items.MultipleOf,
+		i.items.Maximum,
+		i.items.ExclusiveMaximum,
+		i.items.Minimum,
+		i.items.ExclusiveMinimum,
+		i.items.Type,
+		i.items.Format,
+		i.Options,
+	)
 }
 
 func (i *itemsValidator) stringValidator() valueValidator {
-	return &stringValidator{
-		In:              i.in,
-		Default:         i.items.Default,
-		MaxLength:       i.items.MaxLength,
-		MinLength:       i.items.MinLength,
-		Pattern:         i.items.Pattern,
-		AllowEmptyValue: false,
-	}
+	return newStringValidator(
+		"",
+		i.in,
+		i.items.Default,
+		false, // Required
+		false, // AllowEmpty
+		i.items.MaxLength,
+		i.items.MinLength,
+		i.items.Pattern,
+		i.Options,
+	)
 }
 
 func (i *itemsValidator) formatValidator() valueValidator {
-	return &formatValidator{
-		In: i.in,
-		//Default:      i.items.Default,
-		Format:       i.items.Format,
-		KnownFormats: i.KnownFormats,
+	return newFormatValidator(
+		"",
+		i.in,
+		i.items.Format,
+		i.KnownFormats,
+		i.Options,
+	)
+}
+
+func (i *itemsValidator) redeem() {
+	pools.poolOfItemsValidators.RedeemValidator(i)
+}
+
+func (i *itemsValidator) redeemChildren() {
+	for idx, validator := range i.validators {
+		if validator == nil {
+			continue
+		}
+		if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok {
+			redeemableChildren.redeemChildren()
+		}
+		if redeemable, ok := validator.(interface{ redeem() }); ok {
+			redeemable.redeem()
+		}
+		i.validators[idx] = nil // free up allocated children if not in pool
 	}
 }
 
@@ -142,265 +228,501 @@ type basicCommonValidator struct {
 	In      string
 	Default interface{}
 	Enum    []interface{}
+	Options *SchemaValidatorOptions
+}
+
+func newBasicCommonValidator(path, in string, def interface{}, enum []interface{}, opts *SchemaValidatorOptions) *basicCommonValidator {
+	if opts == nil {
+		opts = new(SchemaValidatorOptions)
+	}
+
+	var b *basicCommonValidator
+	if opts.recycleValidators {
+		b = pools.poolOfBasicCommonValidators.BorrowValidator()
+	} else {
+		b = new(basicCommonValidator)
+	}
+
+	b.Path = path
+	b.In = in
+	b.Default = def
+	b.Enum = enum
+	b.Options = opts
+
+	return b
 }
 
 func (b *basicCommonValidator) SetPath(path string) {
 	b.Path = path
 }
 
-func (b *basicCommonValidator) Applies(source interface{}, kind reflect.Kind) bool {
+func (b *basicCommonValidator) Applies(source interface{}, _ reflect.Kind) bool {
 	switch source.(type) {
 	case *spec.Parameter, *spec.Schema, *spec.Header:
 		return true
+	default:
+		return false
 	}
-	return false
 }
 
 func (b *basicCommonValidator) Validate(data interface{}) (res *Result) {
-	if len(b.Enum) > 0 {
-		for _, enumValue := range b.Enum {
-			actualType := reflect.TypeOf(enumValue)
-			if actualType != nil { // Safeguard
-				expectedValue := reflect.ValueOf(data)
-				if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) {
-					if reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), enumValue) {
-						return nil
-					}
-				}
-			}
+	if b.Options.recycleValidators {
+		defer func() {
+			b.redeem()
+		}()
+	}
+
+	if len(b.Enum) == 0 {
+		return nil
+	}
+
+	for _, enumValue := range b.Enum {
+		actualType := reflect.TypeOf(enumValue)
+		if actualType == nil { // Safeguard
+			continue
+		}
+
+		expectedValue := reflect.ValueOf(data)
+		if expectedValue.IsValid() &&
+			expectedValue.Type().ConvertibleTo(actualType) &&
+			reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), enumValue) {
+			return nil
 		}
-		return errorHelp.sErr(errors.EnumFail(b.Path, b.In, data, b.Enum))
 	}
-	return nil
+
+	return errorHelp.sErr(errors.EnumFail(b.Path, b.In, data, b.Enum), b.Options.recycleResult)
+}
+
+func (b *basicCommonValidator) redeem() {
+	pools.poolOfBasicCommonValidators.RedeemValidator(b)
 }
 
 // A HeaderValidator has very limited subset of validations to apply
 type HeaderValidator struct {
 	name         string
 	header       *spec.Header
-	validators   []valueValidator
+	validators   [6]valueValidator
 	KnownFormats strfmt.Registry
+	Options      *SchemaValidatorOptions
 }
 
 // NewHeaderValidator creates a new header validator object
-func NewHeaderValidator(name string, header *spec.Header, formats strfmt.Registry) *HeaderValidator {
-	p := &HeaderValidator{name: name, header: header, KnownFormats: formats}
-	p.validators = []valueValidator{
-		&typeValidator{
-			Type:     spec.StringOrArray([]string{header.Type}),
-			Nullable: header.Nullable,
-			Format:   header.Format,
-			In:       "header",
-			Path:     name,
-		},
+func NewHeaderValidator(name string, header *spec.Header, formats strfmt.Registry, options ...Option) *HeaderValidator {
+	opts := new(SchemaValidatorOptions)
+	for _, o := range options {
+		o(opts)
+	}
+
+	return newHeaderValidator(name, header, formats, opts)
+}
+
+func newHeaderValidator(name string, header *spec.Header, formats strfmt.Registry, opts *SchemaValidatorOptions) *HeaderValidator {
+	if opts == nil {
+		opts = new(SchemaValidatorOptions)
+	}
+
+	var p *HeaderValidator
+	if opts.recycleValidators {
+		p = pools.poolOfHeaderValidators.BorrowValidator()
+	} else {
+		p = new(HeaderValidator)
+	}
+
+	p.name = name
+	p.header = header
+	p.KnownFormats = formats
+	p.Options = opts
+	p.validators = [6]valueValidator{
+		newTypeValidator(
+			name,
+			"header",
+			spec.StringOrArray([]string{header.Type}),
+			header.Nullable,
+			header.Format,
+			p.Options,
+		),
 		p.stringValidator(),
 		p.formatValidator(),
 		p.numberValidator(),
 		p.sliceValidator(),
 		p.commonValidator(),
 	}
+
 	return p
 }
 
 // Validate the value of the header against its schema
 func (p *HeaderValidator) Validate(data interface{}) *Result {
-	result := new(Result)
+	if p.Options.recycleValidators {
+		defer func() {
+			p.redeemChildren()
+			p.redeem()
+		}()
+	}
+
+	if data == nil {
+		return nil
+	}
+
+	var result *Result
+	if p.Options.recycleResult {
+		result = pools.poolOfResults.BorrowResult()
+	} else {
+		result = new(Result)
+	}
+
 	tpe := reflect.TypeOf(data)
 	kind := tpe.Kind()
 
-	for _, validator := range p.validators {
-		if validator.Applies(p.header, kind) {
-			if err := validator.Validate(data); err != nil {
-				result.Merge(err)
-				if err.HasErrors() {
-					return result
+	for idx, validator := range p.validators {
+		if !validator.Applies(p.header, kind) {
+			if p.Options.recycleValidators {
+				// Validate won't be called, so relinquish this validator
+				if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok {
+					redeemableChildren.redeemChildren()
+				}
+				if redeemable, ok := validator.(interface{ redeem() }); ok {
+					redeemable.redeem()
 				}
+				p.validators[idx] = nil // prevents further (unsafe) usage
 			}
+
+			continue
+		}
+
+		err := validator.Validate(data)
+		if p.Options.recycleValidators {
+			p.validators[idx] = nil // prevents further (unsafe) usage
+		}
+		if err != nil {
+			if err.HasErrors() {
+				result.Merge(err)
+				break
+			}
+			result.Merge(err)
 		}
 	}
-	return nil
+
+	return result
 }
 
 func (p *HeaderValidator) commonValidator() valueValidator {
-	return &basicCommonValidator{
-		Path:    p.name,
-		In:      "response",
-		Default: p.header.Default,
-		Enum:    p.header.Enum,
-	}
+	return newBasicCommonValidator(
+		p.name,
+		"response",
+		p.header.Default,
+		p.header.Enum,
+		p.Options,
+	)
 }
 
 func (p *HeaderValidator) sliceValidator() valueValidator {
-	return &basicSliceValidator{
-		Path:         p.name,
-		In:           "response",
-		Default:      p.header.Default,
-		MaxItems:     p.header.MaxItems,
-		MinItems:     p.header.MinItems,
-		UniqueItems:  p.header.UniqueItems,
-		Items:        p.header.Items,
-		Source:       p.header,
-		KnownFormats: p.KnownFormats,
-	}
+	return newBasicSliceValidator(
+		p.name,
+		"response",
+		p.header.Default,
+		p.header.MaxItems,
+		p.header.MinItems,
+		p.header.UniqueItems,
+		p.header.Items,
+		p.header,
+		p.KnownFormats,
+		p.Options,
+	)
 }
 
 func (p *HeaderValidator) numberValidator() valueValidator {
-	return &numberValidator{
-		Path:             p.name,
-		In:               "response",
-		Default:          p.header.Default,
-		MultipleOf:       p.header.MultipleOf,
-		Maximum:          p.header.Maximum,
-		ExclusiveMaximum: p.header.ExclusiveMaximum,
-		Minimum:          p.header.Minimum,
-		ExclusiveMinimum: p.header.ExclusiveMinimum,
-		Type:             p.header.Type,
-		Format:           p.header.Format,
-	}
+	return newNumberValidator(
+		p.name,
+		"response",
+		p.header.Default,
+		p.header.MultipleOf,
+		p.header.Maximum,
+		p.header.ExclusiveMaximum,
+		p.header.Minimum,
+		p.header.ExclusiveMinimum,
+		p.header.Type,
+		p.header.Format,
+		p.Options,
+	)
 }
 
 func (p *HeaderValidator) stringValidator() valueValidator {
-	return &stringValidator{
-		Path:            p.name,
-		In:              "response",
-		Default:         p.header.Default,
-		Required:        true,
-		MaxLength:       p.header.MaxLength,
-		MinLength:       p.header.MinLength,
-		Pattern:         p.header.Pattern,
-		AllowEmptyValue: false,
-	}
+	return newStringValidator(
+		p.name,
+		"response",
+		p.header.Default,
+		true,
+		false,
+		p.header.MaxLength,
+		p.header.MinLength,
+		p.header.Pattern,
+		p.Options,
+	)
 }
 
 func (p *HeaderValidator) formatValidator() valueValidator {
-	return &formatValidator{
-		Path: p.name,
-		In:   "response",
-		//Default:      p.header.Default,
-		Format:       p.header.Format,
-		KnownFormats: p.KnownFormats,
+	return newFormatValidator(
+		p.name,
+		"response",
+		p.header.Format,
+		p.KnownFormats,
+		p.Options,
+	)
+}
+
+func (p *HeaderValidator) redeem() {
+	pools.poolOfHeaderValidators.RedeemValidator(p)
+}
+
+func (p *HeaderValidator) redeemChildren() {
+	for idx, validator := range p.validators {
+		if validator == nil {
+			continue
+		}
+		if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok {
+			redeemableChildren.redeemChildren()
+		}
+		if redeemable, ok := validator.(interface{ redeem() }); ok {
+			redeemable.redeem()
+		}
+		p.validators[idx] = nil // free up allocated children if not in pool
 	}
 }
 
 // A ParamValidator has very limited subset of validations to apply
 type ParamValidator struct {
 	param        *spec.Parameter
-	validators   []valueValidator
+	validators   [6]valueValidator
 	KnownFormats strfmt.Registry
+	Options      *SchemaValidatorOptions
 }
 
 // NewParamValidator creates a new param validator object
-func NewParamValidator(param *spec.Parameter, formats strfmt.Registry) *ParamValidator {
-	p := &ParamValidator{param: param, KnownFormats: formats}
-	p.validators = []valueValidator{
-		&typeValidator{
-			Type:     spec.StringOrArray([]string{param.Type}),
-			Nullable: param.Nullable,
-			Format:   param.Format,
-			In:       param.In,
-			Path:     param.Name,
-		},
+func NewParamValidator(param *spec.Parameter, formats strfmt.Registry, options ...Option) *ParamValidator {
+	opts := new(SchemaValidatorOptions)
+	for _, o := range options {
+		o(opts)
+	}
+
+	return newParamValidator(param, formats, opts)
+}
+
+func newParamValidator(param *spec.Parameter, formats strfmt.Registry, opts *SchemaValidatorOptions) *ParamValidator {
+	if opts == nil {
+		opts = new(SchemaValidatorOptions)
+	}
+
+	var p *ParamValidator
+	if opts.recycleValidators {
+		p = pools.poolOfParamValidators.BorrowValidator()
+	} else {
+		p = new(ParamValidator)
+	}
+
+	p.param = param
+	p.KnownFormats = formats
+	p.Options = opts
+	p.validators = [6]valueValidator{
+		newTypeValidator(
+			param.Name,
+			param.In,
+			spec.StringOrArray([]string{param.Type}),
+			param.Nullable,
+			param.Format,
+			p.Options,
+		),
 		p.stringValidator(),
 		p.formatValidator(),
 		p.numberValidator(),
 		p.sliceValidator(),
 		p.commonValidator(),
 	}
+
 	return p
 }
 
 // Validate the data against the description of the parameter
 func (p *ParamValidator) Validate(data interface{}) *Result {
-	result := new(Result)
+	if data == nil {
+		return nil
+	}
+
+	var result *Result
+	if p.Options.recycleResult {
+		result = pools.poolOfResults.BorrowResult()
+	} else {
+		result = new(Result)
+	}
+
 	tpe := reflect.TypeOf(data)
 	kind := tpe.Kind()
 
+	if p.Options.recycleValidators {
+		defer func() {
+			p.redeemChildren()
+			p.redeem()
+		}()
+	}
+
 	// TODO: validate type
-	for _, validator := range p.validators {
-		if validator.Applies(p.param, kind) {
-			if err := validator.Validate(data); err != nil {
-				result.Merge(err)
-				if err.HasErrors() {
-					return result
+	for idx, validator := range p.validators {
+		if !validator.Applies(p.param, kind) {
+			if p.Options.recycleValidators {
+				// Validate won't be called, so relinquish this validator
+				if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok {
+					redeemableChildren.redeemChildren()
+				}
+				if redeemable, ok := validator.(interface{ redeem() }); ok {
+					redeemable.redeem()
 				}
+				p.validators[idx] = nil // prevents further (unsafe) usage
 			}
+
+			continue
+		}
+
+		err := validator.Validate(data)
+		if p.Options.recycleValidators {
+			p.validators[idx] = nil // prevents further (unsafe) usage
+		}
+		if err != nil {
+			if err.HasErrors() {
+				result.Merge(err)
+				break
+			}
+			result.Merge(err)
 		}
 	}
-	return nil
+
+	return result
 }
 
 func (p *ParamValidator) commonValidator() valueValidator {
-	return &basicCommonValidator{
-		Path:    p.param.Name,
-		In:      p.param.In,
-		Default: p.param.Default,
-		Enum:    p.param.Enum,
-	}
+	return newBasicCommonValidator(
+		p.param.Name,
+		p.param.In,
+		p.param.Default,
+		p.param.Enum,
+		p.Options,
+	)
 }
 
 func (p *ParamValidator) sliceValidator() valueValidator {
-	return &basicSliceValidator{
-		Path:         p.param.Name,
-		In:           p.param.In,
-		Default:      p.param.Default,
-		MaxItems:     p.param.MaxItems,
-		MinItems:     p.param.MinItems,
-		UniqueItems:  p.param.UniqueItems,
-		Items:        p.param.Items,
-		Source:       p.param,
-		KnownFormats: p.KnownFormats,
-	}
+	return newBasicSliceValidator(
+		p.param.Name,
+		p.param.In,
+		p.param.Default,
+		p.param.MaxItems,
+		p.param.MinItems,
+		p.param.UniqueItems,
+		p.param.Items,
+		p.param,
+		p.KnownFormats,
+		p.Options,
+	)
 }
 
 func (p *ParamValidator) numberValidator() valueValidator {
-	return &numberValidator{
-		Path:             p.param.Name,
-		In:               p.param.In,
-		Default:          p.param.Default,
-		MultipleOf:       p.param.MultipleOf,
-		Maximum:          p.param.Maximum,
-		ExclusiveMaximum: p.param.ExclusiveMaximum,
-		Minimum:          p.param.Minimum,
-		ExclusiveMinimum: p.param.ExclusiveMinimum,
-		Type:             p.param.Type,
-		Format:           p.param.Format,
-	}
+	return newNumberValidator(
+		p.param.Name,
+		p.param.In,
+		p.param.Default,
+		p.param.MultipleOf,
+		p.param.Maximum,
+		p.param.ExclusiveMaximum,
+		p.param.Minimum,
+		p.param.ExclusiveMinimum,
+		p.param.Type,
+		p.param.Format,
+		p.Options,
+	)
 }
 
 func (p *ParamValidator) stringValidator() valueValidator {
-	return &stringValidator{
-		Path:            p.param.Name,
-		In:              p.param.In,
-		Default:         p.param.Default,
-		AllowEmptyValue: p.param.AllowEmptyValue,
-		Required:        p.param.Required,
-		MaxLength:       p.param.MaxLength,
-		MinLength:       p.param.MinLength,
-		Pattern:         p.param.Pattern,
-	}
+	return newStringValidator(
+		p.param.Name,
+		p.param.In,
+		p.param.Default,
+		p.param.Required,
+		p.param.AllowEmptyValue,
+		p.param.MaxLength,
+		p.param.MinLength,
+		p.param.Pattern,
+		p.Options,
+	)
 }
 
 func (p *ParamValidator) formatValidator() valueValidator {
-	return &formatValidator{
-		Path: p.param.Name,
-		In:   p.param.In,
-		//Default:      p.param.Default,
-		Format:       p.param.Format,
-		KnownFormats: p.KnownFormats,
+	return newFormatValidator(
+		p.param.Name,
+		p.param.In,
+		p.param.Format,
+		p.KnownFormats,
+		p.Options,
+	)
+}
+
+func (p *ParamValidator) redeem() {
+	pools.poolOfParamValidators.RedeemValidator(p)
+}
+
+func (p *ParamValidator) redeemChildren() {
+	for idx, validator := range p.validators {
+		if validator == nil {
+			continue
+		}
+		if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok {
+			redeemableChildren.redeemChildren()
+		}
+		if redeemable, ok := validator.(interface{ redeem() }); ok {
+			redeemable.redeem()
+		}
+		p.validators[idx] = nil // free up allocated children if not in pool
 	}
 }
 
 type basicSliceValidator struct {
-	Path           string
-	In             string
-	Default        interface{}
-	MaxItems       *int64
-	MinItems       *int64
-	UniqueItems    bool
-	Items          *spec.Items
-	Source         interface{}
-	itemsValidator *itemsValidator
-	KnownFormats   strfmt.Registry
+	Path         string
+	In           string
+	Default      interface{}
+	MaxItems     *int64
+	MinItems     *int64
+	UniqueItems  bool
+	Items        *spec.Items
+	Source       interface{}
+	KnownFormats strfmt.Registry
+	Options      *SchemaValidatorOptions
+}
+
+func newBasicSliceValidator(
+	path, in string,
+	def interface{}, maxItems, minItems *int64, uniqueItems bool, items *spec.Items,
+	source interface{}, formats strfmt.Registry,
+	opts *SchemaValidatorOptions) *basicSliceValidator {
+	if opts == nil {
+		opts = new(SchemaValidatorOptions)
+	}
+
+	var s *basicSliceValidator
+	if opts.recycleValidators {
+		s = pools.poolOfBasicSliceValidators.BorrowValidator()
+	} else {
+		s = new(basicSliceValidator)
+	}
+
+	s.Path = path
+	s.In = in
+	s.Default = def
+	s.MaxItems = maxItems
+	s.MinItems = minItems
+	s.UniqueItems = uniqueItems
+	s.Items = items
+	s.Source = source
+	s.KnownFormats = formats
+	s.Options = opts
+
+	return s
 }
 
 func (s *basicSliceValidator) SetPath(path string) {
@@ -411,60 +733,61 @@ func (s *basicSliceValidator) Applies(source interface{}, kind reflect.Kind) boo
 	switch source.(type) {
 	case *spec.Parameter, *spec.Items, *spec.Header:
 		return kind == reflect.Slice
+	default:
+		return false
 	}
-	return false
 }
 
 func (s *basicSliceValidator) Validate(data interface{}) *Result {
+	if s.Options.recycleValidators {
+		defer func() {
+			s.redeem()
+		}()
+	}
 	val := reflect.ValueOf(data)
 
 	size := int64(val.Len())
 	if s.MinItems != nil {
 		if err := MinItems(s.Path, s.In, size, *s.MinItems); err != nil {
-			return errorHelp.sErr(err)
+			return errorHelp.sErr(err, s.Options.recycleResult)
 		}
 	}
 
 	if s.MaxItems != nil {
 		if err := MaxItems(s.Path, s.In, size, *s.MaxItems); err != nil {
-			return errorHelp.sErr(err)
+			return errorHelp.sErr(err, s.Options.recycleResult)
 		}
 	}
 
 	if s.UniqueItems {
 		if err := UniqueItems(s.Path, s.In, data); err != nil {
-			return errorHelp.sErr(err)
+			return errorHelp.sErr(err, s.Options.recycleResult)
 		}
 	}
 
-	if s.itemsValidator == nil && s.Items != nil {
-		s.itemsValidator = newItemsValidator(s.Path, s.In, s.Items, s.Source, s.KnownFormats)
+	if s.Items == nil {
+		return nil
 	}
 
-	if s.itemsValidator != nil {
-		for i := 0; i < int(size); i++ {
-			ele := val.Index(i)
-			if err := s.itemsValidator.Validate(i, ele.Interface()); err != nil && err.HasErrors() {
+	for i := 0; i < int(size); i++ {
+		itemsValidator := newItemsValidator(s.Path, s.In, s.Items, s.Source, s.KnownFormats, s.Options)
+		ele := val.Index(i)
+		if err := itemsValidator.Validate(i, ele.Interface()); err != nil {
+			if err.HasErrors() {
 				return err
 			}
+			if err.wantsRedeemOnMerge {
+				pools.poolOfResults.RedeemResult(err)
+			}
 		}
 	}
+
 	return nil
 }
 
-/* unused
-func (s *basicSliceValidator) hasDuplicates(value reflect.Value, size int) bool {
-	dict := make(map[interface{}]struct{})
-	for i := 0; i < size; i++ {
-		ele := value.Index(i)
-		if _, ok := dict[ele.Interface()]; ok {
-			return true
-		}
-		dict[ele.Interface()] = struct{}{}
-	}
-	return false
+func (s *basicSliceValidator) redeem() {
+	pools.poolOfBasicSliceValidators.RedeemValidator(s)
 }
-*/
 
 type numberValidator struct {
 	Path             string
@@ -476,8 +799,40 @@ type numberValidator struct {
 	Minimum          *float64
 	ExclusiveMinimum bool
 	// Allows for more accurate behavior regarding integers
-	Type   string
-	Format string
+	Type    string
+	Format  string
+	Options *SchemaValidatorOptions
+}
+
+func newNumberValidator(
+	path, in string, def interface{},
+	multipleOf, maximum *float64, exclusiveMaximum bool, minimum *float64, exclusiveMinimum bool,
+	typ, format string,
+	opts *SchemaValidatorOptions) *numberValidator {
+	if opts == nil {
+		opts = new(SchemaValidatorOptions)
+	}
+
+	var n *numberValidator
+	if opts.recycleValidators {
+		n = pools.poolOfNumberValidators.BorrowValidator()
+	} else {
+		n = new(numberValidator)
+	}
+
+	n.Path = path
+	n.In = in
+	n.Default = def
+	n.MultipleOf = multipleOf
+	n.Maximum = maximum
+	n.ExclusiveMaximum = exclusiveMaximum
+	n.Minimum = minimum
+	n.ExclusiveMinimum = exclusiveMinimum
+	n.Type = typ
+	n.Format = format
+	n.Options = opts
+
+	return n
 }
 
 func (n *numberValidator) SetPath(path string) {
@@ -489,12 +844,10 @@ func (n *numberValidator) Applies(source interface{}, kind reflect.Kind) bool {
 	case *spec.Parameter, *spec.Schema, *spec.Items, *spec.Header:
 		isInt := kind >= reflect.Int && kind <= reflect.Uint64
 		isFloat := kind == reflect.Float32 || kind == reflect.Float64
-		r := isInt || isFloat
-		debugLog("schema props validator for %q applies %t for %T (kind: %v) isInt=%t, isFloat=%t\n", n.Path, r, source, kind, isInt, isFloat)
-		return r
+		return isInt || isFloat
+	default:
+		return false
 	}
-	debugLog("schema props validator for %q applies %t for %T (kind: %v)\n", n.Path, false, source, kind)
-	return false
 }
 
 // Validate provides a validator for generic JSON numbers,
@@ -519,11 +872,18 @@ func (n *numberValidator) Applies(source interface{}, kind reflect.Kind) bool {
 //
 // TODO: default boundaries with MAX_SAFE_INTEGER are not checked (specific to json.Number?)
 func (n *numberValidator) Validate(val interface{}) *Result {
-	res := new(Result)
+	if n.Options.recycleValidators {
+		defer func() {
+			n.redeem()
+		}()
+	}
 
-	resMultiple := new(Result)
-	resMinimum := new(Result)
-	resMaximum := new(Result)
+	var res, resMultiple, resMinimum, resMaximum *Result
+	if n.Options.recycleResult {
+		res = pools.poolOfResults.BorrowResult()
+	} else {
+		res = new(Result)
+	}
 
 	// Used only to attempt to validate constraint on value,
 	// even though value or constraint specified do not match type and format
@@ -533,68 +893,106 @@ func (n *numberValidator) Validate(val interface{}) *Result {
 	res.AddErrors(IsValueValidAgainstRange(val, n.Type, n.Format, "Checked", n.Path))
 
 	if n.MultipleOf != nil {
+		resMultiple = pools.poolOfResults.BorrowResult()
+
 		// Is the constraint specifier within the range of the specific numeric type and format?
 		resMultiple.AddErrors(IsValueValidAgainstRange(*n.MultipleOf, n.Type, n.Format, "MultipleOf", n.Path))
 		if resMultiple.IsValid() {
 			// Constraint validated with compatible types
 			if err := MultipleOfNativeType(n.Path, n.In, val, *n.MultipleOf); err != nil {
-				resMultiple.Merge(errorHelp.sErr(err))
+				resMultiple.Merge(errorHelp.sErr(err, n.Options.recycleResult))
 			}
 		} else {
 			// Constraint nevertheless validated, converted as general number
 			if err := MultipleOf(n.Path, n.In, data, *n.MultipleOf); err != nil {
-				resMultiple.Merge(errorHelp.sErr(err))
+				resMultiple.Merge(errorHelp.sErr(err, n.Options.recycleResult))
 			}
 		}
 	}
 
-	// nolint: dupl
 	if n.Maximum != nil {
+		resMaximum = pools.poolOfResults.BorrowResult()
+
 		// Is the constraint specifier within the range of the specific numeric type and format?
 		resMaximum.AddErrors(IsValueValidAgainstRange(*n.Maximum, n.Type, n.Format, "Maximum boundary", n.Path))
 		if resMaximum.IsValid() {
 			// Constraint validated with compatible types
 			if err := MaximumNativeType(n.Path, n.In, val, *n.Maximum, n.ExclusiveMaximum); err != nil {
-				resMaximum.Merge(errorHelp.sErr(err))
+				resMaximum.Merge(errorHelp.sErr(err, n.Options.recycleResult))
 			}
 		} else {
 			// Constraint nevertheless validated, converted as general number
 			if err := Maximum(n.Path, n.In, data, *n.Maximum, n.ExclusiveMaximum); err != nil {
-				resMaximum.Merge(errorHelp.sErr(err))
+				resMaximum.Merge(errorHelp.sErr(err, n.Options.recycleResult))
 			}
 		}
 	}
 
-	// nolint: dupl
 	if n.Minimum != nil {
+		resMinimum = pools.poolOfResults.BorrowResult()
+
 		// Is the constraint specifier within the range of the specific numeric type and format?
 		resMinimum.AddErrors(IsValueValidAgainstRange(*n.Minimum, n.Type, n.Format, "Minimum boundary", n.Path))
 		if resMinimum.IsValid() {
 			// Constraint validated with compatible types
 			if err := MinimumNativeType(n.Path, n.In, val, *n.Minimum, n.ExclusiveMinimum); err != nil {
-				resMinimum.Merge(errorHelp.sErr(err))
+				resMinimum.Merge(errorHelp.sErr(err, n.Options.recycleResult))
 			}
 		} else {
 			// Constraint nevertheless validated, converted as general number
 			if err := Minimum(n.Path, n.In, data, *n.Minimum, n.ExclusiveMinimum); err != nil {
-				resMinimum.Merge(errorHelp.sErr(err))
+				resMinimum.Merge(errorHelp.sErr(err, n.Options.recycleResult))
 			}
 		}
 	}
 	res.Merge(resMultiple, resMinimum, resMaximum)
 	res.Inc()
+
 	return res
 }
 
+func (n *numberValidator) redeem() {
+	pools.poolOfNumberValidators.RedeemValidator(n)
+}
+
 type stringValidator struct {
+	Path            string
+	In              string
 	Default         interface{}
 	Required        bool
 	AllowEmptyValue bool
 	MaxLength       *int64
 	MinLength       *int64
 	Pattern         string
-	Path            string
-	In              string
+	Options         *SchemaValidatorOptions
+}
+
+func newStringValidator(
+	path, in string,
+	def interface{}, required, allowEmpty bool, maxLength, minLength *int64, pattern string,
+	opts *SchemaValidatorOptions) *stringValidator {
+	if opts == nil {
+		opts = new(SchemaValidatorOptions)
+	}
+
+	var s *stringValidator
+	if opts.recycleValidators {
+		s = pools.poolOfStringValidators.BorrowValidator()
+	} else {
+		s = new(stringValidator)
+	}
+
+	s.Path = path
+	s.In = in
+	s.Default = def
+	s.Required = required
+	s.AllowEmptyValue = allowEmpty
+	s.MaxLength = maxLength
+	s.MinLength = minLength
+	s.Pattern = pattern
+	s.Options = opts
+
+	return s
 }
 
 func (s *stringValidator) SetPath(path string) {
@@ -604,42 +1002,50 @@ func (s *stringValidator) SetPath(path string) {
 func (s *stringValidator) Applies(source interface{}, kind reflect.Kind) bool {
 	switch source.(type) {
 	case *spec.Parameter, *spec.Schema, *spec.Items, *spec.Header:
-		r := kind == reflect.String
-		debugLog("string validator for %q applies %t for %T (kind: %v)\n", s.Path, r, source, kind)
-		return r
+		return kind == reflect.String
+	default:
+		return false
 	}
-	debugLog("string validator for %q applies %t for %T (kind: %v)\n", s.Path, false, source, kind)
-	return false
 }
 
 func (s *stringValidator) Validate(val interface{}) *Result {
+	if s.Options.recycleValidators {
+		defer func() {
+			s.redeem()
+		}()
+	}
+
 	data, ok := val.(string)
 	if !ok {
-		return errorHelp.sErr(errors.InvalidType(s.Path, s.In, stringType, val))
+		return errorHelp.sErr(errors.InvalidType(s.Path, s.In, stringType, val), s.Options.recycleResult)
 	}
 
 	if s.Required && !s.AllowEmptyValue && (s.Default == nil || s.Default == "") {
 		if err := RequiredString(s.Path, s.In, data); err != nil {
-			return errorHelp.sErr(err)
+			return errorHelp.sErr(err, s.Options.recycleResult)
 		}
 	}
 
 	if s.MaxLength != nil {
 		if err := MaxLength(s.Path, s.In, data, *s.MaxLength); err != nil {
-			return errorHelp.sErr(err)
+			return errorHelp.sErr(err, s.Options.recycleResult)
 		}
 	}
 
 	if s.MinLength != nil {
 		if err := MinLength(s.Path, s.In, data, *s.MinLength); err != nil {
-			return errorHelp.sErr(err)
+			return errorHelp.sErr(err, s.Options.recycleResult)
 		}
 	}
 
 	if s.Pattern != "" {
 		if err := Pattern(s.Path, s.In, data, s.Pattern); err != nil {
-			return errorHelp.sErr(err)
+			return errorHelp.sErr(err, s.Options.recycleResult)
 		}
 	}
 	return nil
 }
+
+func (s *stringValidator) redeem() {
+	pools.poolOfStringValidators.RedeemValidator(s)
+}
diff --git a/vendor/github.com/go-openapi/validate/values.go b/vendor/github.com/go-openapi/validate/values.go
index e7ad8c10..5f6f5ee6 100644
--- a/vendor/github.com/go-openapi/validate/values.go
+++ b/vendor/github.com/go-openapi/validate/values.go
@@ -120,7 +120,7 @@ func UniqueItems(path, in string, data interface{}) *errors.Validation {
 
 // MinLength validates a string for minimum length
 func MinLength(path, in, data string, minLength int64) *errors.Validation {
-	strLen := int64(utf8.RuneCount([]byte(data)))
+	strLen := int64(utf8.RuneCountInString(data))
 	if strLen < minLength {
 		return errors.TooShort(path, in, minLength, data)
 	}
@@ -129,7 +129,7 @@ func MinLength(path, in, data string, minLength int64) *errors.Validation {
 
 // MaxLength validates a string for maximum length
 func MaxLength(path, in, data string, maxLength int64) *errors.Validation {
-	strLen := int64(utf8.RuneCount([]byte(data)))
+	strLen := int64(utf8.RuneCountInString(data))
 	if strLen > maxLength {
 		return errors.TooLong(path, in, maxLength, data)
 	}
@@ -315,7 +315,7 @@ func FormatOf(path, in, format, data string, registry strfmt.Registry) *errors.V
 // TODO: Normally, a JSON MAX_SAFE_INTEGER check would ensure conversion remains loss-free
 func MaximumNativeType(path, in string, val interface{}, max float64, exclusive bool) *errors.Validation {
 	kind := reflect.ValueOf(val).Type().Kind()
-	switch kind {
+	switch kind { //nolint:exhaustive
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 		value := valueHelp.asInt64(val)
 		return MaximumInt(path, in, value, int64(max), exclusive)
@@ -345,7 +345,7 @@ func MaximumNativeType(path, in string, val interface{}, max float64, exclusive
 // TODO: Normally, a JSON MAX_SAFE_INTEGER check would ensure conversion remains loss-free
 func MinimumNativeType(path, in string, val interface{}, min float64, exclusive bool) *errors.Validation {
 	kind := reflect.ValueOf(val).Type().Kind()
-	switch kind {
+	switch kind { //nolint:exhaustive
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 		value := valueHelp.asInt64(val)
 		return MinimumInt(path, in, value, int64(min), exclusive)
@@ -375,7 +375,7 @@ func MinimumNativeType(path, in string, val interface{}, min float64, exclusive
 // TODO: Normally, a JSON MAX_SAFE_INTEGER check would ensure conversion remains loss-free
 func MultipleOfNativeType(path, in string, val interface{}, multipleOf float64) *errors.Validation {
 	kind := reflect.ValueOf(val).Type().Kind()
-	switch kind {
+	switch kind { //nolint:exhaustive
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 		value := valueHelp.asInt64(val)
 		return MultipleOfInt(path, in, value, int64(multipleOf))
@@ -399,7 +399,7 @@ func IsValueValidAgainstRange(val interface{}, typeName, format, prefix, path st
 
 	// What is the string representation of val
 	var stringRep string
-	switch kind {
+	switch kind { //nolint:exhaustive
 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
 		stringRep = swag.FormatUint64(valueHelp.asUint64(val))
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
diff --git a/vendor/github.com/klauspost/compress/.goreleaser.yml b/vendor/github.com/klauspost/compress/.goreleaser.yml
index 7a008a4d..a2295380 100644
--- a/vendor/github.com/klauspost/compress/.goreleaser.yml
+++ b/vendor/github.com/klauspost/compress/.goreleaser.yml
@@ -3,7 +3,6 @@
 before:
   hooks:
     - ./gen.sh
-    - go install mvdan.cc/garble@v0.9.3
 
 builds:
   -
@@ -32,7 +31,6 @@ builds:
       - mips64le
     goarm:
       - 7
-    gobinary: garble
   -
     id: "s2d"
     binary: s2d
@@ -59,7 +57,6 @@ builds:
       - mips64le
     goarm:
       - 7
-    gobinary: garble
   -
     id: "s2sx"
     binary: s2sx
@@ -87,21 +84,11 @@ builds:
       - mips64le
     goarm:
       - 7
-    gobinary: garble
 
 archives:
   -
     id: s2-binaries
-    name_template: "s2-{{ .Os }}_{{ .Arch }}_{{ .Version }}"
-    replacements:
-      aix: AIX
-      darwin: OSX
-      linux: Linux
-      windows: Windows
-      386: i386
-      amd64: x86_64
-      freebsd: FreeBSD
-      netbsd: NetBSD
+    name_template: "s2-{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
     format_overrides:
       - goos: windows
         format: zip
@@ -125,7 +112,7 @@ changelog:
 
 nfpms:
   -
-    file_name_template: "s2_package_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
+    file_name_template: "s2_package__{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
     vendor: Klaus Post
     homepage: https://github.com/klauspost/compress
     maintainer: Klaus Post <klauspost@gmail.com>
@@ -134,8 +121,3 @@ nfpms:
     formats:
       - deb
       - rpm
-    replacements:
-      darwin: Darwin
-      linux: Linux
-      freebsd: FreeBSD
-      amd64: x86_64
diff --git a/vendor/github.com/klauspost/compress/README.md b/vendor/github.com/klauspost/compress/README.md
index f710a34e..05c7359e 100644
--- a/vendor/github.com/klauspost/compress/README.md
+++ b/vendor/github.com/klauspost/compress/README.md
@@ -16,6 +16,60 @@ This package provides various compression algorithms.
 
 # changelog
 
+* Feb 5th, 2024 - [1.17.6](https://github.com/klauspost/compress/releases/tag/v1.17.6)
+	* zstd: Fix incorrect repeat coding in best mode https://github.com/klauspost/compress/pull/923
+	* s2: Fix DecodeConcurrent deadlock on errors https://github.com/klauspost/compress/pull/925
+  
+* Jan 26th, 2024 - [v1.17.5](https://github.com/klauspost/compress/releases/tag/v1.17.5)
+	* flate: Fix reset with dictionary on custom window encodes https://github.com/klauspost/compress/pull/912
+	* zstd: Add Frame header encoding and stripping https://github.com/klauspost/compress/pull/908
+	* zstd: Limit better/best default window to 8MB https://github.com/klauspost/compress/pull/913
+	* zstd: Speed improvements by @greatroar in https://github.com/klauspost/compress/pull/896 https://github.com/klauspost/compress/pull/910
+	* s2: Fix callbacks for skippable blocks and disallow 0xfe (Padding) by @Jille in https://github.com/klauspost/compress/pull/916 https://github.com/klauspost/compress/pull/917
+https://github.com/klauspost/compress/pull/919 https://github.com/klauspost/compress/pull/918
+
+* Dec 1st, 2023 - [v1.17.4](https://github.com/klauspost/compress/releases/tag/v1.17.4)
+	* huff0: Speed up symbol counting by @greatroar in https://github.com/klauspost/compress/pull/887
+	* huff0: Remove byteReader by @greatroar in https://github.com/klauspost/compress/pull/886
+	* gzhttp: Allow overriding decompression on transport https://github.com/klauspost/compress/pull/892
+	* gzhttp: Clamp compression level https://github.com/klauspost/compress/pull/890
+	* gzip: Error out if reserved bits are set https://github.com/klauspost/compress/pull/891
+
+* Nov 15th, 2023 - [v1.17.3](https://github.com/klauspost/compress/releases/tag/v1.17.3)
+	* fse: Fix max header size https://github.com/klauspost/compress/pull/881
+	* zstd: Improve better/best compression https://github.com/klauspost/compress/pull/877
+	* gzhttp: Fix missing content type on Close https://github.com/klauspost/compress/pull/883
+
+* Oct 22nd, 2023 - [v1.17.2](https://github.com/klauspost/compress/releases/tag/v1.17.2)
+	* zstd: Fix rare *CORRUPTION* output in "best" mode. See https://github.com/klauspost/compress/pull/876
+
+* Oct 14th, 2023 - [v1.17.1](https://github.com/klauspost/compress/releases/tag/v1.17.1)
+	* s2: Fix S2 "best" dictionary wrong encoding by @klauspost in https://github.com/klauspost/compress/pull/871
+	* flate: Reduce allocations in decompressor and minor code improvements by @fakefloordiv in https://github.com/klauspost/compress/pull/869
+	* s2: Fix EstimateBlockSize on 6&7 length input by @klauspost in https://github.com/klauspost/compress/pull/867
+
+* Sept 19th, 2023 - [v1.17.0](https://github.com/klauspost/compress/releases/tag/v1.17.0)
+	* Add experimental dictionary builder  https://github.com/klauspost/compress/pull/853
+	* Add xerial snappy read/writer https://github.com/klauspost/compress/pull/838
+	* flate: Add limited window compression https://github.com/klauspost/compress/pull/843
+	* s2: Do 2 overlapping match checks https://github.com/klauspost/compress/pull/839
+	* flate: Add amd64 assembly matchlen https://github.com/klauspost/compress/pull/837
+	* gzip: Copy bufio.Reader on Reset by @thatguystone in https://github.com/klauspost/compress/pull/860
+
+<details>
+	<summary>See changes to v1.16.x</summary>
+
+   
+* July 1st, 2023 - [v1.16.7](https://github.com/klauspost/compress/releases/tag/v1.16.7)
+	* zstd: Fix default level first dictionary encode https://github.com/klauspost/compress/pull/829
+	* s2: add GetBufferCapacity() method by @GiedriusS in https://github.com/klauspost/compress/pull/832
+
+* June 13, 2023 - [v1.16.6](https://github.com/klauspost/compress/releases/tag/v1.16.6)
+	* zstd: correctly ignore WithEncoderPadding(1) by @ianlancetaylor in https://github.com/klauspost/compress/pull/806
+	* zstd: Add amd64 match length assembly https://github.com/klauspost/compress/pull/824
+	* gzhttp: Handle informational headers by @rtribotte in https://github.com/klauspost/compress/pull/815
+	* s2: Improve Better compression slightly https://github.com/klauspost/compress/pull/663
+
 * Apr 16, 2023 - [v1.16.5](https://github.com/klauspost/compress/releases/tag/v1.16.5)
 	* zstd: readByte needs to use io.ReadFull by @jnoxon in https://github.com/klauspost/compress/pull/802
 	* gzip: Fix WriterTo after initial read https://github.com/klauspost/compress/pull/804
@@ -43,7 +97,11 @@ This package provides various compression algorithms.
 	* s2: Add LZ4 block converter. https://github.com/klauspost/compress/pull/748
 	* s2: Support io.ReaderAt in ReadSeeker. https://github.com/klauspost/compress/pull/747
 	* s2c/s2sx: Use concurrent decoding. https://github.com/klauspost/compress/pull/746
+</details>
 
+<details>
+	<summary>See changes to v1.15.x</summary>
+	
 * Jan 21st, 2023 (v1.15.15)
 	* deflate: Improve level 7-9 by @klauspost in https://github.com/klauspost/compress/pull/739
 	* zstd: Add delta encoding support by @greatroar in https://github.com/klauspost/compress/pull/728
@@ -170,6 +228,8 @@ Stream decompression is now faster on asynchronous, since the goroutine allocati
 
 While the release has been extensively tested, it is recommended to testing when upgrading.
 
+</details>
+
 <details>
 	<summary>See changes to v1.14.x</summary>
 	
@@ -505,6 +565,8 @@ the stateless compress described below.
 
 For compression performance, see: [this spreadsheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing).
 
+To disable all assembly add `-tags=noasm`. This works across all packages.
+
 # Stateless compression
 
 This package offers stateless compression as a special option for gzip/deflate. 
@@ -523,7 +585,7 @@ For direct deflate use, NewStatelessWriter and StatelessDeflate are available. S
 
 A `bufio.Writer` can of course be used to control write sizes. For example, to use a 4KB buffer:
 
-```
+```go
 	// replace 'ioutil.Discard' with your output.
 	gzw, err := gzip.NewWriterLevel(ioutil.Discard, gzip.StatelessCompression)
 	if err != nil {
@@ -630,6 +692,8 @@ Here are other packages of good quality and pure Go (no cgo wrappers or autoconv
 * [github.com/dsnet/compress](https://github.com/dsnet/compress) - brotli decompression, bzip2 writer.
 * [github.com/ronanh/intcomp](https://github.com/ronanh/intcomp) - Integer compression.
 * [github.com/spenczar/fpc](https://github.com/spenczar/fpc) - Float compression.
+* [github.com/minio/zipindex](https://github.com/minio/zipindex) - External ZIP directory index.
+* [github.com/ybirader/pzip](https://github.com/ybirader/pzip) - Fast concurrent zip archiver and extractor.
 
 # license
 
diff --git a/vendor/github.com/klauspost/compress/SECURITY.md b/vendor/github.com/klauspost/compress/SECURITY.md
index 23a43387..ca6685e2 100644
--- a/vendor/github.com/klauspost/compress/SECURITY.md
+++ b/vendor/github.com/klauspost/compress/SECURITY.md
@@ -20,6 +20,6 @@ Vulnerabilities resulting from compiler/assembler errors should be reported upst
 
 If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
 
-Please disclose it at [security advisory](https://github.com/klaupost/compress/security/advisories/new). If possible please provide a minimal reproducer. If the issue only applies to a single platform, it would be helpful to provide access to that.
+Please disclose it at [security advisory](https://github.com/klauspost/compress/security/advisories/new). If possible please provide a minimal reproducer. If the issue only applies to a single platform, it would be helpful to provide access to that.
 
 This project is maintained by a team of volunteers on a reasonable-effort basis. As such, vulnerabilities will be disclosed in a best effort base.
diff --git a/vendor/github.com/klauspost/compress/fse/bitwriter.go b/vendor/github.com/klauspost/compress/fse/bitwriter.go
index 43e46361..e82fa3bb 100644
--- a/vendor/github.com/klauspost/compress/fse/bitwriter.go
+++ b/vendor/github.com/klauspost/compress/fse/bitwriter.go
@@ -152,12 +152,11 @@ func (b *bitWriter) flushAlign() {
 
 // close will write the alignment bit and write the final byte(s)
 // to the output.
-func (b *bitWriter) close() error {
+func (b *bitWriter) close() {
 	// End mark
 	b.addBits16Clean(1, 1)
 	// flush until next byte.
 	b.flushAlign()
-	return nil
 }
 
 // reset and continue writing by appending to out.
diff --git a/vendor/github.com/klauspost/compress/fse/compress.go b/vendor/github.com/klauspost/compress/fse/compress.go
index dac97e58..074018d8 100644
--- a/vendor/github.com/klauspost/compress/fse/compress.go
+++ b/vendor/github.com/klauspost/compress/fse/compress.go
@@ -199,7 +199,8 @@ func (s *Scratch) compress(src []byte) error {
 	c2.flush(s.actualTableLog)
 	c1.flush(s.actualTableLog)
 
-	return s.bw.close()
+	s.bw.close()
+	return nil
 }
 
 // writeCount will write the normalized histogram count to header.
@@ -211,7 +212,7 @@ func (s *Scratch) writeCount() error {
 		previous0 bool
 		charnum   uint16
 
-		maxHeaderSize = ((int(s.symbolLen) * int(tableLog)) >> 3) + 3
+		maxHeaderSize = ((int(s.symbolLen)*int(tableLog) + 4 + 2) >> 3) + 3
 
 		// Write Table Size
 		bitStream = uint32(tableLog - minTablelog)
diff --git a/vendor/github.com/klauspost/compress/huff0/bitwriter.go b/vendor/github.com/klauspost/compress/huff0/bitwriter.go
index b4d7164e..0ebc9aaa 100644
--- a/vendor/github.com/klauspost/compress/huff0/bitwriter.go
+++ b/vendor/github.com/klauspost/compress/huff0/bitwriter.go
@@ -94,10 +94,9 @@ func (b *bitWriter) flushAlign() {
 
 // close will write the alignment bit and write the final byte(s)
 // to the output.
-func (b *bitWriter) close() error {
+func (b *bitWriter) close() {
 	// End mark
 	b.addBits16Clean(1, 1)
 	// flush until next byte.
 	b.flushAlign()
-	return nil
 }
diff --git a/vendor/github.com/klauspost/compress/huff0/bytereader.go b/vendor/github.com/klauspost/compress/huff0/bytereader.go
deleted file mode 100644
index 4dcab8d2..00000000
--- a/vendor/github.com/klauspost/compress/huff0/bytereader.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018 Klaus Post. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.
-
-package huff0
-
-// byteReader provides a byte reader that reads
-// little endian values from a byte stream.
-// The input stream is manually advanced.
-// The reader performs no bounds checks.
-type byteReader struct {
-	b   []byte
-	off int
-}
-
-// init will initialize the reader and set the input.
-func (b *byteReader) init(in []byte) {
-	b.b = in
-	b.off = 0
-}
-
-// Int32 returns a little endian int32 starting at current offset.
-func (b byteReader) Int32() int32 {
-	v3 := int32(b.b[b.off+3])
-	v2 := int32(b.b[b.off+2])
-	v1 := int32(b.b[b.off+1])
-	v0 := int32(b.b[b.off])
-	return (v3 << 24) | (v2 << 16) | (v1 << 8) | v0
-}
-
-// Uint32 returns a little endian uint32 starting at current offset.
-func (b byteReader) Uint32() uint32 {
-	v3 := uint32(b.b[b.off+3])
-	v2 := uint32(b.b[b.off+2])
-	v1 := uint32(b.b[b.off+1])
-	v0 := uint32(b.b[b.off])
-	return (v3 << 24) | (v2 << 16) | (v1 << 8) | v0
-}
-
-// 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 4ee4fa18..84aa3d12 100644
--- a/vendor/github.com/klauspost/compress/huff0/compress.go
+++ b/vendor/github.com/klauspost/compress/huff0/compress.go
@@ -227,10 +227,10 @@ func EstimateSizes(in []byte, s *Scratch) (tableSz, dataSz, reuseSz int, err err
 }
 
 func (s *Scratch) compress1X(src []byte) ([]byte, error) {
-	return s.compress1xDo(s.Out, src)
+	return s.compress1xDo(s.Out, src), nil
 }
 
-func (s *Scratch) compress1xDo(dst, src []byte) ([]byte, error) {
+func (s *Scratch) compress1xDo(dst, src []byte) []byte {
 	var bw = bitWriter{out: dst}
 
 	// N is length divisible by 4.
@@ -260,8 +260,8 @@ func (s *Scratch) compress1xDo(dst, src []byte) ([]byte, error) {
 			bw.encTwoSymbols(cTable, tmp[1], tmp[0])
 		}
 	}
-	err := bw.close()
-	return bw.out, err
+	bw.close()
+	return bw.out
 }
 
 var sixZeros [6]byte
@@ -283,12 +283,8 @@ func (s *Scratch) compress4X(src []byte) ([]byte, error) {
 		}
 		src = src[len(toDo):]
 
-		var err error
 		idx := len(s.Out)
-		s.Out, err = s.compress1xDo(s.Out, toDo)
-		if err != nil {
-			return nil, err
-		}
+		s.Out = s.compress1xDo(s.Out, toDo)
 		if len(s.Out)-idx > math.MaxUint16 {
 			// We cannot store the size in the jump table
 			return nil, ErrIncompressible
@@ -315,7 +311,6 @@ func (s *Scratch) compress4Xp(src []byte) ([]byte, error) {
 
 	segmentSize := (len(src) + 3) / 4
 	var wg sync.WaitGroup
-	var errs [4]error
 	wg.Add(4)
 	for i := 0; i < 4; i++ {
 		toDo := src
@@ -326,15 +321,12 @@ func (s *Scratch) compress4Xp(src []byte) ([]byte, error) {
 
 		// Separate goroutine for each block.
 		go func(i int) {
-			s.tmpOut[i], errs[i] = s.compress1xDo(s.tmpOut[i][:0], toDo)
+			s.tmpOut[i] = s.compress1xDo(s.tmpOut[i][:0], toDo)
 			wg.Done()
 		}(i)
 	}
 	wg.Wait()
 	for i := 0; i < 4; i++ {
-		if errs[i] != nil {
-			return nil, errs[i]
-		}
 		o := s.tmpOut[i]
 		if len(o) > math.MaxUint16 {
 			// We cannot store the size in the jump table
@@ -358,6 +350,7 @@ func (s *Scratch) compress4Xp(src []byte) ([]byte, error) {
 // Does not update s.clearCount.
 func (s *Scratch) countSimple(in []byte) (max int, reuse bool) {
 	reuse = true
+	_ = s.count // Assert that s != nil to speed up the following loop.
 	for _, v := range in {
 		s.count[v]++
 	}
@@ -423,7 +416,7 @@ func (s *Scratch) validateTable(c cTable) bool {
 
 // minTableLog provides the minimum logSize to safely represent a distribution.
 func (s *Scratch) minTableLog() uint8 {
-	minBitsSrc := highBit32(uint32(s.br.remain())) + 1
+	minBitsSrc := highBit32(uint32(s.srcLen)) + 1
 	minBitsSymbols := highBit32(uint32(s.symbolLen-1)) + 2
 	if minBitsSrc < minBitsSymbols {
 		return uint8(minBitsSrc)
@@ -435,7 +428,7 @@ func (s *Scratch) minTableLog() uint8 {
 func (s *Scratch) optimalTableLog() {
 	tableLog := s.TableLog
 	minBits := s.minTableLog()
-	maxBitsSrc := uint8(highBit32(uint32(s.br.remain()-1))) - 1
+	maxBitsSrc := uint8(highBit32(uint32(s.srcLen-1))) - 1
 	if maxBitsSrc < tableLog {
 		// Accuracy can be reduced
 		tableLog = maxBitsSrc
diff --git a/vendor/github.com/klauspost/compress/huff0/huff0.go b/vendor/github.com/klauspost/compress/huff0/huff0.go
index e8ad17ad..77ecd68e 100644
--- a/vendor/github.com/klauspost/compress/huff0/huff0.go
+++ b/vendor/github.com/klauspost/compress/huff0/huff0.go
@@ -88,7 +88,7 @@ type Scratch struct {
 	// Decoders will return ErrMaxDecodedSizeExceeded is this limit is exceeded.
 	MaxDecodedSize int
 
-	br byteReader
+	srcLen int
 
 	// MaxSymbolValue will override the maximum symbol value of the next block.
 	MaxSymbolValue uint8
@@ -170,7 +170,7 @@ func (s *Scratch) prepare(in []byte) (*Scratch, error) {
 	if s.fse == nil {
 		s.fse = &fse.Scratch{}
 	}
-	s.br.init(in)
+	s.srcLen = len(in)
 
 	return s, nil
 }
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 2aa6a95a..2754bac6 100644
--- a/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go
+++ b/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go
@@ -51,7 +51,7 @@ func emitCopy(dst []byte, offset, length int) int {
 	i := 0
 	// The maximum length for a single tagCopy1 or tagCopy2 op is 64 bytes. The
 	// threshold for this loop is a little higher (at 68 = 64 + 4), and the
-	// length emitted down below is is a little lower (at 60 = 64 - 4), because
+	// length emitted down below is a little lower (at 60 = 64 - 4), because
 	// it's shorter to encode a length 67 copy as a length 60 tagCopy2 followed
 	// by a length 7 tagCopy1 (which encodes as 3+2 bytes) than to encode it as
 	// a length 64 tagCopy2 followed by a length 3 tagCopy2 (which encodes as
diff --git a/vendor/github.com/klauspost/compress/s2sx.mod b/vendor/github.com/klauspost/compress/s2sx.mod
index 2263853f..5a4412f9 100644
--- a/vendor/github.com/klauspost/compress/s2sx.mod
+++ b/vendor/github.com/klauspost/compress/s2sx.mod
@@ -1,4 +1,4 @@
 module github.com/klauspost/compress
 
-go 1.16
+go 1.19
 
diff --git a/vendor/github.com/klauspost/compress/zstd/README.md b/vendor/github.com/klauspost/compress/zstd/README.md
index bdd49c8b..92e2347b 100644
--- a/vendor/github.com/klauspost/compress/zstd/README.md
+++ b/vendor/github.com/klauspost/compress/zstd/README.md
@@ -259,7 +259,7 @@ nyc-taxi-data-10M.csv   gzkp    1   3325605752  922273214   13929   227.68
 
 ## Decompressor
 
-Staus: STABLE - there may still be subtle bugs, but a wide variety of content has been tested.
+Status: STABLE - there may still be subtle bugs, but a wide variety of content has been tested.
 
 This library is being continuously [fuzz-tested](https://github.com/klauspost/compress-fuzz),
 kindly supplied by [fuzzit.dev](https://fuzzit.dev/). 
diff --git a/vendor/github.com/klauspost/compress/zstd/bitreader.go b/vendor/github.com/klauspost/compress/zstd/bitreader.go
index 97299d49..25ca9839 100644
--- a/vendor/github.com/klauspost/compress/zstd/bitreader.go
+++ b/vendor/github.com/klauspost/compress/zstd/bitreader.go
@@ -17,7 +17,6 @@ import (
 // for aligning the input.
 type bitReader struct {
 	in       []byte
-	off      uint   // next byte to read is at in[off - 1]
 	value    uint64 // Maybe use [16]byte, but shifting is awkward.
 	bitsRead uint8
 }
@@ -28,7 +27,6 @@ func (b *bitReader) init(in []byte) error {
 		return errors.New("corrupt stream: too short")
 	}
 	b.in = in
-	b.off = uint(len(in))
 	// The highest bit of the last byte indicates where to start
 	v := in[len(in)-1]
 	if v == 0 {
@@ -69,21 +67,19 @@ func (b *bitReader) fillFast() {
 	if b.bitsRead < 32 {
 		return
 	}
-	// 2 bounds checks.
-	v := b.in[b.off-4:]
-	v = v[:4]
+	v := b.in[len(b.in)-4:]
+	b.in = b.in[:len(b.in)-4]
 	low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
 	b.value = (b.value << 32) | uint64(low)
 	b.bitsRead -= 32
-	b.off -= 4
 }
 
 // fillFastStart() assumes the bitreader is empty and there is at least 8 bytes to read.
 func (b *bitReader) fillFastStart() {
-	// Do single re-slice to avoid bounds checks.
-	b.value = binary.LittleEndian.Uint64(b.in[b.off-8:])
+	v := b.in[len(b.in)-8:]
+	b.in = b.in[:len(b.in)-8]
+	b.value = binary.LittleEndian.Uint64(v)
 	b.bitsRead = 0
-	b.off -= 8
 }
 
 // fill() will make sure at least 32 bits are available.
@@ -91,25 +87,25 @@ func (b *bitReader) fill() {
 	if b.bitsRead < 32 {
 		return
 	}
-	if b.off >= 4 {
-		v := b.in[b.off-4:]
-		v = v[:4]
+	if len(b.in) >= 4 {
+		v := b.in[len(b.in)-4:]
+		b.in = b.in[:len(b.in)-4]
 		low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
 		b.value = (b.value << 32) | uint64(low)
 		b.bitsRead -= 32
-		b.off -= 4
 		return
 	}
-	for b.off > 0 {
-		b.value = (b.value << 8) | uint64(b.in[b.off-1])
-		b.bitsRead -= 8
-		b.off--
+
+	b.bitsRead -= uint8(8 * len(b.in))
+	for len(b.in) > 0 {
+		b.value = (b.value << 8) | uint64(b.in[len(b.in)-1])
+		b.in = b.in[:len(b.in)-1]
 	}
 }
 
 // finished returns true if all bits have been read from the bit stream.
 func (b *bitReader) finished() bool {
-	return b.off == 0 && b.bitsRead >= 64
+	return len(b.in) == 0 && b.bitsRead >= 64
 }
 
 // overread returns true if more bits have been requested than is on the stream.
@@ -119,7 +115,7 @@ func (b *bitReader) overread() bool {
 
 // remain returns the number of bits remaining.
 func (b *bitReader) remain() uint {
-	return b.off*8 + 64 - uint(b.bitsRead)
+	return 8*uint(len(b.in)) + 64 - uint(b.bitsRead)
 }
 
 // close the bitstream and returns an error if out-of-buffer reads occurred.
diff --git a/vendor/github.com/klauspost/compress/zstd/bitwriter.go b/vendor/github.com/klauspost/compress/zstd/bitwriter.go
index 78b3c61b..1952f175 100644
--- a/vendor/github.com/klauspost/compress/zstd/bitwriter.go
+++ b/vendor/github.com/klauspost/compress/zstd/bitwriter.go
@@ -97,12 +97,11 @@ func (b *bitWriter) flushAlign() {
 
 // close will write the alignment bit and write the final byte(s)
 // to the output.
-func (b *bitWriter) close() error {
+func (b *bitWriter) close() {
 	// End mark
 	b.addBits16Clean(1, 1)
 	// flush until next byte.
 	b.flushAlign()
-	return nil
 }
 
 // reset and continue writing by appending to out.
diff --git a/vendor/github.com/klauspost/compress/zstd/blockdec.go b/vendor/github.com/klauspost/compress/zstd/blockdec.go
index 9f17ce60..03744fbc 100644
--- a/vendor/github.com/klauspost/compress/zstd/blockdec.go
+++ b/vendor/github.com/klauspost/compress/zstd/blockdec.go
@@ -554,6 +554,9 @@ func (b *blockDec) prepareSequences(in []byte, hist *history) (err error) {
 		if debugDecoder {
 			printf("Compression modes: 0b%b", compMode)
 		}
+		if compMode&3 != 0 {
+			return errors.New("corrupt block: reserved bits not zero")
+		}
 		for i := uint(0); i < 3; i++ {
 			mode := seqCompMode((compMode >> (6 - i*2)) & 3)
 			if debugDecoder {
diff --git a/vendor/github.com/klauspost/compress/zstd/blockenc.go b/vendor/github.com/klauspost/compress/zstd/blockenc.go
index fd4a36f7..32a7f401 100644
--- a/vendor/github.com/klauspost/compress/zstd/blockenc.go
+++ b/vendor/github.com/klauspost/compress/zstd/blockenc.go
@@ -361,14 +361,21 @@ func (b *blockEnc) encodeLits(lits []byte, raw bool) error {
 	if len(lits) >= 1024 {
 		// Use 4 Streams.
 		out, reUsed, err = huff0.Compress4X(lits, b.litEnc)
-	} else if len(lits) > 32 {
+	} else if len(lits) > 16 {
 		// Use 1 stream
 		single = true
 		out, reUsed, err = huff0.Compress1X(lits, b.litEnc)
 	} else {
 		err = huff0.ErrIncompressible
 	}
-
+	if err == nil && len(out)+5 > len(lits) {
+		// If we are close, we may still be worse or equal to raw.
+		var lh literalsHeader
+		lh.setSizes(len(out), len(lits), single)
+		if len(out)+lh.size() >= len(lits) {
+			err = huff0.ErrIncompressible
+		}
+	}
 	switch err {
 	case huff0.ErrIncompressible:
 		if debugEncoder {
@@ -420,6 +427,16 @@ func (b *blockEnc) encodeLits(lits []byte, raw bool) error {
 	return nil
 }
 
+// encodeRLE will encode an RLE block.
+func (b *blockEnc) encodeRLE(val byte, length uint32) {
+	var bh blockHeader
+	bh.setLast(b.last)
+	bh.setSize(length)
+	bh.setType(blockTypeRLE)
+	b.output = bh.appendTo(b.output)
+	b.output = append(b.output, val)
+}
+
 // fuzzFseEncoder can be used to fuzz the FSE encoder.
 func fuzzFseEncoder(data []byte) int {
 	if len(data) > maxSequences || len(data) < 2 {
@@ -472,6 +489,16 @@ func (b *blockEnc) encode(org []byte, raw, rawAllLits bool) error {
 	if len(b.sequences) == 0 {
 		return b.encodeLits(b.literals, rawAllLits)
 	}
+	if len(b.sequences) == 1 && len(org) > 0 && len(b.literals) <= 1 {
+		// Check common RLE cases.
+		seq := b.sequences[0]
+		if seq.litLen == uint32(len(b.literals)) && seq.offset-3 == 1 {
+			// Offset == 1 and 0 or 1 literals.
+			b.encodeRLE(org[0], b.sequences[0].matchLen+zstdMinMatch+seq.litLen)
+			return nil
+		}
+	}
+
 	// We want some difference to at least account for the headers.
 	saved := b.size - len(b.literals) - (b.size >> 6)
 	if saved < 16 {
@@ -503,7 +530,7 @@ func (b *blockEnc) encode(org []byte, raw, rawAllLits bool) error {
 	if len(b.literals) >= 1024 && !raw {
 		// Use 4 Streams.
 		out, reUsed, err = huff0.Compress4X(b.literals, b.litEnc)
-	} else if len(b.literals) > 32 && !raw {
+	} else if len(b.literals) > 16 && !raw {
 		// Use 1 stream
 		single = true
 		out, reUsed, err = huff0.Compress1X(b.literals, b.litEnc)
@@ -511,6 +538,17 @@ func (b *blockEnc) encode(org []byte, raw, rawAllLits bool) error {
 		err = huff0.ErrIncompressible
 	}
 
+	if err == nil && len(out)+5 > len(b.literals) {
+		// If we are close, we may still be worse or equal to raw.
+		var lh literalsHeader
+		lh.setSize(len(b.literals))
+		szRaw := lh.size()
+		lh.setSizes(len(out), len(b.literals), single)
+		szComp := lh.size()
+		if len(out)+szComp >= len(b.literals)+szRaw {
+			err = huff0.ErrIncompressible
+		}
+	}
 	switch err {
 	case huff0.ErrIncompressible:
 		lh.setType(literalsBlockRaw)
@@ -773,10 +811,7 @@ func (b *blockEnc) encode(org []byte, raw, rawAllLits bool) error {
 	ml.flush(mlEnc.actualTableLog)
 	of.flush(ofEnc.actualTableLog)
 	ll.flush(llEnc.actualTableLog)
-	err = wr.close()
-	if err != nil {
-		return err
-	}
+	wr.close()
 	b.output = wr.out
 
 	// Maybe even add a bigger margin.
diff --git a/vendor/github.com/klauspost/compress/zstd/decodeheader.go b/vendor/github.com/klauspost/compress/zstd/decodeheader.go
index f6a24097..6a5a2988 100644
--- a/vendor/github.com/klauspost/compress/zstd/decodeheader.go
+++ b/vendor/github.com/klauspost/compress/zstd/decodeheader.go
@@ -95,42 +95,54 @@ type Header struct {
 // If there isn't enough input, io.ErrUnexpectedEOF is returned.
 // The FirstBlock.OK will indicate if enough information was available to decode the first block header.
 func (h *Header) Decode(in []byte) error {
+	_, err := h.DecodeAndStrip(in)
+	return err
+}
+
+// DecodeAndStrip will decode the header from the beginning of the stream
+// and on success return the remaining bytes.
+// This will decode the frame header and the first block header if enough bytes are provided.
+// It is recommended to provide at least HeaderMaxSize bytes.
+// If the frame header cannot be read an error will be returned.
+// If there isn't enough input, io.ErrUnexpectedEOF is returned.
+// The FirstBlock.OK will indicate if enough information was available to decode the first block header.
+func (h *Header) DecodeAndStrip(in []byte) (remain []byte, err error) {
 	*h = Header{}
 	if len(in) < 4 {
-		return io.ErrUnexpectedEOF
+		return nil, io.ErrUnexpectedEOF
 	}
 	h.HeaderSize += 4
 	b, in := in[:4], in[4:]
 	if string(b) != frameMagic {
 		if string(b[1:4]) != skippableFrameMagic || b[0]&0xf0 != 0x50 {
-			return ErrMagicMismatch
+			return nil, ErrMagicMismatch
 		}
 		if len(in) < 4 {
-			return io.ErrUnexpectedEOF
+			return nil, io.ErrUnexpectedEOF
 		}
 		h.HeaderSize += 4
 		h.Skippable = true
 		h.SkippableID = int(b[0] & 0xf)
 		h.SkippableSize = binary.LittleEndian.Uint32(in)
-		return nil
+		return in[4:], nil
 	}
 
 	// Read Window_Descriptor
 	// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#window_descriptor
 	if len(in) < 1 {
-		return io.ErrUnexpectedEOF
+		return nil, io.ErrUnexpectedEOF
 	}
 	fhd, in := in[0], in[1:]
 	h.HeaderSize++
 	h.SingleSegment = fhd&(1<<5) != 0
 	h.HasCheckSum = fhd&(1<<2) != 0
 	if fhd&(1<<3) != 0 {
-		return errors.New("reserved bit set on frame header")
+		return nil, errors.New("reserved bit set on frame header")
 	}
 
 	if !h.SingleSegment {
 		if len(in) < 1 {
-			return io.ErrUnexpectedEOF
+			return nil, io.ErrUnexpectedEOF
 		}
 		var wd byte
 		wd, in = in[0], in[1:]
@@ -148,7 +160,7 @@ func (h *Header) Decode(in []byte) error {
 			size = 4
 		}
 		if len(in) < int(size) {
-			return io.ErrUnexpectedEOF
+			return nil, io.ErrUnexpectedEOF
 		}
 		b, in = in[:size], in[size:]
 		h.HeaderSize += int(size)
@@ -178,7 +190,7 @@ func (h *Header) Decode(in []byte) error {
 	if fcsSize > 0 {
 		h.HasFCS = true
 		if len(in) < fcsSize {
-			return io.ErrUnexpectedEOF
+			return nil, io.ErrUnexpectedEOF
 		}
 		b, in = in[:fcsSize], in[fcsSize:]
 		h.HeaderSize += int(fcsSize)
@@ -199,7 +211,7 @@ func (h *Header) Decode(in []byte) error {
 
 	// Frame Header done, we will not fail from now on.
 	if len(in) < 3 {
-		return nil
+		return in, nil
 	}
 	tmp := in[:3]
 	bh := uint32(tmp[0]) | (uint32(tmp[1]) << 8) | (uint32(tmp[2]) << 16)
@@ -209,7 +221,7 @@ func (h *Header) Decode(in []byte) error {
 	cSize := int(bh >> 3)
 	switch blockType {
 	case blockTypeReserved:
-		return nil
+		return in, nil
 	case blockTypeRLE:
 		h.FirstBlock.Compressed = true
 		h.FirstBlock.DecompressedSize = cSize
@@ -225,5 +237,25 @@ func (h *Header) Decode(in []byte) error {
 	}
 
 	h.FirstBlock.OK = true
-	return nil
+	return in, nil
+}
+
+// AppendTo will append the encoded header to the dst slice.
+// There is no error checking performed on the header values.
+func (h *Header) AppendTo(dst []byte) ([]byte, error) {
+	if h.Skippable {
+		magic := [4]byte{0x50, 0x2a, 0x4d, 0x18}
+		magic[0] |= byte(h.SkippableID & 0xf)
+		dst = append(dst, magic[:]...)
+		f := h.SkippableSize
+		return append(dst, uint8(f), uint8(f>>8), uint8(f>>16), uint8(f>>24)), nil
+	}
+	f := frameHeader{
+		ContentSize:   h.FrameContentSize,
+		WindowSize:    uint32(h.WindowSize),
+		SingleSegment: h.SingleSegment,
+		Checksum:      h.HasCheckSum,
+		DictID:        h.DictionaryID,
+	}
+	return f.appendTo(dst), nil
 }
diff --git a/vendor/github.com/klauspost/compress/zstd/decoder.go b/vendor/github.com/klauspost/compress/zstd/decoder.go
index f04aaa21..bbca1723 100644
--- a/vendor/github.com/klauspost/compress/zstd/decoder.go
+++ b/vendor/github.com/klauspost/compress/zstd/decoder.go
@@ -82,7 +82,7 @@ var (
 // can run multiple concurrent stateless decodes. It is even possible to
 // use stateless decodes while a stream is being decoded.
 //
-// The Reset function can be used to initiate a new stream, which is will considerably
+// The Reset function can be used to initiate a new stream, which will considerably
 // reduce the allocations normally caused by NewReader.
 func NewReader(r io.Reader, opts ...DOption) (*Decoder, error) {
 	initPredefined()
diff --git a/vendor/github.com/klauspost/compress/zstd/dict.go b/vendor/github.com/klauspost/compress/zstd/dict.go
index ca095145..b7b83164 100644
--- a/vendor/github.com/klauspost/compress/zstd/dict.go
+++ b/vendor/github.com/klauspost/compress/zstd/dict.go
@@ -1,10 +1,13 @@
 package zstd
 
 import (
+	"bytes"
 	"encoding/binary"
 	"errors"
 	"fmt"
 	"io"
+	"math"
+	"sort"
 
 	"github.com/klauspost/compress/huff0"
 )
@@ -14,9 +17,8 @@ type dict struct {
 
 	litEnc              *huff0.Scratch
 	llDec, ofDec, mlDec sequenceDec
-	//llEnc, ofEnc, mlEnc []*fseEncoder
-	offsets [3]int
-	content []byte
+	offsets             [3]int
+	content             []byte
 }
 
 const dictMagic = "\x37\xa4\x30\xec"
@@ -159,3 +161,405 @@ func InspectDictionary(b []byte) (interface {
 	d, err := loadDict(b)
 	return d, err
 }
+
+type BuildDictOptions struct {
+	// Dictionary ID.
+	ID uint32
+
+	// Content to use to create dictionary tables.
+	Contents [][]byte
+
+	// History to use for all blocks.
+	History []byte
+
+	// Offsets to use.
+	Offsets [3]int
+
+	// CompatV155 will make the dictionary compatible with Zstd v1.5.5 and earlier.
+	// See https://github.com/facebook/zstd/issues/3724
+	CompatV155 bool
+
+	// Use the specified encoder level.
+	// The dictionary will be built using the specified encoder level,
+	// which will reflect speed and make the dictionary tailored for that level.
+	// If not set SpeedBestCompression will be used.
+	Level EncoderLevel
+
+	// DebugOut will write stats and other details here if set.
+	DebugOut io.Writer
+}
+
+func BuildDict(o BuildDictOptions) ([]byte, error) {
+	initPredefined()
+	hist := o.History
+	contents := o.Contents
+	debug := o.DebugOut != nil
+	println := func(args ...interface{}) {
+		if o.DebugOut != nil {
+			fmt.Fprintln(o.DebugOut, args...)
+		}
+	}
+	printf := func(s string, args ...interface{}) {
+		if o.DebugOut != nil {
+			fmt.Fprintf(o.DebugOut, s, args...)
+		}
+	}
+	print := func(args ...interface{}) {
+		if o.DebugOut != nil {
+			fmt.Fprint(o.DebugOut, args...)
+		}
+	}
+
+	if int64(len(hist)) > dictMaxLength {
+		return nil, fmt.Errorf("dictionary of size %d > %d", len(hist), int64(dictMaxLength))
+	}
+	if len(hist) < 8 {
+		return nil, fmt.Errorf("dictionary of size %d < %d", len(hist), 8)
+	}
+	if len(contents) == 0 {
+		return nil, errors.New("no content provided")
+	}
+	d := dict{
+		id:      o.ID,
+		litEnc:  nil,
+		llDec:   sequenceDec{},
+		ofDec:   sequenceDec{},
+		mlDec:   sequenceDec{},
+		offsets: o.Offsets,
+		content: hist,
+	}
+	block := blockEnc{lowMem: false}
+	block.init()
+	enc := encoder(&bestFastEncoder{fastBase: fastBase{maxMatchOff: int32(maxMatchLen), bufferReset: math.MaxInt32 - int32(maxMatchLen*2), lowMem: false}})
+	if o.Level != 0 {
+		eOpts := encoderOptions{
+			level:      o.Level,
+			blockSize:  maxMatchLen,
+			windowSize: maxMatchLen,
+			dict:       &d,
+			lowMem:     false,
+		}
+		enc = eOpts.encoder()
+	} else {
+		o.Level = SpeedBestCompression
+	}
+	var (
+		remain [256]int
+		ll     [256]int
+		ml     [256]int
+		of     [256]int
+	)
+	addValues := func(dst *[256]int, src []byte) {
+		for _, v := range src {
+			dst[v]++
+		}
+	}
+	addHist := func(dst *[256]int, src *[256]uint32) {
+		for i, v := range src {
+			dst[i] += int(v)
+		}
+	}
+	seqs := 0
+	nUsed := 0
+	litTotal := 0
+	newOffsets := make(map[uint32]int, 1000)
+	for _, b := range contents {
+		block.reset(nil)
+		if len(b) < 8 {
+			continue
+		}
+		nUsed++
+		enc.Reset(&d, true)
+		enc.Encode(&block, b)
+		addValues(&remain, block.literals)
+		litTotal += len(block.literals)
+		if len(block.sequences) == 0 {
+			continue
+		}
+		seqs += len(block.sequences)
+		block.genCodes()
+		addHist(&ll, block.coders.llEnc.Histogram())
+		addHist(&ml, block.coders.mlEnc.Histogram())
+		addHist(&of, block.coders.ofEnc.Histogram())
+		for i, seq := range block.sequences {
+			if i > 3 {
+				break
+			}
+			offset := seq.offset
+			if offset == 0 {
+				continue
+			}
+			if int(offset) >= len(o.History) {
+				continue
+			}
+			if offset > 3 {
+				newOffsets[offset-3]++
+			} else {
+				newOffsets[uint32(o.Offsets[offset-1])]++
+			}
+		}
+	}
+	// Find most used offsets.
+	var sortedOffsets []uint32
+	for k := range newOffsets {
+		sortedOffsets = append(sortedOffsets, k)
+	}
+	sort.Slice(sortedOffsets, func(i, j int) bool {
+		a, b := sortedOffsets[i], sortedOffsets[j]
+		if a == b {
+			// Prefer the longer offset
+			return sortedOffsets[i] > sortedOffsets[j]
+		}
+		return newOffsets[sortedOffsets[i]] > newOffsets[sortedOffsets[j]]
+	})
+	if len(sortedOffsets) > 3 {
+		if debug {
+			print("Offsets:")
+			for i, v := range sortedOffsets {
+				if i > 20 {
+					break
+				}
+				printf("[%d: %d],", v, newOffsets[v])
+			}
+			println("")
+		}
+
+		sortedOffsets = sortedOffsets[:3]
+	}
+	for i, v := range sortedOffsets {
+		o.Offsets[i] = int(v)
+	}
+	if debug {
+		println("New repeat offsets", o.Offsets)
+	}
+
+	if nUsed == 0 || seqs == 0 {
+		return nil, fmt.Errorf("%d blocks, %d sequences found", nUsed, seqs)
+	}
+	if debug {
+		println("Sequences:", seqs, "Blocks:", nUsed, "Literals:", litTotal)
+	}
+	if seqs/nUsed < 512 {
+		// Use 512 as minimum.
+		nUsed = seqs / 512
+		if nUsed == 0 {
+			nUsed = 1
+		}
+	}
+	copyHist := func(dst *fseEncoder, src *[256]int) ([]byte, error) {
+		hist := dst.Histogram()
+		var maxSym uint8
+		var maxCount int
+		var fakeLength int
+		for i, v := range src {
+			if v > 0 {
+				v = v / nUsed
+				if v == 0 {
+					v = 1
+				}
+			}
+			if v > maxCount {
+				maxCount = v
+			}
+			if v != 0 {
+				maxSym = uint8(i)
+			}
+			fakeLength += v
+			hist[i] = uint32(v)
+		}
+
+		// Ensure we aren't trying to represent RLE.
+		if maxCount == fakeLength {
+			for i := range hist {
+				if uint8(i) == maxSym {
+					fakeLength++
+					maxSym++
+					hist[i+1] = 1
+					if maxSym > 1 {
+						break
+					}
+				}
+				if hist[0] == 0 {
+					fakeLength++
+					hist[i] = 1
+					if maxSym > 1 {
+						break
+					}
+				}
+			}
+		}
+
+		dst.HistogramFinished(maxSym, maxCount)
+		dst.reUsed = false
+		dst.useRLE = false
+		err := dst.normalizeCount(fakeLength)
+		if err != nil {
+			return nil, err
+		}
+		if debug {
+			println("RAW:", dst.count[:maxSym+1], "NORM:", dst.norm[:maxSym+1], "LEN:", fakeLength)
+		}
+		return dst.writeCount(nil)
+	}
+	if debug {
+		print("Literal lengths: ")
+	}
+	llTable, err := copyHist(block.coders.llEnc, &ll)
+	if err != nil {
+		return nil, err
+	}
+	if debug {
+		print("Match lengths: ")
+	}
+	mlTable, err := copyHist(block.coders.mlEnc, &ml)
+	if err != nil {
+		return nil, err
+	}
+	if debug {
+		print("Offsets: ")
+	}
+	ofTable, err := copyHist(block.coders.ofEnc, &of)
+	if err != nil {
+		return nil, err
+	}
+
+	// Literal table
+	avgSize := litTotal
+	if avgSize > huff0.BlockSizeMax/2 {
+		avgSize = huff0.BlockSizeMax / 2
+	}
+	huffBuff := make([]byte, 0, avgSize)
+	// Target size
+	div := litTotal / avgSize
+	if div < 1 {
+		div = 1
+	}
+	if debug {
+		println("Huffman weights:")
+	}
+	for i, n := range remain[:] {
+		if n > 0 {
+			n = n / div
+			// Allow all entries to be represented.
+			if n == 0 {
+				n = 1
+			}
+			huffBuff = append(huffBuff, bytes.Repeat([]byte{byte(i)}, n)...)
+			if debug {
+				printf("[%d: %d], ", i, n)
+			}
+		}
+	}
+	if o.CompatV155 && remain[255]/div == 0 {
+		huffBuff = append(huffBuff, 255)
+	}
+	scratch := &huff0.Scratch{TableLog: 11}
+	for tries := 0; tries < 255; tries++ {
+		scratch = &huff0.Scratch{TableLog: 11}
+		_, _, err = huff0.Compress1X(huffBuff, scratch)
+		if err == nil {
+			break
+		}
+		if debug {
+			printf("Try %d: Huffman error: %v\n", tries+1, err)
+		}
+		huffBuff = huffBuff[:0]
+		if tries == 250 {
+			if debug {
+				println("Huffman: Bailing out with predefined table")
+			}
+
+			// Bail out.... Just generate something
+			huffBuff = append(huffBuff, bytes.Repeat([]byte{255}, 10000)...)
+			for i := 0; i < 128; i++ {
+				huffBuff = append(huffBuff, byte(i))
+			}
+			continue
+		}
+		if errors.Is(err, huff0.ErrIncompressible) {
+			// Try truncating least common.
+			for i, n := range remain[:] {
+				if n > 0 {
+					n = n / (div * (i + 1))
+					if n > 0 {
+						huffBuff = append(huffBuff, bytes.Repeat([]byte{byte(i)}, n)...)
+					}
+				}
+			}
+			if o.CompatV155 && len(huffBuff) > 0 && huffBuff[len(huffBuff)-1] != 255 {
+				huffBuff = append(huffBuff, 255)
+			}
+			if len(huffBuff) == 0 {
+				huffBuff = append(huffBuff, 0, 255)
+			}
+		}
+		if errors.Is(err, huff0.ErrUseRLE) {
+			for i, n := range remain[:] {
+				n = n / (div * (i + 1))
+				// Allow all entries to be represented.
+				if n == 0 {
+					n = 1
+				}
+				huffBuff = append(huffBuff, bytes.Repeat([]byte{byte(i)}, n)...)
+			}
+		}
+	}
+
+	var out bytes.Buffer
+	out.Write([]byte(dictMagic))
+	out.Write(binary.LittleEndian.AppendUint32(nil, o.ID))
+	out.Write(scratch.OutTable)
+	if debug {
+		println("huff table:", len(scratch.OutTable), "bytes")
+		println("of table:", len(ofTable), "bytes")
+		println("ml table:", len(mlTable), "bytes")
+		println("ll table:", len(llTable), "bytes")
+	}
+	out.Write(ofTable)
+	out.Write(mlTable)
+	out.Write(llTable)
+	out.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[0])))
+	out.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[1])))
+	out.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[2])))
+	out.Write(hist)
+	if debug {
+		_, err := loadDict(out.Bytes())
+		if err != nil {
+			panic(err)
+		}
+		i, err := InspectDictionary(out.Bytes())
+		if err != nil {
+			panic(err)
+		}
+		println("ID:", i.ID())
+		println("Content size:", i.ContentSize())
+		println("Encoder:", i.LitEncoder() != nil)
+		println("Offsets:", i.Offsets())
+		var totalSize int
+		for _, b := range contents {
+			totalSize += len(b)
+		}
+
+		encWith := func(opts ...EOption) int {
+			enc, err := NewWriter(nil, opts...)
+			if err != nil {
+				panic(err)
+			}
+			defer enc.Close()
+			var dst []byte
+			var totalSize int
+			for _, b := range contents {
+				dst = enc.EncodeAll(b, dst[:0])
+				totalSize += len(dst)
+			}
+			return totalSize
+		}
+		plain := encWith(WithEncoderLevel(o.Level))
+		withDict := encWith(WithEncoderLevel(o.Level), WithEncoderDict(out.Bytes()))
+		println("Input size:", totalSize)
+		println("Plain Compressed:", plain)
+		println("Dict Compressed:", withDict)
+		println("Saved:", plain-withDict, (plain-withDict)/len(contents), "bytes per input (rounded down)")
+	}
+	return out.Bytes(), nil
+}
diff --git a/vendor/github.com/klauspost/compress/zstd/enc_base.go b/vendor/github.com/klauspost/compress/zstd/enc_base.go
index e008b992..5ca46038 100644
--- a/vendor/github.com/klauspost/compress/zstd/enc_base.go
+++ b/vendor/github.com/klauspost/compress/zstd/enc_base.go
@@ -144,6 +144,7 @@ func (e *fastBase) resetBase(d *dict, singleBlock bool) {
 	} else {
 		e.crc.Reset()
 	}
+	e.blk.dictLitEnc = nil
 	if d != nil {
 		low := e.lowMem
 		if singleBlock {
diff --git a/vendor/github.com/klauspost/compress/zstd/enc_best.go b/vendor/github.com/klauspost/compress/zstd/enc_best.go
index 9819d414..4613724e 100644
--- a/vendor/github.com/klauspost/compress/zstd/enc_best.go
+++ b/vendor/github.com/klauspost/compress/zstd/enc_best.go
@@ -43,7 +43,7 @@ func (m *match) estBits(bitsPerByte int32) {
 	if m.rep < 0 {
 		ofc = ofCode(uint32(m.s-m.offset) + 3)
 	} else {
-		ofc = ofCode(uint32(m.rep))
+		ofc = ofCode(uint32(m.rep) & 3)
 	}
 	// Cost, excluding
 	ofTT, mlTT := fsePredefEnc[tableOffsets].ct.symbolTT[ofc], fsePredefEnc[tableMatchLengths].ct.symbolTT[mlc]
@@ -135,8 +135,20 @@ func (e *bestFastEncoder) Encode(blk *blockEnc, src []byte) {
 		break
 	}
 
+	// Add block to history
 	s := e.addBlock(src)
 	blk.size = len(src)
+
+	// Check RLE first
+	if len(src) > zstdMinMatch {
+		ml := matchLen(src[1:], src)
+		if ml == len(src)-1 {
+			blk.literals = append(blk.literals, src[0])
+			blk.sequences = append(blk.sequences, seq{litLen: 1, matchLen: uint32(len(src)-1) - zstdMinMatch, offset: 1 + 3})
+			return
+		}
+	}
+
 	if len(src) < minNonLiteralBlockSize {
 		blk.extraLits = len(src)
 		blk.literals = blk.literals[:len(src)]
@@ -197,17 +209,10 @@ encodeLoop:
 
 		// Set m to a match at offset if it looks like that will improve compression.
 		improve := func(m *match, offset int32, s int32, first uint32, rep int32) {
-			if s-offset >= e.maxMatchOff || load3232(src, offset) != first {
+			delta := s - offset
+			if delta >= e.maxMatchOff || delta <= 0 || load3232(src, offset) != first {
 				return
 			}
-			if debugAsserts {
-				if offset <= 0 {
-					panic(offset)
-				}
-				if !bytes.Equal(src[s:s+4], src[offset:offset+4]) {
-					panic(fmt.Sprintf("first match mismatch: %v != %v, first: %08x", src[s:s+4], src[offset:offset+4], first))
-				}
-			}
 			// Try to quick reject if we already have a long match.
 			if m.length > 16 {
 				left := len(src) - int(m.s+m.length)
@@ -226,8 +231,10 @@ encodeLoop:
 				}
 			}
 			l := 4 + e.matchlen(s+4, offset+4, src)
-			if rep < 0 {
+			if m.rep <= 0 {
 				// Extend candidate match backwards as far as possible.
+				// Do not extend repeats as we can assume they are optimal
+				// and offsets change if s == nextEmit.
 				tMin := s - e.maxMatchOff
 				if tMin < 0 {
 					tMin = 0
@@ -238,7 +245,14 @@ encodeLoop:
 					l++
 				}
 			}
-
+			if debugAsserts {
+				if offset >= s {
+					panic(fmt.Sprintf("offset: %d - s:%d - rep: %d - cur :%d - max: %d", offset, s, rep, e.cur, e.maxMatchOff))
+				}
+				if !bytes.Equal(src[s:s+l], src[offset:offset+l]) {
+					panic(fmt.Sprintf("second match mismatch: %v != %v, first: %08x", src[s:s+4], src[offset:offset+4], first))
+				}
+			}
 			cand := match{offset: offset, s: s, length: l, rep: rep}
 			cand.estBits(bitsPerByte)
 			if m.est >= highScore || cand.est-m.est+(cand.s-m.s)*bitsPerByte>>10 < 0 {
@@ -281,6 +295,7 @@ encodeLoop:
 		// Load next and check...
 		e.longTable[nextHashL] = prevEntry{offset: s + e.cur, prev: candidateL.offset}
 		e.table[nextHashS] = prevEntry{offset: s + e.cur, prev: candidateS.offset}
+		index0 := s + 1
 
 		// Look far ahead, unless we have a really long match already...
 		if best.length < goodEnough {
@@ -334,41 +349,45 @@ encodeLoop:
 		}
 
 		if debugAsserts {
+			if best.offset >= best.s {
+				panic(fmt.Sprintf("best.offset > s: %d >= %d", best.offset, best.s))
+			}
+			if best.s < nextEmit {
+				panic(fmt.Sprintf("s %d < nextEmit %d", best.s, nextEmit))
+			}
+			if best.offset < s-e.maxMatchOff {
+				panic(fmt.Sprintf("best.offset < s-e.maxMatchOff: %d < %d", best.offset, s-e.maxMatchOff))
+			}
 			if !bytes.Equal(src[best.s:best.s+best.length], src[best.offset:best.offset+best.length]) {
 				panic(fmt.Sprintf("match mismatch: %v != %v", src[best.s:best.s+best.length], src[best.offset:best.offset+best.length]))
 			}
 		}
 
 		// We have a match, we can store the forward value
+		s = best.s
 		if best.rep > 0 {
 			var seq seq
 			seq.matchLen = uint32(best.length - zstdMinMatch)
-			if debugAsserts && s <= nextEmit {
-				panic("s <= nextEmit")
-			}
 			addLiterals(&seq, best.s)
 
 			// Repeat. If bit 4 is set, this is a non-lit repeat.
 			seq.offset = uint32(best.rep & 3)
 			if debugSequences {
-				println("repeat sequence", seq, "next s:", s)
+				println("repeat sequence", seq, "next s:", best.s, "off:", best.s-best.offset)
 			}
 			blk.sequences = append(blk.sequences, seq)
 
 			// Index old s + 1 -> s - 1
-			index0 := s + 1
 			s = best.s + best.length
-
 			nextEmit = s
-			if s >= sLimit {
-				if debugEncoder {
-					println("repeat ended", s, best.length)
-				}
-				break encodeLoop
-			}
+
 			// Index skipped...
+			end := s
+			if s > sLimit+4 {
+				end = sLimit + 4
+			}
 			off := index0 + e.cur
-			for index0 < s {
+			for index0 < end {
 				cv0 := load6432(src, index0)
 				h0 := hashLen(cv0, bestLongTableBits, bestLongLen)
 				h1 := hashLen(cv0, bestShortTableBits, bestShortLen)
@@ -377,6 +396,7 @@ encodeLoop:
 				off++
 				index0++
 			}
+
 			switch best.rep {
 			case 2, 4 | 1:
 				offset1, offset2 = offset2, offset1
@@ -385,13 +405,17 @@ encodeLoop:
 			case 4 | 3:
 				offset1, offset2, offset3 = offset1-1, offset1, offset2
 			}
+			if s >= sLimit {
+				if debugEncoder {
+					println("repeat ended", s, best.length)
+				}
+				break encodeLoop
+			}
 			continue
 		}
 
 		// A 4-byte match has been found. Update recent offsets.
 		// We'll later see if more than 4 bytes.
-		index0 := s + 1
-		s = best.s
 		t := best.offset
 		offset1, offset2, offset3 = s-t, offset1, offset2
 
@@ -418,19 +442,25 @@ encodeLoop:
 		}
 		blk.sequences = append(blk.sequences, seq)
 		nextEmit = s
-		if s >= sLimit {
-			break encodeLoop
+
+		// Index old s + 1 -> s - 1 or sLimit
+		end := s
+		if s > sLimit-4 {
+			end = sLimit - 4
 		}
 
-		// Index old s + 1 -> s - 1
-		for index0 < s {
+		off := index0 + e.cur
+		for index0 < end {
 			cv0 := load6432(src, index0)
 			h0 := hashLen(cv0, bestLongTableBits, bestLongLen)
 			h1 := hashLen(cv0, bestShortTableBits, bestShortLen)
-			off := index0 + e.cur
 			e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}
 			e.table[h1] = prevEntry{offset: off, prev: e.table[h1].offset}
 			index0++
+			off++
+		}
+		if s >= sLimit {
+			break encodeLoop
 		}
 	}
 
diff --git a/vendor/github.com/klauspost/compress/zstd/enc_better.go b/vendor/github.com/klauspost/compress/zstd/enc_better.go
index 8582f31a..a4f5bf91 100644
--- a/vendor/github.com/klauspost/compress/zstd/enc_better.go
+++ b/vendor/github.com/klauspost/compress/zstd/enc_better.go
@@ -102,9 +102,20 @@ func (e *betterFastEncoder) Encode(blk *blockEnc, src []byte) {
 		e.cur = e.maxMatchOff
 		break
 	}
-
+	// Add block to history
 	s := e.addBlock(src)
 	blk.size = len(src)
+
+	// Check RLE first
+	if len(src) > zstdMinMatch {
+		ml := matchLen(src[1:], src)
+		if ml == len(src)-1 {
+			blk.literals = append(blk.literals, src[0])
+			blk.sequences = append(blk.sequences, seq{litLen: 1, matchLen: uint32(len(src)-1) - zstdMinMatch, offset: 1 + 3})
+			return
+		}
+	}
+
 	if len(src) < minNonLiteralBlockSize {
 		blk.extraLits = len(src)
 		blk.literals = blk.literals[:len(src)]
@@ -145,7 +156,7 @@ encodeLoop:
 		var t int32
 		// We allow the encoder to optionally turn off repeat offsets across blocks
 		canRepeat := len(blk.sequences) > 2
-		var matched int32
+		var matched, index0 int32
 
 		for {
 			if debugAsserts && canRepeat && offset1 == 0 {
@@ -162,6 +173,7 @@ encodeLoop:
 			off := s + e.cur
 			e.longTable[nextHashL] = prevEntry{offset: off, prev: candidateL.offset}
 			e.table[nextHashS] = tableEntry{offset: off, val: uint32(cv)}
+			index0 = s + 1
 
 			if canRepeat {
 				if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
@@ -258,7 +270,6 @@ encodeLoop:
 					}
 					blk.sequences = append(blk.sequences, seq)
 
-					index0 := s + repOff2
 					s += lenght + repOff2
 					nextEmit = s
 					if s >= sLimit {
@@ -498,15 +509,15 @@ encodeLoop:
 		}
 
 		// Index match start+1 (long) -> s - 1
-		index0 := s - l + 1
+		off := index0 + e.cur
 		for index0 < s-1 {
 			cv0 := load6432(src, index0)
 			cv1 := cv0 >> 8
 			h0 := hashLen(cv0, betterLongTableBits, betterLongLen)
-			off := index0 + e.cur
 			e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}
 			e.table[hashLen(cv1, betterShortTableBits, betterShortLen)] = tableEntry{offset: off + 1, val: uint32(cv1)}
 			index0 += 2
+			off += 2
 		}
 
 		cv = load6432(src, s)
@@ -672,7 +683,7 @@ encodeLoop:
 		var t int32
 		// We allow the encoder to optionally turn off repeat offsets across blocks
 		canRepeat := len(blk.sequences) > 2
-		var matched int32
+		var matched, index0 int32
 
 		for {
 			if debugAsserts && canRepeat && offset1 == 0 {
@@ -691,6 +702,7 @@ encodeLoop:
 			e.markLongShardDirty(nextHashL)
 			e.table[nextHashS] = tableEntry{offset: off, val: uint32(cv)}
 			e.markShortShardDirty(nextHashS)
+			index0 = s + 1
 
 			if canRepeat {
 				if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
@@ -726,7 +738,6 @@ encodeLoop:
 					blk.sequences = append(blk.sequences, seq)
 
 					// Index match start+1 (long) -> s - 1
-					index0 := s + repOff
 					s += lenght + repOff
 
 					nextEmit = s
@@ -790,7 +801,6 @@ encodeLoop:
 					}
 					blk.sequences = append(blk.sequences, seq)
 
-					index0 := s + repOff2
 					s += lenght + repOff2
 					nextEmit = s
 					if s >= sLimit {
@@ -1024,18 +1034,18 @@ encodeLoop:
 		}
 
 		// Index match start+1 (long) -> s - 1
-		index0 := s - l + 1
+		off := index0 + e.cur
 		for index0 < s-1 {
 			cv0 := load6432(src, index0)
 			cv1 := cv0 >> 8
 			h0 := hashLen(cv0, betterLongTableBits, betterLongLen)
-			off := index0 + e.cur
 			e.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}
 			e.markLongShardDirty(h0)
 			h1 := hashLen(cv1, betterShortTableBits, betterShortLen)
 			e.table[h1] = tableEntry{offset: off + 1, val: uint32(cv1)}
 			e.markShortShardDirty(h1)
 			index0 += 2
+			off += 2
 		}
 
 		cv = load6432(src, s)
diff --git a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go
index 7d425109..a154c18f 100644
--- a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go
+++ b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go
@@ -1084,7 +1084,7 @@ func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) {
 			}
 		}
 		e.lastDictID = d.id
-		e.allDirty = true
+		allDirty = true
 	}
 	// Reset table to initial state
 	e.cur = e.maxMatchOff
diff --git a/vendor/github.com/klauspost/compress/zstd/enc_fast.go b/vendor/github.com/klauspost/compress/zstd/enc_fast.go
index cbc626ee..f45a3da7 100644
--- a/vendor/github.com/klauspost/compress/zstd/enc_fast.go
+++ b/vendor/github.com/klauspost/compress/zstd/enc_fast.go
@@ -829,13 +829,12 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) {
 		}
 		if true {
 			end := e.maxMatchOff + int32(len(d.content)) - 8
-			for i := e.maxMatchOff; i < end; i += 3 {
+			for i := e.maxMatchOff; i < end; i += 2 {
 				const hashLog = tableBits
 
 				cv := load6432(d.content, i-e.maxMatchOff)
-				nextHash := hashLen(cv, hashLog, tableFastHashLen)      // 0 -> 5
-				nextHash1 := hashLen(cv>>8, hashLog, tableFastHashLen)  // 1 -> 6
-				nextHash2 := hashLen(cv>>16, hashLog, tableFastHashLen) // 2 -> 7
+				nextHash := hashLen(cv, hashLog, tableFastHashLen)     // 0 -> 6
+				nextHash1 := hashLen(cv>>8, hashLog, tableFastHashLen) // 1 -> 7
 				e.dictTable[nextHash] = tableEntry{
 					val:    uint32(cv),
 					offset: i,
@@ -844,10 +843,6 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) {
 					val:    uint32(cv >> 8),
 					offset: i + 1,
 				}
-				e.dictTable[nextHash2] = tableEntry{
-					val:    uint32(cv >> 16),
-					offset: i + 2,
-				}
 			}
 		}
 		e.lastDictID = d.id
diff --git a/vendor/github.com/klauspost/compress/zstd/encoder.go b/vendor/github.com/klauspost/compress/zstd/encoder.go
index 4de0aed0..72af7ef0 100644
--- a/vendor/github.com/klauspost/compress/zstd/encoder.go
+++ b/vendor/github.com/klauspost/compress/zstd/encoder.go
@@ -227,10 +227,7 @@ func (e *Encoder) nextBlock(final bool) error {
 			DictID:        e.o.dict.ID(),
 		}
 
-		dst, err := fh.appendTo(tmp[:0])
-		if err != nil {
-			return err
-		}
+		dst := fh.appendTo(tmp[:0])
 		s.headerWritten = true
 		s.wWg.Wait()
 		var n2 int
@@ -483,7 +480,7 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte {
 				Checksum: false,
 				DictID:   0,
 			}
-			dst, _ = fh.appendTo(dst)
+			dst = fh.appendTo(dst)
 
 			// Write raw block as last one only.
 			var blk blockHeader
@@ -518,10 +515,7 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte {
 	if len(dst) == 0 && cap(dst) == 0 && len(src) < 1<<20 && !e.o.lowMem {
 		dst = make([]byte, 0, len(src))
 	}
-	dst, err := fh.appendTo(dst)
-	if err != nil {
-		panic(err)
-	}
+	dst = fh.appendTo(dst)
 
 	// If we can do everything in one block, prefer that.
 	if len(src) <= e.o.blockSize {
@@ -581,6 +575,7 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte {
 	// Add padding with content from crypto/rand.Reader
 	if e.o.pad > 0 {
 		add := calcSkippableFrame(int64(len(dst)), int64(e.o.pad))
+		var err error
 		dst, err = skippableFrame(dst, add, rand.Reader)
 		if err != nil {
 			panic(err)
diff --git a/vendor/github.com/klauspost/compress/zstd/encoder_options.go b/vendor/github.com/klauspost/compress/zstd/encoder_options.go
index faaf8192..20671dcb 100644
--- a/vendor/github.com/klauspost/compress/zstd/encoder_options.go
+++ b/vendor/github.com/klauspost/compress/zstd/encoder_options.go
@@ -94,7 +94,7 @@ func WithEncoderConcurrency(n int) EOption {
 // The value must be a power of two between MinWindowSize and MaxWindowSize.
 // A larger value will enable better compression but allocate more memory and,
 // for above-default values, take considerably longer.
-// The default value is determined by the compression level.
+// The default value is determined by the compression level and max 8MB.
 func WithWindowSize(n int) EOption {
 	return func(o *encoderOptions) error {
 		switch {
@@ -232,9 +232,9 @@ func WithEncoderLevel(l EncoderLevel) EOption {
 			case SpeedDefault:
 				o.windowSize = 8 << 20
 			case SpeedBetterCompression:
-				o.windowSize = 16 << 20
+				o.windowSize = 8 << 20
 			case SpeedBestCompression:
-				o.windowSize = 32 << 20
+				o.windowSize = 8 << 20
 			}
 		}
 		if !o.customALEntropy {
diff --git a/vendor/github.com/klauspost/compress/zstd/frameenc.go b/vendor/github.com/klauspost/compress/zstd/frameenc.go
index 4ef7f5a3..667ca067 100644
--- a/vendor/github.com/klauspost/compress/zstd/frameenc.go
+++ b/vendor/github.com/klauspost/compress/zstd/frameenc.go
@@ -22,7 +22,7 @@ type frameHeader struct {
 
 const maxHeaderSize = 14
 
-func (f frameHeader) appendTo(dst []byte) ([]byte, error) {
+func (f frameHeader) appendTo(dst []byte) []byte {
 	dst = append(dst, frameMagic...)
 	var fhd uint8
 	if f.Checksum {
@@ -76,7 +76,7 @@ func (f frameHeader) appendTo(dst []byte) ([]byte, error) {
 		if f.SingleSegment {
 			dst = append(dst, uint8(f.ContentSize))
 		}
-		// Unless SingleSegment is set, framessizes < 256 are nto stored.
+		// Unless SingleSegment is set, framessizes < 256 are not stored.
 	case 1:
 		f.ContentSize -= 256
 		dst = append(dst, uint8(f.ContentSize), uint8(f.ContentSize>>8))
@@ -88,7 +88,7 @@ func (f frameHeader) appendTo(dst []byte) ([]byte, error) {
 	default:
 		panic("invalid fcs")
 	}
-	return dst, nil
+	return dst
 }
 
 const skippableFrameHeader = 4 + 4
diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go b/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go
index 332e51fe..8adfebb0 100644
--- a/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go
+++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go
@@ -20,10 +20,9 @@ func (s *fseDecoder) buildDtable() error {
 			if v == -1 {
 				s.dt[highThreshold].setAddBits(uint8(i))
 				highThreshold--
-				symbolNext[i] = 1
-			} else {
-				symbolNext[i] = uint16(v)
+				v = 1
 			}
+			symbolNext[i] = uint16(v)
 		}
 	}
 
@@ -35,10 +34,12 @@ func (s *fseDecoder) buildDtable() error {
 		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 {
+				for {
 					// lowprob area
 					position = (position + step) & tableMask
+					if position <= highThreshold {
+						break
+					}
 				}
 			}
 		}
diff --git a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s
index 17901e08..ae7d4d32 100644
--- a/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s
+++ b/vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s
@@ -162,12 +162,12 @@ finalize:
 	MOVD h, ret+24(FP)
 	RET
 
-// func writeBlocks(d *Digest, b []byte) int
+// func writeBlocks(s *Digest, b []byte) int
 TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40
 	LDP ·primes+0(SB), (prime1, prime2)
 
 	// Load state. Assume v[1-4] are stored contiguously.
-	MOVD d+0(FP), digest
+	MOVD s+0(FP), digest
 	LDP  0(digest), (v1, v2)
 	LDP  16(digest), (v3, v4)
 
diff --git a/vendor/github.com/klauspost/compress/zstd/matchlen_amd64.s b/vendor/github.com/klauspost/compress/zstd/matchlen_amd64.s
index 9a7655c0..0782b86e 100644
--- a/vendor/github.com/klauspost/compress/zstd/matchlen_amd64.s
+++ b/vendor/github.com/klauspost/compress/zstd/matchlen_amd64.s
@@ -5,7 +5,6 @@
 #include "textflag.h"
 
 // func matchLen(a []byte, b []byte) int
-// Requires: BMI
 TEXT ·matchLen(SB), NOSPLIT, $0-56
 	MOVQ a_base+0(FP), AX
 	MOVQ b_base+24(FP), CX
@@ -17,17 +16,16 @@ TEXT ·matchLen(SB), NOSPLIT, $0-56
 	JB   matchlen_match4_standalone
 
 matchlen_loopback_standalone:
-	MOVQ  (AX)(SI*1), BX
-	XORQ  (CX)(SI*1), BX
-	TESTQ BX, BX
-	JZ    matchlen_loop_standalone
+	MOVQ (AX)(SI*1), BX
+	XORQ (CX)(SI*1), BX
+	JZ   matchlen_loop_standalone
 
 #ifdef GOAMD64_v3
 	TZCNTQ BX, BX
 #else
 	BSFQ BX, BX
 #endif
-	SARQ $0x03, BX
+	SHRL $0x03, BX
 	LEAL (SI)(BX*1), SI
 	JMP  gen_match_len_end
 
diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec.go b/vendor/github.com/klauspost/compress/zstd/seqdec.go
index 9405fcf1..d7fe6d82 100644
--- a/vendor/github.com/klauspost/compress/zstd/seqdec.go
+++ b/vendor/github.com/klauspost/compress/zstd/seqdec.go
@@ -245,7 +245,7 @@ func (s *sequenceDecs) decodeSync(hist []byte) error {
 			return io.ErrUnexpectedEOF
 		}
 		var ll, mo, ml int
-		if br.off > 4+((maxOffsetBits+16+16)>>3) {
+		if len(br.in) > 4+((maxOffsetBits+16+16)>>3) {
 			// inlined function:
 			// ll, mo, ml = s.nextFast(br, llState, mlState, ofState)
 
@@ -452,18 +452,13 @@ func (s *sequenceDecs) next(br *bitReader, llState, mlState, ofState decSymbol)
 
 	// extra bits are stored in reverse order.
 	br.fill()
-	if s.maxBits <= 32 {
-		mo += br.getBits(moB)
-		ml += br.getBits(mlB)
-		ll += br.getBits(llB)
-	} else {
-		mo += br.getBits(moB)
+	mo += br.getBits(moB)
+	if s.maxBits > 32 {
 		br.fill()
-		// matchlength+literal length, max 32 bits
-		ml += br.getBits(mlB)
-		ll += br.getBits(llB)
-
 	}
+	// matchlength+literal length, max 32 bits
+	ml += br.getBits(mlB)
+	ll += br.getBits(llB)
 	mo = s.adjustOffset(mo, ll, moB)
 	return
 }
diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s
index b6f4ba6f..5b06174b 100644
--- a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s
+++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s
@@ -5,11 +5,11 @@
 // 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
+	MOVQ    br+8(FP), CX
+	MOVQ    24(CX), DX
+	MOVBQZX 32(CX), BX
+	MOVQ    (CX), AX
+	MOVQ    8(CX), SI
 	ADDQ    SI, AX
 	MOVQ    AX, (SP)
 	MOVQ    ctx+16(FP), AX
@@ -157,8 +157,7 @@ sequenceDecs_decode_amd64_ll_update_zero:
 
 	// Update Literal Length State
 	MOVBQZX DI, R14
-	SHRQ    $0x10, DI
-	MOVWQZX DI, DI
+	SHRL    $0x10, DI
 	LEAQ    (BX)(R14*1), CX
 	MOVQ    DX, R15
 	MOVQ    CX, BX
@@ -177,8 +176,7 @@ sequenceDecs_decode_amd64_ll_update_zero:
 
 	// Update Match Length State
 	MOVBQZX R8, R14
-	SHRQ    $0x10, R8
-	MOVWQZX R8, R8
+	SHRL    $0x10, R8
 	LEAQ    (BX)(R14*1), CX
 	MOVQ    DX, R15
 	MOVQ    CX, BX
@@ -197,8 +195,7 @@ sequenceDecs_decode_amd64_ll_update_zero:
 
 	// Update Offset State
 	MOVBQZX R9, R14
-	SHRQ    $0x10, R9
-	MOVWQZX R9, R9
+	SHRL    $0x10, R9
 	LEAQ    (BX)(R14*1), CX
 	MOVQ    DX, R15
 	MOVQ    CX, BX
@@ -301,9 +298,9 @@ sequenceDecs_decode_amd64_match_len_ofs_ok:
 	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)
+	MOVQ DX, 24(AX)
+	MOVB BL, 32(AX)
+	MOVQ SI, 8(AX)
 
 	// Return success
 	MOVQ $0x00000000, ret+24(FP)
@@ -336,11 +333,11 @@ error_overread:
 // 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
+	MOVQ    br+8(FP), CX
+	MOVQ    24(CX), DX
+	MOVBQZX 32(CX), BX
+	MOVQ    (CX), AX
+	MOVQ    8(CX), SI
 	ADDQ    SI, AX
 	MOVQ    AX, (SP)
 	MOVQ    ctx+16(FP), AX
@@ -459,8 +456,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero:
 
 	// Update Literal Length State
 	MOVBQZX DI, R14
-	SHRQ    $0x10, DI
-	MOVWQZX DI, DI
+	SHRL    $0x10, DI
 	LEAQ    (BX)(R14*1), CX
 	MOVQ    DX, R15
 	MOVQ    CX, BX
@@ -479,8 +475,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero:
 
 	// Update Match Length State
 	MOVBQZX R8, R14
-	SHRQ    $0x10, R8
-	MOVWQZX R8, R8
+	SHRL    $0x10, R8
 	LEAQ    (BX)(R14*1), CX
 	MOVQ    DX, R15
 	MOVQ    CX, BX
@@ -499,8 +494,7 @@ sequenceDecs_decode_56_amd64_ll_update_zero:
 
 	// Update Offset State
 	MOVBQZX R9, R14
-	SHRQ    $0x10, R9
-	MOVWQZX R9, R9
+	SHRL    $0x10, R9
 	LEAQ    (BX)(R14*1), CX
 	MOVQ    DX, R15
 	MOVQ    CX, BX
@@ -603,9 +597,9 @@ sequenceDecs_decode_56_amd64_match_len_ofs_ok:
 	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)
+	MOVQ DX, 24(AX)
+	MOVB BL, 32(AX)
+	MOVQ SI, 8(AX)
 
 	// Return success
 	MOVQ $0x00000000, ret+24(FP)
@@ -638,11 +632,11 @@ error_overread:
 // 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
+	MOVQ    br+8(FP), BX
+	MOVQ    24(BX), AX
+	MOVBQZX 32(BX), DX
+	MOVQ    (BX), CX
+	MOVQ    8(BX), BX
 	ADDQ    BX, CX
 	MOVQ    CX, (SP)
 	MOVQ    ctx+16(FP), CX
@@ -772,11 +766,10 @@ sequenceDecs_decode_bmi2_fill_2_end:
 	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
+	BZHIQ R8, R15, CX
+	SHRXQ R8, R15, R15
+	SHRL  $0x10, R8
+	ADDQ  CX, R8
 
 	// Load ctx.ofTable
 	MOVQ ctx+16(FP), CX
@@ -784,11 +777,10 @@ sequenceDecs_decode_bmi2_fill_2_end:
 	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
+	BZHIQ DI, R15, CX
+	SHRXQ DI, R15, R15
+	SHRL  $0x10, DI
+	ADDQ  CX, DI
 
 	// Load ctx.mlTable
 	MOVQ ctx+16(FP), CX
@@ -796,10 +788,9 @@ sequenceDecs_decode_bmi2_fill_2_end:
 	MOVQ (CX)(DI*8), DI
 
 	// Update Literal Length State
-	BZHIQ  SI, R15, CX
-	MOVQ   $0x00001010, R14
-	BEXTRQ R14, SI, SI
-	ADDQ   CX, SI
+	BZHIQ SI, R15, CX
+	SHRL  $0x10, SI
+	ADDQ  CX, SI
 
 	// Load ctx.llTable
 	MOVQ ctx+16(FP), CX
@@ -892,9 +883,9 @@ sequenceDecs_decode_bmi2_match_len_ofs_ok:
 	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)
+	MOVQ AX, 24(CX)
+	MOVB DL, 32(CX)
+	MOVQ BX, 8(CX)
 
 	// Return success
 	MOVQ $0x00000000, ret+24(FP)
@@ -927,11 +918,11 @@ error_overread:
 // 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
+	MOVQ    br+8(FP), BX
+	MOVQ    24(BX), AX
+	MOVBQZX 32(BX), DX
+	MOVQ    (BX), CX
+	MOVQ    8(BX), BX
 	ADDQ    BX, CX
 	MOVQ    CX, (SP)
 	MOVQ    ctx+16(FP), CX
@@ -1032,11 +1023,10 @@ sequenceDecs_decode_56_bmi2_fill_end:
 	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
+	BZHIQ R8, R15, CX
+	SHRXQ R8, R15, R15
+	SHRL  $0x10, R8
+	ADDQ  CX, R8
 
 	// Load ctx.ofTable
 	MOVQ ctx+16(FP), CX
@@ -1044,11 +1034,10 @@ sequenceDecs_decode_56_bmi2_fill_end:
 	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
+	BZHIQ DI, R15, CX
+	SHRXQ DI, R15, R15
+	SHRL  $0x10, DI
+	ADDQ  CX, DI
 
 	// Load ctx.mlTable
 	MOVQ ctx+16(FP), CX
@@ -1056,10 +1045,9 @@ sequenceDecs_decode_56_bmi2_fill_end:
 	MOVQ (CX)(DI*8), DI
 
 	// Update Literal Length State
-	BZHIQ  SI, R15, CX
-	MOVQ   $0x00001010, R14
-	BEXTRQ R14, SI, SI
-	ADDQ   CX, SI
+	BZHIQ SI, R15, CX
+	SHRL  $0x10, SI
+	ADDQ  CX, SI
 
 	// Load ctx.llTable
 	MOVQ ctx+16(FP), CX
@@ -1152,9 +1140,9 @@ sequenceDecs_decode_56_bmi2_match_len_ofs_ok:
 	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)
+	MOVQ AX, 24(CX)
+	MOVB DL, 32(CX)
+	MOVQ BX, 8(CX)
 
 	// Return success
 	MOVQ $0x00000000, ret+24(FP)
@@ -1797,11 +1785,11 @@ empty_seqs:
 // 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
+	MOVQ    br+8(FP), CX
+	MOVQ    24(CX), DX
+	MOVBQZX 32(CX), BX
+	MOVQ    (CX), AX
+	MOVQ    8(CX), SI
 	ADDQ    SI, AX
 	MOVQ    AX, (SP)
 	MOVQ    ctx+16(FP), AX
@@ -1967,8 +1955,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero:
 
 	// Update Literal Length State
 	MOVBQZX DI, R13
-	SHRQ    $0x10, DI
-	MOVWQZX DI, DI
+	SHRL    $0x10, DI
 	LEAQ    (BX)(R13*1), CX
 	MOVQ    DX, R14
 	MOVQ    CX, BX
@@ -1987,8 +1974,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero:
 
 	// Update Match Length State
 	MOVBQZX R8, R13
-	SHRQ    $0x10, R8
-	MOVWQZX R8, R8
+	SHRL    $0x10, R8
 	LEAQ    (BX)(R13*1), CX
 	MOVQ    DX, R14
 	MOVQ    CX, BX
@@ -2007,8 +1993,7 @@ sequenceDecs_decodeSync_amd64_ll_update_zero:
 
 	// Update Offset State
 	MOVBQZX R9, R13
-	SHRQ    $0x10, R9
-	MOVWQZX R9, R9
+	SHRL    $0x10, R9
 	LEAQ    (BX)(R13*1), CX
 	MOVQ    DX, R14
 	MOVQ    CX, BX
@@ -2295,9 +2280,9 @@ handle_loop:
 
 loop_finished:
 	MOVQ br+8(FP), AX
-	MOVQ DX, 32(AX)
-	MOVB BL, 40(AX)
-	MOVQ SI, 24(AX)
+	MOVQ DX, 24(AX)
+	MOVB BL, 32(AX)
+	MOVQ SI, 8(AX)
 
 	// Update the context
 	MOVQ ctx+16(FP), AX
@@ -2362,11 +2347,11 @@ error_not_enough_space:
 // 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
+	MOVQ    br+8(FP), BX
+	MOVQ    24(BX), AX
+	MOVBQZX 32(BX), DX
+	MOVQ    (BX), CX
+	MOVQ    8(BX), BX
 	ADDQ    BX, CX
 	MOVQ    CX, (SP)
 	MOVQ    ctx+16(FP), CX
@@ -2514,11 +2499,10 @@ sequenceDecs_decodeSync_bmi2_fill_2_end:
 	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
+	BZHIQ R8, R14, CX
+	SHRXQ R8, R14, R14
+	SHRL  $0x10, R8
+	ADDQ  CX, R8
 
 	// Load ctx.ofTable
 	MOVQ ctx+16(FP), CX
@@ -2526,11 +2510,10 @@ sequenceDecs_decodeSync_bmi2_fill_2_end:
 	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
+	BZHIQ DI, R14, CX
+	SHRXQ DI, R14, R14
+	SHRL  $0x10, DI
+	ADDQ  CX, DI
 
 	// Load ctx.mlTable
 	MOVQ ctx+16(FP), CX
@@ -2538,10 +2521,9 @@ sequenceDecs_decodeSync_bmi2_fill_2_end:
 	MOVQ (CX)(DI*8), DI
 
 	// Update Literal Length State
-	BZHIQ  SI, R14, CX
-	MOVQ   $0x00001010, R13
-	BEXTRQ R13, SI, SI
-	ADDQ   CX, SI
+	BZHIQ SI, R14, CX
+	SHRL  $0x10, SI
+	ADDQ  CX, SI
 
 	// Load ctx.llTable
 	MOVQ ctx+16(FP), CX
@@ -2818,9 +2800,9 @@ handle_loop:
 
 loop_finished:
 	MOVQ br+8(FP), CX
-	MOVQ AX, 32(CX)
-	MOVB DL, 40(CX)
-	MOVQ BX, 24(CX)
+	MOVQ AX, 24(CX)
+	MOVB DL, 32(CX)
+	MOVQ BX, 8(CX)
 
 	// Update the context
 	MOVQ ctx+16(FP), AX
@@ -2885,11 +2867,11 @@ error_not_enough_space:
 // 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
+	MOVQ    br+8(FP), CX
+	MOVQ    24(CX), DX
+	MOVBQZX 32(CX), BX
+	MOVQ    (CX), AX
+	MOVQ    8(CX), SI
 	ADDQ    SI, AX
 	MOVQ    AX, (SP)
 	MOVQ    ctx+16(FP), AX
@@ -3055,8 +3037,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero:
 
 	// Update Literal Length State
 	MOVBQZX DI, R13
-	SHRQ    $0x10, DI
-	MOVWQZX DI, DI
+	SHRL    $0x10, DI
 	LEAQ    (BX)(R13*1), CX
 	MOVQ    DX, R14
 	MOVQ    CX, BX
@@ -3075,8 +3056,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero:
 
 	// Update Match Length State
 	MOVBQZX R8, R13
-	SHRQ    $0x10, R8
-	MOVWQZX R8, R8
+	SHRL    $0x10, R8
 	LEAQ    (BX)(R13*1), CX
 	MOVQ    DX, R14
 	MOVQ    CX, BX
@@ -3095,8 +3075,7 @@ sequenceDecs_decodeSync_safe_amd64_ll_update_zero:
 
 	// Update Offset State
 	MOVBQZX R9, R13
-	SHRQ    $0x10, R9
-	MOVWQZX R9, R9
+	SHRL    $0x10, R9
 	LEAQ    (BX)(R13*1), CX
 	MOVQ    DX, R14
 	MOVQ    CX, BX
@@ -3485,9 +3464,9 @@ handle_loop:
 
 loop_finished:
 	MOVQ br+8(FP), AX
-	MOVQ DX, 32(AX)
-	MOVB BL, 40(AX)
-	MOVQ SI, 24(AX)
+	MOVQ DX, 24(AX)
+	MOVB BL, 32(AX)
+	MOVQ SI, 8(AX)
 
 	// Update the context
 	MOVQ ctx+16(FP), AX
@@ -3552,11 +3531,11 @@ error_not_enough_space:
 // 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
+	MOVQ    br+8(FP), BX
+	MOVQ    24(BX), AX
+	MOVBQZX 32(BX), DX
+	MOVQ    (BX), CX
+	MOVQ    8(BX), BX
 	ADDQ    BX, CX
 	MOVQ    CX, (SP)
 	MOVQ    ctx+16(FP), CX
@@ -3704,11 +3683,10 @@ sequenceDecs_decodeSync_safe_bmi2_fill_2_end:
 	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
+	BZHIQ R8, R14, CX
+	SHRXQ R8, R14, R14
+	SHRL  $0x10, R8
+	ADDQ  CX, R8
 
 	// Load ctx.ofTable
 	MOVQ ctx+16(FP), CX
@@ -3716,11 +3694,10 @@ sequenceDecs_decodeSync_safe_bmi2_fill_2_end:
 	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
+	BZHIQ DI, R14, CX
+	SHRXQ DI, R14, R14
+	SHRL  $0x10, DI
+	ADDQ  CX, DI
 
 	// Load ctx.mlTable
 	MOVQ ctx+16(FP), CX
@@ -3728,10 +3705,9 @@ sequenceDecs_decodeSync_safe_bmi2_fill_2_end:
 	MOVQ (CX)(DI*8), DI
 
 	// Update Literal Length State
-	BZHIQ  SI, R14, CX
-	MOVQ   $0x00001010, R13
-	BEXTRQ R13, SI, SI
-	ADDQ   CX, SI
+	BZHIQ SI, R14, CX
+	SHRL  $0x10, SI
+	ADDQ  CX, SI
 
 	// Load ctx.llTable
 	MOVQ ctx+16(FP), CX
@@ -4110,9 +4086,9 @@ handle_loop:
 
 loop_finished:
 	MOVQ br+8(FP), CX
-	MOVQ AX, 32(CX)
-	MOVB DL, 40(CX)
-	MOVQ BX, 24(CX)
+	MOVQ AX, 24(CX)
+	MOVB DL, 32(CX)
+	MOVQ BX, 8(CX)
 
 	// Update the context
 	MOVQ ctx+16(FP), AX
diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go b/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go
index ac2a80d2..2fb35b78 100644
--- a/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go
+++ b/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go
@@ -29,7 +29,7 @@ func (s *sequenceDecs) decode(seqs []seqVals) error {
 	}
 	for i := range seqs {
 		var ll, mo, ml int
-		if br.off > 4+((maxOffsetBits+16+16)>>3) {
+		if len(br.in) > 4+((maxOffsetBits+16+16)>>3) {
 			// inlined function:
 			// ll, mo, ml = s.nextFast(br, llState, mlState, ofState)
 
diff --git a/vendor/github.com/klauspost/compress/zstd/snappy.go b/vendor/github.com/klauspost/compress/zstd/snappy.go
index 9e1baad7..ec13594e 100644
--- a/vendor/github.com/klauspost/compress/zstd/snappy.go
+++ b/vendor/github.com/klauspost/compress/zstd/snappy.go
@@ -95,10 +95,9 @@ func (r *SnappyConverter) Convert(in io.Reader, w io.Writer) (int64, error) {
 	var written int64
 	var readHeader bool
 	{
-		var header []byte
-		var n int
-		header, r.err = frameHeader{WindowSize: snappyMaxBlockSize}.appendTo(r.buf[:0])
+		header := frameHeader{WindowSize: snappyMaxBlockSize}.appendTo(r.buf[:0])
 
+		var n int
 		n, r.err = w.Write(header)
 		if r.err != nil {
 			return written, r.err
diff --git a/vendor/github.com/klauspost/cpuid/v2/README.md b/vendor/github.com/klauspost/cpuid/v2/README.md
index 30f8d296..21508edb 100644
--- a/vendor/github.com/klauspost/cpuid/v2/README.md
+++ b/vendor/github.com/klauspost/cpuid/v2/README.md
@@ -310,6 +310,7 @@ Exit Code 1
 | AVXSLOW            | Indicates the CPU performs 2 128 bit operations instead of one                                                                                                                     |
 | AVXVNNI            | AVX (VEX encoded) VNNI neural network instructions                                                                                                                                 |
 | AVXVNNIINT8        | AVX-VNNI-INT8 instructions                                                                                                                                                         |
+| AVXVNNIINT16       | AVX-VNNI-INT16 instructions                                                                                                                                                        |
 | BHI_CTRL           | Branch History Injection and Intra-mode Branch Target Injection / CVE-2022-0001, CVE-2022-0002 / INTEL-SA-00598                                                                    |
 | BMI1               | Bit Manipulation Instruction Set 1                                                                                                                                                 |
 | BMI2               | Bit Manipulation Instruction Set 2                                                                                                                                                 |
diff --git a/vendor/github.com/klauspost/cpuid/v2/cpuid.go b/vendor/github.com/klauspost/cpuid/v2/cpuid.go
index 15b76033..53bc18ca 100644
--- a/vendor/github.com/klauspost/cpuid/v2/cpuid.go
+++ b/vendor/github.com/klauspost/cpuid/v2/cpuid.go
@@ -67,195 +67,201 @@ const (
 	// Keep index -1 as unknown
 	UNKNOWN = -1
 
-	// Add features
-	ADX                FeatureID = iota // Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
-	AESNI                               // Advanced Encryption Standard New Instructions
-	AMD3DNOW                            // AMD 3DNOW
-	AMD3DNOWEXT                         // AMD 3DNowExt
-	AMXBF16                             // Tile computational operations on BFLOAT16 numbers
-	AMXFP16                             // Tile computational operations on FP16 numbers
-	AMXINT8                             // Tile computational operations on 8-bit integers
-	AMXTILE                             // Tile architecture
-	APX_F                               // Intel APX
-	AVX                                 // AVX functions
-	AVX10                               // If set the Intel AVX10 Converged Vector ISA is supported
-	AVX10_128                           // If set indicates that AVX10 128-bit vector support is present
-	AVX10_256                           // If set indicates that AVX10 256-bit vector support is present
-	AVX10_512                           // If set indicates that AVX10 512-bit vector support is present
-	AVX2                                // AVX2 functions
-	AVX512BF16                          // AVX-512 BFLOAT16 Instructions
-	AVX512BITALG                        // AVX-512 Bit Algorithms
-	AVX512BW                            // AVX-512 Byte and Word Instructions
-	AVX512CD                            // AVX-512 Conflict Detection Instructions
-	AVX512DQ                            // AVX-512 Doubleword and Quadword Instructions
-	AVX512ER                            // AVX-512 Exponential and Reciprocal Instructions
-	AVX512F                             // AVX-512 Foundation
-	AVX512FP16                          // AVX-512 FP16 Instructions
-	AVX512IFMA                          // AVX-512 Integer Fused Multiply-Add Instructions
-	AVX512PF                            // AVX-512 Prefetch Instructions
-	AVX512VBMI                          // AVX-512 Vector Bit Manipulation Instructions
-	AVX512VBMI2                         // AVX-512 Vector Bit Manipulation Instructions, Version 2
-	AVX512VL                            // AVX-512 Vector Length Extensions
-	AVX512VNNI                          // AVX-512 Vector Neural Network Instructions
-	AVX512VP2INTERSECT                  // AVX-512 Intersect for D/Q
-	AVX512VPOPCNTDQ                     // AVX-512 Vector Population Count Doubleword and Quadword
-	AVXIFMA                             // AVX-IFMA instructions
-	AVXNECONVERT                        // AVX-NE-CONVERT instructions
-	AVXSLOW                             // Indicates the CPU performs 2 128 bit operations instead of one
-	AVXVNNI                             // AVX (VEX encoded) VNNI neural network instructions
-	AVXVNNIINT8                         // AVX-VNNI-INT8 instructions
-	BHI_CTRL                            // Branch History Injection and Intra-mode Branch Target Injection / CVE-2022-0001, CVE-2022-0002 / INTEL-SA-00598
-	BMI1                                // Bit Manipulation Instruction Set 1
-	BMI2                                // Bit Manipulation Instruction Set 2
-	CETIBT                              // Intel CET Indirect Branch Tracking
-	CETSS                               // Intel CET Shadow Stack
-	CLDEMOTE                            // Cache Line Demote
-	CLMUL                               // Carry-less Multiplication
-	CLZERO                              // CLZERO instruction supported
-	CMOV                                // i686 CMOV
-	CMPCCXADD                           // CMPCCXADD instructions
-	CMPSB_SCADBS_SHORT                  // Fast short CMPSB and SCASB
-	CMPXCHG8                            // CMPXCHG8 instruction
-	CPBOOST                             // Core Performance Boost
-	CPPC                                // AMD: Collaborative Processor Performance Control
-	CX16                                // CMPXCHG16B Instruction
-	EFER_LMSLE_UNS                      // AMD: =Core::X86::Msr::EFER[LMSLE] is not supported, and MBZ
-	ENQCMD                              // Enqueue Command
-	ERMS                                // Enhanced REP MOVSB/STOSB
-	F16C                                // Half-precision floating-point conversion
-	FLUSH_L1D                           // Flush L1D cache
-	FMA3                                // Intel FMA 3. Does not imply AVX.
-	FMA4                                // Bulldozer FMA4 functions
-	FP128                               // AMD: When set, the internal FP/SIMD execution datapath is no more than 128-bits wide
-	FP256                               // AMD: When set, the internal FP/SIMD execution datapath is no more than 256-bits wide
-	FSRM                                // Fast Short Rep Mov
-	FXSR                                // FXSAVE, FXRESTOR instructions, CR4 bit 9
-	FXSROPT                             // FXSAVE/FXRSTOR optimizations
-	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
-	HYBRID_CPU                          // This part has CPUs of more than one type.
-	HYPERVISOR                          // This bit has been reserved by Intel & AMD for use by hypervisors
-	IA32_ARCH_CAP                       // IA32_ARCH_CAPABILITIES MSR (Intel)
-	IA32_CORE_CAP                       // IA32_CORE_CAPABILITIES MSR
-	IBPB                                // Indirect Branch Restricted Speculation (IBRS) and Indirect Branch Predictor Barrier (IBPB)
-	IBRS                                // AMD: Indirect Branch Restricted Speculation
-	IBRS_PREFERRED                      // AMD: IBRS is preferred over software solution
-	IBRS_PROVIDES_SMP                   // AMD: IBRS provides Same Mode Protection
-	IBS                                 // Instruction Based Sampling (AMD)
-	IBSBRNTRGT                          // Instruction Based Sampling Feature (AMD)
-	IBSFETCHSAM                         // Instruction Based Sampling Feature (AMD)
-	IBSFFV                              // Instruction Based Sampling Feature (AMD)
-	IBSOPCNT                            // Instruction Based Sampling Feature (AMD)
-	IBSOPCNTEXT                         // Instruction Based Sampling Feature (AMD)
-	IBSOPSAM                            // Instruction Based Sampling Feature (AMD)
-	IBSRDWROPCNT                        // Instruction Based Sampling Feature (AMD)
-	IBSRIPINVALIDCHK                    // Instruction Based Sampling Feature (AMD)
-	IBS_FETCH_CTLX                      // AMD: IBS fetch control extended MSR supported
-	IBS_OPDATA4                         // AMD: IBS op data 4 MSR supported
-	IBS_OPFUSE                          // AMD: Indicates support for IbsOpFuse
-	IBS_PREVENTHOST                     // Disallowing IBS use by the host supported
-	IBS_ZEN4                            // AMD: Fetch and Op IBS support IBS extensions added with Zen4
-	IDPRED_CTRL                         // IPRED_DIS
-	INT_WBINVD                          // WBINVD/WBNOINVD are interruptible.
-	INVLPGB                             // NVLPGB and TLBSYNC instruction supported
-	KEYLOCKER                           // Key locker
-	KEYLOCKERW                          // Key locker wide
-	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.
-	MCDT_NO                             // Processor do not exhibit MXCSR Configuration Dependent Timing behavior and do not need to mitigate it.
-	MCOMMIT                             // MCOMMIT instruction supported
-	MD_CLEAR                            // VERW clears CPU buffers
-	MMX                                 // standard MMX
-	MMXEXT                              // SSE integer functions or AMD MMX ext
-	MOVBE                               // MOVBE instruction (big-endian)
-	MOVDIR64B                           // Move 64 Bytes as Direct Store
-	MOVDIRI                             // Move Doubleword as Direct Store
-	MOVSB_ZL                            // Fast Zero-Length MOVSB
-	MOVU                                // AMD: MOVU SSE instructions are more efficient and should be preferred to SSE	MOVL/MOVH. MOVUPS is more efficient than MOVLPS/MOVHPS. MOVUPD is more efficient than MOVLPD/MOVHPD
-	MPX                                 // Intel MPX (Memory Protection Extensions)
-	MSRIRC                              // Instruction Retired Counter MSR available
-	MSRLIST                             // Read/Write List of Model Specific Registers
-	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
-	POPCNT                              // POPCNT instruction
-	PPIN                                // AMD: Protected Processor Inventory Number support. Indicates that Protected Processor Inventory Number (PPIN) capability can be enabled
-	PREFETCHI                           // PREFETCHIT0/1 instructions
-	PSFD                                // Predictive Store Forward Disable
-	RDPRU                               // RDPRU instruction supported
-	RDRAND                              // RDRAND instruction is available
-	RDSEED                              // RDSEED instruction is available
-	RDTSCP                              // RDTSCP Instruction
-	RRSBA_CTRL                          // Restricted RSB Alternate
-	RTM                                 // Restricted Transactional Memory
-	RTM_ALWAYS_ABORT                    // Indicates that the loaded microcode is forcing RTM abort.
-	SERIALIZE                           // Serialize Instruction Execution
-	SEV                                 // AMD Secure Encrypted Virtualization supported
-	SEV_64BIT                           // AMD SEV guest execution only allowed from a 64-bit host
-	SEV_ALTERNATIVE                     // AMD SEV Alternate Injection supported
-	SEV_DEBUGSWAP                       // Full debug state swap supported for SEV-ES guests
-	SEV_ES                              // AMD SEV Encrypted State supported
-	SEV_RESTRICTED                      // AMD SEV Restricted Injection supported
-	SEV_SNP                             // AMD SEV Secure Nested Paging supported
-	SGX                                 // Software Guard Extensions
-	SGXLC                               // Software Guard Extensions Launch Control
-	SHA                                 // Intel SHA Extensions
-	SME                                 // AMD Secure Memory Encryption supported
-	SME_COHERENT                        // AMD Hardware cache coherency across encryption domains enforced
-	SPEC_CTRL_SSBD                      // Speculative Store Bypass Disable
-	SRBDS_CTRL                          // SRBDS mitigation MSR available
-	SSE                                 // SSE functions
-	SSE2                                // P4 SSE functions
-	SSE3                                // Prescott SSE3 functions
-	SSE4                                // Penryn SSE4.1 functions
-	SSE42                               // Nehalem SSE4.2 functions
-	SSE4A                               // AMD Barcelona microarchitecture SSE4a instructions
-	SSSE3                               // Conroe SSSE3 functions
-	STIBP                               // Single Thread Indirect Branch Predictors
-	STIBP_ALWAYSON                      // AMD: Single Thread Indirect Branch Prediction Mode has Enhanced Performance and may be left Always On
-	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
-	TDX_GUEST                           // Intel Trust Domain Extensions Guest
-	TLB_FLUSH_NESTED                    // AMD: Flushing includes all the nested translations for guest translations
-	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.
-	TOPEXT                              // TopologyExtensions: topology extensions support. Indicates support for CPUID Fn8000_001D_EAX_x[N:0]-CPUID Fn8000_001E_EDX.
-	TSCRATEMSR                          // MSR based TSC rate control. Indicates support for MSR TSC ratio MSRC000_0104
-	TSXLDTRK                            // Intel TSX Suspend Load Address Tracking
-	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. Requires AVX for 3 register versions.
-	VTE                                 // AMD Virtual Transparent Encryption supported
-	WAITPKG                             // TPAUSE, UMONITOR, UMWAIT
-	WBNOINVD                            // Write Back and Do Not Invalidate Cache
-	WRMSRNS                             // Non-Serializing Write to Model Specific Register
-	X87                                 // FPU
-	XGETBV1                             // Supports XGETBV with ECX = 1
-	XOP                                 // Bulldozer XOP functions
-	XSAVE                               // XSAVE, XRESTOR, XSETBV, XGETBV
-	XSAVEC                              // Supports XSAVEC and the compacted form of XRSTOR.
-	XSAVEOPT                            // XSAVEOPT available
-	XSAVES                              // Supports XSAVES/XRSTORS and IA32_XSS
+	// x86 features
+	ADX                 FeatureID = iota // Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
+	AESNI                                // Advanced Encryption Standard New Instructions
+	AMD3DNOW                             // AMD 3DNOW
+	AMD3DNOWEXT                          // AMD 3DNowExt
+	AMXBF16                              // Tile computational operations on BFLOAT16 numbers
+	AMXFP16                              // Tile computational operations on FP16 numbers
+	AMXINT8                              // Tile computational operations on 8-bit integers
+	AMXTILE                              // Tile architecture
+	APX_F                                // Intel APX
+	AVX                                  // AVX functions
+	AVX10                                // If set the Intel AVX10 Converged Vector ISA is supported
+	AVX10_128                            // If set indicates that AVX10 128-bit vector support is present
+	AVX10_256                            // If set indicates that AVX10 256-bit vector support is present
+	AVX10_512                            // If set indicates that AVX10 512-bit vector support is present
+	AVX2                                 // AVX2 functions
+	AVX512BF16                           // AVX-512 BFLOAT16 Instructions
+	AVX512BITALG                         // AVX-512 Bit Algorithms
+	AVX512BW                             // AVX-512 Byte and Word Instructions
+	AVX512CD                             // AVX-512 Conflict Detection Instructions
+	AVX512DQ                             // AVX-512 Doubleword and Quadword Instructions
+	AVX512ER                             // AVX-512 Exponential and Reciprocal Instructions
+	AVX512F                              // AVX-512 Foundation
+	AVX512FP16                           // AVX-512 FP16 Instructions
+	AVX512IFMA                           // AVX-512 Integer Fused Multiply-Add Instructions
+	AVX512PF                             // AVX-512 Prefetch Instructions
+	AVX512VBMI                           // AVX-512 Vector Bit Manipulation Instructions
+	AVX512VBMI2                          // AVX-512 Vector Bit Manipulation Instructions, Version 2
+	AVX512VL                             // AVX-512 Vector Length Extensions
+	AVX512VNNI                           // AVX-512 Vector Neural Network Instructions
+	AVX512VP2INTERSECT                   // AVX-512 Intersect for D/Q
+	AVX512VPOPCNTDQ                      // AVX-512 Vector Population Count Doubleword and Quadword
+	AVXIFMA                              // AVX-IFMA instructions
+	AVXNECONVERT                         // AVX-NE-CONVERT instructions
+	AVXSLOW                              // Indicates the CPU performs 2 128 bit operations instead of one
+	AVXVNNI                              // AVX (VEX encoded) VNNI neural network instructions
+	AVXVNNIINT8                          // AVX-VNNI-INT8 instructions
+	AVXVNNIINT16                         // AVX-VNNI-INT16 instructions
+	BHI_CTRL                             // Branch History Injection and Intra-mode Branch Target Injection / CVE-2022-0001, CVE-2022-0002 / INTEL-SA-00598
+	BMI1                                 // Bit Manipulation Instruction Set 1
+	BMI2                                 // Bit Manipulation Instruction Set 2
+	CETIBT                               // Intel CET Indirect Branch Tracking
+	CETSS                                // Intel CET Shadow Stack
+	CLDEMOTE                             // Cache Line Demote
+	CLMUL                                // Carry-less Multiplication
+	CLZERO                               // CLZERO instruction supported
+	CMOV                                 // i686 CMOV
+	CMPCCXADD                            // CMPCCXADD instructions
+	CMPSB_SCADBS_SHORT                   // Fast short CMPSB and SCASB
+	CMPXCHG8                             // CMPXCHG8 instruction
+	CPBOOST                              // Core Performance Boost
+	CPPC                                 // AMD: Collaborative Processor Performance Control
+	CX16                                 // CMPXCHG16B Instruction
+	EFER_LMSLE_UNS                       // AMD: =Core::X86::Msr::EFER[LMSLE] is not supported, and MBZ
+	ENQCMD                               // Enqueue Command
+	ERMS                                 // Enhanced REP MOVSB/STOSB
+	F16C                                 // Half-precision floating-point conversion
+	FLUSH_L1D                            // Flush L1D cache
+	FMA3                                 // Intel FMA 3. Does not imply AVX.
+	FMA4                                 // Bulldozer FMA4 functions
+	FP128                                // AMD: When set, the internal FP/SIMD execution datapath is no more than 128-bits wide
+	FP256                                // AMD: When set, the internal FP/SIMD execution datapath is no more than 256-bits wide
+	FSRM                                 // Fast Short Rep Mov
+	FXSR                                 // FXSAVE, FXRESTOR instructions, CR4 bit 9
+	FXSROPT                              // FXSAVE/FXRSTOR optimizations
+	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
+	HYBRID_CPU                           // This part has CPUs of more than one type.
+	HYPERVISOR                           // This bit has been reserved by Intel & AMD for use by hypervisors
+	IA32_ARCH_CAP                        // IA32_ARCH_CAPABILITIES MSR (Intel)
+	IA32_CORE_CAP                        // IA32_CORE_CAPABILITIES MSR
+	IBPB                                 // Indirect Branch Restricted Speculation (IBRS) and Indirect Branch Predictor Barrier (IBPB)
+	IBPB_BRTYPE                          // Indicates that MSR 49h (PRED_CMD) bit 0 (IBPB) flushes	all branch type predictions from the CPU branch predictor
+	IBRS                                 // AMD: Indirect Branch Restricted Speculation
+	IBRS_PREFERRED                       // AMD: IBRS is preferred over software solution
+	IBRS_PROVIDES_SMP                    // AMD: IBRS provides Same Mode Protection
+	IBS                                  // Instruction Based Sampling (AMD)
+	IBSBRNTRGT                           // Instruction Based Sampling Feature (AMD)
+	IBSFETCHSAM                          // Instruction Based Sampling Feature (AMD)
+	IBSFFV                               // Instruction Based Sampling Feature (AMD)
+	IBSOPCNT                             // Instruction Based Sampling Feature (AMD)
+	IBSOPCNTEXT                          // Instruction Based Sampling Feature (AMD)
+	IBSOPSAM                             // Instruction Based Sampling Feature (AMD)
+	IBSRDWROPCNT                         // Instruction Based Sampling Feature (AMD)
+	IBSRIPINVALIDCHK                     // Instruction Based Sampling Feature (AMD)
+	IBS_FETCH_CTLX                       // AMD: IBS fetch control extended MSR supported
+	IBS_OPDATA4                          // AMD: IBS op data 4 MSR supported
+	IBS_OPFUSE                           // AMD: Indicates support for IbsOpFuse
+	IBS_PREVENTHOST                      // Disallowing IBS use by the host supported
+	IBS_ZEN4                             // AMD: Fetch and Op IBS support IBS extensions added with Zen4
+	IDPRED_CTRL                          // IPRED_DIS
+	INT_WBINVD                           // WBINVD/WBNOINVD are interruptible.
+	INVLPGB                              // NVLPGB and TLBSYNC instruction supported
+	KEYLOCKER                            // Key locker
+	KEYLOCKERW                           // Key locker wide
+	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.
+	MCDT_NO                              // Processor do not exhibit MXCSR Configuration Dependent Timing behavior and do not need to mitigate it.
+	MCOMMIT                              // MCOMMIT instruction supported
+	MD_CLEAR                             // VERW clears CPU buffers
+	MMX                                  // standard MMX
+	MMXEXT                               // SSE integer functions or AMD MMX ext
+	MOVBE                                // MOVBE instruction (big-endian)
+	MOVDIR64B                            // Move 64 Bytes as Direct Store
+	MOVDIRI                              // Move Doubleword as Direct Store
+	MOVSB_ZL                             // Fast Zero-Length MOVSB
+	MOVU                                 // AMD: MOVU SSE instructions are more efficient and should be preferred to SSE	MOVL/MOVH. MOVUPS is more efficient than MOVLPS/MOVHPS. MOVUPD is more efficient than MOVLPD/MOVHPD
+	MPX                                  // Intel MPX (Memory Protection Extensions)
+	MSRIRC                               // Instruction Retired Counter MSR available
+	MSRLIST                              // Read/Write List of Model Specific Registers
+	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
+	POPCNT                               // POPCNT instruction
+	PPIN                                 // AMD: Protected Processor Inventory Number support. Indicates that Protected Processor Inventory Number (PPIN) capability can be enabled
+	PREFETCHI                            // PREFETCHIT0/1 instructions
+	PSFD                                 // Predictive Store Forward Disable
+	RDPRU                                // RDPRU instruction supported
+	RDRAND                               // RDRAND instruction is available
+	RDSEED                               // RDSEED instruction is available
+	RDTSCP                               // RDTSCP Instruction
+	RRSBA_CTRL                           // Restricted RSB Alternate
+	RTM                                  // Restricted Transactional Memory
+	RTM_ALWAYS_ABORT                     // Indicates that the loaded microcode is forcing RTM abort.
+	SBPB                                 // Indicates support for the Selective Branch Predictor Barrier
+	SERIALIZE                            // Serialize Instruction Execution
+	SEV                                  // AMD Secure Encrypted Virtualization supported
+	SEV_64BIT                            // AMD SEV guest execution only allowed from a 64-bit host
+	SEV_ALTERNATIVE                      // AMD SEV Alternate Injection supported
+	SEV_DEBUGSWAP                        // Full debug state swap supported for SEV-ES guests
+	SEV_ES                               // AMD SEV Encrypted State supported
+	SEV_RESTRICTED                       // AMD SEV Restricted Injection supported
+	SEV_SNP                              // AMD SEV Secure Nested Paging supported
+	SGX                                  // Software Guard Extensions
+	SGXLC                                // Software Guard Extensions Launch Control
+	SHA                                  // Intel SHA Extensions
+	SME                                  // AMD Secure Memory Encryption supported
+	SME_COHERENT                         // AMD Hardware cache coherency across encryption domains enforced
+	SPEC_CTRL_SSBD                       // Speculative Store Bypass Disable
+	SRBDS_CTRL                           // SRBDS mitigation MSR available
+	SRSO_MSR_FIX                         // Indicates that software may use MSR BP_CFG[BpSpecReduce] to mitigate SRSO.
+	SRSO_NO                              // Indicates the CPU is not subject to the SRSO vulnerability
+	SRSO_USER_KERNEL_NO                  // Indicates the CPU is not subject to the SRSO vulnerability across user/kernel boundaries
+	SSE                                  // SSE functions
+	SSE2                                 // P4 SSE functions
+	SSE3                                 // Prescott SSE3 functions
+	SSE4                                 // Penryn SSE4.1 functions
+	SSE42                                // Nehalem SSE4.2 functions
+	SSE4A                                // AMD Barcelona microarchitecture SSE4a instructions
+	SSSE3                                // Conroe SSSE3 functions
+	STIBP                                // Single Thread Indirect Branch Predictors
+	STIBP_ALWAYSON                       // AMD: Single Thread Indirect Branch Prediction Mode has Enhanced Performance and may be left Always On
+	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
+	TDX_GUEST                            // Intel Trust Domain Extensions Guest
+	TLB_FLUSH_NESTED                     // AMD: Flushing includes all the nested translations for guest translations
+	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.
+	TOPEXT                               // TopologyExtensions: topology extensions support. Indicates support for CPUID Fn8000_001D_EAX_x[N:0]-CPUID Fn8000_001E_EDX.
+	TSCRATEMSR                           // MSR based TSC rate control. Indicates support for MSR TSC ratio MSRC000_0104
+	TSXLDTRK                             // Intel TSX Suspend Load Address Tracking
+	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. Requires AVX for 3 register versions.
+	VTE                                  // AMD Virtual Transparent Encryption supported
+	WAITPKG                              // TPAUSE, UMONITOR, UMWAIT
+	WBNOINVD                             // Write Back and Do Not Invalidate Cache
+	WRMSRNS                              // Non-Serializing Write to Model Specific Register
+	X87                                  // FPU
+	XGETBV1                              // Supports XGETBV with ECX = 1
+	XOP                                  // Bulldozer XOP functions
+	XSAVE                                // XSAVE, XRESTOR, XSETBV, XGETBV
+	XSAVEC                               // Supports XSAVEC and the compacted form of XRSTOR.
+	XSAVEOPT                             // XSAVEOPT available
+	XSAVES                               // Supports XSAVES/XRSTORS and IA32_XSS
 
 	// ARM features:
 	AESARM   // AES instructions
@@ -309,10 +315,11 @@ type CPUInfo struct {
 		L2  int // L2 Cache (per core or shared). Will be -1 if undetected
 		L3  int // L3 Cache (per core, per ccx or shared). Will be -1 if undetected
 	}
-	SGX        SGXSupport
-	AVX10Level uint8
-	maxFunc    uint32
-	maxExFunc  uint32
+	SGX              SGXSupport
+	AMDMemEncryption AMDMemEncryptionSupport
+	AVX10Level       uint8
+	maxFunc          uint32
+	maxExFunc        uint32
 }
 
 var cpuid func(op uint32) (eax, ebx, ecx, edx uint32)
@@ -1079,6 +1086,32 @@ func hasSGX(available, lc bool) (rval SGXSupport) {
 	return
 }
 
+type AMDMemEncryptionSupport struct {
+	Available          bool
+	CBitPossition      uint32
+	NumVMPL            uint32
+	PhysAddrReduction  uint32
+	NumEntryptedGuests uint32
+	MinSevNoEsAsid     uint32
+}
+
+func hasAMDMemEncryption(available bool) (rval AMDMemEncryptionSupport) {
+	rval.Available = available
+	if !available {
+		return
+	}
+
+	_, b, c, d := cpuidex(0x8000001f, 0)
+
+	rval.CBitPossition = b & 0x3f
+	rval.PhysAddrReduction = (b >> 6) & 0x3F
+	rval.NumVMPL = (b >> 12) & 0xf
+	rval.NumEntryptedGuests = c
+	rval.MinSevNoEsAsid = d
+
+	return
+}
+
 func support() flagSet {
 	var fs flagSet
 	mfi := maxFunctionID()
@@ -1210,6 +1243,7 @@ func support() flagSet {
 		// CPUID.(EAX=7, ECX=1).EDX
 		fs.setIf(edx1&(1<<4) != 0, AVXVNNIINT8)
 		fs.setIf(edx1&(1<<5) != 0, AVXNECONVERT)
+		fs.setIf(edx1&(1<<10) != 0, AVXVNNIINT16)
 		fs.setIf(edx1&(1<<14) != 0, PREFETCHI)
 		fs.setIf(edx1&(1<<19) != 0, AVX10)
 		fs.setIf(edx1&(1<<21) != 0, APX_F)
@@ -1418,6 +1452,15 @@ func support() flagSet {
 		fs.setIf((a>>24)&1 == 1, VMSA_REGPROT)
 	}
 
+	if maxExtendedFunction() >= 0x80000021 && vend == AMD {
+		a, _, _, _ := cpuid(0x80000021)
+		fs.setIf((a>>31)&1 == 1, SRSO_MSR_FIX)
+		fs.setIf((a>>30)&1 == 1, SRSO_USER_KERNEL_NO)
+		fs.setIf((a>>29)&1 == 1, SRSO_NO)
+		fs.setIf((a>>28)&1 == 1, IBPB_BRTYPE)
+		fs.setIf((a>>27)&1 == 1, SBPB)
+	}
+
 	if mfi >= 0x20 {
 		// Microsoft has decided to purposefully hide the information
 		// of the guest TEE when VMs are being created using Hyper-V.
diff --git a/vendor/github.com/klauspost/cpuid/v2/detect_x86.go b/vendor/github.com/klauspost/cpuid/v2/detect_x86.go
index c7dfa125..799b400c 100644
--- a/vendor/github.com/klauspost/cpuid/v2/detect_x86.go
+++ b/vendor/github.com/klauspost/cpuid/v2/detect_x86.go
@@ -27,6 +27,7 @@ func addInfo(c *CPUInfo, safe bool) {
 	c.Family, c.Model, c.Stepping = familyModel()
 	c.featureSet = support()
 	c.SGX = hasSGX(c.featureSet.inSet(SGX), c.featureSet.inSet(SGXLC))
+	c.AMDMemEncryption = hasAMDMemEncryption(c.featureSet.inSet(SME) || c.featureSet.inSet(SEV))
 	c.ThreadsPerCore = threadsPerCore()
 	c.LogicalCores = logicalCores()
 	c.PhysicalCores = physicalCores()
diff --git a/vendor/github.com/klauspost/cpuid/v2/featureid_string.go b/vendor/github.com/klauspost/cpuid/v2/featureid_string.go
index 43bd05f5..3a256031 100644
--- a/vendor/github.com/klauspost/cpuid/v2/featureid_string.go
+++ b/vendor/github.com/klauspost/cpuid/v2/featureid_string.go
@@ -44,189 +44,195 @@ func _() {
 	_ = x[AVXSLOW-34]
 	_ = x[AVXVNNI-35]
 	_ = x[AVXVNNIINT8-36]
-	_ = x[BHI_CTRL-37]
-	_ = x[BMI1-38]
-	_ = x[BMI2-39]
-	_ = x[CETIBT-40]
-	_ = x[CETSS-41]
-	_ = x[CLDEMOTE-42]
-	_ = x[CLMUL-43]
-	_ = x[CLZERO-44]
-	_ = x[CMOV-45]
-	_ = x[CMPCCXADD-46]
-	_ = x[CMPSB_SCADBS_SHORT-47]
-	_ = x[CMPXCHG8-48]
-	_ = x[CPBOOST-49]
-	_ = x[CPPC-50]
-	_ = x[CX16-51]
-	_ = x[EFER_LMSLE_UNS-52]
-	_ = x[ENQCMD-53]
-	_ = x[ERMS-54]
-	_ = x[F16C-55]
-	_ = x[FLUSH_L1D-56]
-	_ = x[FMA3-57]
-	_ = x[FMA4-58]
-	_ = x[FP128-59]
-	_ = x[FP256-60]
-	_ = x[FSRM-61]
-	_ = x[FXSR-62]
-	_ = x[FXSROPT-63]
-	_ = x[GFNI-64]
-	_ = x[HLE-65]
-	_ = x[HRESET-66]
-	_ = x[HTT-67]
-	_ = x[HWA-68]
-	_ = x[HYBRID_CPU-69]
-	_ = x[HYPERVISOR-70]
-	_ = x[IA32_ARCH_CAP-71]
-	_ = x[IA32_CORE_CAP-72]
-	_ = x[IBPB-73]
-	_ = x[IBRS-74]
-	_ = x[IBRS_PREFERRED-75]
-	_ = x[IBRS_PROVIDES_SMP-76]
-	_ = x[IBS-77]
-	_ = x[IBSBRNTRGT-78]
-	_ = x[IBSFETCHSAM-79]
-	_ = x[IBSFFV-80]
-	_ = x[IBSOPCNT-81]
-	_ = x[IBSOPCNTEXT-82]
-	_ = x[IBSOPSAM-83]
-	_ = x[IBSRDWROPCNT-84]
-	_ = x[IBSRIPINVALIDCHK-85]
-	_ = x[IBS_FETCH_CTLX-86]
-	_ = x[IBS_OPDATA4-87]
-	_ = x[IBS_OPFUSE-88]
-	_ = x[IBS_PREVENTHOST-89]
-	_ = x[IBS_ZEN4-90]
-	_ = x[IDPRED_CTRL-91]
-	_ = x[INT_WBINVD-92]
-	_ = x[INVLPGB-93]
-	_ = x[KEYLOCKER-94]
-	_ = x[KEYLOCKERW-95]
-	_ = x[LAHF-96]
-	_ = x[LAM-97]
-	_ = x[LBRVIRT-98]
-	_ = x[LZCNT-99]
-	_ = x[MCAOVERFLOW-100]
-	_ = x[MCDT_NO-101]
-	_ = x[MCOMMIT-102]
-	_ = x[MD_CLEAR-103]
-	_ = x[MMX-104]
-	_ = x[MMXEXT-105]
-	_ = x[MOVBE-106]
-	_ = x[MOVDIR64B-107]
-	_ = x[MOVDIRI-108]
-	_ = x[MOVSB_ZL-109]
-	_ = x[MOVU-110]
-	_ = x[MPX-111]
-	_ = x[MSRIRC-112]
-	_ = x[MSRLIST-113]
-	_ = x[MSR_PAGEFLUSH-114]
-	_ = x[NRIPS-115]
-	_ = x[NX-116]
-	_ = x[OSXSAVE-117]
-	_ = x[PCONFIG-118]
-	_ = x[POPCNT-119]
-	_ = x[PPIN-120]
-	_ = x[PREFETCHI-121]
-	_ = x[PSFD-122]
-	_ = x[RDPRU-123]
-	_ = x[RDRAND-124]
-	_ = x[RDSEED-125]
-	_ = x[RDTSCP-126]
-	_ = x[RRSBA_CTRL-127]
-	_ = x[RTM-128]
-	_ = x[RTM_ALWAYS_ABORT-129]
-	_ = x[SERIALIZE-130]
-	_ = x[SEV-131]
-	_ = x[SEV_64BIT-132]
-	_ = x[SEV_ALTERNATIVE-133]
-	_ = x[SEV_DEBUGSWAP-134]
-	_ = x[SEV_ES-135]
-	_ = x[SEV_RESTRICTED-136]
-	_ = x[SEV_SNP-137]
-	_ = x[SGX-138]
-	_ = x[SGXLC-139]
-	_ = x[SHA-140]
-	_ = x[SME-141]
-	_ = x[SME_COHERENT-142]
-	_ = x[SPEC_CTRL_SSBD-143]
-	_ = x[SRBDS_CTRL-144]
-	_ = x[SSE-145]
-	_ = x[SSE2-146]
-	_ = x[SSE3-147]
-	_ = x[SSE4-148]
-	_ = x[SSE42-149]
-	_ = x[SSE4A-150]
-	_ = x[SSSE3-151]
-	_ = x[STIBP-152]
-	_ = x[STIBP_ALWAYSON-153]
-	_ = x[STOSB_SHORT-154]
-	_ = x[SUCCOR-155]
-	_ = x[SVM-156]
-	_ = x[SVMDA-157]
-	_ = x[SVMFBASID-158]
-	_ = x[SVML-159]
-	_ = x[SVMNP-160]
-	_ = x[SVMPF-161]
-	_ = x[SVMPFT-162]
-	_ = x[SYSCALL-163]
-	_ = x[SYSEE-164]
-	_ = x[TBM-165]
-	_ = x[TDX_GUEST-166]
-	_ = x[TLB_FLUSH_NESTED-167]
-	_ = x[TME-168]
-	_ = x[TOPEXT-169]
-	_ = x[TSCRATEMSR-170]
-	_ = x[TSXLDTRK-171]
-	_ = x[VAES-172]
-	_ = x[VMCBCLEAN-173]
-	_ = x[VMPL-174]
-	_ = x[VMSA_REGPROT-175]
-	_ = x[VMX-176]
-	_ = x[VPCLMULQDQ-177]
-	_ = x[VTE-178]
-	_ = x[WAITPKG-179]
-	_ = x[WBNOINVD-180]
-	_ = x[WRMSRNS-181]
-	_ = x[X87-182]
-	_ = x[XGETBV1-183]
-	_ = x[XOP-184]
-	_ = x[XSAVE-185]
-	_ = x[XSAVEC-186]
-	_ = x[XSAVEOPT-187]
-	_ = x[XSAVES-188]
-	_ = x[AESARM-189]
-	_ = x[ARMCPUID-190]
-	_ = x[ASIMD-191]
-	_ = x[ASIMDDP-192]
-	_ = x[ASIMDHP-193]
-	_ = x[ASIMDRDM-194]
-	_ = x[ATOMICS-195]
-	_ = x[CRC32-196]
-	_ = x[DCPOP-197]
-	_ = x[EVTSTRM-198]
-	_ = x[FCMA-199]
-	_ = x[FP-200]
-	_ = x[FPHP-201]
-	_ = x[GPA-202]
-	_ = x[JSCVT-203]
-	_ = x[LRCPC-204]
-	_ = x[PMULL-205]
-	_ = x[SHA1-206]
-	_ = x[SHA2-207]
-	_ = x[SHA3-208]
-	_ = x[SHA512-209]
-	_ = x[SM3-210]
-	_ = x[SM4-211]
-	_ = x[SVE-212]
-	_ = x[lastID-213]
+	_ = x[AVXVNNIINT16-37]
+	_ = x[BHI_CTRL-38]
+	_ = x[BMI1-39]
+	_ = x[BMI2-40]
+	_ = x[CETIBT-41]
+	_ = x[CETSS-42]
+	_ = x[CLDEMOTE-43]
+	_ = x[CLMUL-44]
+	_ = x[CLZERO-45]
+	_ = x[CMOV-46]
+	_ = x[CMPCCXADD-47]
+	_ = x[CMPSB_SCADBS_SHORT-48]
+	_ = x[CMPXCHG8-49]
+	_ = x[CPBOOST-50]
+	_ = x[CPPC-51]
+	_ = x[CX16-52]
+	_ = x[EFER_LMSLE_UNS-53]
+	_ = x[ENQCMD-54]
+	_ = x[ERMS-55]
+	_ = x[F16C-56]
+	_ = x[FLUSH_L1D-57]
+	_ = x[FMA3-58]
+	_ = x[FMA4-59]
+	_ = x[FP128-60]
+	_ = x[FP256-61]
+	_ = x[FSRM-62]
+	_ = x[FXSR-63]
+	_ = x[FXSROPT-64]
+	_ = x[GFNI-65]
+	_ = x[HLE-66]
+	_ = x[HRESET-67]
+	_ = x[HTT-68]
+	_ = x[HWA-69]
+	_ = x[HYBRID_CPU-70]
+	_ = x[HYPERVISOR-71]
+	_ = x[IA32_ARCH_CAP-72]
+	_ = x[IA32_CORE_CAP-73]
+	_ = x[IBPB-74]
+	_ = x[IBPB_BRTYPE-75]
+	_ = x[IBRS-76]
+	_ = x[IBRS_PREFERRED-77]
+	_ = x[IBRS_PROVIDES_SMP-78]
+	_ = x[IBS-79]
+	_ = x[IBSBRNTRGT-80]
+	_ = x[IBSFETCHSAM-81]
+	_ = x[IBSFFV-82]
+	_ = x[IBSOPCNT-83]
+	_ = x[IBSOPCNTEXT-84]
+	_ = x[IBSOPSAM-85]
+	_ = x[IBSRDWROPCNT-86]
+	_ = x[IBSRIPINVALIDCHK-87]
+	_ = x[IBS_FETCH_CTLX-88]
+	_ = x[IBS_OPDATA4-89]
+	_ = x[IBS_OPFUSE-90]
+	_ = x[IBS_PREVENTHOST-91]
+	_ = x[IBS_ZEN4-92]
+	_ = x[IDPRED_CTRL-93]
+	_ = x[INT_WBINVD-94]
+	_ = x[INVLPGB-95]
+	_ = x[KEYLOCKER-96]
+	_ = x[KEYLOCKERW-97]
+	_ = x[LAHF-98]
+	_ = x[LAM-99]
+	_ = x[LBRVIRT-100]
+	_ = x[LZCNT-101]
+	_ = x[MCAOVERFLOW-102]
+	_ = x[MCDT_NO-103]
+	_ = x[MCOMMIT-104]
+	_ = x[MD_CLEAR-105]
+	_ = x[MMX-106]
+	_ = x[MMXEXT-107]
+	_ = x[MOVBE-108]
+	_ = x[MOVDIR64B-109]
+	_ = x[MOVDIRI-110]
+	_ = x[MOVSB_ZL-111]
+	_ = x[MOVU-112]
+	_ = x[MPX-113]
+	_ = x[MSRIRC-114]
+	_ = x[MSRLIST-115]
+	_ = x[MSR_PAGEFLUSH-116]
+	_ = x[NRIPS-117]
+	_ = x[NX-118]
+	_ = x[OSXSAVE-119]
+	_ = x[PCONFIG-120]
+	_ = x[POPCNT-121]
+	_ = x[PPIN-122]
+	_ = x[PREFETCHI-123]
+	_ = x[PSFD-124]
+	_ = x[RDPRU-125]
+	_ = x[RDRAND-126]
+	_ = x[RDSEED-127]
+	_ = x[RDTSCP-128]
+	_ = x[RRSBA_CTRL-129]
+	_ = x[RTM-130]
+	_ = x[RTM_ALWAYS_ABORT-131]
+	_ = x[SBPB-132]
+	_ = x[SERIALIZE-133]
+	_ = x[SEV-134]
+	_ = x[SEV_64BIT-135]
+	_ = x[SEV_ALTERNATIVE-136]
+	_ = x[SEV_DEBUGSWAP-137]
+	_ = x[SEV_ES-138]
+	_ = x[SEV_RESTRICTED-139]
+	_ = x[SEV_SNP-140]
+	_ = x[SGX-141]
+	_ = x[SGXLC-142]
+	_ = x[SHA-143]
+	_ = x[SME-144]
+	_ = x[SME_COHERENT-145]
+	_ = x[SPEC_CTRL_SSBD-146]
+	_ = x[SRBDS_CTRL-147]
+	_ = x[SRSO_MSR_FIX-148]
+	_ = x[SRSO_NO-149]
+	_ = x[SRSO_USER_KERNEL_NO-150]
+	_ = x[SSE-151]
+	_ = x[SSE2-152]
+	_ = x[SSE3-153]
+	_ = x[SSE4-154]
+	_ = x[SSE42-155]
+	_ = x[SSE4A-156]
+	_ = x[SSSE3-157]
+	_ = x[STIBP-158]
+	_ = x[STIBP_ALWAYSON-159]
+	_ = x[STOSB_SHORT-160]
+	_ = x[SUCCOR-161]
+	_ = x[SVM-162]
+	_ = x[SVMDA-163]
+	_ = x[SVMFBASID-164]
+	_ = x[SVML-165]
+	_ = x[SVMNP-166]
+	_ = x[SVMPF-167]
+	_ = x[SVMPFT-168]
+	_ = x[SYSCALL-169]
+	_ = x[SYSEE-170]
+	_ = x[TBM-171]
+	_ = x[TDX_GUEST-172]
+	_ = x[TLB_FLUSH_NESTED-173]
+	_ = x[TME-174]
+	_ = x[TOPEXT-175]
+	_ = x[TSCRATEMSR-176]
+	_ = x[TSXLDTRK-177]
+	_ = x[VAES-178]
+	_ = x[VMCBCLEAN-179]
+	_ = x[VMPL-180]
+	_ = x[VMSA_REGPROT-181]
+	_ = x[VMX-182]
+	_ = x[VPCLMULQDQ-183]
+	_ = x[VTE-184]
+	_ = x[WAITPKG-185]
+	_ = x[WBNOINVD-186]
+	_ = x[WRMSRNS-187]
+	_ = x[X87-188]
+	_ = x[XGETBV1-189]
+	_ = x[XOP-190]
+	_ = x[XSAVE-191]
+	_ = x[XSAVEC-192]
+	_ = x[XSAVEOPT-193]
+	_ = x[XSAVES-194]
+	_ = x[AESARM-195]
+	_ = x[ARMCPUID-196]
+	_ = x[ASIMD-197]
+	_ = x[ASIMDDP-198]
+	_ = x[ASIMDHP-199]
+	_ = x[ASIMDRDM-200]
+	_ = x[ATOMICS-201]
+	_ = x[CRC32-202]
+	_ = x[DCPOP-203]
+	_ = x[EVTSTRM-204]
+	_ = x[FCMA-205]
+	_ = x[FP-206]
+	_ = x[FPHP-207]
+	_ = x[GPA-208]
+	_ = x[JSCVT-209]
+	_ = x[LRCPC-210]
+	_ = x[PMULL-211]
+	_ = x[SHA1-212]
+	_ = x[SHA2-213]
+	_ = x[SHA3-214]
+	_ = x[SHA512-215]
+	_ = x[SM3-216]
+	_ = x[SM4-217]
+	_ = x[SVE-218]
+	_ = x[lastID-219]
 	_ = x[firstID-0]
 }
 
-const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXFP16AMXINT8AMXTILEAPX_FAVXAVX10AVX10_128AVX10_256AVX10_512AVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXIFMAAVXNECONVERTAVXSLOWAVXVNNIAVXVNNIINT8BHI_CTRLBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPCCXADDCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCPPCCX16EFER_LMSLE_UNSENQCMDERMSF16CFLUSH_L1DFMA3FMA4FP128FP256FSRMFXSRFXSROPTGFNIHLEHRESETHTTHWAHYBRID_CPUHYPERVISORIA32_ARCH_CAPIA32_CORE_CAPIBPBIBRSIBRS_PREFERREDIBRS_PROVIDES_SMPIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_FETCH_CTLXIBS_OPDATA4IBS_OPFUSEIBS_PREVENTHOSTIBS_ZEN4IDPRED_CTRLINT_WBINVDINVLPGBKEYLOCKERKEYLOCKERWLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCDT_NOMCOMMITMD_CLEARMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMOVUMPXMSRIRCMSRLISTMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTPPINPREFETCHIPSFDRDPRURDRANDRDSEEDRDTSCPRRSBA_CTRLRTMRTM_ALWAYS_ABORTSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSPEC_CTRL_SSBDSRBDS_CTRLSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTIBP_ALWAYSONSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTDX_GUESTTLB_FLUSH_NESTEDTMETOPEXTTSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDWRMSRNSX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID"
+const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXFP16AMXINT8AMXTILEAPX_FAVXAVX10AVX10_128AVX10_256AVX10_512AVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXIFMAAVXNECONVERTAVXSLOWAVXVNNIAVXVNNIINT8AVXVNNIINT16BHI_CTRLBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPCCXADDCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCPPCCX16EFER_LMSLE_UNSENQCMDERMSF16CFLUSH_L1DFMA3FMA4FP128FP256FSRMFXSRFXSROPTGFNIHLEHRESETHTTHWAHYBRID_CPUHYPERVISORIA32_ARCH_CAPIA32_CORE_CAPIBPBIBPB_BRTYPEIBRSIBRS_PREFERREDIBRS_PROVIDES_SMPIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_FETCH_CTLXIBS_OPDATA4IBS_OPFUSEIBS_PREVENTHOSTIBS_ZEN4IDPRED_CTRLINT_WBINVDINVLPGBKEYLOCKERKEYLOCKERWLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCDT_NOMCOMMITMD_CLEARMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMOVUMPXMSRIRCMSRLISTMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTPPINPREFETCHIPSFDRDPRURDRANDRDSEEDRDTSCPRRSBA_CTRLRTMRTM_ALWAYS_ABORTSBPBSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSPEC_CTRL_SSBDSRBDS_CTRLSRSO_MSR_FIXSRSO_NOSRSO_USER_KERNEL_NOSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTIBP_ALWAYSONSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTDX_GUESTTLB_FLUSH_NESTEDTMETOPEXTTSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDWRMSRNSX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID"
 
-var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 62, 67, 70, 75, 84, 93, 102, 106, 116, 128, 136, 144, 152, 160, 167, 177, 187, 195, 205, 216, 224, 234, 252, 267, 274, 286, 293, 300, 311, 319, 323, 327, 333, 338, 346, 351, 357, 361, 370, 388, 396, 403, 407, 411, 425, 431, 435, 439, 448, 452, 456, 461, 466, 470, 474, 481, 485, 488, 494, 497, 500, 510, 520, 533, 546, 550, 554, 568, 585, 588, 598, 609, 615, 623, 634, 642, 654, 670, 684, 695, 705, 720, 728, 739, 749, 756, 765, 775, 779, 782, 789, 794, 805, 812, 819, 827, 830, 836, 841, 850, 857, 865, 869, 872, 878, 885, 898, 903, 905, 912, 919, 925, 929, 938, 942, 947, 953, 959, 965, 975, 978, 994, 1003, 1006, 1015, 1030, 1043, 1049, 1063, 1070, 1073, 1078, 1081, 1084, 1096, 1110, 1120, 1123, 1127, 1131, 1135, 1140, 1145, 1150, 1155, 1169, 1180, 1186, 1189, 1194, 1203, 1207, 1212, 1217, 1223, 1230, 1235, 1238, 1247, 1263, 1266, 1272, 1282, 1290, 1294, 1303, 1307, 1319, 1322, 1332, 1335, 1342, 1350, 1357, 1360, 1367, 1370, 1375, 1381, 1389, 1395, 1401, 1409, 1414, 1421, 1428, 1436, 1443, 1448, 1453, 1460, 1464, 1466, 1470, 1473, 1478, 1483, 1488, 1492, 1496, 1500, 1506, 1509, 1512, 1515, 1521}
+var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 62, 67, 70, 75, 84, 93, 102, 106, 116, 128, 136, 144, 152, 160, 167, 177, 187, 195, 205, 216, 224, 234, 252, 267, 274, 286, 293, 300, 311, 323, 331, 335, 339, 345, 350, 358, 363, 369, 373, 382, 400, 408, 415, 419, 423, 437, 443, 447, 451, 460, 464, 468, 473, 478, 482, 486, 493, 497, 500, 506, 509, 512, 522, 532, 545, 558, 562, 573, 577, 591, 608, 611, 621, 632, 638, 646, 657, 665, 677, 693, 707, 718, 728, 743, 751, 762, 772, 779, 788, 798, 802, 805, 812, 817, 828, 835, 842, 850, 853, 859, 864, 873, 880, 888, 892, 895, 901, 908, 921, 926, 928, 935, 942, 948, 952, 961, 965, 970, 976, 982, 988, 998, 1001, 1017, 1021, 1030, 1033, 1042, 1057, 1070, 1076, 1090, 1097, 1100, 1105, 1108, 1111, 1123, 1137, 1147, 1159, 1166, 1185, 1188, 1192, 1196, 1200, 1205, 1210, 1215, 1220, 1234, 1245, 1251, 1254, 1259, 1268, 1272, 1277, 1282, 1288, 1295, 1300, 1303, 1312, 1328, 1331, 1337, 1347, 1355, 1359, 1368, 1372, 1384, 1387, 1397, 1400, 1407, 1415, 1422, 1425, 1432, 1435, 1440, 1446, 1454, 1460, 1466, 1474, 1479, 1486, 1493, 1501, 1508, 1513, 1518, 1525, 1529, 1531, 1535, 1538, 1543, 1548, 1553, 1557, 1561, 1565, 1571, 1574, 1577, 1580, 1586}
 
 func (i FeatureID) String() string {
 	if i < 0 || i >= FeatureID(len(_FeatureID_index)-1) {
diff --git a/vendor/github.com/klauspost/reedsolomon/README.md b/vendor/github.com/klauspost/reedsolomon/README.md
index bdcb9e78..d94512a3 100644
--- a/vendor/github.com/klauspost/reedsolomon/README.md
+++ b/vendor/github.com/klauspost/reedsolomon/README.md
@@ -25,6 +25,10 @@ Using Go modules is recommended.
 
 # Changes
 
+## 2024
+
+ * Auto-generation of SVE and NEON routines for ARM based on AVX2 code. This results in a speedup of 2x for SVE (as measured using Graviton 3 on AWS) and a speedup of 1.5x as compared to the existing NEON-accelerated code.
+
 ## 2022
 
 * [GFNI](https://github.com/klauspost/reedsolomon/pull/224) support for amd64, for up to 3x faster processing.
@@ -558,8 +562,9 @@ The removed code may not be infringing and even after `-tags=nopshufb` there may
 * [Reed-Solomon Erasure Coding in Haskell](https://github.com/NicolasT/reedsolomon). Haskell port of the package with similar performance.
 * [reed-solomon-erasure](https://github.com/darrenldl/reed-solomon-erasure). Compatible Rust implementation.
 * [go-erasure](https://github.com/somethingnew2-0/go-erasure). A similar library using cgo, slower in my tests.
-* [Screaming Fast Galois Field Arithmetic](http://www.snia.org/sites/default/files2/SDC2013/presentations/NewThinking/EthanMiller_Screaming_Fast_Galois_Field%20Arithmetic_SIMD%20Instructions.pdf). Basis for SSE3 optimizations.
+* [Screaming Fast Galois Field Arithmetic](https://www.snia.org/sites/default/files/files2/files2/SDC2013/presentations/NewThinking/EthanMiller_Screaming_Fast_Galois_Field%20Arithmetic_SIMD%20Instructions.pdf). Basis for SSE3 optimizations.
 * [Leopard-RS](https://github.com/catid/leopard) C library used as basis for GF16 implementation.
+* [reed-solomon-simd](https://github.com/AndersTrier/reed-solomon-simd) Leopard-RS Rust implementation.
 
 # License
 
diff --git a/vendor/github.com/klauspost/reedsolomon/galois.go b/vendor/github.com/klauspost/reedsolomon/galois.go
index 697f9ca6..9b363950 100644
--- a/vendor/github.com/klauspost/reedsolomon/galois.go
+++ b/vendor/github.com/klauspost/reedsolomon/galois.go
@@ -910,8 +910,8 @@ func galExp(a byte, n int) byte {
 	return expTable[uint8(logResult)]
 }
 
-func genAvx2Matrix(matrixRows [][]byte, inputs, inIdx, outputs int, dst []byte) []byte {
-	if !avx2CodeGen {
+func genCodeGenMatrix(matrixRows [][]byte, inputs, inIdx, outputs int, dst []byte) []byte {
+	if !codeGen {
 		panic("codegen not enabled")
 	}
 	total := inputs * outputs
@@ -942,7 +942,7 @@ func genAvx2Matrix(matrixRows [][]byte, inputs, inIdx, outputs int, dst []byte)
 var gf2p811dMulMatrices = [256]uint64{0, 0x102040810204080, 0x8001828488102040, 0x8103868c983060c0, 0x408041c2c4881020, 0x418245cad4a850a0, 0xc081c3464c983060, 0xc183c74e5cb870e0, 0x2040a061e2c48810, 0x2142a469f2e4c890, 0xa04122e56ad4a850, 0xa14326ed7af4e8d0, 0x60c0e1a3264c9830, 0x61c2e5ab366cd8b0, 0xe0c16327ae5cb870, 0xe1c3672fbe7cf8f0, 0x102050b071e2c488, 0x112254b861c28408, 0x9021d234f9f2e4c8, 0x9123d63ce9d2a448, 0x50a01172b56ad4a8, 0x51a2157aa54a9428, 0xd0a193f63d7af4e8, 0xd1a397fe2d5ab468, 0x3060f0d193264c98, 0x3162f4d983060c18, 0xb06172551b366cd8, 0xb163765d0b162c58, 0x70e0b11357ae5cb8, 0x71e2b51b478e1c38, 0xf0e13397dfbe7cf8, 0xf1e3379fcf9e3c78, 0x8810a8d83871e2c4, 0x8912acd02851a244, 0x8112a5cb061c284, 0x9132e54a0418204, 0xc890e91afcf9f2e4, 0xc992ed12ecd9b264, 0x48916b9e74e9d2a4, 0x49936f9664c99224, 0xa85008b9dab56ad4, 0xa9520cb1ca952a54, 0x28518a3d52a54a94, 0x29538e3542850a14, 0xe8d0497b1e3d7af4, 0xe9d24d730e1d3a74, 0x68d1cbff962d5ab4, 0x69d3cff7860d1a34, 0x9830f8684993264c, 0x9932fc6059b366cc, 0x18317aecc183060c, 0x19337ee4d1a3468c, 0xd8b0b9aa8d1b366c, 0xd9b2bda29d3b76ec, 0x58b13b2e050b162c, 0x59b33f26152b56ac, 0xb8705809ab57ae5c, 0xb9725c01bb77eedc, 0x3871da8d23478e1c, 0x3973de853367ce9c, 0xf8f019cb6fdfbe7c, 0xf9f21dc37ffffefc, 0x78f19b4fe7cf9e3c, 0x79f39f47f7efdebc, 0xc488d46c1c3871e2, 0xc58ad0640c183162, 0x448956e8942851a2, 0x458b52e084081122, 0x840895aed8b061c2, 0x850a91a6c8902142, 0x409172a50a04182, 0x50b132240800102, 0xe4c8740dfefcf9f2, 0xe5ca7005eedcb972, 0x64c9f68976ecd9b2, 0x65cbf28166cc9932, 0xa44835cf3a74e9d2, 0xa54a31c72a54a952, 0x2449b74bb264c992, 0x254bb343a2448912, 0xd4a884dc6ddab56a, 0xd5aa80d47dfaf5ea, 0x54a90658e5ca952a, 0x55ab0250f5ead5aa, 0x9428c51ea952a54a, 0x952ac116b972e5ca, 0x1429479a2142850a, 0x152b43923162c58a, 0xf4e824bd8f1e3d7a, 0xf5ea20b59f3e7dfa, 0x74e9a639070e1d3a, 0x75eba231172e5dba, 0xb468657f4b962d5a, 0xb56a61775bb66dda, 0x3469e7fbc3860d1a, 0x356be3f3d3a64d9a, 0x4c987cb424499326, 0x4d9a78bc3469d3a6, 0xcc99fe30ac59b366, 0xcd9bfa38bc79f3e6, 0xc183d76e0c18306, 0xd1a397ef0e1c386, 0x8c19bff268d1a346, 0x8d1bbbfa78f1e3c6, 0x6cd8dcd5c68d1b36, 0x6ddad8ddd6ad5bb6, 0xecd95e514e9d3b76, 0xeddb5a595ebd7bf6, 0x2c589d1702050b16, 0x2d5a991f12254b96, 0xac591f938a152b56, 0xad5b1b9b9a356bd6, 0x5cb82c0455ab57ae, 0x5dba280c458b172e, 0xdcb9ae80ddbb77ee, 0xddbbaa88cd9b376e, 0x1c386dc69123478e, 0x1d3a69ce8103070e, 0x9c39ef42193367ce, 0x9d3beb4a0913274e, 0x7cf88c65b76fdfbe, 0x7dfa886da74f9f3e, 0xfcf90ee13f7ffffe, 0xfdfb0ae92f5fbf7e, 0x3c78cda773e7cf9e, 0x3d7ac9af63c78f1e, 0xbc794f23fbf7efde, 0xbd7b4b2bebd7af5e, 0xe2c46a368e1c3871, 0xe3c66e3e9e3c78f1, 0x62c5e8b2060c1831, 0x63c7ecba162c58b1, 0xa2442bf44a942851, 0xa3462ffc5ab468d1, 0x2245a970c2840811, 0x2347ad78d2a44891, 0xc284ca576cd8b061, 0xc386ce5f7cf8f0e1, 0x428548d3e4c89021, 0x43874cdbf4e8d0a1, 0x82048b95a850a041, 0x83068f9db870e0c1, 0x205091120408001, 0x3070d193060c081, 0xf2e43a86fffefcf9, 0xf3e63e8eefdebc79, 0x72e5b80277eedcb9, 0x73e7bc0a67ce9c39, 0xb2647b443b76ecd9, 0xb3667f4c2b56ac59, 0x3265f9c0b366cc99, 0x3367fdc8a3468c19, 0xd2a49ae71d3a74e9, 0xd3a69eef0d1a3469, 0x52a51863952a54a9, 0x53a71c6b850a1429, 0x9224db25d9b264c9, 0x9326df2dc9922449, 0x122559a151a24489, 0x13275da941820409, 0x6ad4c2eeb66ddab5, 0x6bd6c6e6a64d9a35, 0xead5406a3e7dfaf5, 0xebd744622e5dba75, 0x2a54832c72e5ca95, 0x2b56872462c58a15, 0xaa5501a8faf5ead5, 0xab5705a0ead5aa55, 0x4a94628f54a952a5, 0x4b96668744891225, 0xca95e00bdcb972e5, 0xcb97e403cc993265, 0xa14234d90214285, 0xb16274580010205, 0x8a15a1c9183162c5, 0x8b17a5c108112245, 0x7af4925ec78f1e3d, 0x7bf69656d7af5ebd, 0xfaf510da4f9f3e7d, 0xfbf714d25fbf7efd, 0x3a74d39c03070e1d, 0x3b76d79413274e9d, 0xba7551188b172e5d, 0xbb7755109b376edd, 0x5ab4323f254b962d, 0x5bb63637356bd6ad, 0xdab5b0bbad5bb66d, 0xdbb7b4b3bd7bf6ed, 0x1a3473fde1c3860d, 0x1b3677f5f1e3c68d, 0x9a35f17969d3a64d, 0x9b37f57179f3e6cd, 0x264cbe5a92244993, 0x274eba5282040913, 0xa64d3cde1a3469d3, 0xa74f38d60a142953, 0x66ccff9856ac59b3, 0x67cefb90468c1933, 0xe6cd7d1cdebc79f3, 0xe7cf7914ce9c3973, 0x60c1e3b70e0c183, 0x70e1a3360c08103, 0x860d9cbff8f0e1c3, 0x870f98b7e8d0a143, 0x468c5ff9b468d1a3, 0x478e5bf1a4489123, 0xc68ddd7d3c78f1e3, 0xc78fd9752c58b163, 0x366ceeeae3c68d1b, 0x376eeae2f3e6cd9b, 0xb66d6c6e6bd6ad5b, 0xb76f68667bf6eddb, 0x76ecaf28274e9d3b, 0x77eeab20376eddbb, 0xf6ed2dacaf5ebd7b, 0xf7ef29a4bf7efdfb, 0x162c4e8b0102050b, 0x172e4a831122458b, 0x962dcc0f8912254b, 0x972fc807993265cb, 0x56ac0f49c58a152b, 0x57ae0b41d5aa55ab, 0xd6ad8dcd4d9a356b, 0xd7af89c55dba75eb, 0xae5c1682aa55ab57, 0xaf5e128aba75ebd7, 0x2e5d940622458b17, 0x2f5f900e3265cb97, 0xeedc57406eddbb77, 0xefde53487efdfbf7, 0x6eddd5c4e6cd9b37, 0x6fdfd1ccf6eddbb7, 0x8e1cb6e348912347, 0x8f1eb2eb58b163c7, 0xe1d3467c0810307, 0xf1f306fd0a14387, 0xce9cf7218c193367, 0xcf9ef3299c3973e7, 0x4e9d75a504091327, 0x4f9f71ad142953a7, 0xbe7c4632dbb76fdf, 0xbf7e423acb972f5f, 0x3e7dc4b653a74f9f, 0x3f7fc0be43870f1f, 0xfefc07f01f3f7fff, 0xfffe03f80f1f3f7f, 0x7efd8574972f5fbf, 0x7fff817c870f1f3f, 0x9e3ce6533973e7cf, 0x9f3ee25b2953a74f, 0x1e3d64d7b163c78f, 0x1f3f60dfa143870f, 0xdebca791fdfbf7ef, 0xdfbea399eddbb76f, 0x5ebd251575ebd7af, 0x5fbf211d65cb972f}
 
 func genGFNIMatrix(matrixRows [][]byte, inputs, inIdx, outputs int, dst []uint64) []uint64 {
-	if !avx2CodeGen {
+	if !codeGen {
 		panic("codegen not enabled")
 	}
 	total := inputs * outputs
diff --git a/vendor/github.com/klauspost/reedsolomon/galois_gen_amd64.s b/vendor/github.com/klauspost/reedsolomon/galois_gen_amd64.s
index ad253a65..8ff74bf4 100644
--- a/vendor/github.com/klauspost/reedsolomon/galois_gen_amd64.s
+++ b/vendor/github.com/klauspost/reedsolomon/galois_gen_amd64.s
@@ -126,7 +126,6 @@ TEXT ·mulAvxTwo_1x1_64(SB), $0-88
 	MOVQ    in_base+24(FP), CX
 	MOVQ    (CX), CX
 	MOVQ    out_base+48(FP), DX
-	MOVQ    out_base+48(FP), DX
 	MOVQ    (DX), DX
 	MOVQ    start+72(FP), BX
 
@@ -366,7 +365,6 @@ TEXT ·mulAvxTwo_1x1_64Xor(SB), $0-88
 	MOVQ    in_base+24(FP), CX
 	MOVQ    (CX), CX
 	MOVQ    out_base+48(FP), DX
-	MOVQ    out_base+48(FP), DX
 	MOVQ    (DX), DX
 	MOVQ    start+72(FP), BX
 
@@ -428,7 +426,6 @@ TEXT ·mulAvxTwo_1x2_64(SB), $0-88
 	MOVQ  in_base+24(FP), DX
 	MOVQ  (DX), DX
 	MOVQ  out_base+48(FP), BX
-	MOVQ  out_base+48(FP), BX
 	MOVQ  (BX), SI
 	MOVQ  24(BX), BX
 	MOVQ  start+72(FP), DI
@@ -709,7 +706,6 @@ TEXT ·mulAvxTwo_1x2_64Xor(SB), $0-88
 	MOVQ  in_base+24(FP), DX
 	MOVQ  (DX), DX
 	MOVQ  out_base+48(FP), BX
-	MOVQ  out_base+48(FP), BX
 	MOVQ  (BX), SI
 	MOVQ  24(BX), BX
 	MOVQ  start+72(FP), DI
@@ -788,7 +784,6 @@ TEXT ·mulAvxTwo_1x3_64(SB), $0-88
 	MOVQ  in_base+24(FP), DX
 	MOVQ  (DX), DX
 	MOVQ  out_base+48(FP), BX
-	MOVQ  out_base+48(FP), BX
 	MOVQ  (BX), SI
 	MOVQ  24(BX), DI
 	MOVQ  48(BX), BX
@@ -1110,7 +1105,6 @@ TEXT ·mulAvxTwo_1x3_64Xor(SB), $0-88
 	MOVQ  in_base+24(FP), DX
 	MOVQ  (DX), DX
 	MOVQ  out_base+48(FP), BX
-	MOVQ  out_base+48(FP), BX
 	MOVQ  (BX), SI
 	MOVQ  24(BX), DI
 	MOVQ  48(BX), BX
@@ -5164,7 +5158,6 @@ TEXT ·mulAvxTwo_2x1_64(SB), $0-88
 	MOVQ    (CX), DX
 	MOVQ    24(CX), CX
 	MOVQ    out_base+48(FP), BX
-	MOVQ    out_base+48(FP), BX
 	MOVQ    (BX), BX
 	MOVQ    start+72(FP), SI
 
@@ -5461,7 +5454,6 @@ TEXT ·mulAvxTwo_2x1_64Xor(SB), $0-88
 	MOVQ    (CX), DX
 	MOVQ    24(CX), CX
 	MOVQ    out_base+48(FP), BX
-	MOVQ    out_base+48(FP), BX
 	MOVQ    (BX), BX
 	MOVQ    start+72(FP), SI
 
@@ -5542,7 +5534,6 @@ TEXT ·mulAvxTwo_2x2_64(SB), $0-88
 	MOVQ  (DX), BX
 	MOVQ  24(DX), DX
 	MOVQ  out_base+48(FP), SI
-	MOVQ  out_base+48(FP), SI
 	MOVQ  (SI), DI
 	MOVQ  24(SI), SI
 	MOVQ  start+72(FP), R8
@@ -5900,7 +5891,6 @@ TEXT ·mulAvxTwo_2x2_64Xor(SB), $0-88
 	MOVQ  (DX), BX
 	MOVQ  24(DX), DX
 	MOVQ  out_base+48(FP), SI
-	MOVQ  out_base+48(FP), SI
 	MOVQ  (SI), DI
 	MOVQ  24(SI), SI
 	MOVQ  start+72(FP), R8
@@ -6008,7 +5998,6 @@ TEXT ·mulAvxTwo_2x3_64(SB), $0-88
 	MOVQ  (DX), BX
 	MOVQ  24(DX), DX
 	MOVQ  out_base+48(FP), SI
-	MOVQ  out_base+48(FP), SI
 	MOVQ  (SI), DI
 	MOVQ  24(SI), R8
 	MOVQ  48(SI), SI
@@ -6427,7 +6416,6 @@ TEXT ·mulAvxTwo_2x3_64Xor(SB), $0-88
 	MOVQ  (DX), BX
 	MOVQ  24(DX), DX
 	MOVQ  out_base+48(FP), SI
-	MOVQ  out_base+48(FP), SI
 	MOVQ  (SI), DI
 	MOVQ  24(SI), R8
 	MOVQ  48(SI), SI
@@ -11886,7 +11874,6 @@ TEXT ·mulAvxTwo_3x1_64(SB), $0-88
 	MOVQ  24(DX), SI
 	MOVQ  48(DX), DX
 	MOVQ  out_base+48(FP), DI
-	MOVQ  out_base+48(FP), DI
 	MOVQ  (DI), DI
 	MOVQ  start+72(FP), R8
 
@@ -12240,7 +12227,6 @@ TEXT ·mulAvxTwo_3x1_64Xor(SB), $0-88
 	MOVQ  24(DX), SI
 	MOVQ  48(DX), DX
 	MOVQ  out_base+48(FP), DI
-	MOVQ  out_base+48(FP), DI
 	MOVQ  (DI), DI
 	MOVQ  start+72(FP), R8
 
@@ -12346,7 +12332,6 @@ TEXT ·mulAvxTwo_3x2_64(SB), $0-88
 	MOVQ  24(DX), SI
 	MOVQ  48(DX), DX
 	MOVQ  out_base+48(FP), DI
-	MOVQ  out_base+48(FP), DI
 	MOVQ  (DI), R8
 	MOVQ  24(DI), DI
 	MOVQ  start+72(FP), R9
@@ -12781,7 +12766,6 @@ TEXT ·mulAvxTwo_3x2_64Xor(SB), $0-88
 	MOVQ  24(DX), SI
 	MOVQ  48(DX), DX
 	MOVQ  out_base+48(FP), DI
-	MOVQ  out_base+48(FP), DI
 	MOVQ  (DI), R8
 	MOVQ  24(DI), DI
 	MOVQ  start+72(FP), R9
@@ -12918,7 +12902,6 @@ TEXT ·mulAvxTwo_3x3_64(SB), $0-88
 	MOVQ  24(DX), SI
 	MOVQ  48(DX), DX
 	MOVQ  out_base+48(FP), DI
-	MOVQ  out_base+48(FP), DI
 	MOVQ  (DI), R8
 	MOVQ  24(DI), R9
 	MOVQ  48(DI), DI
@@ -13434,7 +13417,6 @@ TEXT ·mulAvxTwo_3x3_64Xor(SB), $0-88
 	MOVQ  24(DX), SI
 	MOVQ  48(DX), DX
 	MOVQ  out_base+48(FP), DI
-	MOVQ  out_base+48(FP), DI
 	MOVQ  (DI), R8
 	MOVQ  24(DI), R9
 	MOVQ  48(DI), DI
@@ -20286,7 +20268,6 @@ TEXT ·mulAvxTwo_4x1_64(SB), $0-88
 	MOVQ  48(DX), DI
 	MOVQ  72(DX), DX
 	MOVQ  out_base+48(FP), R8
-	MOVQ  out_base+48(FP), R8
 	MOVQ  (R8), R8
 	MOVQ  start+72(FP), R9
 
@@ -20697,7 +20678,6 @@ TEXT ·mulAvxTwo_4x1_64Xor(SB), $0-88
 	MOVQ  48(DX), DI
 	MOVQ  72(DX), DX
 	MOVQ  out_base+48(FP), R8
-	MOVQ  out_base+48(FP), R8
 	MOVQ  (R8), R8
 	MOVQ  start+72(FP), R9
 
@@ -20824,7 +20804,6 @@ TEXT ·mulAvxTwo_4x2_64(SB), $0-88
 	MOVQ  48(DX), DI
 	MOVQ  72(DX), DX
 	MOVQ  out_base+48(FP), R8
-	MOVQ  out_base+48(FP), R8
 	MOVQ  (R8), R9
 	MOVQ  24(R8), R8
 	MOVQ  start+72(FP), R10
@@ -21336,7 +21315,6 @@ TEXT ·mulAvxTwo_4x2_64Xor(SB), $0-88
 	MOVQ  48(DX), DI
 	MOVQ  72(DX), DX
 	MOVQ  out_base+48(FP), R8
-	MOVQ  out_base+48(FP), R8
 	MOVQ  (R8), R9
 	MOVQ  24(R8), R8
 	MOVQ  start+72(FP), R10
@@ -21502,7 +21480,6 @@ TEXT ·mulAvxTwo_4x3_64(SB), $0-88
 	MOVQ  48(DX), DI
 	MOVQ  72(DX), DX
 	MOVQ  out_base+48(FP), R8
-	MOVQ  out_base+48(FP), R8
 	MOVQ  (R8), R9
 	MOVQ  24(R8), R10
 	MOVQ  48(R8), R8
@@ -22115,7 +22092,6 @@ TEXT ·mulAvxTwo_4x3_64Xor(SB), $0-88
 	MOVQ  48(DX), DI
 	MOVQ  72(DX), DX
 	MOVQ  out_base+48(FP), R8
-	MOVQ  out_base+48(FP), R8
 	MOVQ  (R8), R9
 	MOVQ  24(R8), R10
 	MOVQ  48(R8), R8
@@ -30216,7 +30192,6 @@ TEXT ·mulAvxTwo_5x1_64(SB), $0-88
 	MOVQ  72(DX), R8
 	MOVQ  96(DX), DX
 	MOVQ  out_base+48(FP), R9
-	MOVQ  out_base+48(FP), R9
 	MOVQ  (R9), R9
 	MOVQ  start+72(FP), R10
 
@@ -30684,7 +30659,6 @@ TEXT ·mulAvxTwo_5x1_64Xor(SB), $0-88
 	MOVQ  72(DX), R8
 	MOVQ  96(DX), DX
 	MOVQ  out_base+48(FP), R9
-	MOVQ  out_base+48(FP), R9
 	MOVQ  (R9), R9
 	MOVQ  start+72(FP), R10
 
@@ -30832,7 +30806,6 @@ TEXT ·mulAvxTwo_5x2_64(SB), $0-88
 	MOVQ  72(DX), R8
 	MOVQ  96(DX), DX
 	MOVQ  out_base+48(FP), R9
-	MOVQ  out_base+48(FP), R9
 	MOVQ  (R9), R10
 	MOVQ  24(R9), R9
 	MOVQ  start+72(FP), R11
@@ -31421,7 +31394,6 @@ TEXT ·mulAvxTwo_5x2_64Xor(SB), $0-88
 	MOVQ  72(DX), R8
 	MOVQ  96(DX), DX
 	MOVQ  out_base+48(FP), R9
-	MOVQ  out_base+48(FP), R9
 	MOVQ  (R9), R10
 	MOVQ  24(R9), R9
 	MOVQ  start+72(FP), R11
@@ -31616,7 +31588,6 @@ TEXT ·mulAvxTwo_5x3_64(SB), $0-88
 	MOVQ  72(DX), R8
 	MOVQ  96(DX), DX
 	MOVQ  out_base+48(FP), R9
-	MOVQ  out_base+48(FP), R9
 	MOVQ  (R9), R10
 	MOVQ  24(R9), R11
 	MOVQ  48(R9), R9
@@ -32326,7 +32297,6 @@ TEXT ·mulAvxTwo_5x3_64Xor(SB), $0-88
 	MOVQ  72(DX), R8
 	MOVQ  96(DX), DX
 	MOVQ  out_base+48(FP), R9
-	MOVQ  out_base+48(FP), R9
 	MOVQ  (R9), R10
 	MOVQ  24(R9), R11
 	MOVQ  48(R9), R9
@@ -41669,7 +41639,6 @@ TEXT ·mulAvxTwo_6x1_64(SB), $0-88
 	MOVQ  96(DX), R9
 	MOVQ  120(DX), DX
 	MOVQ  out_base+48(FP), R10
-	MOVQ  out_base+48(FP), R10
 	MOVQ  (R10), R10
 	MOVQ  start+72(FP), R11
 
@@ -42194,7 +42163,6 @@ TEXT ·mulAvxTwo_6x1_64Xor(SB), $0-88
 	MOVQ  96(DX), R9
 	MOVQ  120(DX), DX
 	MOVQ  out_base+48(FP), R10
-	MOVQ  out_base+48(FP), R10
 	MOVQ  (R10), R10
 	MOVQ  start+72(FP), R11
 
@@ -42363,7 +42331,6 @@ TEXT ·mulAvxTwo_6x2_64(SB), $0-88
 	MOVQ  96(DX), R9
 	MOVQ  120(DX), DX
 	MOVQ  out_base+48(FP), R10
-	MOVQ  out_base+48(FP), R10
 	MOVQ  (R10), R11
 	MOVQ  24(R10), R10
 	MOVQ  start+72(FP), R12
@@ -43029,7 +42996,6 @@ TEXT ·mulAvxTwo_6x2_64Xor(SB), $0-88
 	MOVQ  96(DX), R9
 	MOVQ  120(DX), DX
 	MOVQ  out_base+48(FP), R10
-	MOVQ  out_base+48(FP), R10
 	MOVQ  (R10), R11
 	MOVQ  24(R10), R10
 	MOVQ  start+72(FP), R12
@@ -43253,7 +43219,6 @@ TEXT ·mulAvxTwo_6x3_64(SB), $0-88
 	MOVQ  96(DX), R9
 	MOVQ  120(DX), DX
 	MOVQ  out_base+48(FP), R10
-	MOVQ  out_base+48(FP), R10
 	MOVQ  (R10), R11
 	MOVQ  24(R10), R12
 	MOVQ  48(R10), R10
@@ -44060,7 +44025,6 @@ TEXT ·mulAvxTwo_6x3_64Xor(SB), $0-88
 	MOVQ  96(DX), R9
 	MOVQ  120(DX), DX
 	MOVQ  out_base+48(FP), R10
-	MOVQ  out_base+48(FP), R10
 	MOVQ  (R10), R11
 	MOVQ  24(R10), R12
 	MOVQ  48(R10), R10
@@ -54644,7 +54608,6 @@ TEXT ·mulAvxTwo_7x1_64(SB), $0-88
 	MOVQ  120(DX), R10
 	MOVQ  144(DX), DX
 	MOVQ  out_base+48(FP), R11
-	MOVQ  out_base+48(FP), R11
 	MOVQ  (R11), R11
 	MOVQ  start+72(FP), R12
 
@@ -55226,7 +55189,6 @@ TEXT ·mulAvxTwo_7x1_64Xor(SB), $0-88
 	MOVQ  120(DX), R10
 	MOVQ  144(DX), DX
 	MOVQ  out_base+48(FP), R11
-	MOVQ  out_base+48(FP), R11
 	MOVQ  (R11), R11
 	MOVQ  start+72(FP), R12
 
@@ -55416,7 +55378,6 @@ TEXT ·mulAvxTwo_7x2_64(SB), $0-88
 	MOVQ  120(DX), R10
 	MOVQ  144(DX), DX
 	MOVQ  out_base+48(FP), R11
-	MOVQ  out_base+48(FP), R11
 	MOVQ  (R11), R12
 	MOVQ  24(R11), R11
 	MOVQ  start+72(FP), R13
@@ -56159,7 +56120,6 @@ TEXT ·mulAvxTwo_7x2_64Xor(SB), $0-88
 	MOVQ  120(DX), R10
 	MOVQ  144(DX), DX
 	MOVQ  out_base+48(FP), R11
-	MOVQ  out_base+48(FP), R11
 	MOVQ  (R11), R12
 	MOVQ  24(R11), R11
 	MOVQ  start+72(FP), R13
@@ -56412,7 +56372,6 @@ TEXT ·mulAvxTwo_7x3_64(SB), $0-88
 	MOVQ  120(DX), R10
 	MOVQ  144(DX), DX
 	MOVQ  out_base+48(FP), R11
-	MOVQ  out_base+48(FP), R11
 	MOVQ  (R11), R12
 	MOVQ  24(R11), R13
 	MOVQ  48(R11), R11
@@ -57316,7 +57275,6 @@ TEXT ·mulAvxTwo_7x3_64Xor(SB), $0-88
 	MOVQ  120(DX), R10
 	MOVQ  144(DX), DX
 	MOVQ  out_base+48(FP), R11
-	MOVQ  out_base+48(FP), R11
 	MOVQ  (R11), R12
 	MOVQ  24(R11), R13
 	MOVQ  48(R11), R11
@@ -69146,7 +69104,6 @@ TEXT ·mulAvxTwo_8x1_64(SB), $0-88
 	MOVQ  144(DX), R11
 	MOVQ  168(DX), DX
 	MOVQ  out_base+48(FP), R12
-	MOVQ  out_base+48(FP), R12
 	MOVQ  (R12), R12
 	MOVQ  start+72(FP), R13
 
@@ -69785,7 +69742,6 @@ TEXT ·mulAvxTwo_8x1_64Xor(SB), $0-88
 	MOVQ  144(DX), R11
 	MOVQ  168(DX), DX
 	MOVQ  out_base+48(FP), R12
-	MOVQ  out_base+48(FP), R12
 	MOVQ  (R12), R12
 	MOVQ  start+72(FP), R13
 
@@ -69996,7 +69952,6 @@ TEXT ·mulAvxTwo_8x2_64(SB), $0-88
 	MOVQ  144(DX), R11
 	MOVQ  168(DX), DX
 	MOVQ  out_base+48(FP), R12
-	MOVQ  out_base+48(FP), R12
 	MOVQ  (R12), R13
 	MOVQ  24(R12), R12
 	MOVQ  start+72(FP), R14
@@ -70816,7 +70771,6 @@ TEXT ·mulAvxTwo_8x2_64Xor(SB), $0-88
 	MOVQ  144(DX), R11
 	MOVQ  168(DX), DX
 	MOVQ  out_base+48(FP), R12
-	MOVQ  out_base+48(FP), R12
 	MOVQ  (R12), R13
 	MOVQ  24(R12), R12
 	MOVQ  start+72(FP), R14
@@ -71098,7 +71052,6 @@ TEXT ·mulAvxTwo_8x3_64(SB), $0-88
 	MOVQ  144(DX), R11
 	MOVQ  168(DX), DX
 	MOVQ  out_base+48(FP), R12
-	MOVQ  out_base+48(FP), R12
 	MOVQ  (R12), R13
 	MOVQ  24(R12), R14
 	MOVQ  48(R12), R12
@@ -72099,7 +72052,6 @@ TEXT ·mulAvxTwo_8x3_64Xor(SB), $0-88
 	MOVQ  144(DX), R11
 	MOVQ  168(DX), DX
 	MOVQ  out_base+48(FP), R12
-	MOVQ  out_base+48(FP), R12
 	MOVQ  (R12), R13
 	MOVQ  24(R12), R14
 	MOVQ  48(R12), R12
@@ -85180,7 +85132,6 @@ TEXT ·mulAvxTwo_9x1_64(SB), $0-88
 	MOVQ  168(DX), R12
 	MOVQ  192(DX), DX
 	MOVQ  out_base+48(FP), R13
-	MOVQ  out_base+48(FP), R13
 	MOVQ  (R13), R13
 	MOVQ  start+72(FP), R14
 
@@ -85876,7 +85827,6 @@ TEXT ·mulAvxTwo_9x1_64Xor(SB), $0-88
 	MOVQ  168(DX), R12
 	MOVQ  192(DX), DX
 	MOVQ  out_base+48(FP), R13
-	MOVQ  out_base+48(FP), R13
 	MOVQ  (R13), R13
 	MOVQ  start+72(FP), R14
 
@@ -86108,7 +86058,6 @@ TEXT ·mulAvxTwo_9x2_64(SB), $0-88
 	MOVQ  168(DX), R12
 	MOVQ  192(DX), DX
 	MOVQ  out_base+48(FP), R13
-	MOVQ  out_base+48(FP), R13
 	MOVQ  (R13), R14
 	MOVQ  24(R13), R13
 	MOVQ  start+72(FP), R15
@@ -87005,7 +86954,6 @@ TEXT ·mulAvxTwo_9x2_64Xor(SB), $0-88
 	MOVQ  168(DX), R12
 	MOVQ  192(DX), DX
 	MOVQ  out_base+48(FP), R13
-	MOVQ  out_base+48(FP), R13
 	MOVQ  (R13), R14
 	MOVQ  24(R13), R13
 	MOVQ  start+72(FP), R15
@@ -87316,7 +87264,6 @@ TEXT ·mulAvxTwo_9x3_64(SB), $8-88
 	MOVQ  168(DX), R12
 	MOVQ  192(DX), DX
 	MOVQ  out_base+48(FP), R13
-	MOVQ  out_base+48(FP), R13
 	MOVQ  (R13), R14
 	MOVQ  24(R13), R15
 	MOVQ  48(R13), R13
@@ -88414,7 +88361,6 @@ TEXT ·mulAvxTwo_9x3_64Xor(SB), $8-88
 	MOVQ  168(DX), R12
 	MOVQ  192(DX), DX
 	MOVQ  out_base+48(FP), R13
-	MOVQ  out_base+48(FP), R13
 	MOVQ  (R13), R14
 	MOVQ  24(R13), R15
 	MOVQ  48(R13), R13
@@ -102755,7 +102701,6 @@ TEXT ·mulAvxTwo_10x1_64(SB), $0-88
 	MOVQ  192(DX), R13
 	MOVQ  216(DX), DX
 	MOVQ  out_base+48(FP), R14
-	MOVQ  out_base+48(FP), R14
 	MOVQ  (R14), R14
 	MOVQ  start+72(FP), R15
 
@@ -103508,7 +103453,6 @@ TEXT ·mulAvxTwo_10x1_64Xor(SB), $0-88
 	MOVQ  192(DX), R13
 	MOVQ  216(DX), DX
 	MOVQ  out_base+48(FP), R14
-	MOVQ  out_base+48(FP), R14
 	MOVQ  (R14), R14
 	MOVQ  start+72(FP), R15
 
@@ -103761,7 +103705,6 @@ TEXT ·mulAvxTwo_10x2_64(SB), $8-88
 	MOVQ  192(DX), R13
 	MOVQ  216(DX), DX
 	MOVQ  out_base+48(FP), R14
-	MOVQ  out_base+48(FP), R14
 	MOVQ  (R14), R15
 	MOVQ  24(R14), R14
 	MOVQ  start+72(FP), BP
@@ -104735,7 +104678,6 @@ TEXT ·mulAvxTwo_10x2_64Xor(SB), $8-88
 	MOVQ  192(DX), R13
 	MOVQ  216(DX), DX
 	MOVQ  out_base+48(FP), R14
-	MOVQ  out_base+48(FP), R14
 	MOVQ  (R14), R15
 	MOVQ  24(R14), R14
 	MOVQ  start+72(FP), BP
@@ -105075,7 +105017,6 @@ TEXT ·mulAvxTwo_10x3_64(SB), $8-88
 	MOVQ  192(AX), R12
 	MOVQ  216(AX), AX
 	MOVQ  out_base+48(FP), R13
-	MOVQ  out_base+48(FP), R13
 	MOVQ  (R13), R14
 	MOVQ  24(R13), R15
 	MOVQ  48(R13), R13
@@ -106284,7 +106225,6 @@ TEXT ·mulAvxTwo_10x3_64Xor(SB), $8-88
 	MOVQ  192(AX), R12
 	MOVQ  216(AX), AX
 	MOVQ  out_base+48(FP), R13
-	MOVQ  out_base+48(FP), R13
 	MOVQ  (R13), R14
 	MOVQ  24(R13), R15
 	MOVQ  48(R13), R13
diff --git a/vendor/github.com/klauspost/reedsolomon/galois_gen_arm64.go b/vendor/github.com/klauspost/reedsolomon/galois_gen_arm64.go
new file mode 100644
index 00000000..2f871903
--- /dev/null
+++ b/vendor/github.com/klauspost/reedsolomon/galois_gen_arm64.go
@@ -0,0 +1,125 @@
+// Code generated by command: go generate gen.go. DO NOT EDIT.
+
+//go:build !noasm && !appengine && !gccgo && !nopshufb
+
+package reedsolomon
+
+//go:noescape
+func mulSve_10x1_64(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x1_64Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x2_64(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x2_64Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x3_64(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x3_64Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x4(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x4Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x5(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x5Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x6(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x6Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x7(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x7Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x8(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x8Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x9(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x9Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x10(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulSve_10x10Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x1_64(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x1_64Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x2_64(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x2_64Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x3_64(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x3_64Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x4(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x4Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x5(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x5Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x6(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x6Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x7(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x7Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x8(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x8Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x9(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x9Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x10(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+
+//go:noescape
+func mulNeon_10x10Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
diff --git a/vendor/github.com/klauspost/reedsolomon/galois_gen_arm64.s b/vendor/github.com/klauspost/reedsolomon/galois_gen_arm64.s
new file mode 100644
index 00000000..335b94c3
--- /dev/null
+++ b/vendor/github.com/klauspost/reedsolomon/galois_gen_arm64.s
@@ -0,0 +1,26958 @@
+// Code generated by command: go generate gen.go. DO NOT EDIT.
+
+//go:build !appengine && !noasm && !nogen && !nopshufb && gc
+
+#include "textflag.h"
+
+// func mulSve_10x1_64(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x1_64(SB), $0-88
+    // Loading no tables to registers
+    // Destination kept in GP registers
+    // Full registers estimated 46 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd346fc00 // lsr x0, x0, #6                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x1_64_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD (R14), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to output
+    WORD $0x8b0f01ce // add x14, x14, x15                           
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd28001ef // mov x15, #15                                
+    WORD $0x05e039e2 // mov z2.d, x15                               
+    WORD $0x05212042 // dup z2.b, z2.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x1_64_loop:
+    // Load and process 64 bytes from input 0 to 1 outputs
+    WORD $0x85804026 // ldr z6, [x1]                                
+    WORD $0x85804425 // ldr z5, [x1, #1, MUL VL]                    
+    WORD $0x91010021 // add x1, x1, #64                             
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85804043 // ldr z3, [x2]                                
+    WORD $0x85804444 // ldr z4, [x2, #1, MUL VL]                    
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33080 // eor z0.d, z4.d, z3.d                        
+    WORD $0x04a530c1 // eor z1.d, z6.d, z5.d                        
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x1_64_store
+
+    // Load and process 64 bytes from input 1 to 1 outputs
+    WORD $0x85804086 // ldr z6, [x4]                                
+    WORD $0x85804485 // ldr z5, [x4, #1, MUL VL]                    
+    WORD $0x91010084 // add x4, x4, #64                             
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85804843 // ldr z3, [x2, #2, MUL VL]                    
+    WORD $0x85804c44 // ldr z4, [x2, #3, MUL VL]                    
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x1_64_store
+
+    // Load and process 64 bytes from input 2 to 1 outputs
+    WORD $0x858040a6 // ldr z6, [x5]                                
+    WORD $0x858044a5 // ldr z5, [x5, #1, MUL VL]                    
+    WORD $0x910100a5 // add x5, x5, #64                             
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85805043 // ldr z3, [x2, #4, MUL VL]                    
+    WORD $0x85805444 // ldr z4, [x2, #5, MUL VL]                    
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x1_64_store
+
+    // Load and process 64 bytes from input 3 to 1 outputs
+    WORD $0x85804106 // ldr z6, [x8]                                
+    WORD $0x85804505 // ldr z5, [x8, #1, MUL VL]                    
+    WORD $0x91010108 // add x8, x8, #64                             
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85805843 // ldr z3, [x2, #6, MUL VL]                    
+    WORD $0x85805c44 // ldr z4, [x2, #7, MUL VL]                    
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x1_64_store
+
+    // Load and process 64 bytes from input 4 to 1 outputs
+    WORD $0x85804126 // ldr z6, [x9]                                
+    WORD $0x85804525 // ldr z5, [x9, #1, MUL VL]                    
+    WORD $0x91010129 // add x9, x9, #64                             
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85814043 // ldr z3, [x2, #8, MUL VL]                    
+    WORD $0x85814444 // ldr z4, [x2, #9, MUL VL]                    
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x1_64_store
+
+    // Load and process 64 bytes from input 5 to 1 outputs
+    WORD $0x85804146 // ldr z6, [x10]                               
+    WORD $0x85804545 // ldr z5, [x10, #1, MUL VL]                   
+    WORD $0x9101014a // add x10, x10, #64                           
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85814843 // ldr z3, [x2, #10, MUL VL]                   
+    WORD $0x85814c44 // ldr z4, [x2, #11, MUL VL]                   
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x1_64_store
+
+    // Load and process 64 bytes from input 6 to 1 outputs
+    WORD $0x85804166 // ldr z6, [x11]                               
+    WORD $0x85804565 // ldr z5, [x11, #1, MUL VL]                   
+    WORD $0x9101016b // add x11, x11, #64                           
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85815043 // ldr z3, [x2, #12, MUL VL]                   
+    WORD $0x85815444 // ldr z4, [x2, #13, MUL VL]                   
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x1_64_store
+
+    // Load and process 64 bytes from input 7 to 1 outputs
+    WORD $0x85804186 // ldr z6, [x12]                               
+    WORD $0x85804585 // ldr z5, [x12, #1, MUL VL]                   
+    WORD $0x9101018c // add x12, x12, #64                           
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85815843 // ldr z3, [x2, #14, MUL VL]                   
+    WORD $0x85815c44 // ldr z4, [x2, #15, MUL VL]                   
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x1_64_store
+
+    // Load and process 64 bytes from input 8 to 1 outputs
+    WORD $0x858041a6 // ldr z6, [x13]                               
+    WORD $0x858045a5 // ldr z5, [x13, #1, MUL VL]                   
+    WORD $0x910101ad // add x13, x13, #64                           
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85824043 // ldr z3, [x2, #16, MUL VL]                   
+    WORD $0x85824444 // ldr z4, [x2, #17, MUL VL]                   
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x1_64_store
+
+    // Load and process 64 bytes from input 9 to 1 outputs
+    WORD $0x85804066 // ldr z6, [x3]                                
+    WORD $0x85804465 // ldr z5, [x3, #1, MUL VL]                    
+    WORD $0x91010063 // add x3, x3, #64                             
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85824843 // ldr z3, [x2, #18, MUL VL]                   
+    WORD $0x85824c44 // ldr z4, [x2, #19, MUL VL]                   
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+
+mulSve_10x1_64_store:
+    // Store 1 outputs
+    WORD $0xe58041c0 // str z0, [x14]                               
+    WORD $0xe58045c1 // str z1, [x14, #1, MUL VL]                   
+    WORD $0x910101ce // add x14, x14, #64                           
+
+    // Prepare for next loop
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x1_64_loop
+
+mulSve_10x1_64_end:
+    RET
+
+// func mulSve_10x1_64Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x1_64Xor(SB), $0-88
+    // Loading no tables to registers
+    // Destination kept in GP registers
+    // Full registers estimated 46 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd346fc00 // lsr x0, x0, #6                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x1_64Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD (R14), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to output
+    WORD $0x8b0f01ce // add x14, x14, x15                           
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd28001ef // mov x15, #15                                
+    WORD $0x05e039e2 // mov z2.d, x15                               
+    WORD $0x05212042 // dup z2.b, z2.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x1_64Xor_loop:
+    // Load 1 outputs
+    WORD $0x858041c0 // ldr z0, [x14]                               
+    WORD $0x858045c1 // ldr z1, [x14, #1, MUL VL]                   
+
+    // Load and process 64 bytes from input 0 to 1 outputs
+    WORD $0x85804026 // ldr z6, [x1]                                
+    WORD $0x85804425 // ldr z5, [x1, #1, MUL VL]                    
+    WORD $0x91010021 // add x1, x1, #64                             
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85804043 // ldr z3, [x2]                                
+    WORD $0x85804444 // ldr z4, [x2, #1, MUL VL]                    
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 1 to 1 outputs
+    WORD $0x85804086 // ldr z6, [x4]                                
+    WORD $0x85804485 // ldr z5, [x4, #1, MUL VL]                    
+    WORD $0x91010084 // add x4, x4, #64                             
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85804843 // ldr z3, [x2, #2, MUL VL]                    
+    WORD $0x85804c44 // ldr z4, [x2, #3, MUL VL]                    
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 2 to 1 outputs
+    WORD $0x858040a6 // ldr z6, [x5]                                
+    WORD $0x858044a5 // ldr z5, [x5, #1, MUL VL]                    
+    WORD $0x910100a5 // add x5, x5, #64                             
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85805043 // ldr z3, [x2, #4, MUL VL]                    
+    WORD $0x85805444 // ldr z4, [x2, #5, MUL VL]                    
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 3 to 1 outputs
+    WORD $0x85804106 // ldr z6, [x8]                                
+    WORD $0x85804505 // ldr z5, [x8, #1, MUL VL]                    
+    WORD $0x91010108 // add x8, x8, #64                             
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85805843 // ldr z3, [x2, #6, MUL VL]                    
+    WORD $0x85805c44 // ldr z4, [x2, #7, MUL VL]                    
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 4 to 1 outputs
+    WORD $0x85804126 // ldr z6, [x9]                                
+    WORD $0x85804525 // ldr z5, [x9, #1, MUL VL]                    
+    WORD $0x91010129 // add x9, x9, #64                             
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85814043 // ldr z3, [x2, #8, MUL VL]                    
+    WORD $0x85814444 // ldr z4, [x2, #9, MUL VL]                    
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 5 to 1 outputs
+    WORD $0x85804146 // ldr z6, [x10]                               
+    WORD $0x85804545 // ldr z5, [x10, #1, MUL VL]                   
+    WORD $0x9101014a // add x10, x10, #64                           
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85814843 // ldr z3, [x2, #10, MUL VL]                   
+    WORD $0x85814c44 // ldr z4, [x2, #11, MUL VL]                   
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 6 to 1 outputs
+    WORD $0x85804166 // ldr z6, [x11]                               
+    WORD $0x85804565 // ldr z5, [x11, #1, MUL VL]                   
+    WORD $0x9101016b // add x11, x11, #64                           
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85815043 // ldr z3, [x2, #12, MUL VL]                   
+    WORD $0x85815444 // ldr z4, [x2, #13, MUL VL]                   
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 7 to 1 outputs
+    WORD $0x85804186 // ldr z6, [x12]                               
+    WORD $0x85804585 // ldr z5, [x12, #1, MUL VL]                   
+    WORD $0x9101018c // add x12, x12, #64                           
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85815843 // ldr z3, [x2, #14, MUL VL]                   
+    WORD $0x85815c44 // ldr z4, [x2, #15, MUL VL]                   
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 8 to 1 outputs
+    WORD $0x858041a6 // ldr z6, [x13]                               
+    WORD $0x858045a5 // ldr z5, [x13, #1, MUL VL]                   
+    WORD $0x910101ad // add x13, x13, #64                           
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85824043 // ldr z3, [x2, #16, MUL VL]                   
+    WORD $0x85824444 // ldr z4, [x2, #17, MUL VL]                   
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 9 to 1 outputs
+    WORD $0x85804066 // ldr z6, [x3]                                
+    WORD $0x85804465 // ldr z5, [x3, #1, MUL VL]                    
+    WORD $0x91010063 // add x3, x3, #64                             
+    WORD $0x04fc94c7 // lsr z7.d, z6.d, #4                          
+    WORD $0x04fc94a8 // lsr z8.d, z5.d, #4                          
+    WORD $0x042230c6 // and z6.d, z6.d, z2.d                        
+    WORD $0x042230a5 // and z5.d, z5.d, z2.d                        
+    WORD $0x042230e7 // and z7.d, z7.d, z2.d                        
+    WORD $0x04223108 // and z8.d, z8.d, z2.d                        
+    WORD $0x85824843 // ldr z3, [x2, #18, MUL VL]                   
+    WORD $0x85824c44 // ldr z4, [x2, #19, MUL VL]                   
+    WORD $0x05253065 // tbl z5.b, z3.b, z5.b                        
+    WORD $0x05263063 // tbl z3.b, z3.b, z6.b                        
+    WORD $0x05283086 // tbl z6.b, z4.b, z8.b                        
+    WORD $0x05273084 // tbl z4.b, z4.b, z7.b                        
+    WORD $0x04a33000 // eor z0.d, z0.d, z3.d                        
+    WORD $0x04a43000 // eor z0.d, z0.d, z4.d                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+
+mulSve_10x1_64Xor_store:
+    // Store 1 outputs
+    WORD $0xe58041c0 // str z0, [x14]                               
+    WORD $0xe58045c1 // str z1, [x14, #1, MUL VL]                   
+    WORD $0x910101ce // add x14, x14, #64                           
+
+    // Prepare for next loop
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x1_64Xor_loop
+
+mulSve_10x1_64Xor_end:
+    RET
+
+// func mulSve_10x2_64(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x2_64(SB), $8-88
+    // Loading no tables to registers
+    // Destination kept in GP registers
+    // Full registers estimated 89 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd346fc00 // lsr x0, x0, #6                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x2_64_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD (R14), R15
+    MOVD 24(R14), R14
+    MOVD start+72(FP), R6
+
+    // Add start offset to output
+    WORD $0x8b0601ef // add x15, x15, x6                            
+    WORD $0x8b0601ce // add x14, x14, x6                            
+
+    // Add start offset to input
+    WORD $0x8b060021 // add x1, x1, x6                              
+    WORD $0x8b060084 // add x4, x4, x6                              
+    WORD $0x8b0600a5 // add x5, x5, x6                              
+    WORD $0x8b060108 // add x8, x8, x6                              
+    WORD $0x8b060129 // add x9, x9, x6                              
+    WORD $0x8b06014a // add x10, x10, x6                            
+    WORD $0x8b06016b // add x11, x11, x6                            
+    WORD $0x8b06018c // add x12, x12, x6                            
+    WORD $0x8b0601ad // add x13, x13, x6                            
+    WORD $0x8b060063 // add x3, x3, x6                              
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c4 // mov z4.d, x6                                
+    WORD $0x05212084 // dup z4.b, z4.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x2_64_loop:
+    // Load and process 64 bytes from input 0 to 2 outputs
+    WORD $0x85804029 // ldr z9, [x1]                                
+    WORD $0x8580442b // ldr z11, [x1, #1, MUL VL]                   
+    WORD $0x91010021 // add x1, x1, #64                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85804045 // ldr z5, [x2]                                
+    WORD $0x85804446 // ldr z6, [x2, #1, MUL VL]                    
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a530c0 // eor z0.d, z6.d, z5.d                        
+    WORD $0x04a73101 // eor z1.d, z8.d, z7.d                        
+    WORD $0x85804845 // ldr z5, [x2, #2, MUL VL]                    
+    WORD $0x85804c46 // ldr z6, [x2, #3, MUL VL]                    
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a530c2 // eor z2.d, z6.d, z5.d                        
+    WORD $0x04a73103 // eor z3.d, z8.d, z7.d                        
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x2_64_store
+
+    // Load and process 64 bytes from input 1 to 2 outputs
+    WORD $0x85804089 // ldr z9, [x4]                                
+    WORD $0x8580448b // ldr z11, [x4, #1, MUL VL]                   
+    WORD $0x91010084 // add x4, x4, #64                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85805045 // ldr z5, [x2, #4, MUL VL]                    
+    WORD $0x85805446 // ldr z6, [x2, #5, MUL VL]                    
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85805845 // ldr z5, [x2, #6, MUL VL]                    
+    WORD $0x85805c46 // ldr z6, [x2, #7, MUL VL]                    
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x2_64_store
+
+    // Load and process 64 bytes from input 2 to 2 outputs
+    WORD $0x858040a9 // ldr z9, [x5]                                
+    WORD $0x858044ab // ldr z11, [x5, #1, MUL VL]                   
+    WORD $0x910100a5 // add x5, x5, #64                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85814045 // ldr z5, [x2, #8, MUL VL]                    
+    WORD $0x85814446 // ldr z6, [x2, #9, MUL VL]                    
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85814845 // ldr z5, [x2, #10, MUL VL]                   
+    WORD $0x85814c46 // ldr z6, [x2, #11, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x2_64_store
+
+    // Load and process 64 bytes from input 3 to 2 outputs
+    WORD $0x85804109 // ldr z9, [x8]                                
+    WORD $0x8580450b // ldr z11, [x8, #1, MUL VL]                   
+    WORD $0x91010108 // add x8, x8, #64                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85815045 // ldr z5, [x2, #12, MUL VL]                   
+    WORD $0x85815446 // ldr z6, [x2, #13, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85815845 // ldr z5, [x2, #14, MUL VL]                   
+    WORD $0x85815c46 // ldr z6, [x2, #15, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x2_64_store
+
+    // Load and process 64 bytes from input 4 to 2 outputs
+    WORD $0x85804129 // ldr z9, [x9]                                
+    WORD $0x8580452b // ldr z11, [x9, #1, MUL VL]                   
+    WORD $0x91010129 // add x9, x9, #64                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85824045 // ldr z5, [x2, #16, MUL VL]                   
+    WORD $0x85824446 // ldr z6, [x2, #17, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85824845 // ldr z5, [x2, #18, MUL VL]                   
+    WORD $0x85824c46 // ldr z6, [x2, #19, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x2_64_store
+
+    // Load and process 64 bytes from input 5 to 2 outputs
+    WORD $0x85804149 // ldr z9, [x10]                               
+    WORD $0x8580454b // ldr z11, [x10, #1, MUL VL]                  
+    WORD $0x9101014a // add x10, x10, #64                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85825045 // ldr z5, [x2, #20, MUL VL]                   
+    WORD $0x85825446 // ldr z6, [x2, #21, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85825845 // ldr z5, [x2, #22, MUL VL]                   
+    WORD $0x85825c46 // ldr z6, [x2, #23, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x2_64_store
+
+    // Load and process 64 bytes from input 6 to 2 outputs
+    WORD $0x85804169 // ldr z9, [x11]                               
+    WORD $0x8580456b // ldr z11, [x11, #1, MUL VL]                  
+    WORD $0x9101016b // add x11, x11, #64                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85834045 // ldr z5, [x2, #24, MUL VL]                   
+    WORD $0x85834446 // ldr z6, [x2, #25, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85834845 // ldr z5, [x2, #26, MUL VL]                   
+    WORD $0x85834c46 // ldr z6, [x2, #27, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x2_64_store
+
+    // Load and process 64 bytes from input 7 to 2 outputs
+    WORD $0x85804189 // ldr z9, [x12]                               
+    WORD $0x8580458b // ldr z11, [x12, #1, MUL VL]                  
+    WORD $0x9101018c // add x12, x12, #64                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85835045 // ldr z5, [x2, #28, MUL VL]                   
+    WORD $0x85835446 // ldr z6, [x2, #29, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85835845 // ldr z5, [x2, #30, MUL VL]                   
+    WORD $0x85835c46 // ldr z6, [x2, #31, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x2_64_store
+
+    // Load and process 64 bytes from input 8 to 2 outputs
+    WORD $0x858041a9 // ldr z9, [x13]                               
+    WORD $0x858045ab // ldr z11, [x13, #1, MUL VL]                  
+    WORD $0x910101ad // add x13, x13, #64                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85844045 // ldr z5, [x2, #32, MUL VL]                   
+    WORD $0x85844446 // ldr z6, [x2, #33, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85844845 // ldr z5, [x2, #34, MUL VL]                   
+    WORD $0x85844c46 // ldr z6, [x2, #35, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x2_64_store
+
+    // Load and process 64 bytes from input 9 to 2 outputs
+    WORD $0x85804069 // ldr z9, [x3]                                
+    WORD $0x8580446b // ldr z11, [x3, #1, MUL VL]                   
+    WORD $0x91010063 // add x3, x3, #64                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85845045 // ldr z5, [x2, #36, MUL VL]                   
+    WORD $0x85845446 // ldr z6, [x2, #37, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85845845 // ldr z5, [x2, #38, MUL VL]                   
+    WORD $0x85845c46 // ldr z6, [x2, #39, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+
+mulSve_10x2_64_store:
+    // Store 2 outputs
+    WORD $0xe58041e0 // str z0, [x15]                               
+    WORD $0xe58045e1 // str z1, [x15, #1, MUL VL]                   
+    WORD $0x910101ef // add x15, x15, #64                           
+    WORD $0xe58041c2 // str z2, [x14]                               
+    WORD $0xe58045c3 // str z3, [x14, #1, MUL VL]                   
+    WORD $0x910101ce // add x14, x14, #64                           
+
+    // Prepare for next loop
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x2_64_loop
+
+mulSve_10x2_64_end:
+    RET
+
+// func mulSve_10x2_64Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x2_64Xor(SB), $8-88
+    // Loading no tables to registers
+    // Destination kept in GP registers
+    // Full registers estimated 89 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd346fc00 // lsr x0, x0, #6                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x2_64Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD (R14), R15
+    MOVD 24(R14), R14
+    MOVD start+72(FP), R6
+
+    // Add start offset to output
+    WORD $0x8b0601ef // add x15, x15, x6                            
+    WORD $0x8b0601ce // add x14, x14, x6                            
+
+    // Add start offset to input
+    WORD $0x8b060021 // add x1, x1, x6                              
+    WORD $0x8b060084 // add x4, x4, x6                              
+    WORD $0x8b0600a5 // add x5, x5, x6                              
+    WORD $0x8b060108 // add x8, x8, x6                              
+    WORD $0x8b060129 // add x9, x9, x6                              
+    WORD $0x8b06014a // add x10, x10, x6                            
+    WORD $0x8b06016b // add x11, x11, x6                            
+    WORD $0x8b06018c // add x12, x12, x6                            
+    WORD $0x8b0601ad // add x13, x13, x6                            
+    WORD $0x8b060063 // add x3, x3, x6                              
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c4 // mov z4.d, x6                                
+    WORD $0x05212084 // dup z4.b, z4.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x2_64Xor_loop:
+    // Load 2 outputs
+    WORD $0x858041e0 // ldr z0, [x15]                               
+    WORD $0x858045e1 // ldr z1, [x15, #1, MUL VL]                   
+    WORD $0x858041c2 // ldr z2, [x14]                               
+    WORD $0x858045c3 // ldr z3, [x14, #1, MUL VL]                   
+
+    // Load and process 64 bytes from input 0 to 2 outputs
+    WORD $0x85804029 // ldr z9, [x1]                                
+    WORD $0x8580442b // ldr z11, [x1, #1, MUL VL]                   
+    WORD $0x91010021 // add x1, x1, #64                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85804045 // ldr z5, [x2]                                
+    WORD $0x85804446 // ldr z6, [x2, #1, MUL VL]                    
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85804845 // ldr z5, [x2, #2, MUL VL]                    
+    WORD $0x85804c46 // ldr z6, [x2, #3, MUL VL]                    
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 1 to 2 outputs
+    WORD $0x85804089 // ldr z9, [x4]                                
+    WORD $0x8580448b // ldr z11, [x4, #1, MUL VL]                   
+    WORD $0x91010084 // add x4, x4, #64                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85805045 // ldr z5, [x2, #4, MUL VL]                    
+    WORD $0x85805446 // ldr z6, [x2, #5, MUL VL]                    
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85805845 // ldr z5, [x2, #6, MUL VL]                    
+    WORD $0x85805c46 // ldr z6, [x2, #7, MUL VL]                    
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 2 to 2 outputs
+    WORD $0x858040a9 // ldr z9, [x5]                                
+    WORD $0x858044ab // ldr z11, [x5, #1, MUL VL]                   
+    WORD $0x910100a5 // add x5, x5, #64                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85814045 // ldr z5, [x2, #8, MUL VL]                    
+    WORD $0x85814446 // ldr z6, [x2, #9, MUL VL]                    
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85814845 // ldr z5, [x2, #10, MUL VL]                   
+    WORD $0x85814c46 // ldr z6, [x2, #11, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 3 to 2 outputs
+    WORD $0x85804109 // ldr z9, [x8]                                
+    WORD $0x8580450b // ldr z11, [x8, #1, MUL VL]                   
+    WORD $0x91010108 // add x8, x8, #64                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85815045 // ldr z5, [x2, #12, MUL VL]                   
+    WORD $0x85815446 // ldr z6, [x2, #13, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85815845 // ldr z5, [x2, #14, MUL VL]                   
+    WORD $0x85815c46 // ldr z6, [x2, #15, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 4 to 2 outputs
+    WORD $0x85804129 // ldr z9, [x9]                                
+    WORD $0x8580452b // ldr z11, [x9, #1, MUL VL]                   
+    WORD $0x91010129 // add x9, x9, #64                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85824045 // ldr z5, [x2, #16, MUL VL]                   
+    WORD $0x85824446 // ldr z6, [x2, #17, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85824845 // ldr z5, [x2, #18, MUL VL]                   
+    WORD $0x85824c46 // ldr z6, [x2, #19, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 5 to 2 outputs
+    WORD $0x85804149 // ldr z9, [x10]                               
+    WORD $0x8580454b // ldr z11, [x10, #1, MUL VL]                  
+    WORD $0x9101014a // add x10, x10, #64                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85825045 // ldr z5, [x2, #20, MUL VL]                   
+    WORD $0x85825446 // ldr z6, [x2, #21, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85825845 // ldr z5, [x2, #22, MUL VL]                   
+    WORD $0x85825c46 // ldr z6, [x2, #23, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 6 to 2 outputs
+    WORD $0x85804169 // ldr z9, [x11]                               
+    WORD $0x8580456b // ldr z11, [x11, #1, MUL VL]                  
+    WORD $0x9101016b // add x11, x11, #64                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85834045 // ldr z5, [x2, #24, MUL VL]                   
+    WORD $0x85834446 // ldr z6, [x2, #25, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85834845 // ldr z5, [x2, #26, MUL VL]                   
+    WORD $0x85834c46 // ldr z6, [x2, #27, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 7 to 2 outputs
+    WORD $0x85804189 // ldr z9, [x12]                               
+    WORD $0x8580458b // ldr z11, [x12, #1, MUL VL]                  
+    WORD $0x9101018c // add x12, x12, #64                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85835045 // ldr z5, [x2, #28, MUL VL]                   
+    WORD $0x85835446 // ldr z6, [x2, #29, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85835845 // ldr z5, [x2, #30, MUL VL]                   
+    WORD $0x85835c46 // ldr z6, [x2, #31, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 8 to 2 outputs
+    WORD $0x858041a9 // ldr z9, [x13]                               
+    WORD $0x858045ab // ldr z11, [x13, #1, MUL VL]                  
+    WORD $0x910101ad // add x13, x13, #64                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85844045 // ldr z5, [x2, #32, MUL VL]                   
+    WORD $0x85844446 // ldr z6, [x2, #33, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85844845 // ldr z5, [x2, #34, MUL VL]                   
+    WORD $0x85844c46 // ldr z6, [x2, #35, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 9 to 2 outputs
+    WORD $0x85804069 // ldr z9, [x3]                                
+    WORD $0x8580446b // ldr z11, [x3, #1, MUL VL]                   
+    WORD $0x91010063 // add x3, x3, #64                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04243129 // and z9.d, z9.d, z4.d                        
+    WORD $0x0424316b // and z11.d, z11.d, z4.d                      
+    WORD $0x0424314a // and z10.d, z10.d, z4.d                      
+    WORD $0x0424318c // and z12.d, z12.d, z4.d                      
+    WORD $0x85845045 // ldr z5, [x2, #36, MUL VL]                   
+    WORD $0x85845446 // ldr z6, [x2, #37, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85845845 // ldr z5, [x2, #38, MUL VL]                   
+    WORD $0x85845c46 // ldr z6, [x2, #39, MUL VL]                   
+    WORD $0x052b30a7 // tbl z7.b, z5.b, z11.b                       
+    WORD $0x052930a5 // tbl z5.b, z5.b, z9.b                        
+    WORD $0x052c30c8 // tbl z8.b, z6.b, z12.b                       
+    WORD $0x052a30c6 // tbl z6.b, z6.b, z10.b                       
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+
+mulSve_10x2_64Xor_store:
+    // Store 2 outputs
+    WORD $0xe58041e0 // str z0, [x15]                               
+    WORD $0xe58045e1 // str z1, [x15, #1, MUL VL]                   
+    WORD $0x910101ef // add x15, x15, #64                           
+    WORD $0xe58041c2 // str z2, [x14]                               
+    WORD $0xe58045c3 // str z3, [x14, #1, MUL VL]                   
+    WORD $0x910101ce // add x14, x14, #64                           
+
+    // Prepare for next loop
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x2_64Xor_loop
+
+mulSve_10x2_64Xor_end:
+    RET
+
+// func mulSve_10x3_64(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x3_64(SB), $8-88
+    // Loading no tables to registers
+    // Destination kept in GP registers
+    // Full registers estimated 130 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd346fc00 // lsr x0, x0, #6                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x3_64_end
+    MOVD in_base+24(FP), R0
+    MOVD (R0), R3
+    MOVD 24(R0), R1
+    MOVD 48(R0), R4
+    MOVD 72(R0), R5
+    MOVD 96(R0), R8
+    MOVD 120(R0), R9
+    MOVD 144(R0), R10
+    MOVD 168(R0), R11
+    MOVD 192(R0), R12
+    MOVD 216(R0), R0
+    MOVD out_base+48(FP), R13
+    MOVD (R13), R14
+    MOVD 24(R13), R15
+    MOVD 48(R13), R13
+    MOVD start+72(FP), R6
+
+    // Add start offset to output
+    WORD $0x8b0601ce // add x14, x14, x6                            
+    WORD $0x8b0601ef // add x15, x15, x6                            
+    WORD $0x8b0601ad // add x13, x13, x6                            
+
+    // Add start offset to input
+    WORD $0x8b060063 // add x3, x3, x6                              
+    WORD $0x8b060021 // add x1, x1, x6                              
+    WORD $0x8b060084 // add x4, x4, x6                              
+    WORD $0x8b0600a5 // add x5, x5, x6                              
+    WORD $0x8b060108 // add x8, x8, x6                              
+    WORD $0x8b060129 // add x9, x9, x6                              
+    WORD $0x8b06014a // add x10, x10, x6                            
+    WORD $0x8b06016b // add x11, x11, x6                            
+    WORD $0x8b06018c // add x12, x12, x6                            
+    WORD $0x8b060000 // add x0, x0, x6                              
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c6 // mov z6.d, x6                                
+    WORD $0x052120c6 // dup z6.b, z6.b[0]                           
+
+    // Reload length to save a register
+    MOVD n+80(FP), R6
+    WORD $0xd346fcc6 // lsr x6, x6, #6                              
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x3_64_loop:
+    // Load and process 64 bytes from input 0 to 3 outputs
+    WORD $0x8580406b // ldr z11, [x3]                               
+    WORD $0x8580446d // ldr z13, [x3, #1, MUL VL]                   
+    WORD $0x91010063 // add x3, x3, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85804047 // ldr z7, [x2]                                
+    WORD $0x85804448 // ldr z8, [x2, #1, MUL VL]                    
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73100 // eor z0.d, z8.d, z7.d                        
+    WORD $0x04a93141 // eor z1.d, z10.d, z9.d                       
+    WORD $0x85804847 // ldr z7, [x2, #2, MUL VL]                    
+    WORD $0x85804c48 // ldr z8, [x2, #3, MUL VL]                    
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73102 // eor z2.d, z8.d, z7.d                        
+    WORD $0x04a93143 // eor z3.d, z10.d, z9.d                       
+    WORD $0x85805047 // ldr z7, [x2, #4, MUL VL]                    
+    WORD $0x85805448 // ldr z8, [x2, #5, MUL VL]                    
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73104 // eor z4.d, z8.d, z7.d                        
+    WORD $0x04a93145 // eor z5.d, z10.d, z9.d                       
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x3_64_store
+
+    // Load and process 64 bytes from input 1 to 3 outputs
+    WORD $0x8580402b // ldr z11, [x1]                               
+    WORD $0x8580442d // ldr z13, [x1, #1, MUL VL]                   
+    WORD $0x91010021 // add x1, x1, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85805847 // ldr z7, [x2, #6, MUL VL]                    
+    WORD $0x85805c48 // ldr z8, [x2, #7, MUL VL]                    
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85814047 // ldr z7, [x2, #8, MUL VL]                    
+    WORD $0x85814448 // ldr z8, [x2, #9, MUL VL]                    
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85814847 // ldr z7, [x2, #10, MUL VL]                   
+    WORD $0x85814c48 // ldr z8, [x2, #11, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x3_64_store
+
+    // Load and process 64 bytes from input 2 to 3 outputs
+    WORD $0x8580408b // ldr z11, [x4]                               
+    WORD $0x8580448d // ldr z13, [x4, #1, MUL VL]                   
+    WORD $0x91010084 // add x4, x4, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85815047 // ldr z7, [x2, #12, MUL VL]                   
+    WORD $0x85815448 // ldr z8, [x2, #13, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85815847 // ldr z7, [x2, #14, MUL VL]                   
+    WORD $0x85815c48 // ldr z8, [x2, #15, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85824047 // ldr z7, [x2, #16, MUL VL]                   
+    WORD $0x85824448 // ldr z8, [x2, #17, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x3_64_store
+
+    // Load and process 64 bytes from input 3 to 3 outputs
+    WORD $0x858040ab // ldr z11, [x5]                               
+    WORD $0x858044ad // ldr z13, [x5, #1, MUL VL]                   
+    WORD $0x910100a5 // add x5, x5, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85824847 // ldr z7, [x2, #18, MUL VL]                   
+    WORD $0x85824c48 // ldr z8, [x2, #19, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85825047 // ldr z7, [x2, #20, MUL VL]                   
+    WORD $0x85825448 // ldr z8, [x2, #21, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85825847 // ldr z7, [x2, #22, MUL VL]                   
+    WORD $0x85825c48 // ldr z8, [x2, #23, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x3_64_store
+
+    // Load and process 64 bytes from input 4 to 3 outputs
+    WORD $0x8580410b // ldr z11, [x8]                               
+    WORD $0x8580450d // ldr z13, [x8, #1, MUL VL]                   
+    WORD $0x91010108 // add x8, x8, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85834047 // ldr z7, [x2, #24, MUL VL]                   
+    WORD $0x85834448 // ldr z8, [x2, #25, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85834847 // ldr z7, [x2, #26, MUL VL]                   
+    WORD $0x85834c48 // ldr z8, [x2, #27, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85835047 // ldr z7, [x2, #28, MUL VL]                   
+    WORD $0x85835448 // ldr z8, [x2, #29, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x3_64_store
+
+    // Load and process 64 bytes from input 5 to 3 outputs
+    WORD $0x8580412b // ldr z11, [x9]                               
+    WORD $0x8580452d // ldr z13, [x9, #1, MUL VL]                   
+    WORD $0x91010129 // add x9, x9, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85835847 // ldr z7, [x2, #30, MUL VL]                   
+    WORD $0x85835c48 // ldr z8, [x2, #31, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85844047 // ldr z7, [x2, #32, MUL VL]                   
+    WORD $0x85844448 // ldr z8, [x2, #33, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85844847 // ldr z7, [x2, #34, MUL VL]                   
+    WORD $0x85844c48 // ldr z8, [x2, #35, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x3_64_store
+
+    // Load and process 64 bytes from input 6 to 3 outputs
+    WORD $0x8580414b // ldr z11, [x10]                              
+    WORD $0x8580454d // ldr z13, [x10, #1, MUL VL]                  
+    WORD $0x9101014a // add x10, x10, #64                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85845047 // ldr z7, [x2, #36, MUL VL]                   
+    WORD $0x85845448 // ldr z8, [x2, #37, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85845847 // ldr z7, [x2, #38, MUL VL]                   
+    WORD $0x85845c48 // ldr z8, [x2, #39, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85854047 // ldr z7, [x2, #40, MUL VL]                   
+    WORD $0x85854448 // ldr z8, [x2, #41, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x3_64_store
+
+    // Load and process 64 bytes from input 7 to 3 outputs
+    WORD $0x8580416b // ldr z11, [x11]                              
+    WORD $0x8580456d // ldr z13, [x11, #1, MUL VL]                  
+    WORD $0x9101016b // add x11, x11, #64                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85854847 // ldr z7, [x2, #42, MUL VL]                   
+    WORD $0x85854c48 // ldr z8, [x2, #43, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85855047 // ldr z7, [x2, #44, MUL VL]                   
+    WORD $0x85855448 // ldr z8, [x2, #45, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85855847 // ldr z7, [x2, #46, MUL VL]                   
+    WORD $0x85855c48 // ldr z8, [x2, #47, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x3_64_store
+
+    // Load and process 64 bytes from input 8 to 3 outputs
+    WORD $0x8580418b // ldr z11, [x12]                              
+    WORD $0x8580458d // ldr z13, [x12, #1, MUL VL]                  
+    WORD $0x9101018c // add x12, x12, #64                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85864047 // ldr z7, [x2, #48, MUL VL]                   
+    WORD $0x85864448 // ldr z8, [x2, #49, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85864847 // ldr z7, [x2, #50, MUL VL]                   
+    WORD $0x85864c48 // ldr z8, [x2, #51, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85865047 // ldr z7, [x2, #52, MUL VL]                   
+    WORD $0x85865448 // ldr z8, [x2, #53, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x3_64_store
+
+    // Load and process 64 bytes from input 9 to 3 outputs
+    WORD $0x8580400b // ldr z11, [x0]                               
+    WORD $0x8580440d // ldr z13, [x0, #1, MUL VL]                   
+    WORD $0x91010000 // add x0, x0, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85865847 // ldr z7, [x2, #54, MUL VL]                   
+    WORD $0x85865c48 // ldr z8, [x2, #55, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85874047 // ldr z7, [x2, #56, MUL VL]                   
+    WORD $0x85874448 // ldr z8, [x2, #57, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85874847 // ldr z7, [x2, #58, MUL VL]                   
+    WORD $0x85874c48 // ldr z8, [x2, #59, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+
+mulSve_10x3_64_store:
+    // Store 3 outputs
+    WORD $0xe58041c0 // str z0, [x14]                               
+    WORD $0xe58045c1 // str z1, [x14, #1, MUL VL]                   
+    WORD $0x910101ce // add x14, x14, #64                           
+    WORD $0xe58041e2 // str z2, [x15]                               
+    WORD $0xe58045e3 // str z3, [x15, #1, MUL VL]                   
+    WORD $0x910101ef // add x15, x15, #64                           
+    WORD $0xe58041a4 // str z4, [x13]                               
+    WORD $0xe58045a5 // str z5, [x13, #1, MUL VL]                   
+    WORD $0x910101ad // add x13, x13, #64                           
+
+    // Prepare for next loop
+    WORD $0xf10004c6 // subs x6, x6, #1                             
+    BNE  mulSve_10x3_64_loop
+
+mulSve_10x3_64_end:
+    RET
+
+// func mulSve_10x3_64Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x3_64Xor(SB), $8-88
+    // Loading no tables to registers
+    // Destination kept in GP registers
+    // Full registers estimated 130 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd346fc00 // lsr x0, x0, #6                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x3_64Xor_end
+    MOVD in_base+24(FP), R0
+    MOVD (R0), R3
+    MOVD 24(R0), R1
+    MOVD 48(R0), R4
+    MOVD 72(R0), R5
+    MOVD 96(R0), R8
+    MOVD 120(R0), R9
+    MOVD 144(R0), R10
+    MOVD 168(R0), R11
+    MOVD 192(R0), R12
+    MOVD 216(R0), R0
+    MOVD out_base+48(FP), R13
+    MOVD (R13), R14
+    MOVD 24(R13), R15
+    MOVD 48(R13), R13
+    MOVD start+72(FP), R6
+
+    // Add start offset to output
+    WORD $0x8b0601ce // add x14, x14, x6                            
+    WORD $0x8b0601ef // add x15, x15, x6                            
+    WORD $0x8b0601ad // add x13, x13, x6                            
+
+    // Add start offset to input
+    WORD $0x8b060063 // add x3, x3, x6                              
+    WORD $0x8b060021 // add x1, x1, x6                              
+    WORD $0x8b060084 // add x4, x4, x6                              
+    WORD $0x8b0600a5 // add x5, x5, x6                              
+    WORD $0x8b060108 // add x8, x8, x6                              
+    WORD $0x8b060129 // add x9, x9, x6                              
+    WORD $0x8b06014a // add x10, x10, x6                            
+    WORD $0x8b06016b // add x11, x11, x6                            
+    WORD $0x8b06018c // add x12, x12, x6                            
+    WORD $0x8b060000 // add x0, x0, x6                              
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c6 // mov z6.d, x6                                
+    WORD $0x052120c6 // dup z6.b, z6.b[0]                           
+
+    // Reload length to save a register
+    MOVD n+80(FP), R6
+    WORD $0xd346fcc6 // lsr x6, x6, #6                              
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x3_64Xor_loop:
+    // Load 3 outputs
+    WORD $0x858041c0 // ldr z0, [x14]                               
+    WORD $0x858045c1 // ldr z1, [x14, #1, MUL VL]                   
+    WORD $0x858041e2 // ldr z2, [x15]                               
+    WORD $0x858045e3 // ldr z3, [x15, #1, MUL VL]                   
+    WORD $0x858041a4 // ldr z4, [x13]                               
+    WORD $0x858045a5 // ldr z5, [x13, #1, MUL VL]                   
+
+    // Load and process 64 bytes from input 0 to 3 outputs
+    WORD $0x8580406b // ldr z11, [x3]                               
+    WORD $0x8580446d // ldr z13, [x3, #1, MUL VL]                   
+    WORD $0x91010063 // add x3, x3, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85804047 // ldr z7, [x2]                                
+    WORD $0x85804448 // ldr z8, [x2, #1, MUL VL]                    
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85804847 // ldr z7, [x2, #2, MUL VL]                    
+    WORD $0x85804c48 // ldr z8, [x2, #3, MUL VL]                    
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85805047 // ldr z7, [x2, #4, MUL VL]                    
+    WORD $0x85805448 // ldr z8, [x2, #5, MUL VL]                    
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 1 to 3 outputs
+    WORD $0x8580402b // ldr z11, [x1]                               
+    WORD $0x8580442d // ldr z13, [x1, #1, MUL VL]                   
+    WORD $0x91010021 // add x1, x1, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85805847 // ldr z7, [x2, #6, MUL VL]                    
+    WORD $0x85805c48 // ldr z8, [x2, #7, MUL VL]                    
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85814047 // ldr z7, [x2, #8, MUL VL]                    
+    WORD $0x85814448 // ldr z8, [x2, #9, MUL VL]                    
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85814847 // ldr z7, [x2, #10, MUL VL]                   
+    WORD $0x85814c48 // ldr z8, [x2, #11, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 2 to 3 outputs
+    WORD $0x8580408b // ldr z11, [x4]                               
+    WORD $0x8580448d // ldr z13, [x4, #1, MUL VL]                   
+    WORD $0x91010084 // add x4, x4, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85815047 // ldr z7, [x2, #12, MUL VL]                   
+    WORD $0x85815448 // ldr z8, [x2, #13, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85815847 // ldr z7, [x2, #14, MUL VL]                   
+    WORD $0x85815c48 // ldr z8, [x2, #15, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85824047 // ldr z7, [x2, #16, MUL VL]                   
+    WORD $0x85824448 // ldr z8, [x2, #17, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 3 to 3 outputs
+    WORD $0x858040ab // ldr z11, [x5]                               
+    WORD $0x858044ad // ldr z13, [x5, #1, MUL VL]                   
+    WORD $0x910100a5 // add x5, x5, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85824847 // ldr z7, [x2, #18, MUL VL]                   
+    WORD $0x85824c48 // ldr z8, [x2, #19, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85825047 // ldr z7, [x2, #20, MUL VL]                   
+    WORD $0x85825448 // ldr z8, [x2, #21, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85825847 // ldr z7, [x2, #22, MUL VL]                   
+    WORD $0x85825c48 // ldr z8, [x2, #23, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 4 to 3 outputs
+    WORD $0x8580410b // ldr z11, [x8]                               
+    WORD $0x8580450d // ldr z13, [x8, #1, MUL VL]                   
+    WORD $0x91010108 // add x8, x8, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85834047 // ldr z7, [x2, #24, MUL VL]                   
+    WORD $0x85834448 // ldr z8, [x2, #25, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85834847 // ldr z7, [x2, #26, MUL VL]                   
+    WORD $0x85834c48 // ldr z8, [x2, #27, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85835047 // ldr z7, [x2, #28, MUL VL]                   
+    WORD $0x85835448 // ldr z8, [x2, #29, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 5 to 3 outputs
+    WORD $0x8580412b // ldr z11, [x9]                               
+    WORD $0x8580452d // ldr z13, [x9, #1, MUL VL]                   
+    WORD $0x91010129 // add x9, x9, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85835847 // ldr z7, [x2, #30, MUL VL]                   
+    WORD $0x85835c48 // ldr z8, [x2, #31, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85844047 // ldr z7, [x2, #32, MUL VL]                   
+    WORD $0x85844448 // ldr z8, [x2, #33, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85844847 // ldr z7, [x2, #34, MUL VL]                   
+    WORD $0x85844c48 // ldr z8, [x2, #35, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 6 to 3 outputs
+    WORD $0x8580414b // ldr z11, [x10]                              
+    WORD $0x8580454d // ldr z13, [x10, #1, MUL VL]                  
+    WORD $0x9101014a // add x10, x10, #64                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85845047 // ldr z7, [x2, #36, MUL VL]                   
+    WORD $0x85845448 // ldr z8, [x2, #37, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85845847 // ldr z7, [x2, #38, MUL VL]                   
+    WORD $0x85845c48 // ldr z8, [x2, #39, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85854047 // ldr z7, [x2, #40, MUL VL]                   
+    WORD $0x85854448 // ldr z8, [x2, #41, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 7 to 3 outputs
+    WORD $0x8580416b // ldr z11, [x11]                              
+    WORD $0x8580456d // ldr z13, [x11, #1, MUL VL]                  
+    WORD $0x9101016b // add x11, x11, #64                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85854847 // ldr z7, [x2, #42, MUL VL]                   
+    WORD $0x85854c48 // ldr z8, [x2, #43, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85855047 // ldr z7, [x2, #44, MUL VL]                   
+    WORD $0x85855448 // ldr z8, [x2, #45, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85855847 // ldr z7, [x2, #46, MUL VL]                   
+    WORD $0x85855c48 // ldr z8, [x2, #47, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 8 to 3 outputs
+    WORD $0x8580418b // ldr z11, [x12]                              
+    WORD $0x8580458d // ldr z13, [x12, #1, MUL VL]                  
+    WORD $0x9101018c // add x12, x12, #64                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85864047 // ldr z7, [x2, #48, MUL VL]                   
+    WORD $0x85864448 // ldr z8, [x2, #49, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85864847 // ldr z7, [x2, #50, MUL VL]                   
+    WORD $0x85864c48 // ldr z8, [x2, #51, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85865047 // ldr z7, [x2, #52, MUL VL]                   
+    WORD $0x85865448 // ldr z8, [x2, #53, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 9 to 3 outputs
+    WORD $0x8580400b // ldr z11, [x0]                               
+    WORD $0x8580440d // ldr z13, [x0, #1, MUL VL]                   
+    WORD $0x91010000 // add x0, x0, #64                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x0426316b // and z11.d, z11.d, z6.d                      
+    WORD $0x042631ad // and z13.d, z13.d, z6.d                      
+    WORD $0x0426318c // and z12.d, z12.d, z6.d                      
+    WORD $0x042631ce // and z14.d, z14.d, z6.d                      
+    WORD $0x85865847 // ldr z7, [x2, #54, MUL VL]                   
+    WORD $0x85865c48 // ldr z8, [x2, #55, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85874047 // ldr z7, [x2, #56, MUL VL]                   
+    WORD $0x85874448 // ldr z8, [x2, #57, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85874847 // ldr z7, [x2, #58, MUL VL]                   
+    WORD $0x85874c48 // ldr z8, [x2, #59, MUL VL]                   
+    WORD $0x052d30e9 // tbl z9.b, z7.b, z13.b                       
+    WORD $0x052b30e7 // tbl z7.b, z7.b, z11.b                       
+    WORD $0x052e310a // tbl z10.b, z8.b, z14.b                      
+    WORD $0x052c3108 // tbl z8.b, z8.b, z12.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+
+mulSve_10x3_64Xor_store:
+    // Store 3 outputs
+    WORD $0xe58041c0 // str z0, [x14]                               
+    WORD $0xe58045c1 // str z1, [x14, #1, MUL VL]                   
+    WORD $0x910101ce // add x14, x14, #64                           
+    WORD $0xe58041e2 // str z2, [x15]                               
+    WORD $0xe58045e3 // str z3, [x15, #1, MUL VL]                   
+    WORD $0x910101ef // add x15, x15, #64                           
+    WORD $0xe58041a4 // str z4, [x13]                               
+    WORD $0xe58045a5 // str z5, [x13, #1, MUL VL]                   
+    WORD $0x910101ad // add x13, x13, #64                           
+
+    // Prepare for next loop
+    WORD $0xf10004c6 // subs x6, x6, #1                             
+    BNE  mulSve_10x3_64Xor_loop
+
+mulSve_10x3_64Xor_end:
+    RET
+
+// func mulSve_10x4(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x4(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 89 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x4_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c4 // mov z4.d, x6                                
+    WORD $0x05212084 // dup z4.b, z4.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x4_loop:
+    // Load and process 32 bytes from input 0 to 4 outputs
+    WORD $0x85804027 // ldr z7, [x1]                                
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85804045 // ldr z5, [x2]                                
+    WORD $0x85804446 // ldr z6, [x2, #1, MUL VL]                    
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a530c0 // eor z0.d, z6.d, z5.d                        
+    WORD $0x85804845 // ldr z5, [x2, #2, MUL VL]                    
+    WORD $0x85804c46 // ldr z6, [x2, #3, MUL VL]                    
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a530c1 // eor z1.d, z6.d, z5.d                        
+    WORD $0x85805045 // ldr z5, [x2, #4, MUL VL]                    
+    WORD $0x85805446 // ldr z6, [x2, #5, MUL VL]                    
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a530c2 // eor z2.d, z6.d, z5.d                        
+    WORD $0x85805845 // ldr z5, [x2, #6, MUL VL]                    
+    WORD $0x85805c46 // ldr z6, [x2, #7, MUL VL]                    
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a530c3 // eor z3.d, z6.d, z5.d                        
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x4_store
+
+    // Load and process 32 bytes from input 1 to 4 outputs
+    WORD $0x85804087 // ldr z7, [x4]                                
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85814045 // ldr z5, [x2, #8, MUL VL]                    
+    WORD $0x85814446 // ldr z6, [x2, #9, MUL VL]                    
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85814845 // ldr z5, [x2, #10, MUL VL]                   
+    WORD $0x85814c46 // ldr z6, [x2, #11, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85815045 // ldr z5, [x2, #12, MUL VL]                   
+    WORD $0x85815446 // ldr z6, [x2, #13, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85815845 // ldr z5, [x2, #14, MUL VL]                   
+    WORD $0x85815c46 // ldr z6, [x2, #15, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x4_store
+
+    // Load and process 32 bytes from input 2 to 4 outputs
+    WORD $0x858040a7 // ldr z7, [x5]                                
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85824045 // ldr z5, [x2, #16, MUL VL]                   
+    WORD $0x85824446 // ldr z6, [x2, #17, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85824845 // ldr z5, [x2, #18, MUL VL]                   
+    WORD $0x85824c46 // ldr z6, [x2, #19, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85825045 // ldr z5, [x2, #20, MUL VL]                   
+    WORD $0x85825446 // ldr z6, [x2, #21, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85825845 // ldr z5, [x2, #22, MUL VL]                   
+    WORD $0x85825c46 // ldr z6, [x2, #23, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x4_store
+
+    // Load and process 32 bytes from input 3 to 4 outputs
+    WORD $0x85804107 // ldr z7, [x8]                                
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85834045 // ldr z5, [x2, #24, MUL VL]                   
+    WORD $0x85834446 // ldr z6, [x2, #25, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85834845 // ldr z5, [x2, #26, MUL VL]                   
+    WORD $0x85834c46 // ldr z6, [x2, #27, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85835045 // ldr z5, [x2, #28, MUL VL]                   
+    WORD $0x85835446 // ldr z6, [x2, #29, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85835845 // ldr z5, [x2, #30, MUL VL]                   
+    WORD $0x85835c46 // ldr z6, [x2, #31, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x4_store
+
+    // Load and process 32 bytes from input 4 to 4 outputs
+    WORD $0x85804127 // ldr z7, [x9]                                
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85844045 // ldr z5, [x2, #32, MUL VL]                   
+    WORD $0x85844446 // ldr z6, [x2, #33, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85844845 // ldr z5, [x2, #34, MUL VL]                   
+    WORD $0x85844c46 // ldr z6, [x2, #35, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85845045 // ldr z5, [x2, #36, MUL VL]                   
+    WORD $0x85845446 // ldr z6, [x2, #37, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85845845 // ldr z5, [x2, #38, MUL VL]                   
+    WORD $0x85845c46 // ldr z6, [x2, #39, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x4_store
+
+    // Load and process 32 bytes from input 5 to 4 outputs
+    WORD $0x85804147 // ldr z7, [x10]                               
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85854045 // ldr z5, [x2, #40, MUL VL]                   
+    WORD $0x85854446 // ldr z6, [x2, #41, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85854845 // ldr z5, [x2, #42, MUL VL]                   
+    WORD $0x85854c46 // ldr z6, [x2, #43, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85855045 // ldr z5, [x2, #44, MUL VL]                   
+    WORD $0x85855446 // ldr z6, [x2, #45, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85855845 // ldr z5, [x2, #46, MUL VL]                   
+    WORD $0x85855c46 // ldr z6, [x2, #47, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x4_store
+
+    // Load and process 32 bytes from input 6 to 4 outputs
+    WORD $0x85804167 // ldr z7, [x11]                               
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85864045 // ldr z5, [x2, #48, MUL VL]                   
+    WORD $0x85864446 // ldr z6, [x2, #49, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85864845 // ldr z5, [x2, #50, MUL VL]                   
+    WORD $0x85864c46 // ldr z6, [x2, #51, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85865045 // ldr z5, [x2, #52, MUL VL]                   
+    WORD $0x85865446 // ldr z6, [x2, #53, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85865845 // ldr z5, [x2, #54, MUL VL]                   
+    WORD $0x85865c46 // ldr z6, [x2, #55, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x4_store
+
+    // Load and process 32 bytes from input 7 to 4 outputs
+    WORD $0x85804187 // ldr z7, [x12]                               
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85874045 // ldr z5, [x2, #56, MUL VL]                   
+    WORD $0x85874446 // ldr z6, [x2, #57, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85874845 // ldr z5, [x2, #58, MUL VL]                   
+    WORD $0x85874c46 // ldr z6, [x2, #59, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85875045 // ldr z5, [x2, #60, MUL VL]                   
+    WORD $0x85875446 // ldr z6, [x2, #61, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85875845 // ldr z5, [x2, #62, MUL VL]                   
+    WORD $0x85875c46 // ldr z6, [x2, #63, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x4_store
+
+    // Load and process 32 bytes from input 8 to 4 outputs
+    WORD $0x858041a7 // ldr z7, [x13]                               
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85884045 // ldr z5, [x2, #64, MUL VL]                   
+    WORD $0x85884446 // ldr z6, [x2, #65, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85884845 // ldr z5, [x2, #66, MUL VL]                   
+    WORD $0x85884c46 // ldr z6, [x2, #67, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85885045 // ldr z5, [x2, #68, MUL VL]                   
+    WORD $0x85885446 // ldr z6, [x2, #69, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85885845 // ldr z5, [x2, #70, MUL VL]                   
+    WORD $0x85885c46 // ldr z6, [x2, #71, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x4_store
+
+    // Load and process 32 bytes from input 9 to 4 outputs
+    WORD $0x85804067 // ldr z7, [x3]                                
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85894045 // ldr z5, [x2, #72, MUL VL]                   
+    WORD $0x85894446 // ldr z6, [x2, #73, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85894845 // ldr z5, [x2, #74, MUL VL]                   
+    WORD $0x85894c46 // ldr z6, [x2, #75, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85895045 // ldr z5, [x2, #76, MUL VL]                   
+    WORD $0x85895446 // ldr z6, [x2, #77, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85895845 // ldr z5, [x2, #78, MUL VL]                   
+    WORD $0x85895c46 // ldr z6, [x2, #79, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+
+mulSve_10x4_store:
+    // Store 4 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x4_loop
+
+mulSve_10x4_end:
+    RET
+
+// func mulSve_10x4Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x4Xor(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 89 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x4Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c4 // mov z4.d, x6                                
+    WORD $0x05212084 // dup z4.b, z4.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x4Xor_loop:
+    // Load and process 32 bytes from input 0 to 4 outputs
+    WORD $0x85804027 // ldr z7, [x1]                                
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    MOVD (R14), R6
+    WORD $0xa5ef40c0 // ld1d { z0.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85804045 // ldr z5, [x2]                                
+    WORD $0x85804446 // ldr z6, [x2, #1, MUL VL]                    
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    MOVD 24(R14), R6
+    WORD $0xa5ef40c1 // ld1d { z1.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85804845 // ldr z5, [x2, #2, MUL VL]                    
+    WORD $0x85804c46 // ldr z6, [x2, #3, MUL VL]                    
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    MOVD 48(R14), R6
+    WORD $0xa5ef40c2 // ld1d { z2.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85805045 // ldr z5, [x2, #4, MUL VL]                    
+    WORD $0x85805446 // ldr z6, [x2, #5, MUL VL]                    
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    MOVD 72(R14), R6
+    WORD $0xa5ef40c3 // ld1d { z3.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85805845 // ldr z5, [x2, #6, MUL VL]                    
+    WORD $0x85805c46 // ldr z6, [x2, #7, MUL VL]                    
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x4Xor_store
+
+    // Load and process 32 bytes from input 1 to 4 outputs
+    WORD $0x85804087 // ldr z7, [x4]                                
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85814045 // ldr z5, [x2, #8, MUL VL]                    
+    WORD $0x85814446 // ldr z6, [x2, #9, MUL VL]                    
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85814845 // ldr z5, [x2, #10, MUL VL]                   
+    WORD $0x85814c46 // ldr z6, [x2, #11, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85815045 // ldr z5, [x2, #12, MUL VL]                   
+    WORD $0x85815446 // ldr z6, [x2, #13, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85815845 // ldr z5, [x2, #14, MUL VL]                   
+    WORD $0x85815c46 // ldr z6, [x2, #15, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x4Xor_store
+
+    // Load and process 32 bytes from input 2 to 4 outputs
+    WORD $0x858040a7 // ldr z7, [x5]                                
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85824045 // ldr z5, [x2, #16, MUL VL]                   
+    WORD $0x85824446 // ldr z6, [x2, #17, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85824845 // ldr z5, [x2, #18, MUL VL]                   
+    WORD $0x85824c46 // ldr z6, [x2, #19, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85825045 // ldr z5, [x2, #20, MUL VL]                   
+    WORD $0x85825446 // ldr z6, [x2, #21, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85825845 // ldr z5, [x2, #22, MUL VL]                   
+    WORD $0x85825c46 // ldr z6, [x2, #23, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x4Xor_store
+
+    // Load and process 32 bytes from input 3 to 4 outputs
+    WORD $0x85804107 // ldr z7, [x8]                                
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85834045 // ldr z5, [x2, #24, MUL VL]                   
+    WORD $0x85834446 // ldr z6, [x2, #25, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85834845 // ldr z5, [x2, #26, MUL VL]                   
+    WORD $0x85834c46 // ldr z6, [x2, #27, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85835045 // ldr z5, [x2, #28, MUL VL]                   
+    WORD $0x85835446 // ldr z6, [x2, #29, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85835845 // ldr z5, [x2, #30, MUL VL]                   
+    WORD $0x85835c46 // ldr z6, [x2, #31, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x4Xor_store
+
+    // Load and process 32 bytes from input 4 to 4 outputs
+    WORD $0x85804127 // ldr z7, [x9]                                
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85844045 // ldr z5, [x2, #32, MUL VL]                   
+    WORD $0x85844446 // ldr z6, [x2, #33, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85844845 // ldr z5, [x2, #34, MUL VL]                   
+    WORD $0x85844c46 // ldr z6, [x2, #35, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85845045 // ldr z5, [x2, #36, MUL VL]                   
+    WORD $0x85845446 // ldr z6, [x2, #37, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85845845 // ldr z5, [x2, #38, MUL VL]                   
+    WORD $0x85845c46 // ldr z6, [x2, #39, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x4Xor_store
+
+    // Load and process 32 bytes from input 5 to 4 outputs
+    WORD $0x85804147 // ldr z7, [x10]                               
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85854045 // ldr z5, [x2, #40, MUL VL]                   
+    WORD $0x85854446 // ldr z6, [x2, #41, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85854845 // ldr z5, [x2, #42, MUL VL]                   
+    WORD $0x85854c46 // ldr z6, [x2, #43, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85855045 // ldr z5, [x2, #44, MUL VL]                   
+    WORD $0x85855446 // ldr z6, [x2, #45, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85855845 // ldr z5, [x2, #46, MUL VL]                   
+    WORD $0x85855c46 // ldr z6, [x2, #47, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x4Xor_store
+
+    // Load and process 32 bytes from input 6 to 4 outputs
+    WORD $0x85804167 // ldr z7, [x11]                               
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85864045 // ldr z5, [x2, #48, MUL VL]                   
+    WORD $0x85864446 // ldr z6, [x2, #49, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85864845 // ldr z5, [x2, #50, MUL VL]                   
+    WORD $0x85864c46 // ldr z6, [x2, #51, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85865045 // ldr z5, [x2, #52, MUL VL]                   
+    WORD $0x85865446 // ldr z6, [x2, #53, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85865845 // ldr z5, [x2, #54, MUL VL]                   
+    WORD $0x85865c46 // ldr z6, [x2, #55, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x4Xor_store
+
+    // Load and process 32 bytes from input 7 to 4 outputs
+    WORD $0x85804187 // ldr z7, [x12]                               
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85874045 // ldr z5, [x2, #56, MUL VL]                   
+    WORD $0x85874446 // ldr z6, [x2, #57, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85874845 // ldr z5, [x2, #58, MUL VL]                   
+    WORD $0x85874c46 // ldr z6, [x2, #59, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85875045 // ldr z5, [x2, #60, MUL VL]                   
+    WORD $0x85875446 // ldr z6, [x2, #61, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85875845 // ldr z5, [x2, #62, MUL VL]                   
+    WORD $0x85875c46 // ldr z6, [x2, #63, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x4Xor_store
+
+    // Load and process 32 bytes from input 8 to 4 outputs
+    WORD $0x858041a7 // ldr z7, [x13]                               
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85884045 // ldr z5, [x2, #64, MUL VL]                   
+    WORD $0x85884446 // ldr z6, [x2, #65, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85884845 // ldr z5, [x2, #66, MUL VL]                   
+    WORD $0x85884c46 // ldr z6, [x2, #67, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85885045 // ldr z5, [x2, #68, MUL VL]                   
+    WORD $0x85885446 // ldr z6, [x2, #69, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85885845 // ldr z5, [x2, #70, MUL VL]                   
+    WORD $0x85885c46 // ldr z6, [x2, #71, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x4Xor_store
+
+    // Load and process 32 bytes from input 9 to 4 outputs
+    WORD $0x85804067 // ldr z7, [x3]                                
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc94e8 // lsr z8.d, z7.d, #4                          
+    WORD $0x042430e7 // and z7.d, z7.d, z4.d                        
+    WORD $0x04243108 // and z8.d, z8.d, z4.d                        
+    WORD $0x85894045 // ldr z5, [x2, #72, MUL VL]                   
+    WORD $0x85894446 // ldr z6, [x2, #73, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53000 // eor z0.d, z0.d, z5.d                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x85894845 // ldr z5, [x2, #74, MUL VL]                   
+    WORD $0x85894c46 // ldr z6, [x2, #75, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53021 // eor z1.d, z1.d, z5.d                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x85895045 // ldr z5, [x2, #76, MUL VL]                   
+    WORD $0x85895446 // ldr z6, [x2, #77, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53042 // eor z2.d, z2.d, z5.d                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x85895845 // ldr z5, [x2, #78, MUL VL]                   
+    WORD $0x85895c46 // ldr z6, [x2, #79, MUL VL]                   
+    WORD $0x052730a5 // tbl z5.b, z5.b, z7.b                        
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x04a53063 // eor z3.d, z3.d, z5.d                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+
+mulSve_10x4Xor_store:
+    // Store 4 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x4Xor_loop
+
+mulSve_10x4Xor_end:
+    RET
+
+// func mulSve_10x5(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x5(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 110 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x5_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c5 // mov z5.d, x6                                
+    WORD $0x052120a5 // dup z5.b, z5.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x5_loop:
+    // Load and process 32 bytes from input 0 to 5 outputs
+    WORD $0x85804028 // ldr z8, [x1]                                
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85804046 // ldr z6, [x2]                                
+    WORD $0x85804447 // ldr z7, [x2, #1, MUL VL]                    
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a630e0 // eor z0.d, z7.d, z6.d                        
+    WORD $0x85804846 // ldr z6, [x2, #2, MUL VL]                    
+    WORD $0x85804c47 // ldr z7, [x2, #3, MUL VL]                    
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a630e1 // eor z1.d, z7.d, z6.d                        
+    WORD $0x85805046 // ldr z6, [x2, #4, MUL VL]                    
+    WORD $0x85805447 // ldr z7, [x2, #5, MUL VL]                    
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a630e2 // eor z2.d, z7.d, z6.d                        
+    WORD $0x85805846 // ldr z6, [x2, #6, MUL VL]                    
+    WORD $0x85805c47 // ldr z7, [x2, #7, MUL VL]                    
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a630e3 // eor z3.d, z7.d, z6.d                        
+    WORD $0x85814046 // ldr z6, [x2, #8, MUL VL]                    
+    WORD $0x85814447 // ldr z7, [x2, #9, MUL VL]                    
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a630e4 // eor z4.d, z7.d, z6.d                        
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x5_store
+
+    // Load and process 32 bytes from input 1 to 5 outputs
+    WORD $0x85804088 // ldr z8, [x4]                                
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85814846 // ldr z6, [x2, #10, MUL VL]                   
+    WORD $0x85814c47 // ldr z7, [x2, #11, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85815046 // ldr z6, [x2, #12, MUL VL]                   
+    WORD $0x85815447 // ldr z7, [x2, #13, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85815846 // ldr z6, [x2, #14, MUL VL]                   
+    WORD $0x85815c47 // ldr z7, [x2, #15, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85824046 // ldr z6, [x2, #16, MUL VL]                   
+    WORD $0x85824447 // ldr z7, [x2, #17, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85824846 // ldr z6, [x2, #18, MUL VL]                   
+    WORD $0x85824c47 // ldr z7, [x2, #19, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x5_store
+
+    // Load and process 32 bytes from input 2 to 5 outputs
+    WORD $0x858040a8 // ldr z8, [x5]                                
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85825046 // ldr z6, [x2, #20, MUL VL]                   
+    WORD $0x85825447 // ldr z7, [x2, #21, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85825846 // ldr z6, [x2, #22, MUL VL]                   
+    WORD $0x85825c47 // ldr z7, [x2, #23, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85834046 // ldr z6, [x2, #24, MUL VL]                   
+    WORD $0x85834447 // ldr z7, [x2, #25, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85834846 // ldr z6, [x2, #26, MUL VL]                   
+    WORD $0x85834c47 // ldr z7, [x2, #27, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85835046 // ldr z6, [x2, #28, MUL VL]                   
+    WORD $0x85835447 // ldr z7, [x2, #29, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x5_store
+
+    // Load and process 32 bytes from input 3 to 5 outputs
+    WORD $0x85804108 // ldr z8, [x8]                                
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85835846 // ldr z6, [x2, #30, MUL VL]                   
+    WORD $0x85835c47 // ldr z7, [x2, #31, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85844046 // ldr z6, [x2, #32, MUL VL]                   
+    WORD $0x85844447 // ldr z7, [x2, #33, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85844846 // ldr z6, [x2, #34, MUL VL]                   
+    WORD $0x85844c47 // ldr z7, [x2, #35, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85845046 // ldr z6, [x2, #36, MUL VL]                   
+    WORD $0x85845447 // ldr z7, [x2, #37, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85845846 // ldr z6, [x2, #38, MUL VL]                   
+    WORD $0x85845c47 // ldr z7, [x2, #39, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x5_store
+
+    // Load and process 32 bytes from input 4 to 5 outputs
+    WORD $0x85804128 // ldr z8, [x9]                                
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85854046 // ldr z6, [x2, #40, MUL VL]                   
+    WORD $0x85854447 // ldr z7, [x2, #41, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85854846 // ldr z6, [x2, #42, MUL VL]                   
+    WORD $0x85854c47 // ldr z7, [x2, #43, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85855046 // ldr z6, [x2, #44, MUL VL]                   
+    WORD $0x85855447 // ldr z7, [x2, #45, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85855846 // ldr z6, [x2, #46, MUL VL]                   
+    WORD $0x85855c47 // ldr z7, [x2, #47, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85864046 // ldr z6, [x2, #48, MUL VL]                   
+    WORD $0x85864447 // ldr z7, [x2, #49, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x5_store
+
+    // Load and process 32 bytes from input 5 to 5 outputs
+    WORD $0x85804148 // ldr z8, [x10]                               
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85864846 // ldr z6, [x2, #50, MUL VL]                   
+    WORD $0x85864c47 // ldr z7, [x2, #51, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85865046 // ldr z6, [x2, #52, MUL VL]                   
+    WORD $0x85865447 // ldr z7, [x2, #53, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85865846 // ldr z6, [x2, #54, MUL VL]                   
+    WORD $0x85865c47 // ldr z7, [x2, #55, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85874046 // ldr z6, [x2, #56, MUL VL]                   
+    WORD $0x85874447 // ldr z7, [x2, #57, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85874846 // ldr z6, [x2, #58, MUL VL]                   
+    WORD $0x85874c47 // ldr z7, [x2, #59, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x5_store
+
+    // Load and process 32 bytes from input 6 to 5 outputs
+    WORD $0x85804168 // ldr z8, [x11]                               
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85875046 // ldr z6, [x2, #60, MUL VL]                   
+    WORD $0x85875447 // ldr z7, [x2, #61, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85875846 // ldr z6, [x2, #62, MUL VL]                   
+    WORD $0x85875c47 // ldr z7, [x2, #63, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85884046 // ldr z6, [x2, #64, MUL VL]                   
+    WORD $0x85884447 // ldr z7, [x2, #65, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85884846 // ldr z6, [x2, #66, MUL VL]                   
+    WORD $0x85884c47 // ldr z7, [x2, #67, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85885046 // ldr z6, [x2, #68, MUL VL]                   
+    WORD $0x85885447 // ldr z7, [x2, #69, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x5_store
+
+    // Load and process 32 bytes from input 7 to 5 outputs
+    WORD $0x85804188 // ldr z8, [x12]                               
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85885846 // ldr z6, [x2, #70, MUL VL]                   
+    WORD $0x85885c47 // ldr z7, [x2, #71, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85894046 // ldr z6, [x2, #72, MUL VL]                   
+    WORD $0x85894447 // ldr z7, [x2, #73, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85894846 // ldr z6, [x2, #74, MUL VL]                   
+    WORD $0x85894c47 // ldr z7, [x2, #75, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85895046 // ldr z6, [x2, #76, MUL VL]                   
+    WORD $0x85895447 // ldr z7, [x2, #77, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85895846 // ldr z6, [x2, #78, MUL VL]                   
+    WORD $0x85895c47 // ldr z7, [x2, #79, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x5_store
+
+    // Load and process 32 bytes from input 8 to 5 outputs
+    WORD $0x858041a8 // ldr z8, [x13]                               
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x858a4046 // ldr z6, [x2, #80, MUL VL]                   
+    WORD $0x858a4447 // ldr z7, [x2, #81, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x858a4846 // ldr z6, [x2, #82, MUL VL]                   
+    WORD $0x858a4c47 // ldr z7, [x2, #83, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x858a5046 // ldr z6, [x2, #84, MUL VL]                   
+    WORD $0x858a5447 // ldr z7, [x2, #85, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x858a5846 // ldr z6, [x2, #86, MUL VL]                   
+    WORD $0x858a5c47 // ldr z7, [x2, #87, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x858b4046 // ldr z6, [x2, #88, MUL VL]                   
+    WORD $0x858b4447 // ldr z7, [x2, #89, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x5_store
+
+    // Load and process 32 bytes from input 9 to 5 outputs
+    WORD $0x85804068 // ldr z8, [x3]                                
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x858b4846 // ldr z6, [x2, #90, MUL VL]                   
+    WORD $0x858b4c47 // ldr z7, [x2, #91, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x858b5046 // ldr z6, [x2, #92, MUL VL]                   
+    WORD $0x858b5447 // ldr z7, [x2, #93, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x858b5846 // ldr z6, [x2, #94, MUL VL]                   
+    WORD $0x858b5c47 // ldr z7, [x2, #95, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x858c4046 // ldr z6, [x2, #96, MUL VL]                   
+    WORD $0x858c4447 // ldr z7, [x2, #97, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x858c4846 // ldr z6, [x2, #98, MUL VL]                   
+    WORD $0x858c4c47 // ldr z7, [x2, #99, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+
+mulSve_10x5_store:
+    // Store 5 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+    MOVD 96(R14), R6
+    WORD $0xe5ef40c4 // st1d { z4.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x5_loop
+
+mulSve_10x5_end:
+    RET
+
+// func mulSve_10x5Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x5Xor(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 110 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x5Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c5 // mov z5.d, x6                                
+    WORD $0x052120a5 // dup z5.b, z5.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x5Xor_loop:
+    // Load and process 32 bytes from input 0 to 5 outputs
+    WORD $0x85804028 // ldr z8, [x1]                                
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    MOVD (R14), R6
+    WORD $0xa5ef40c0 // ld1d { z0.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85804046 // ldr z6, [x2]                                
+    WORD $0x85804447 // ldr z7, [x2, #1, MUL VL]                    
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    MOVD 24(R14), R6
+    WORD $0xa5ef40c1 // ld1d { z1.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85804846 // ldr z6, [x2, #2, MUL VL]                    
+    WORD $0x85804c47 // ldr z7, [x2, #3, MUL VL]                    
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    MOVD 48(R14), R6
+    WORD $0xa5ef40c2 // ld1d { z2.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85805046 // ldr z6, [x2, #4, MUL VL]                    
+    WORD $0x85805447 // ldr z7, [x2, #5, MUL VL]                    
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    MOVD 72(R14), R6
+    WORD $0xa5ef40c3 // ld1d { z3.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85805846 // ldr z6, [x2, #6, MUL VL]                    
+    WORD $0x85805c47 // ldr z7, [x2, #7, MUL VL]                    
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    MOVD 96(R14), R6
+    WORD $0xa5ef40c4 // ld1d { z4.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85814046 // ldr z6, [x2, #8, MUL VL]                    
+    WORD $0x85814447 // ldr z7, [x2, #9, MUL VL]                    
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x5Xor_store
+
+    // Load and process 32 bytes from input 1 to 5 outputs
+    WORD $0x85804088 // ldr z8, [x4]                                
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85814846 // ldr z6, [x2, #10, MUL VL]                   
+    WORD $0x85814c47 // ldr z7, [x2, #11, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85815046 // ldr z6, [x2, #12, MUL VL]                   
+    WORD $0x85815447 // ldr z7, [x2, #13, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85815846 // ldr z6, [x2, #14, MUL VL]                   
+    WORD $0x85815c47 // ldr z7, [x2, #15, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85824046 // ldr z6, [x2, #16, MUL VL]                   
+    WORD $0x85824447 // ldr z7, [x2, #17, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85824846 // ldr z6, [x2, #18, MUL VL]                   
+    WORD $0x85824c47 // ldr z7, [x2, #19, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x5Xor_store
+
+    // Load and process 32 bytes from input 2 to 5 outputs
+    WORD $0x858040a8 // ldr z8, [x5]                                
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85825046 // ldr z6, [x2, #20, MUL VL]                   
+    WORD $0x85825447 // ldr z7, [x2, #21, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85825846 // ldr z6, [x2, #22, MUL VL]                   
+    WORD $0x85825c47 // ldr z7, [x2, #23, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85834046 // ldr z6, [x2, #24, MUL VL]                   
+    WORD $0x85834447 // ldr z7, [x2, #25, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85834846 // ldr z6, [x2, #26, MUL VL]                   
+    WORD $0x85834c47 // ldr z7, [x2, #27, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85835046 // ldr z6, [x2, #28, MUL VL]                   
+    WORD $0x85835447 // ldr z7, [x2, #29, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x5Xor_store
+
+    // Load and process 32 bytes from input 3 to 5 outputs
+    WORD $0x85804108 // ldr z8, [x8]                                
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85835846 // ldr z6, [x2, #30, MUL VL]                   
+    WORD $0x85835c47 // ldr z7, [x2, #31, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85844046 // ldr z6, [x2, #32, MUL VL]                   
+    WORD $0x85844447 // ldr z7, [x2, #33, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85844846 // ldr z6, [x2, #34, MUL VL]                   
+    WORD $0x85844c47 // ldr z7, [x2, #35, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85845046 // ldr z6, [x2, #36, MUL VL]                   
+    WORD $0x85845447 // ldr z7, [x2, #37, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85845846 // ldr z6, [x2, #38, MUL VL]                   
+    WORD $0x85845c47 // ldr z7, [x2, #39, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x5Xor_store
+
+    // Load and process 32 bytes from input 4 to 5 outputs
+    WORD $0x85804128 // ldr z8, [x9]                                
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85854046 // ldr z6, [x2, #40, MUL VL]                   
+    WORD $0x85854447 // ldr z7, [x2, #41, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85854846 // ldr z6, [x2, #42, MUL VL]                   
+    WORD $0x85854c47 // ldr z7, [x2, #43, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85855046 // ldr z6, [x2, #44, MUL VL]                   
+    WORD $0x85855447 // ldr z7, [x2, #45, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85855846 // ldr z6, [x2, #46, MUL VL]                   
+    WORD $0x85855c47 // ldr z7, [x2, #47, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85864046 // ldr z6, [x2, #48, MUL VL]                   
+    WORD $0x85864447 // ldr z7, [x2, #49, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x5Xor_store
+
+    // Load and process 32 bytes from input 5 to 5 outputs
+    WORD $0x85804148 // ldr z8, [x10]                               
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85864846 // ldr z6, [x2, #50, MUL VL]                   
+    WORD $0x85864c47 // ldr z7, [x2, #51, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85865046 // ldr z6, [x2, #52, MUL VL]                   
+    WORD $0x85865447 // ldr z7, [x2, #53, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85865846 // ldr z6, [x2, #54, MUL VL]                   
+    WORD $0x85865c47 // ldr z7, [x2, #55, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85874046 // ldr z6, [x2, #56, MUL VL]                   
+    WORD $0x85874447 // ldr z7, [x2, #57, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85874846 // ldr z6, [x2, #58, MUL VL]                   
+    WORD $0x85874c47 // ldr z7, [x2, #59, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x5Xor_store
+
+    // Load and process 32 bytes from input 6 to 5 outputs
+    WORD $0x85804168 // ldr z8, [x11]                               
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85875046 // ldr z6, [x2, #60, MUL VL]                   
+    WORD $0x85875447 // ldr z7, [x2, #61, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85875846 // ldr z6, [x2, #62, MUL VL]                   
+    WORD $0x85875c47 // ldr z7, [x2, #63, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85884046 // ldr z6, [x2, #64, MUL VL]                   
+    WORD $0x85884447 // ldr z7, [x2, #65, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85884846 // ldr z6, [x2, #66, MUL VL]                   
+    WORD $0x85884c47 // ldr z7, [x2, #67, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85885046 // ldr z6, [x2, #68, MUL VL]                   
+    WORD $0x85885447 // ldr z7, [x2, #69, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x5Xor_store
+
+    // Load and process 32 bytes from input 7 to 5 outputs
+    WORD $0x85804188 // ldr z8, [x12]                               
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x85885846 // ldr z6, [x2, #70, MUL VL]                   
+    WORD $0x85885c47 // ldr z7, [x2, #71, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x85894046 // ldr z6, [x2, #72, MUL VL]                   
+    WORD $0x85894447 // ldr z7, [x2, #73, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x85894846 // ldr z6, [x2, #74, MUL VL]                   
+    WORD $0x85894c47 // ldr z7, [x2, #75, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x85895046 // ldr z6, [x2, #76, MUL VL]                   
+    WORD $0x85895447 // ldr z7, [x2, #77, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x85895846 // ldr z6, [x2, #78, MUL VL]                   
+    WORD $0x85895c47 // ldr z7, [x2, #79, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x5Xor_store
+
+    // Load and process 32 bytes from input 8 to 5 outputs
+    WORD $0x858041a8 // ldr z8, [x13]                               
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x858a4046 // ldr z6, [x2, #80, MUL VL]                   
+    WORD $0x858a4447 // ldr z7, [x2, #81, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x858a4846 // ldr z6, [x2, #82, MUL VL]                   
+    WORD $0x858a4c47 // ldr z7, [x2, #83, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x858a5046 // ldr z6, [x2, #84, MUL VL]                   
+    WORD $0x858a5447 // ldr z7, [x2, #85, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x858a5846 // ldr z6, [x2, #86, MUL VL]                   
+    WORD $0x858a5c47 // ldr z7, [x2, #87, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x858b4046 // ldr z6, [x2, #88, MUL VL]                   
+    WORD $0x858b4447 // ldr z7, [x2, #89, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x5Xor_store
+
+    // Load and process 32 bytes from input 9 to 5 outputs
+    WORD $0x85804068 // ldr z8, [x3]                                
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc9509 // lsr z9.d, z8.d, #4                          
+    WORD $0x04253108 // and z8.d, z8.d, z5.d                        
+    WORD $0x04253129 // and z9.d, z9.d, z5.d                        
+    WORD $0x858b4846 // ldr z6, [x2, #90, MUL VL]                   
+    WORD $0x858b4c47 // ldr z7, [x2, #91, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63000 // eor z0.d, z0.d, z6.d                        
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x858b5046 // ldr z6, [x2, #92, MUL VL]                   
+    WORD $0x858b5447 // ldr z7, [x2, #93, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63021 // eor z1.d, z1.d, z6.d                        
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x858b5846 // ldr z6, [x2, #94, MUL VL]                   
+    WORD $0x858b5c47 // ldr z7, [x2, #95, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63042 // eor z2.d, z2.d, z6.d                        
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x858c4046 // ldr z6, [x2, #96, MUL VL]                   
+    WORD $0x858c4447 // ldr z7, [x2, #97, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63063 // eor z3.d, z3.d, z6.d                        
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x858c4846 // ldr z6, [x2, #98, MUL VL]                   
+    WORD $0x858c4c47 // ldr z7, [x2, #99, MUL VL]                   
+    WORD $0x052830c6 // tbl z6.b, z6.b, z8.b                        
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x04a63084 // eor z4.d, z4.d, z6.d                        
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+
+mulSve_10x5Xor_store:
+    // Store 5 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+    MOVD 96(R14), R6
+    WORD $0xe5ef40c4 // st1d { z4.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x5Xor_loop
+
+mulSve_10x5Xor_end:
+    RET
+
+// func mulSve_10x6(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x6(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 131 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x6_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c6 // mov z6.d, x6                                
+    WORD $0x052120c6 // dup z6.b, z6.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x6_loop:
+    // Load and process 32 bytes from input 0 to 6 outputs
+    WORD $0x85804029 // ldr z9, [x1]                                
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x85804047 // ldr z7, [x2]                                
+    WORD $0x85804448 // ldr z8, [x2, #1, MUL VL]                    
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73100 // eor z0.d, z8.d, z7.d                        
+    WORD $0x85804847 // ldr z7, [x2, #2, MUL VL]                    
+    WORD $0x85804c48 // ldr z8, [x2, #3, MUL VL]                    
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73101 // eor z1.d, z8.d, z7.d                        
+    WORD $0x85805047 // ldr z7, [x2, #4, MUL VL]                    
+    WORD $0x85805448 // ldr z8, [x2, #5, MUL VL]                    
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73102 // eor z2.d, z8.d, z7.d                        
+    WORD $0x85805847 // ldr z7, [x2, #6, MUL VL]                    
+    WORD $0x85805c48 // ldr z8, [x2, #7, MUL VL]                    
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73103 // eor z3.d, z8.d, z7.d                        
+    WORD $0x85814047 // ldr z7, [x2, #8, MUL VL]                    
+    WORD $0x85814448 // ldr z8, [x2, #9, MUL VL]                    
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73104 // eor z4.d, z8.d, z7.d                        
+    WORD $0x85814847 // ldr z7, [x2, #10, MUL VL]                   
+    WORD $0x85814c48 // ldr z8, [x2, #11, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73105 // eor z5.d, z8.d, z7.d                        
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x6_store
+
+    // Load and process 32 bytes from input 1 to 6 outputs
+    WORD $0x85804089 // ldr z9, [x4]                                
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x85815047 // ldr z7, [x2, #12, MUL VL]                   
+    WORD $0x85815448 // ldr z8, [x2, #13, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x85815847 // ldr z7, [x2, #14, MUL VL]                   
+    WORD $0x85815c48 // ldr z8, [x2, #15, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85824047 // ldr z7, [x2, #16, MUL VL]                   
+    WORD $0x85824448 // ldr z8, [x2, #17, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x85824847 // ldr z7, [x2, #18, MUL VL]                   
+    WORD $0x85824c48 // ldr z8, [x2, #19, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x85825047 // ldr z7, [x2, #20, MUL VL]                   
+    WORD $0x85825448 // ldr z8, [x2, #21, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x85825847 // ldr z7, [x2, #22, MUL VL]                   
+    WORD $0x85825c48 // ldr z8, [x2, #23, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x6_store
+
+    // Load and process 32 bytes from input 2 to 6 outputs
+    WORD $0x858040a9 // ldr z9, [x5]                                
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x85834047 // ldr z7, [x2, #24, MUL VL]                   
+    WORD $0x85834448 // ldr z8, [x2, #25, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x85834847 // ldr z7, [x2, #26, MUL VL]                   
+    WORD $0x85834c48 // ldr z8, [x2, #27, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85835047 // ldr z7, [x2, #28, MUL VL]                   
+    WORD $0x85835448 // ldr z8, [x2, #29, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x85835847 // ldr z7, [x2, #30, MUL VL]                   
+    WORD $0x85835c48 // ldr z8, [x2, #31, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x85844047 // ldr z7, [x2, #32, MUL VL]                   
+    WORD $0x85844448 // ldr z8, [x2, #33, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x85844847 // ldr z7, [x2, #34, MUL VL]                   
+    WORD $0x85844c48 // ldr z8, [x2, #35, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x6_store
+
+    // Load and process 32 bytes from input 3 to 6 outputs
+    WORD $0x85804109 // ldr z9, [x8]                                
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x85845047 // ldr z7, [x2, #36, MUL VL]                   
+    WORD $0x85845448 // ldr z8, [x2, #37, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x85845847 // ldr z7, [x2, #38, MUL VL]                   
+    WORD $0x85845c48 // ldr z8, [x2, #39, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85854047 // ldr z7, [x2, #40, MUL VL]                   
+    WORD $0x85854448 // ldr z8, [x2, #41, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x85854847 // ldr z7, [x2, #42, MUL VL]                   
+    WORD $0x85854c48 // ldr z8, [x2, #43, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x85855047 // ldr z7, [x2, #44, MUL VL]                   
+    WORD $0x85855448 // ldr z8, [x2, #45, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x85855847 // ldr z7, [x2, #46, MUL VL]                   
+    WORD $0x85855c48 // ldr z8, [x2, #47, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x6_store
+
+    // Load and process 32 bytes from input 4 to 6 outputs
+    WORD $0x85804129 // ldr z9, [x9]                                
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x85864047 // ldr z7, [x2, #48, MUL VL]                   
+    WORD $0x85864448 // ldr z8, [x2, #49, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x85864847 // ldr z7, [x2, #50, MUL VL]                   
+    WORD $0x85864c48 // ldr z8, [x2, #51, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85865047 // ldr z7, [x2, #52, MUL VL]                   
+    WORD $0x85865448 // ldr z8, [x2, #53, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x85865847 // ldr z7, [x2, #54, MUL VL]                   
+    WORD $0x85865c48 // ldr z8, [x2, #55, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x85874047 // ldr z7, [x2, #56, MUL VL]                   
+    WORD $0x85874448 // ldr z8, [x2, #57, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x85874847 // ldr z7, [x2, #58, MUL VL]                   
+    WORD $0x85874c48 // ldr z8, [x2, #59, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x6_store
+
+    // Load and process 32 bytes from input 5 to 6 outputs
+    WORD $0x85804149 // ldr z9, [x10]                               
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x85875047 // ldr z7, [x2, #60, MUL VL]                   
+    WORD $0x85875448 // ldr z8, [x2, #61, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x85875847 // ldr z7, [x2, #62, MUL VL]                   
+    WORD $0x85875c48 // ldr z8, [x2, #63, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85884047 // ldr z7, [x2, #64, MUL VL]                   
+    WORD $0x85884448 // ldr z8, [x2, #65, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x85884847 // ldr z7, [x2, #66, MUL VL]                   
+    WORD $0x85884c48 // ldr z8, [x2, #67, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x85885047 // ldr z7, [x2, #68, MUL VL]                   
+    WORD $0x85885448 // ldr z8, [x2, #69, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x85885847 // ldr z7, [x2, #70, MUL VL]                   
+    WORD $0x85885c48 // ldr z8, [x2, #71, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x6_store
+
+    // Load and process 32 bytes from input 6 to 6 outputs
+    WORD $0x85804169 // ldr z9, [x11]                               
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x85894047 // ldr z7, [x2, #72, MUL VL]                   
+    WORD $0x85894448 // ldr z8, [x2, #73, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x85894847 // ldr z7, [x2, #74, MUL VL]                   
+    WORD $0x85894c48 // ldr z8, [x2, #75, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85895047 // ldr z7, [x2, #76, MUL VL]                   
+    WORD $0x85895448 // ldr z8, [x2, #77, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x85895847 // ldr z7, [x2, #78, MUL VL]                   
+    WORD $0x85895c48 // ldr z8, [x2, #79, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x858a4047 // ldr z7, [x2, #80, MUL VL]                   
+    WORD $0x858a4448 // ldr z8, [x2, #81, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x858a4847 // ldr z7, [x2, #82, MUL VL]                   
+    WORD $0x858a4c48 // ldr z8, [x2, #83, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x6_store
+
+    // Load and process 32 bytes from input 7 to 6 outputs
+    WORD $0x85804189 // ldr z9, [x12]                               
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x858a5047 // ldr z7, [x2, #84, MUL VL]                   
+    WORD $0x858a5448 // ldr z8, [x2, #85, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x858a5847 // ldr z7, [x2, #86, MUL VL]                   
+    WORD $0x858a5c48 // ldr z8, [x2, #87, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x858b4047 // ldr z7, [x2, #88, MUL VL]                   
+    WORD $0x858b4448 // ldr z8, [x2, #89, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x858b4847 // ldr z7, [x2, #90, MUL VL]                   
+    WORD $0x858b4c48 // ldr z8, [x2, #91, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x858b5047 // ldr z7, [x2, #92, MUL VL]                   
+    WORD $0x858b5448 // ldr z8, [x2, #93, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x858b5847 // ldr z7, [x2, #94, MUL VL]                   
+    WORD $0x858b5c48 // ldr z8, [x2, #95, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x6_store
+
+    // Load and process 32 bytes from input 8 to 6 outputs
+    WORD $0x858041a9 // ldr z9, [x13]                               
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x858c4047 // ldr z7, [x2, #96, MUL VL]                   
+    WORD $0x858c4448 // ldr z8, [x2, #97, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x858c4847 // ldr z7, [x2, #98, MUL VL]                   
+    WORD $0x858c4c48 // ldr z8, [x2, #99, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x858c5047 // ldr z7, [x2, #100, MUL VL]                  
+    WORD $0x858c5448 // ldr z8, [x2, #101, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x858c5847 // ldr z7, [x2, #102, MUL VL]                  
+    WORD $0x858c5c48 // ldr z8, [x2, #103, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x858d4047 // ldr z7, [x2, #104, MUL VL]                  
+    WORD $0x858d4448 // ldr z8, [x2, #105, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x858d4847 // ldr z7, [x2, #106, MUL VL]                  
+    WORD $0x858d4c48 // ldr z8, [x2, #107, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x6_store
+
+    // Load and process 32 bytes from input 9 to 6 outputs
+    WORD $0x85804069 // ldr z9, [x3]                                
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x858d5047 // ldr z7, [x2, #108, MUL VL]                  
+    WORD $0x858d5448 // ldr z8, [x2, #109, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x858d5847 // ldr z7, [x2, #110, MUL VL]                  
+    WORD $0x858d5c48 // ldr z8, [x2, #111, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x858e4047 // ldr z7, [x2, #112, MUL VL]                  
+    WORD $0x858e4448 // ldr z8, [x2, #113, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x858e4847 // ldr z7, [x2, #114, MUL VL]                  
+    WORD $0x858e4c48 // ldr z8, [x2, #115, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x858e5047 // ldr z7, [x2, #116, MUL VL]                  
+    WORD $0x858e5448 // ldr z8, [x2, #117, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x858e5847 // ldr z7, [x2, #118, MUL VL]                  
+    WORD $0x858e5c48 // ldr z8, [x2, #119, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+
+mulSve_10x6_store:
+    // Store 6 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+    MOVD 96(R14), R6
+    WORD $0xe5ef40c4 // st1d { z4.d }, p0, [x6, x15, lsl #3]        
+    MOVD 120(R14), R6
+    WORD $0xe5ef40c5 // st1d { z5.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x6_loop
+
+mulSve_10x6_end:
+    RET
+
+// func mulSve_10x6Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x6Xor(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 131 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x6Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c6 // mov z6.d, x6                                
+    WORD $0x052120c6 // dup z6.b, z6.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x6Xor_loop:
+    // Load and process 32 bytes from input 0 to 6 outputs
+    WORD $0x85804029 // ldr z9, [x1]                                
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    MOVD (R14), R6
+    WORD $0xa5ef40c0 // ld1d { z0.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85804047 // ldr z7, [x2]                                
+    WORD $0x85804448 // ldr z8, [x2, #1, MUL VL]                    
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    MOVD 24(R14), R6
+    WORD $0xa5ef40c1 // ld1d { z1.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85804847 // ldr z7, [x2, #2, MUL VL]                    
+    WORD $0x85804c48 // ldr z8, [x2, #3, MUL VL]                    
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    MOVD 48(R14), R6
+    WORD $0xa5ef40c2 // ld1d { z2.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85805047 // ldr z7, [x2, #4, MUL VL]                    
+    WORD $0x85805448 // ldr z8, [x2, #5, MUL VL]                    
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    MOVD 72(R14), R6
+    WORD $0xa5ef40c3 // ld1d { z3.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85805847 // ldr z7, [x2, #6, MUL VL]                    
+    WORD $0x85805c48 // ldr z8, [x2, #7, MUL VL]                    
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    MOVD 96(R14), R6
+    WORD $0xa5ef40c4 // ld1d { z4.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85814047 // ldr z7, [x2, #8, MUL VL]                    
+    WORD $0x85814448 // ldr z8, [x2, #9, MUL VL]                    
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    MOVD 120(R14), R6
+    WORD $0xa5ef40c5 // ld1d { z5.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85814847 // ldr z7, [x2, #10, MUL VL]                   
+    WORD $0x85814c48 // ldr z8, [x2, #11, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x6Xor_store
+
+    // Load and process 32 bytes from input 1 to 6 outputs
+    WORD $0x85804089 // ldr z9, [x4]                                
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x85815047 // ldr z7, [x2, #12, MUL VL]                   
+    WORD $0x85815448 // ldr z8, [x2, #13, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x85815847 // ldr z7, [x2, #14, MUL VL]                   
+    WORD $0x85815c48 // ldr z8, [x2, #15, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85824047 // ldr z7, [x2, #16, MUL VL]                   
+    WORD $0x85824448 // ldr z8, [x2, #17, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x85824847 // ldr z7, [x2, #18, MUL VL]                   
+    WORD $0x85824c48 // ldr z8, [x2, #19, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x85825047 // ldr z7, [x2, #20, MUL VL]                   
+    WORD $0x85825448 // ldr z8, [x2, #21, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x85825847 // ldr z7, [x2, #22, MUL VL]                   
+    WORD $0x85825c48 // ldr z8, [x2, #23, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x6Xor_store
+
+    // Load and process 32 bytes from input 2 to 6 outputs
+    WORD $0x858040a9 // ldr z9, [x5]                                
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x85834047 // ldr z7, [x2, #24, MUL VL]                   
+    WORD $0x85834448 // ldr z8, [x2, #25, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x85834847 // ldr z7, [x2, #26, MUL VL]                   
+    WORD $0x85834c48 // ldr z8, [x2, #27, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85835047 // ldr z7, [x2, #28, MUL VL]                   
+    WORD $0x85835448 // ldr z8, [x2, #29, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x85835847 // ldr z7, [x2, #30, MUL VL]                   
+    WORD $0x85835c48 // ldr z8, [x2, #31, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x85844047 // ldr z7, [x2, #32, MUL VL]                   
+    WORD $0x85844448 // ldr z8, [x2, #33, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x85844847 // ldr z7, [x2, #34, MUL VL]                   
+    WORD $0x85844c48 // ldr z8, [x2, #35, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x6Xor_store
+
+    // Load and process 32 bytes from input 3 to 6 outputs
+    WORD $0x85804109 // ldr z9, [x8]                                
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x85845047 // ldr z7, [x2, #36, MUL VL]                   
+    WORD $0x85845448 // ldr z8, [x2, #37, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x85845847 // ldr z7, [x2, #38, MUL VL]                   
+    WORD $0x85845c48 // ldr z8, [x2, #39, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85854047 // ldr z7, [x2, #40, MUL VL]                   
+    WORD $0x85854448 // ldr z8, [x2, #41, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x85854847 // ldr z7, [x2, #42, MUL VL]                   
+    WORD $0x85854c48 // ldr z8, [x2, #43, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x85855047 // ldr z7, [x2, #44, MUL VL]                   
+    WORD $0x85855448 // ldr z8, [x2, #45, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x85855847 // ldr z7, [x2, #46, MUL VL]                   
+    WORD $0x85855c48 // ldr z8, [x2, #47, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x6Xor_store
+
+    // Load and process 32 bytes from input 4 to 6 outputs
+    WORD $0x85804129 // ldr z9, [x9]                                
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x85864047 // ldr z7, [x2, #48, MUL VL]                   
+    WORD $0x85864448 // ldr z8, [x2, #49, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x85864847 // ldr z7, [x2, #50, MUL VL]                   
+    WORD $0x85864c48 // ldr z8, [x2, #51, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85865047 // ldr z7, [x2, #52, MUL VL]                   
+    WORD $0x85865448 // ldr z8, [x2, #53, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x85865847 // ldr z7, [x2, #54, MUL VL]                   
+    WORD $0x85865c48 // ldr z8, [x2, #55, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x85874047 // ldr z7, [x2, #56, MUL VL]                   
+    WORD $0x85874448 // ldr z8, [x2, #57, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x85874847 // ldr z7, [x2, #58, MUL VL]                   
+    WORD $0x85874c48 // ldr z8, [x2, #59, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x6Xor_store
+
+    // Load and process 32 bytes from input 5 to 6 outputs
+    WORD $0x85804149 // ldr z9, [x10]                               
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x85875047 // ldr z7, [x2, #60, MUL VL]                   
+    WORD $0x85875448 // ldr z8, [x2, #61, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x85875847 // ldr z7, [x2, #62, MUL VL]                   
+    WORD $0x85875c48 // ldr z8, [x2, #63, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85884047 // ldr z7, [x2, #64, MUL VL]                   
+    WORD $0x85884448 // ldr z8, [x2, #65, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x85884847 // ldr z7, [x2, #66, MUL VL]                   
+    WORD $0x85884c48 // ldr z8, [x2, #67, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x85885047 // ldr z7, [x2, #68, MUL VL]                   
+    WORD $0x85885448 // ldr z8, [x2, #69, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x85885847 // ldr z7, [x2, #70, MUL VL]                   
+    WORD $0x85885c48 // ldr z8, [x2, #71, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x6Xor_store
+
+    // Load and process 32 bytes from input 6 to 6 outputs
+    WORD $0x85804169 // ldr z9, [x11]                               
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x85894047 // ldr z7, [x2, #72, MUL VL]                   
+    WORD $0x85894448 // ldr z8, [x2, #73, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x85894847 // ldr z7, [x2, #74, MUL VL]                   
+    WORD $0x85894c48 // ldr z8, [x2, #75, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x85895047 // ldr z7, [x2, #76, MUL VL]                   
+    WORD $0x85895448 // ldr z8, [x2, #77, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x85895847 // ldr z7, [x2, #78, MUL VL]                   
+    WORD $0x85895c48 // ldr z8, [x2, #79, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x858a4047 // ldr z7, [x2, #80, MUL VL]                   
+    WORD $0x858a4448 // ldr z8, [x2, #81, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x858a4847 // ldr z7, [x2, #82, MUL VL]                   
+    WORD $0x858a4c48 // ldr z8, [x2, #83, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x6Xor_store
+
+    // Load and process 32 bytes from input 7 to 6 outputs
+    WORD $0x85804189 // ldr z9, [x12]                               
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x858a5047 // ldr z7, [x2, #84, MUL VL]                   
+    WORD $0x858a5448 // ldr z8, [x2, #85, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x858a5847 // ldr z7, [x2, #86, MUL VL]                   
+    WORD $0x858a5c48 // ldr z8, [x2, #87, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x858b4047 // ldr z7, [x2, #88, MUL VL]                   
+    WORD $0x858b4448 // ldr z8, [x2, #89, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x858b4847 // ldr z7, [x2, #90, MUL VL]                   
+    WORD $0x858b4c48 // ldr z8, [x2, #91, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x858b5047 // ldr z7, [x2, #92, MUL VL]                   
+    WORD $0x858b5448 // ldr z8, [x2, #93, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x858b5847 // ldr z7, [x2, #94, MUL VL]                   
+    WORD $0x858b5c48 // ldr z8, [x2, #95, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x6Xor_store
+
+    // Load and process 32 bytes from input 8 to 6 outputs
+    WORD $0x858041a9 // ldr z9, [x13]                               
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x858c4047 // ldr z7, [x2, #96, MUL VL]                   
+    WORD $0x858c4448 // ldr z8, [x2, #97, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x858c4847 // ldr z7, [x2, #98, MUL VL]                   
+    WORD $0x858c4c48 // ldr z8, [x2, #99, MUL VL]                   
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x858c5047 // ldr z7, [x2, #100, MUL VL]                  
+    WORD $0x858c5448 // ldr z8, [x2, #101, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x858c5847 // ldr z7, [x2, #102, MUL VL]                  
+    WORD $0x858c5c48 // ldr z8, [x2, #103, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x858d4047 // ldr z7, [x2, #104, MUL VL]                  
+    WORD $0x858d4448 // ldr z8, [x2, #105, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x858d4847 // ldr z7, [x2, #106, MUL VL]                  
+    WORD $0x858d4c48 // ldr z8, [x2, #107, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x6Xor_store
+
+    // Load and process 32 bytes from input 9 to 6 outputs
+    WORD $0x85804069 // ldr z9, [x3]                                
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc952a // lsr z10.d, z9.d, #4                         
+    WORD $0x04263129 // and z9.d, z9.d, z6.d                        
+    WORD $0x0426314a // and z10.d, z10.d, z6.d                      
+    WORD $0x858d5047 // ldr z7, [x2, #108, MUL VL]                  
+    WORD $0x858d5448 // ldr z8, [x2, #109, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73000 // eor z0.d, z0.d, z7.d                        
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x858d5847 // ldr z7, [x2, #110, MUL VL]                  
+    WORD $0x858d5c48 // ldr z8, [x2, #111, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73021 // eor z1.d, z1.d, z7.d                        
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x858e4047 // ldr z7, [x2, #112, MUL VL]                  
+    WORD $0x858e4448 // ldr z8, [x2, #113, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73042 // eor z2.d, z2.d, z7.d                        
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x858e4847 // ldr z7, [x2, #114, MUL VL]                  
+    WORD $0x858e4c48 // ldr z8, [x2, #115, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73063 // eor z3.d, z3.d, z7.d                        
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x858e5047 // ldr z7, [x2, #116, MUL VL]                  
+    WORD $0x858e5448 // ldr z8, [x2, #117, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a73084 // eor z4.d, z4.d, z7.d                        
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x858e5847 // ldr z7, [x2, #118, MUL VL]                  
+    WORD $0x858e5c48 // ldr z8, [x2, #119, MUL VL]                  
+    WORD $0x052930e7 // tbl z7.b, z7.b, z9.b                        
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x04a730a5 // eor z5.d, z5.d, z7.d                        
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+
+mulSve_10x6Xor_store:
+    // Store 6 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+    MOVD 96(R14), R6
+    WORD $0xe5ef40c4 // st1d { z4.d }, p0, [x6, x15, lsl #3]        
+    MOVD 120(R14), R6
+    WORD $0xe5ef40c5 // st1d { z5.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x6Xor_loop
+
+mulSve_10x6Xor_end:
+    RET
+
+// func mulSve_10x7(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x7(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 152 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x7_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c7 // mov z7.d, x6                                
+    WORD $0x052120e7 // dup z7.b, z7.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x7_loop:
+    // Load and process 32 bytes from input 0 to 7 outputs
+    WORD $0x8580402a // ldr z10, [x1]                               
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x85804048 // ldr z8, [x2]                                
+    WORD $0x85804449 // ldr z9, [x2, #1, MUL VL]                    
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83120 // eor z0.d, z9.d, z8.d                        
+    WORD $0x85804848 // ldr z8, [x2, #2, MUL VL]                    
+    WORD $0x85804c49 // ldr z9, [x2, #3, MUL VL]                    
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83121 // eor z1.d, z9.d, z8.d                        
+    WORD $0x85805048 // ldr z8, [x2, #4, MUL VL]                    
+    WORD $0x85805449 // ldr z9, [x2, #5, MUL VL]                    
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83122 // eor z2.d, z9.d, z8.d                        
+    WORD $0x85805848 // ldr z8, [x2, #6, MUL VL]                    
+    WORD $0x85805c49 // ldr z9, [x2, #7, MUL VL]                    
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83123 // eor z3.d, z9.d, z8.d                        
+    WORD $0x85814048 // ldr z8, [x2, #8, MUL VL]                    
+    WORD $0x85814449 // ldr z9, [x2, #9, MUL VL]                    
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83124 // eor z4.d, z9.d, z8.d                        
+    WORD $0x85814848 // ldr z8, [x2, #10, MUL VL]                   
+    WORD $0x85814c49 // ldr z9, [x2, #11, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83125 // eor z5.d, z9.d, z8.d                        
+    WORD $0x85815048 // ldr z8, [x2, #12, MUL VL]                   
+    WORD $0x85815449 // ldr z9, [x2, #13, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83126 // eor z6.d, z9.d, z8.d                        
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x7_store
+
+    // Load and process 32 bytes from input 1 to 7 outputs
+    WORD $0x8580408a // ldr z10, [x4]                               
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x85815848 // ldr z8, [x2, #14, MUL VL]                   
+    WORD $0x85815c49 // ldr z9, [x2, #15, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x85824048 // ldr z8, [x2, #16, MUL VL]                   
+    WORD $0x85824449 // ldr z9, [x2, #17, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x85824848 // ldr z8, [x2, #18, MUL VL]                   
+    WORD $0x85824c49 // ldr z9, [x2, #19, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x85825048 // ldr z8, [x2, #20, MUL VL]                   
+    WORD $0x85825449 // ldr z9, [x2, #21, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x85825848 // ldr z8, [x2, #22, MUL VL]                   
+    WORD $0x85825c49 // ldr z9, [x2, #23, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x85834048 // ldr z8, [x2, #24, MUL VL]                   
+    WORD $0x85834449 // ldr z9, [x2, #25, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x85834848 // ldr z8, [x2, #26, MUL VL]                   
+    WORD $0x85834c49 // ldr z9, [x2, #27, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x7_store
+
+    // Load and process 32 bytes from input 2 to 7 outputs
+    WORD $0x858040aa // ldr z10, [x5]                               
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x85835048 // ldr z8, [x2, #28, MUL VL]                   
+    WORD $0x85835449 // ldr z9, [x2, #29, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x85835848 // ldr z8, [x2, #30, MUL VL]                   
+    WORD $0x85835c49 // ldr z9, [x2, #31, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x85844048 // ldr z8, [x2, #32, MUL VL]                   
+    WORD $0x85844449 // ldr z9, [x2, #33, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x85844848 // ldr z8, [x2, #34, MUL VL]                   
+    WORD $0x85844c49 // ldr z9, [x2, #35, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x85845048 // ldr z8, [x2, #36, MUL VL]                   
+    WORD $0x85845449 // ldr z9, [x2, #37, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x85845848 // ldr z8, [x2, #38, MUL VL]                   
+    WORD $0x85845c49 // ldr z9, [x2, #39, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x85854048 // ldr z8, [x2, #40, MUL VL]                   
+    WORD $0x85854449 // ldr z9, [x2, #41, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x7_store
+
+    // Load and process 32 bytes from input 3 to 7 outputs
+    WORD $0x8580410a // ldr z10, [x8]                               
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x85854848 // ldr z8, [x2, #42, MUL VL]                   
+    WORD $0x85854c49 // ldr z9, [x2, #43, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x85855048 // ldr z8, [x2, #44, MUL VL]                   
+    WORD $0x85855449 // ldr z9, [x2, #45, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x85855848 // ldr z8, [x2, #46, MUL VL]                   
+    WORD $0x85855c49 // ldr z9, [x2, #47, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x85864048 // ldr z8, [x2, #48, MUL VL]                   
+    WORD $0x85864449 // ldr z9, [x2, #49, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x85864848 // ldr z8, [x2, #50, MUL VL]                   
+    WORD $0x85864c49 // ldr z9, [x2, #51, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x85865048 // ldr z8, [x2, #52, MUL VL]                   
+    WORD $0x85865449 // ldr z9, [x2, #53, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x85865848 // ldr z8, [x2, #54, MUL VL]                   
+    WORD $0x85865c49 // ldr z9, [x2, #55, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x7_store
+
+    // Load and process 32 bytes from input 4 to 7 outputs
+    WORD $0x8580412a // ldr z10, [x9]                               
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x85874048 // ldr z8, [x2, #56, MUL VL]                   
+    WORD $0x85874449 // ldr z9, [x2, #57, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x85874848 // ldr z8, [x2, #58, MUL VL]                   
+    WORD $0x85874c49 // ldr z9, [x2, #59, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x85875048 // ldr z8, [x2, #60, MUL VL]                   
+    WORD $0x85875449 // ldr z9, [x2, #61, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x85875848 // ldr z8, [x2, #62, MUL VL]                   
+    WORD $0x85875c49 // ldr z9, [x2, #63, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x85884048 // ldr z8, [x2, #64, MUL VL]                   
+    WORD $0x85884449 // ldr z9, [x2, #65, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x85884848 // ldr z8, [x2, #66, MUL VL]                   
+    WORD $0x85884c49 // ldr z9, [x2, #67, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x85885048 // ldr z8, [x2, #68, MUL VL]                   
+    WORD $0x85885449 // ldr z9, [x2, #69, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x7_store
+
+    // Load and process 32 bytes from input 5 to 7 outputs
+    WORD $0x8580414a // ldr z10, [x10]                              
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x85885848 // ldr z8, [x2, #70, MUL VL]                   
+    WORD $0x85885c49 // ldr z9, [x2, #71, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x85894048 // ldr z8, [x2, #72, MUL VL]                   
+    WORD $0x85894449 // ldr z9, [x2, #73, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x85894848 // ldr z8, [x2, #74, MUL VL]                   
+    WORD $0x85894c49 // ldr z9, [x2, #75, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x85895048 // ldr z8, [x2, #76, MUL VL]                   
+    WORD $0x85895449 // ldr z9, [x2, #77, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x85895848 // ldr z8, [x2, #78, MUL VL]                   
+    WORD $0x85895c49 // ldr z9, [x2, #79, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x858a4048 // ldr z8, [x2, #80, MUL VL]                   
+    WORD $0x858a4449 // ldr z9, [x2, #81, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x858a4848 // ldr z8, [x2, #82, MUL VL]                   
+    WORD $0x858a4c49 // ldr z9, [x2, #83, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x7_store
+
+    // Load and process 32 bytes from input 6 to 7 outputs
+    WORD $0x8580416a // ldr z10, [x11]                              
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x858a5048 // ldr z8, [x2, #84, MUL VL]                   
+    WORD $0x858a5449 // ldr z9, [x2, #85, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x858a5848 // ldr z8, [x2, #86, MUL VL]                   
+    WORD $0x858a5c49 // ldr z9, [x2, #87, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x858b4048 // ldr z8, [x2, #88, MUL VL]                   
+    WORD $0x858b4449 // ldr z9, [x2, #89, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x858b4848 // ldr z8, [x2, #90, MUL VL]                   
+    WORD $0x858b4c49 // ldr z9, [x2, #91, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x858b5048 // ldr z8, [x2, #92, MUL VL]                   
+    WORD $0x858b5449 // ldr z9, [x2, #93, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x858b5848 // ldr z8, [x2, #94, MUL VL]                   
+    WORD $0x858b5c49 // ldr z9, [x2, #95, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x858c4048 // ldr z8, [x2, #96, MUL VL]                   
+    WORD $0x858c4449 // ldr z9, [x2, #97, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x7_store
+
+    // Load and process 32 bytes from input 7 to 7 outputs
+    WORD $0x8580418a // ldr z10, [x12]                              
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x858c4848 // ldr z8, [x2, #98, MUL VL]                   
+    WORD $0x858c4c49 // ldr z9, [x2, #99, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x858c5048 // ldr z8, [x2, #100, MUL VL]                  
+    WORD $0x858c5449 // ldr z9, [x2, #101, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x858c5848 // ldr z8, [x2, #102, MUL VL]                  
+    WORD $0x858c5c49 // ldr z9, [x2, #103, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x858d4048 // ldr z8, [x2, #104, MUL VL]                  
+    WORD $0x858d4449 // ldr z9, [x2, #105, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x858d4848 // ldr z8, [x2, #106, MUL VL]                  
+    WORD $0x858d4c49 // ldr z9, [x2, #107, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x858d5048 // ldr z8, [x2, #108, MUL VL]                  
+    WORD $0x858d5449 // ldr z9, [x2, #109, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x858d5848 // ldr z8, [x2, #110, MUL VL]                  
+    WORD $0x858d5c49 // ldr z9, [x2, #111, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x7_store
+
+    // Load and process 32 bytes from input 8 to 7 outputs
+    WORD $0x858041aa // ldr z10, [x13]                              
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x858e4048 // ldr z8, [x2, #112, MUL VL]                  
+    WORD $0x858e4449 // ldr z9, [x2, #113, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x858e4848 // ldr z8, [x2, #114, MUL VL]                  
+    WORD $0x858e4c49 // ldr z9, [x2, #115, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x858e5048 // ldr z8, [x2, #116, MUL VL]                  
+    WORD $0x858e5449 // ldr z9, [x2, #117, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x858e5848 // ldr z8, [x2, #118, MUL VL]                  
+    WORD $0x858e5c49 // ldr z9, [x2, #119, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x858f4048 // ldr z8, [x2, #120, MUL VL]                  
+    WORD $0x858f4449 // ldr z9, [x2, #121, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x858f4848 // ldr z8, [x2, #122, MUL VL]                  
+    WORD $0x858f4c49 // ldr z9, [x2, #123, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x858f5048 // ldr z8, [x2, #124, MUL VL]                  
+    WORD $0x858f5449 // ldr z9, [x2, #125, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x7_store
+
+    // Load and process 32 bytes from input 9 to 7 outputs
+    WORD $0x8580406a // ldr z10, [x3]                               
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x858f5848 // ldr z8, [x2, #126, MUL VL]                  
+    WORD $0x858f5c49 // ldr z9, [x2, #127, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x85904048 // ldr z8, [x2, #128, MUL VL]                  
+    WORD $0x85904449 // ldr z9, [x2, #129, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x85904848 // ldr z8, [x2, #130, MUL VL]                  
+    WORD $0x85904c49 // ldr z9, [x2, #131, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x85905048 // ldr z8, [x2, #132, MUL VL]                  
+    WORD $0x85905449 // ldr z9, [x2, #133, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x85905848 // ldr z8, [x2, #134, MUL VL]                  
+    WORD $0x85905c49 // ldr z9, [x2, #135, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x85914048 // ldr z8, [x2, #136, MUL VL]                  
+    WORD $0x85914449 // ldr z9, [x2, #137, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x85914848 // ldr z8, [x2, #138, MUL VL]                  
+    WORD $0x85914c49 // ldr z9, [x2, #139, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+
+mulSve_10x7_store:
+    // Store 7 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+    MOVD 96(R14), R6
+    WORD $0xe5ef40c4 // st1d { z4.d }, p0, [x6, x15, lsl #3]        
+    MOVD 120(R14), R6
+    WORD $0xe5ef40c5 // st1d { z5.d }, p0, [x6, x15, lsl #3]        
+    MOVD 144(R14), R6
+    WORD $0xe5ef40c6 // st1d { z6.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x7_loop
+
+mulSve_10x7_end:
+    RET
+
+// func mulSve_10x7Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x7Xor(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 152 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x7Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c7 // mov z7.d, x6                                
+    WORD $0x052120e7 // dup z7.b, z7.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x7Xor_loop:
+    // Load and process 32 bytes from input 0 to 7 outputs
+    WORD $0x8580402a // ldr z10, [x1]                               
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    MOVD (R14), R6
+    WORD $0xa5ef40c0 // ld1d { z0.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85804048 // ldr z8, [x2]                                
+    WORD $0x85804449 // ldr z9, [x2, #1, MUL VL]                    
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    MOVD 24(R14), R6
+    WORD $0xa5ef40c1 // ld1d { z1.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85804848 // ldr z8, [x2, #2, MUL VL]                    
+    WORD $0x85804c49 // ldr z9, [x2, #3, MUL VL]                    
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    MOVD 48(R14), R6
+    WORD $0xa5ef40c2 // ld1d { z2.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85805048 // ldr z8, [x2, #4, MUL VL]                    
+    WORD $0x85805449 // ldr z9, [x2, #5, MUL VL]                    
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    MOVD 72(R14), R6
+    WORD $0xa5ef40c3 // ld1d { z3.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85805848 // ldr z8, [x2, #6, MUL VL]                    
+    WORD $0x85805c49 // ldr z9, [x2, #7, MUL VL]                    
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    MOVD 96(R14), R6
+    WORD $0xa5ef40c4 // ld1d { z4.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85814048 // ldr z8, [x2, #8, MUL VL]                    
+    WORD $0x85814449 // ldr z9, [x2, #9, MUL VL]                    
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    MOVD 120(R14), R6
+    WORD $0xa5ef40c5 // ld1d { z5.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85814848 // ldr z8, [x2, #10, MUL VL]                   
+    WORD $0x85814c49 // ldr z9, [x2, #11, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    MOVD 144(R14), R6
+    WORD $0xa5ef40c6 // ld1d { z6.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85815048 // ldr z8, [x2, #12, MUL VL]                   
+    WORD $0x85815449 // ldr z9, [x2, #13, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x7Xor_store
+
+    // Load and process 32 bytes from input 1 to 7 outputs
+    WORD $0x8580408a // ldr z10, [x4]                               
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x85815848 // ldr z8, [x2, #14, MUL VL]                   
+    WORD $0x85815c49 // ldr z9, [x2, #15, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x85824048 // ldr z8, [x2, #16, MUL VL]                   
+    WORD $0x85824449 // ldr z9, [x2, #17, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x85824848 // ldr z8, [x2, #18, MUL VL]                   
+    WORD $0x85824c49 // ldr z9, [x2, #19, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x85825048 // ldr z8, [x2, #20, MUL VL]                   
+    WORD $0x85825449 // ldr z9, [x2, #21, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x85825848 // ldr z8, [x2, #22, MUL VL]                   
+    WORD $0x85825c49 // ldr z9, [x2, #23, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x85834048 // ldr z8, [x2, #24, MUL VL]                   
+    WORD $0x85834449 // ldr z9, [x2, #25, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x85834848 // ldr z8, [x2, #26, MUL VL]                   
+    WORD $0x85834c49 // ldr z9, [x2, #27, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x7Xor_store
+
+    // Load and process 32 bytes from input 2 to 7 outputs
+    WORD $0x858040aa // ldr z10, [x5]                               
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x85835048 // ldr z8, [x2, #28, MUL VL]                   
+    WORD $0x85835449 // ldr z9, [x2, #29, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x85835848 // ldr z8, [x2, #30, MUL VL]                   
+    WORD $0x85835c49 // ldr z9, [x2, #31, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x85844048 // ldr z8, [x2, #32, MUL VL]                   
+    WORD $0x85844449 // ldr z9, [x2, #33, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x85844848 // ldr z8, [x2, #34, MUL VL]                   
+    WORD $0x85844c49 // ldr z9, [x2, #35, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x85845048 // ldr z8, [x2, #36, MUL VL]                   
+    WORD $0x85845449 // ldr z9, [x2, #37, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x85845848 // ldr z8, [x2, #38, MUL VL]                   
+    WORD $0x85845c49 // ldr z9, [x2, #39, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x85854048 // ldr z8, [x2, #40, MUL VL]                   
+    WORD $0x85854449 // ldr z9, [x2, #41, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x7Xor_store
+
+    // Load and process 32 bytes from input 3 to 7 outputs
+    WORD $0x8580410a // ldr z10, [x8]                               
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x85854848 // ldr z8, [x2, #42, MUL VL]                   
+    WORD $0x85854c49 // ldr z9, [x2, #43, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x85855048 // ldr z8, [x2, #44, MUL VL]                   
+    WORD $0x85855449 // ldr z9, [x2, #45, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x85855848 // ldr z8, [x2, #46, MUL VL]                   
+    WORD $0x85855c49 // ldr z9, [x2, #47, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x85864048 // ldr z8, [x2, #48, MUL VL]                   
+    WORD $0x85864449 // ldr z9, [x2, #49, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x85864848 // ldr z8, [x2, #50, MUL VL]                   
+    WORD $0x85864c49 // ldr z9, [x2, #51, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x85865048 // ldr z8, [x2, #52, MUL VL]                   
+    WORD $0x85865449 // ldr z9, [x2, #53, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x85865848 // ldr z8, [x2, #54, MUL VL]                   
+    WORD $0x85865c49 // ldr z9, [x2, #55, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x7Xor_store
+
+    // Load and process 32 bytes from input 4 to 7 outputs
+    WORD $0x8580412a // ldr z10, [x9]                               
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x85874048 // ldr z8, [x2, #56, MUL VL]                   
+    WORD $0x85874449 // ldr z9, [x2, #57, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x85874848 // ldr z8, [x2, #58, MUL VL]                   
+    WORD $0x85874c49 // ldr z9, [x2, #59, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x85875048 // ldr z8, [x2, #60, MUL VL]                   
+    WORD $0x85875449 // ldr z9, [x2, #61, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x85875848 // ldr z8, [x2, #62, MUL VL]                   
+    WORD $0x85875c49 // ldr z9, [x2, #63, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x85884048 // ldr z8, [x2, #64, MUL VL]                   
+    WORD $0x85884449 // ldr z9, [x2, #65, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x85884848 // ldr z8, [x2, #66, MUL VL]                   
+    WORD $0x85884c49 // ldr z9, [x2, #67, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x85885048 // ldr z8, [x2, #68, MUL VL]                   
+    WORD $0x85885449 // ldr z9, [x2, #69, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x7Xor_store
+
+    // Load and process 32 bytes from input 5 to 7 outputs
+    WORD $0x8580414a // ldr z10, [x10]                              
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x85885848 // ldr z8, [x2, #70, MUL VL]                   
+    WORD $0x85885c49 // ldr z9, [x2, #71, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x85894048 // ldr z8, [x2, #72, MUL VL]                   
+    WORD $0x85894449 // ldr z9, [x2, #73, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x85894848 // ldr z8, [x2, #74, MUL VL]                   
+    WORD $0x85894c49 // ldr z9, [x2, #75, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x85895048 // ldr z8, [x2, #76, MUL VL]                   
+    WORD $0x85895449 // ldr z9, [x2, #77, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x85895848 // ldr z8, [x2, #78, MUL VL]                   
+    WORD $0x85895c49 // ldr z9, [x2, #79, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x858a4048 // ldr z8, [x2, #80, MUL VL]                   
+    WORD $0x858a4449 // ldr z9, [x2, #81, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x858a4848 // ldr z8, [x2, #82, MUL VL]                   
+    WORD $0x858a4c49 // ldr z9, [x2, #83, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x7Xor_store
+
+    // Load and process 32 bytes from input 6 to 7 outputs
+    WORD $0x8580416a // ldr z10, [x11]                              
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x858a5048 // ldr z8, [x2, #84, MUL VL]                   
+    WORD $0x858a5449 // ldr z9, [x2, #85, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x858a5848 // ldr z8, [x2, #86, MUL VL]                   
+    WORD $0x858a5c49 // ldr z9, [x2, #87, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x858b4048 // ldr z8, [x2, #88, MUL VL]                   
+    WORD $0x858b4449 // ldr z9, [x2, #89, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x858b4848 // ldr z8, [x2, #90, MUL VL]                   
+    WORD $0x858b4c49 // ldr z9, [x2, #91, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x858b5048 // ldr z8, [x2, #92, MUL VL]                   
+    WORD $0x858b5449 // ldr z9, [x2, #93, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x858b5848 // ldr z8, [x2, #94, MUL VL]                   
+    WORD $0x858b5c49 // ldr z9, [x2, #95, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x858c4048 // ldr z8, [x2, #96, MUL VL]                   
+    WORD $0x858c4449 // ldr z9, [x2, #97, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x7Xor_store
+
+    // Load and process 32 bytes from input 7 to 7 outputs
+    WORD $0x8580418a // ldr z10, [x12]                              
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x858c4848 // ldr z8, [x2, #98, MUL VL]                   
+    WORD $0x858c4c49 // ldr z9, [x2, #99, MUL VL]                   
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x858c5048 // ldr z8, [x2, #100, MUL VL]                  
+    WORD $0x858c5449 // ldr z9, [x2, #101, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x858c5848 // ldr z8, [x2, #102, MUL VL]                  
+    WORD $0x858c5c49 // ldr z9, [x2, #103, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x858d4048 // ldr z8, [x2, #104, MUL VL]                  
+    WORD $0x858d4449 // ldr z9, [x2, #105, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x858d4848 // ldr z8, [x2, #106, MUL VL]                  
+    WORD $0x858d4c49 // ldr z9, [x2, #107, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x858d5048 // ldr z8, [x2, #108, MUL VL]                  
+    WORD $0x858d5449 // ldr z9, [x2, #109, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x858d5848 // ldr z8, [x2, #110, MUL VL]                  
+    WORD $0x858d5c49 // ldr z9, [x2, #111, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x7Xor_store
+
+    // Load and process 32 bytes from input 8 to 7 outputs
+    WORD $0x858041aa // ldr z10, [x13]                              
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x858e4048 // ldr z8, [x2, #112, MUL VL]                  
+    WORD $0x858e4449 // ldr z9, [x2, #113, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x858e4848 // ldr z8, [x2, #114, MUL VL]                  
+    WORD $0x858e4c49 // ldr z9, [x2, #115, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x858e5048 // ldr z8, [x2, #116, MUL VL]                  
+    WORD $0x858e5449 // ldr z9, [x2, #117, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x858e5848 // ldr z8, [x2, #118, MUL VL]                  
+    WORD $0x858e5c49 // ldr z9, [x2, #119, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x858f4048 // ldr z8, [x2, #120, MUL VL]                  
+    WORD $0x858f4449 // ldr z9, [x2, #121, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x858f4848 // ldr z8, [x2, #122, MUL VL]                  
+    WORD $0x858f4c49 // ldr z9, [x2, #123, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x858f5048 // ldr z8, [x2, #124, MUL VL]                  
+    WORD $0x858f5449 // ldr z9, [x2, #125, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x7Xor_store
+
+    // Load and process 32 bytes from input 9 to 7 outputs
+    WORD $0x8580406a // ldr z10, [x3]                               
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc954b // lsr z11.d, z10.d, #4                        
+    WORD $0x0427314a // and z10.d, z10.d, z7.d                      
+    WORD $0x0427316b // and z11.d, z11.d, z7.d                      
+    WORD $0x858f5848 // ldr z8, [x2, #126, MUL VL]                  
+    WORD $0x858f5c49 // ldr z9, [x2, #127, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83000 // eor z0.d, z0.d, z8.d                        
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x85904048 // ldr z8, [x2, #128, MUL VL]                  
+    WORD $0x85904449 // ldr z9, [x2, #129, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83021 // eor z1.d, z1.d, z8.d                        
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x85904848 // ldr z8, [x2, #130, MUL VL]                  
+    WORD $0x85904c49 // ldr z9, [x2, #131, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83042 // eor z2.d, z2.d, z8.d                        
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x85905048 // ldr z8, [x2, #132, MUL VL]                  
+    WORD $0x85905449 // ldr z9, [x2, #133, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83063 // eor z3.d, z3.d, z8.d                        
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x85905848 // ldr z8, [x2, #134, MUL VL]                  
+    WORD $0x85905c49 // ldr z9, [x2, #135, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a83084 // eor z4.d, z4.d, z8.d                        
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x85914048 // ldr z8, [x2, #136, MUL VL]                  
+    WORD $0x85914449 // ldr z9, [x2, #137, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830a5 // eor z5.d, z5.d, z8.d                        
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x85914848 // ldr z8, [x2, #138, MUL VL]                  
+    WORD $0x85914c49 // ldr z9, [x2, #139, MUL VL]                  
+    WORD $0x052a3108 // tbl z8.b, z8.b, z10.b                       
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x04a830c6 // eor z6.d, z6.d, z8.d                        
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+
+mulSve_10x7Xor_store:
+    // Store 7 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+    MOVD 96(R14), R6
+    WORD $0xe5ef40c4 // st1d { z4.d }, p0, [x6, x15, lsl #3]        
+    MOVD 120(R14), R6
+    WORD $0xe5ef40c5 // st1d { z5.d }, p0, [x6, x15, lsl #3]        
+    MOVD 144(R14), R6
+    WORD $0xe5ef40c6 // st1d { z6.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x7Xor_loop
+
+mulSve_10x7Xor_end:
+    RET
+
+// func mulSve_10x8(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x8(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 173 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x8_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c8 // mov z8.d, x6                                
+    WORD $0x05212108 // dup z8.b, z8.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x8_loop:
+    // Load and process 32 bytes from input 0 to 8 outputs
+    WORD $0x8580402b // ldr z11, [x1]                               
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x85804049 // ldr z9, [x2]                                
+    WORD $0x8580444a // ldr z10, [x2, #1, MUL VL]                   
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93140 // eor z0.d, z10.d, z9.d                       
+    WORD $0x85804849 // ldr z9, [x2, #2, MUL VL]                    
+    WORD $0x85804c4a // ldr z10, [x2, #3, MUL VL]                   
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93141 // eor z1.d, z10.d, z9.d                       
+    WORD $0x85805049 // ldr z9, [x2, #4, MUL VL]                    
+    WORD $0x8580544a // ldr z10, [x2, #5, MUL VL]                   
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93142 // eor z2.d, z10.d, z9.d                       
+    WORD $0x85805849 // ldr z9, [x2, #6, MUL VL]                    
+    WORD $0x85805c4a // ldr z10, [x2, #7, MUL VL]                   
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93143 // eor z3.d, z10.d, z9.d                       
+    WORD $0x85814049 // ldr z9, [x2, #8, MUL VL]                    
+    WORD $0x8581444a // ldr z10, [x2, #9, MUL VL]                   
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93144 // eor z4.d, z10.d, z9.d                       
+    WORD $0x85814849 // ldr z9, [x2, #10, MUL VL]                   
+    WORD $0x85814c4a // ldr z10, [x2, #11, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93145 // eor z5.d, z10.d, z9.d                       
+    WORD $0x85815049 // ldr z9, [x2, #12, MUL VL]                   
+    WORD $0x8581544a // ldr z10, [x2, #13, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93146 // eor z6.d, z10.d, z9.d                       
+    WORD $0x85815849 // ldr z9, [x2, #14, MUL VL]                   
+    WORD $0x85815c4a // ldr z10, [x2, #15, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93147 // eor z7.d, z10.d, z9.d                       
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x8_store
+
+    // Load and process 32 bytes from input 1 to 8 outputs
+    WORD $0x8580408b // ldr z11, [x4]                               
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x85824049 // ldr z9, [x2, #16, MUL VL]                   
+    WORD $0x8582444a // ldr z10, [x2, #17, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x85824849 // ldr z9, [x2, #18, MUL VL]                   
+    WORD $0x85824c4a // ldr z10, [x2, #19, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85825049 // ldr z9, [x2, #20, MUL VL]                   
+    WORD $0x8582544a // ldr z10, [x2, #21, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x85825849 // ldr z9, [x2, #22, MUL VL]                   
+    WORD $0x85825c4a // ldr z10, [x2, #23, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85834049 // ldr z9, [x2, #24, MUL VL]                   
+    WORD $0x8583444a // ldr z10, [x2, #25, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x85834849 // ldr z9, [x2, #26, MUL VL]                   
+    WORD $0x85834c4a // ldr z10, [x2, #27, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x85835049 // ldr z9, [x2, #28, MUL VL]                   
+    WORD $0x8583544a // ldr z10, [x2, #29, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x85835849 // ldr z9, [x2, #30, MUL VL]                   
+    WORD $0x85835c4a // ldr z10, [x2, #31, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x8_store
+
+    // Load and process 32 bytes from input 2 to 8 outputs
+    WORD $0x858040ab // ldr z11, [x5]                               
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x85844049 // ldr z9, [x2, #32, MUL VL]                   
+    WORD $0x8584444a // ldr z10, [x2, #33, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x85844849 // ldr z9, [x2, #34, MUL VL]                   
+    WORD $0x85844c4a // ldr z10, [x2, #35, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85845049 // ldr z9, [x2, #36, MUL VL]                   
+    WORD $0x8584544a // ldr z10, [x2, #37, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x85845849 // ldr z9, [x2, #38, MUL VL]                   
+    WORD $0x85845c4a // ldr z10, [x2, #39, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85854049 // ldr z9, [x2, #40, MUL VL]                   
+    WORD $0x8585444a // ldr z10, [x2, #41, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x85854849 // ldr z9, [x2, #42, MUL VL]                   
+    WORD $0x85854c4a // ldr z10, [x2, #43, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x85855049 // ldr z9, [x2, #44, MUL VL]                   
+    WORD $0x8585544a // ldr z10, [x2, #45, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x85855849 // ldr z9, [x2, #46, MUL VL]                   
+    WORD $0x85855c4a // ldr z10, [x2, #47, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x8_store
+
+    // Load and process 32 bytes from input 3 to 8 outputs
+    WORD $0x8580410b // ldr z11, [x8]                               
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x85864049 // ldr z9, [x2, #48, MUL VL]                   
+    WORD $0x8586444a // ldr z10, [x2, #49, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x85864849 // ldr z9, [x2, #50, MUL VL]                   
+    WORD $0x85864c4a // ldr z10, [x2, #51, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85865049 // ldr z9, [x2, #52, MUL VL]                   
+    WORD $0x8586544a // ldr z10, [x2, #53, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x85865849 // ldr z9, [x2, #54, MUL VL]                   
+    WORD $0x85865c4a // ldr z10, [x2, #55, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85874049 // ldr z9, [x2, #56, MUL VL]                   
+    WORD $0x8587444a // ldr z10, [x2, #57, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x85874849 // ldr z9, [x2, #58, MUL VL]                   
+    WORD $0x85874c4a // ldr z10, [x2, #59, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x85875049 // ldr z9, [x2, #60, MUL VL]                   
+    WORD $0x8587544a // ldr z10, [x2, #61, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x85875849 // ldr z9, [x2, #62, MUL VL]                   
+    WORD $0x85875c4a // ldr z10, [x2, #63, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x8_store
+
+    // Load and process 32 bytes from input 4 to 8 outputs
+    WORD $0x8580412b // ldr z11, [x9]                               
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x85884049 // ldr z9, [x2, #64, MUL VL]                   
+    WORD $0x8588444a // ldr z10, [x2, #65, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x85884849 // ldr z9, [x2, #66, MUL VL]                   
+    WORD $0x85884c4a // ldr z10, [x2, #67, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85885049 // ldr z9, [x2, #68, MUL VL]                   
+    WORD $0x8588544a // ldr z10, [x2, #69, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x85885849 // ldr z9, [x2, #70, MUL VL]                   
+    WORD $0x85885c4a // ldr z10, [x2, #71, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85894049 // ldr z9, [x2, #72, MUL VL]                   
+    WORD $0x8589444a // ldr z10, [x2, #73, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x85894849 // ldr z9, [x2, #74, MUL VL]                   
+    WORD $0x85894c4a // ldr z10, [x2, #75, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x85895049 // ldr z9, [x2, #76, MUL VL]                   
+    WORD $0x8589544a // ldr z10, [x2, #77, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x85895849 // ldr z9, [x2, #78, MUL VL]                   
+    WORD $0x85895c4a // ldr z10, [x2, #79, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x8_store
+
+    // Load and process 32 bytes from input 5 to 8 outputs
+    WORD $0x8580414b // ldr z11, [x10]                              
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x858a4049 // ldr z9, [x2, #80, MUL VL]                   
+    WORD $0x858a444a // ldr z10, [x2, #81, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x858a4849 // ldr z9, [x2, #82, MUL VL]                   
+    WORD $0x858a4c4a // ldr z10, [x2, #83, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x858a5049 // ldr z9, [x2, #84, MUL VL]                   
+    WORD $0x858a544a // ldr z10, [x2, #85, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x858a5849 // ldr z9, [x2, #86, MUL VL]                   
+    WORD $0x858a5c4a // ldr z10, [x2, #87, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x858b4049 // ldr z9, [x2, #88, MUL VL]                   
+    WORD $0x858b444a // ldr z10, [x2, #89, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x858b4849 // ldr z9, [x2, #90, MUL VL]                   
+    WORD $0x858b4c4a // ldr z10, [x2, #91, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x858b5049 // ldr z9, [x2, #92, MUL VL]                   
+    WORD $0x858b544a // ldr z10, [x2, #93, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x858b5849 // ldr z9, [x2, #94, MUL VL]                   
+    WORD $0x858b5c4a // ldr z10, [x2, #95, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x8_store
+
+    // Load and process 32 bytes from input 6 to 8 outputs
+    WORD $0x8580416b // ldr z11, [x11]                              
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x858c4049 // ldr z9, [x2, #96, MUL VL]                   
+    WORD $0x858c444a // ldr z10, [x2, #97, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x858c4849 // ldr z9, [x2, #98, MUL VL]                   
+    WORD $0x858c4c4a // ldr z10, [x2, #99, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x858c5049 // ldr z9, [x2, #100, MUL VL]                  
+    WORD $0x858c544a // ldr z10, [x2, #101, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x858c5849 // ldr z9, [x2, #102, MUL VL]                  
+    WORD $0x858c5c4a // ldr z10, [x2, #103, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x858d4049 // ldr z9, [x2, #104, MUL VL]                  
+    WORD $0x858d444a // ldr z10, [x2, #105, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x858d4849 // ldr z9, [x2, #106, MUL VL]                  
+    WORD $0x858d4c4a // ldr z10, [x2, #107, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x858d5049 // ldr z9, [x2, #108, MUL VL]                  
+    WORD $0x858d544a // ldr z10, [x2, #109, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x858d5849 // ldr z9, [x2, #110, MUL VL]                  
+    WORD $0x858d5c4a // ldr z10, [x2, #111, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x8_store
+
+    // Load and process 32 bytes from input 7 to 8 outputs
+    WORD $0x8580418b // ldr z11, [x12]                              
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x858e4049 // ldr z9, [x2, #112, MUL VL]                  
+    WORD $0x858e444a // ldr z10, [x2, #113, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x858e4849 // ldr z9, [x2, #114, MUL VL]                  
+    WORD $0x858e4c4a // ldr z10, [x2, #115, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x858e5049 // ldr z9, [x2, #116, MUL VL]                  
+    WORD $0x858e544a // ldr z10, [x2, #117, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x858e5849 // ldr z9, [x2, #118, MUL VL]                  
+    WORD $0x858e5c4a // ldr z10, [x2, #119, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x858f4049 // ldr z9, [x2, #120, MUL VL]                  
+    WORD $0x858f444a // ldr z10, [x2, #121, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x858f4849 // ldr z9, [x2, #122, MUL VL]                  
+    WORD $0x858f4c4a // ldr z10, [x2, #123, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x858f5049 // ldr z9, [x2, #124, MUL VL]                  
+    WORD $0x858f544a // ldr z10, [x2, #125, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x858f5849 // ldr z9, [x2, #126, MUL VL]                  
+    WORD $0x858f5c4a // ldr z10, [x2, #127, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x8_store
+
+    // Load and process 32 bytes from input 8 to 8 outputs
+    WORD $0x858041ab // ldr z11, [x13]                              
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x85904049 // ldr z9, [x2, #128, MUL VL]                  
+    WORD $0x8590444a // ldr z10, [x2, #129, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x85904849 // ldr z9, [x2, #130, MUL VL]                  
+    WORD $0x85904c4a // ldr z10, [x2, #131, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85905049 // ldr z9, [x2, #132, MUL VL]                  
+    WORD $0x8590544a // ldr z10, [x2, #133, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x85905849 // ldr z9, [x2, #134, MUL VL]                  
+    WORD $0x85905c4a // ldr z10, [x2, #135, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85914049 // ldr z9, [x2, #136, MUL VL]                  
+    WORD $0x8591444a // ldr z10, [x2, #137, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x85914849 // ldr z9, [x2, #138, MUL VL]                  
+    WORD $0x85914c4a // ldr z10, [x2, #139, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x85915049 // ldr z9, [x2, #140, MUL VL]                  
+    WORD $0x8591544a // ldr z10, [x2, #141, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x85915849 // ldr z9, [x2, #142, MUL VL]                  
+    WORD $0x85915c4a // ldr z10, [x2, #143, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x8_store
+
+    // Load and process 32 bytes from input 9 to 8 outputs
+    WORD $0x8580406b // ldr z11, [x3]                               
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x85924049 // ldr z9, [x2, #144, MUL VL]                  
+    WORD $0x8592444a // ldr z10, [x2, #145, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x85924849 // ldr z9, [x2, #146, MUL VL]                  
+    WORD $0x85924c4a // ldr z10, [x2, #147, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85925049 // ldr z9, [x2, #148, MUL VL]                  
+    WORD $0x8592544a // ldr z10, [x2, #149, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x85925849 // ldr z9, [x2, #150, MUL VL]                  
+    WORD $0x85925c4a // ldr z10, [x2, #151, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85934049 // ldr z9, [x2, #152, MUL VL]                  
+    WORD $0x8593444a // ldr z10, [x2, #153, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x85934849 // ldr z9, [x2, #154, MUL VL]                  
+    WORD $0x85934c4a // ldr z10, [x2, #155, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x85935049 // ldr z9, [x2, #156, MUL VL]                  
+    WORD $0x8593544a // ldr z10, [x2, #157, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x85935849 // ldr z9, [x2, #158, MUL VL]                  
+    WORD $0x85935c4a // ldr z10, [x2, #159, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+
+mulSve_10x8_store:
+    // Store 8 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+    MOVD 96(R14), R6
+    WORD $0xe5ef40c4 // st1d { z4.d }, p0, [x6, x15, lsl #3]        
+    MOVD 120(R14), R6
+    WORD $0xe5ef40c5 // st1d { z5.d }, p0, [x6, x15, lsl #3]        
+    MOVD 144(R14), R6
+    WORD $0xe5ef40c6 // st1d { z6.d }, p0, [x6, x15, lsl #3]        
+    MOVD 168(R14), R6
+    WORD $0xe5ef40c7 // st1d { z7.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x8_loop
+
+mulSve_10x8_end:
+    RET
+
+// func mulSve_10x8Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x8Xor(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 173 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x8Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c8 // mov z8.d, x6                                
+    WORD $0x05212108 // dup z8.b, z8.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x8Xor_loop:
+    // Load and process 32 bytes from input 0 to 8 outputs
+    WORD $0x8580402b // ldr z11, [x1]                               
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    MOVD (R14), R6
+    WORD $0xa5ef40c0 // ld1d { z0.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85804049 // ldr z9, [x2]                                
+    WORD $0x8580444a // ldr z10, [x2, #1, MUL VL]                   
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    MOVD 24(R14), R6
+    WORD $0xa5ef40c1 // ld1d { z1.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85804849 // ldr z9, [x2, #2, MUL VL]                    
+    WORD $0x85804c4a // ldr z10, [x2, #3, MUL VL]                   
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    MOVD 48(R14), R6
+    WORD $0xa5ef40c2 // ld1d { z2.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85805049 // ldr z9, [x2, #4, MUL VL]                    
+    WORD $0x8580544a // ldr z10, [x2, #5, MUL VL]                   
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    MOVD 72(R14), R6
+    WORD $0xa5ef40c3 // ld1d { z3.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85805849 // ldr z9, [x2, #6, MUL VL]                    
+    WORD $0x85805c4a // ldr z10, [x2, #7, MUL VL]                   
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    MOVD 96(R14), R6
+    WORD $0xa5ef40c4 // ld1d { z4.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85814049 // ldr z9, [x2, #8, MUL VL]                    
+    WORD $0x8581444a // ldr z10, [x2, #9, MUL VL]                   
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    MOVD 120(R14), R6
+    WORD $0xa5ef40c5 // ld1d { z5.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85814849 // ldr z9, [x2, #10, MUL VL]                   
+    WORD $0x85814c4a // ldr z10, [x2, #11, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    MOVD 144(R14), R6
+    WORD $0xa5ef40c6 // ld1d { z6.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85815049 // ldr z9, [x2, #12, MUL VL]                   
+    WORD $0x8581544a // ldr z10, [x2, #13, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    MOVD 168(R14), R6
+    WORD $0xa5ef40c7 // ld1d { z7.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x85815849 // ldr z9, [x2, #14, MUL VL]                   
+    WORD $0x85815c4a // ldr z10, [x2, #15, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x8Xor_store
+
+    // Load and process 32 bytes from input 1 to 8 outputs
+    WORD $0x8580408b // ldr z11, [x4]                               
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x85824049 // ldr z9, [x2, #16, MUL VL]                   
+    WORD $0x8582444a // ldr z10, [x2, #17, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x85824849 // ldr z9, [x2, #18, MUL VL]                   
+    WORD $0x85824c4a // ldr z10, [x2, #19, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85825049 // ldr z9, [x2, #20, MUL VL]                   
+    WORD $0x8582544a // ldr z10, [x2, #21, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x85825849 // ldr z9, [x2, #22, MUL VL]                   
+    WORD $0x85825c4a // ldr z10, [x2, #23, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85834049 // ldr z9, [x2, #24, MUL VL]                   
+    WORD $0x8583444a // ldr z10, [x2, #25, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x85834849 // ldr z9, [x2, #26, MUL VL]                   
+    WORD $0x85834c4a // ldr z10, [x2, #27, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x85835049 // ldr z9, [x2, #28, MUL VL]                   
+    WORD $0x8583544a // ldr z10, [x2, #29, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x85835849 // ldr z9, [x2, #30, MUL VL]                   
+    WORD $0x85835c4a // ldr z10, [x2, #31, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x8Xor_store
+
+    // Load and process 32 bytes from input 2 to 8 outputs
+    WORD $0x858040ab // ldr z11, [x5]                               
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x85844049 // ldr z9, [x2, #32, MUL VL]                   
+    WORD $0x8584444a // ldr z10, [x2, #33, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x85844849 // ldr z9, [x2, #34, MUL VL]                   
+    WORD $0x85844c4a // ldr z10, [x2, #35, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85845049 // ldr z9, [x2, #36, MUL VL]                   
+    WORD $0x8584544a // ldr z10, [x2, #37, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x85845849 // ldr z9, [x2, #38, MUL VL]                   
+    WORD $0x85845c4a // ldr z10, [x2, #39, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85854049 // ldr z9, [x2, #40, MUL VL]                   
+    WORD $0x8585444a // ldr z10, [x2, #41, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x85854849 // ldr z9, [x2, #42, MUL VL]                   
+    WORD $0x85854c4a // ldr z10, [x2, #43, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x85855049 // ldr z9, [x2, #44, MUL VL]                   
+    WORD $0x8585544a // ldr z10, [x2, #45, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x85855849 // ldr z9, [x2, #46, MUL VL]                   
+    WORD $0x85855c4a // ldr z10, [x2, #47, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x8Xor_store
+
+    // Load and process 32 bytes from input 3 to 8 outputs
+    WORD $0x8580410b // ldr z11, [x8]                               
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x85864049 // ldr z9, [x2, #48, MUL VL]                   
+    WORD $0x8586444a // ldr z10, [x2, #49, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x85864849 // ldr z9, [x2, #50, MUL VL]                   
+    WORD $0x85864c4a // ldr z10, [x2, #51, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85865049 // ldr z9, [x2, #52, MUL VL]                   
+    WORD $0x8586544a // ldr z10, [x2, #53, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x85865849 // ldr z9, [x2, #54, MUL VL]                   
+    WORD $0x85865c4a // ldr z10, [x2, #55, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85874049 // ldr z9, [x2, #56, MUL VL]                   
+    WORD $0x8587444a // ldr z10, [x2, #57, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x85874849 // ldr z9, [x2, #58, MUL VL]                   
+    WORD $0x85874c4a // ldr z10, [x2, #59, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x85875049 // ldr z9, [x2, #60, MUL VL]                   
+    WORD $0x8587544a // ldr z10, [x2, #61, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x85875849 // ldr z9, [x2, #62, MUL VL]                   
+    WORD $0x85875c4a // ldr z10, [x2, #63, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x8Xor_store
+
+    // Load and process 32 bytes from input 4 to 8 outputs
+    WORD $0x8580412b // ldr z11, [x9]                               
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x85884049 // ldr z9, [x2, #64, MUL VL]                   
+    WORD $0x8588444a // ldr z10, [x2, #65, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x85884849 // ldr z9, [x2, #66, MUL VL]                   
+    WORD $0x85884c4a // ldr z10, [x2, #67, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85885049 // ldr z9, [x2, #68, MUL VL]                   
+    WORD $0x8588544a // ldr z10, [x2, #69, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x85885849 // ldr z9, [x2, #70, MUL VL]                   
+    WORD $0x85885c4a // ldr z10, [x2, #71, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85894049 // ldr z9, [x2, #72, MUL VL]                   
+    WORD $0x8589444a // ldr z10, [x2, #73, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x85894849 // ldr z9, [x2, #74, MUL VL]                   
+    WORD $0x85894c4a // ldr z10, [x2, #75, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x85895049 // ldr z9, [x2, #76, MUL VL]                   
+    WORD $0x8589544a // ldr z10, [x2, #77, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x85895849 // ldr z9, [x2, #78, MUL VL]                   
+    WORD $0x85895c4a // ldr z10, [x2, #79, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x8Xor_store
+
+    // Load and process 32 bytes from input 5 to 8 outputs
+    WORD $0x8580414b // ldr z11, [x10]                              
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x858a4049 // ldr z9, [x2, #80, MUL VL]                   
+    WORD $0x858a444a // ldr z10, [x2, #81, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x858a4849 // ldr z9, [x2, #82, MUL VL]                   
+    WORD $0x858a4c4a // ldr z10, [x2, #83, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x858a5049 // ldr z9, [x2, #84, MUL VL]                   
+    WORD $0x858a544a // ldr z10, [x2, #85, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x858a5849 // ldr z9, [x2, #86, MUL VL]                   
+    WORD $0x858a5c4a // ldr z10, [x2, #87, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x858b4049 // ldr z9, [x2, #88, MUL VL]                   
+    WORD $0x858b444a // ldr z10, [x2, #89, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x858b4849 // ldr z9, [x2, #90, MUL VL]                   
+    WORD $0x858b4c4a // ldr z10, [x2, #91, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x858b5049 // ldr z9, [x2, #92, MUL VL]                   
+    WORD $0x858b544a // ldr z10, [x2, #93, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x858b5849 // ldr z9, [x2, #94, MUL VL]                   
+    WORD $0x858b5c4a // ldr z10, [x2, #95, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x8Xor_store
+
+    // Load and process 32 bytes from input 6 to 8 outputs
+    WORD $0x8580416b // ldr z11, [x11]                              
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x858c4049 // ldr z9, [x2, #96, MUL VL]                   
+    WORD $0x858c444a // ldr z10, [x2, #97, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x858c4849 // ldr z9, [x2, #98, MUL VL]                   
+    WORD $0x858c4c4a // ldr z10, [x2, #99, MUL VL]                  
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x858c5049 // ldr z9, [x2, #100, MUL VL]                  
+    WORD $0x858c544a // ldr z10, [x2, #101, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x858c5849 // ldr z9, [x2, #102, MUL VL]                  
+    WORD $0x858c5c4a // ldr z10, [x2, #103, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x858d4049 // ldr z9, [x2, #104, MUL VL]                  
+    WORD $0x858d444a // ldr z10, [x2, #105, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x858d4849 // ldr z9, [x2, #106, MUL VL]                  
+    WORD $0x858d4c4a // ldr z10, [x2, #107, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x858d5049 // ldr z9, [x2, #108, MUL VL]                  
+    WORD $0x858d544a // ldr z10, [x2, #109, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x858d5849 // ldr z9, [x2, #110, MUL VL]                  
+    WORD $0x858d5c4a // ldr z10, [x2, #111, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x8Xor_store
+
+    // Load and process 32 bytes from input 7 to 8 outputs
+    WORD $0x8580418b // ldr z11, [x12]                              
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x858e4049 // ldr z9, [x2, #112, MUL VL]                  
+    WORD $0x858e444a // ldr z10, [x2, #113, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x858e4849 // ldr z9, [x2, #114, MUL VL]                  
+    WORD $0x858e4c4a // ldr z10, [x2, #115, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x858e5049 // ldr z9, [x2, #116, MUL VL]                  
+    WORD $0x858e544a // ldr z10, [x2, #117, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x858e5849 // ldr z9, [x2, #118, MUL VL]                  
+    WORD $0x858e5c4a // ldr z10, [x2, #119, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x858f4049 // ldr z9, [x2, #120, MUL VL]                  
+    WORD $0x858f444a // ldr z10, [x2, #121, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x858f4849 // ldr z9, [x2, #122, MUL VL]                  
+    WORD $0x858f4c4a // ldr z10, [x2, #123, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x858f5049 // ldr z9, [x2, #124, MUL VL]                  
+    WORD $0x858f544a // ldr z10, [x2, #125, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x858f5849 // ldr z9, [x2, #126, MUL VL]                  
+    WORD $0x858f5c4a // ldr z10, [x2, #127, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x8Xor_store
+
+    // Load and process 32 bytes from input 8 to 8 outputs
+    WORD $0x858041ab // ldr z11, [x13]                              
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x85904049 // ldr z9, [x2, #128, MUL VL]                  
+    WORD $0x8590444a // ldr z10, [x2, #129, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x85904849 // ldr z9, [x2, #130, MUL VL]                  
+    WORD $0x85904c4a // ldr z10, [x2, #131, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85905049 // ldr z9, [x2, #132, MUL VL]                  
+    WORD $0x8590544a // ldr z10, [x2, #133, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x85905849 // ldr z9, [x2, #134, MUL VL]                  
+    WORD $0x85905c4a // ldr z10, [x2, #135, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85914049 // ldr z9, [x2, #136, MUL VL]                  
+    WORD $0x8591444a // ldr z10, [x2, #137, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x85914849 // ldr z9, [x2, #138, MUL VL]                  
+    WORD $0x85914c4a // ldr z10, [x2, #139, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x85915049 // ldr z9, [x2, #140, MUL VL]                  
+    WORD $0x8591544a // ldr z10, [x2, #141, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x85915849 // ldr z9, [x2, #142, MUL VL]                  
+    WORD $0x85915c4a // ldr z10, [x2, #143, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x8Xor_store
+
+    // Load and process 32 bytes from input 9 to 8 outputs
+    WORD $0x8580406b // ldr z11, [x3]                               
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc956c // lsr z12.d, z11.d, #4                        
+    WORD $0x0428316b // and z11.d, z11.d, z8.d                      
+    WORD $0x0428318c // and z12.d, z12.d, z8.d                      
+    WORD $0x85924049 // ldr z9, [x2, #144, MUL VL]                  
+    WORD $0x8592444a // ldr z10, [x2, #145, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93000 // eor z0.d, z0.d, z9.d                        
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x85924849 // ldr z9, [x2, #146, MUL VL]                  
+    WORD $0x85924c4a // ldr z10, [x2, #147, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93021 // eor z1.d, z1.d, z9.d                        
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x85925049 // ldr z9, [x2, #148, MUL VL]                  
+    WORD $0x8592544a // ldr z10, [x2, #149, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93042 // eor z2.d, z2.d, z9.d                        
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x85925849 // ldr z9, [x2, #150, MUL VL]                  
+    WORD $0x85925c4a // ldr z10, [x2, #151, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93063 // eor z3.d, z3.d, z9.d                        
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x85934049 // ldr z9, [x2, #152, MUL VL]                  
+    WORD $0x8593444a // ldr z10, [x2, #153, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a93084 // eor z4.d, z4.d, z9.d                        
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x85934849 // ldr z9, [x2, #154, MUL VL]                  
+    WORD $0x85934c4a // ldr z10, [x2, #155, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930a5 // eor z5.d, z5.d, z9.d                        
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x85935049 // ldr z9, [x2, #156, MUL VL]                  
+    WORD $0x8593544a // ldr z10, [x2, #157, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930c6 // eor z6.d, z6.d, z9.d                        
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x85935849 // ldr z9, [x2, #158, MUL VL]                  
+    WORD $0x85935c4a // ldr z10, [x2, #159, MUL VL]                 
+    WORD $0x052b3129 // tbl z9.b, z9.b, z11.b                       
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x04a930e7 // eor z7.d, z7.d, z9.d                        
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+
+mulSve_10x8Xor_store:
+    // Store 8 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+    MOVD 96(R14), R6
+    WORD $0xe5ef40c4 // st1d { z4.d }, p0, [x6, x15, lsl #3]        
+    MOVD 120(R14), R6
+    WORD $0xe5ef40c5 // st1d { z5.d }, p0, [x6, x15, lsl #3]        
+    MOVD 144(R14), R6
+    WORD $0xe5ef40c6 // st1d { z6.d }, p0, [x6, x15, lsl #3]        
+    MOVD 168(R14), R6
+    WORD $0xe5ef40c7 // st1d { z7.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x8Xor_loop
+
+mulSve_10x8Xor_end:
+    RET
+
+// func mulSve_10x9(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x9(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 194 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x9_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c9 // mov z9.d, x6                                
+    WORD $0x05212129 // dup z9.b, z9.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x9_loop:
+    // Load and process 32 bytes from input 0 to 9 outputs
+    WORD $0x8580402c // ldr z12, [x1]                               
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x8580404a // ldr z10, [x2]                               
+    WORD $0x8580444b // ldr z11, [x2, #1, MUL VL]                   
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3160 // eor z0.d, z11.d, z10.d                      
+    WORD $0x8580484a // ldr z10, [x2, #2, MUL VL]                   
+    WORD $0x85804c4b // ldr z11, [x2, #3, MUL VL]                   
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3161 // eor z1.d, z11.d, z10.d                      
+    WORD $0x8580504a // ldr z10, [x2, #4, MUL VL]                   
+    WORD $0x8580544b // ldr z11, [x2, #5, MUL VL]                   
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3162 // eor z2.d, z11.d, z10.d                      
+    WORD $0x8580584a // ldr z10, [x2, #6, MUL VL]                   
+    WORD $0x85805c4b // ldr z11, [x2, #7, MUL VL]                   
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3163 // eor z3.d, z11.d, z10.d                      
+    WORD $0x8581404a // ldr z10, [x2, #8, MUL VL]                   
+    WORD $0x8581444b // ldr z11, [x2, #9, MUL VL]                   
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3164 // eor z4.d, z11.d, z10.d                      
+    WORD $0x8581484a // ldr z10, [x2, #10, MUL VL]                  
+    WORD $0x85814c4b // ldr z11, [x2, #11, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3165 // eor z5.d, z11.d, z10.d                      
+    WORD $0x8581504a // ldr z10, [x2, #12, MUL VL]                  
+    WORD $0x8581544b // ldr z11, [x2, #13, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3166 // eor z6.d, z11.d, z10.d                      
+    WORD $0x8581584a // ldr z10, [x2, #14, MUL VL]                  
+    WORD $0x85815c4b // ldr z11, [x2, #15, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3167 // eor z7.d, z11.d, z10.d                      
+    WORD $0x8582404a // ldr z10, [x2, #16, MUL VL]                  
+    WORD $0x8582444b // ldr z11, [x2, #17, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3168 // eor z8.d, z11.d, z10.d                      
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x9_store
+
+    // Load and process 32 bytes from input 1 to 9 outputs
+    WORD $0x8580408c // ldr z12, [x4]                               
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x8582484a // ldr z10, [x2, #18, MUL VL]                  
+    WORD $0x85824c4b // ldr z11, [x2, #19, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8582504a // ldr z10, [x2, #20, MUL VL]                  
+    WORD $0x8582544b // ldr z11, [x2, #21, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8582584a // ldr z10, [x2, #22, MUL VL]                  
+    WORD $0x85825c4b // ldr z11, [x2, #23, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8583404a // ldr z10, [x2, #24, MUL VL]                  
+    WORD $0x8583444b // ldr z11, [x2, #25, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x8583484a // ldr z10, [x2, #26, MUL VL]                  
+    WORD $0x85834c4b // ldr z11, [x2, #27, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x8583504a // ldr z10, [x2, #28, MUL VL]                  
+    WORD $0x8583544b // ldr z11, [x2, #29, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x8583584a // ldr z10, [x2, #30, MUL VL]                  
+    WORD $0x85835c4b // ldr z11, [x2, #31, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x8584404a // ldr z10, [x2, #32, MUL VL]                  
+    WORD $0x8584444b // ldr z11, [x2, #33, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x8584484a // ldr z10, [x2, #34, MUL VL]                  
+    WORD $0x85844c4b // ldr z11, [x2, #35, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x9_store
+
+    // Load and process 32 bytes from input 2 to 9 outputs
+    WORD $0x858040ac // ldr z12, [x5]                               
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x8584504a // ldr z10, [x2, #36, MUL VL]                  
+    WORD $0x8584544b // ldr z11, [x2, #37, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8584584a // ldr z10, [x2, #38, MUL VL]                  
+    WORD $0x85845c4b // ldr z11, [x2, #39, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8585404a // ldr z10, [x2, #40, MUL VL]                  
+    WORD $0x8585444b // ldr z11, [x2, #41, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8585484a // ldr z10, [x2, #42, MUL VL]                  
+    WORD $0x85854c4b // ldr z11, [x2, #43, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x8585504a // ldr z10, [x2, #44, MUL VL]                  
+    WORD $0x8585544b // ldr z11, [x2, #45, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x8585584a // ldr z10, [x2, #46, MUL VL]                  
+    WORD $0x85855c4b // ldr z11, [x2, #47, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x8586404a // ldr z10, [x2, #48, MUL VL]                  
+    WORD $0x8586444b // ldr z11, [x2, #49, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x8586484a // ldr z10, [x2, #50, MUL VL]                  
+    WORD $0x85864c4b // ldr z11, [x2, #51, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x8586504a // ldr z10, [x2, #52, MUL VL]                  
+    WORD $0x8586544b // ldr z11, [x2, #53, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x9_store
+
+    // Load and process 32 bytes from input 3 to 9 outputs
+    WORD $0x8580410c // ldr z12, [x8]                               
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x8586584a // ldr z10, [x2, #54, MUL VL]                  
+    WORD $0x85865c4b // ldr z11, [x2, #55, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8587404a // ldr z10, [x2, #56, MUL VL]                  
+    WORD $0x8587444b // ldr z11, [x2, #57, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8587484a // ldr z10, [x2, #58, MUL VL]                  
+    WORD $0x85874c4b // ldr z11, [x2, #59, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8587504a // ldr z10, [x2, #60, MUL VL]                  
+    WORD $0x8587544b // ldr z11, [x2, #61, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x8587584a // ldr z10, [x2, #62, MUL VL]                  
+    WORD $0x85875c4b // ldr z11, [x2, #63, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x8588404a // ldr z10, [x2, #64, MUL VL]                  
+    WORD $0x8588444b // ldr z11, [x2, #65, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x8588484a // ldr z10, [x2, #66, MUL VL]                  
+    WORD $0x85884c4b // ldr z11, [x2, #67, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x8588504a // ldr z10, [x2, #68, MUL VL]                  
+    WORD $0x8588544b // ldr z11, [x2, #69, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x8588584a // ldr z10, [x2, #70, MUL VL]                  
+    WORD $0x85885c4b // ldr z11, [x2, #71, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x9_store
+
+    // Load and process 32 bytes from input 4 to 9 outputs
+    WORD $0x8580412c // ldr z12, [x9]                               
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x8589404a // ldr z10, [x2, #72, MUL VL]                  
+    WORD $0x8589444b // ldr z11, [x2, #73, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8589484a // ldr z10, [x2, #74, MUL VL]                  
+    WORD $0x85894c4b // ldr z11, [x2, #75, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8589504a // ldr z10, [x2, #76, MUL VL]                  
+    WORD $0x8589544b // ldr z11, [x2, #77, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8589584a // ldr z10, [x2, #78, MUL VL]                  
+    WORD $0x85895c4b // ldr z11, [x2, #79, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x858a404a // ldr z10, [x2, #80, MUL VL]                  
+    WORD $0x858a444b // ldr z11, [x2, #81, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x858a484a // ldr z10, [x2, #82, MUL VL]                  
+    WORD $0x858a4c4b // ldr z11, [x2, #83, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x858a504a // ldr z10, [x2, #84, MUL VL]                  
+    WORD $0x858a544b // ldr z11, [x2, #85, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x858a584a // ldr z10, [x2, #86, MUL VL]                  
+    WORD $0x858a5c4b // ldr z11, [x2, #87, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x858b404a // ldr z10, [x2, #88, MUL VL]                  
+    WORD $0x858b444b // ldr z11, [x2, #89, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x9_store
+
+    // Load and process 32 bytes from input 5 to 9 outputs
+    WORD $0x8580414c // ldr z12, [x10]                              
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x858b484a // ldr z10, [x2, #90, MUL VL]                  
+    WORD $0x858b4c4b // ldr z11, [x2, #91, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x858b504a // ldr z10, [x2, #92, MUL VL]                  
+    WORD $0x858b544b // ldr z11, [x2, #93, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x858b584a // ldr z10, [x2, #94, MUL VL]                  
+    WORD $0x858b5c4b // ldr z11, [x2, #95, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x858c404a // ldr z10, [x2, #96, MUL VL]                  
+    WORD $0x858c444b // ldr z11, [x2, #97, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x858c484a // ldr z10, [x2, #98, MUL VL]                  
+    WORD $0x858c4c4b // ldr z11, [x2, #99, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x858c504a // ldr z10, [x2, #100, MUL VL]                 
+    WORD $0x858c544b // ldr z11, [x2, #101, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x858c584a // ldr z10, [x2, #102, MUL VL]                 
+    WORD $0x858c5c4b // ldr z11, [x2, #103, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x858d404a // ldr z10, [x2, #104, MUL VL]                 
+    WORD $0x858d444b // ldr z11, [x2, #105, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x858d484a // ldr z10, [x2, #106, MUL VL]                 
+    WORD $0x858d4c4b // ldr z11, [x2, #107, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x9_store
+
+    // Load and process 32 bytes from input 6 to 9 outputs
+    WORD $0x8580416c // ldr z12, [x11]                              
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x858d504a // ldr z10, [x2, #108, MUL VL]                 
+    WORD $0x858d544b // ldr z11, [x2, #109, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x858d584a // ldr z10, [x2, #110, MUL VL]                 
+    WORD $0x858d5c4b // ldr z11, [x2, #111, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x858e404a // ldr z10, [x2, #112, MUL VL]                 
+    WORD $0x858e444b // ldr z11, [x2, #113, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x858e484a // ldr z10, [x2, #114, MUL VL]                 
+    WORD $0x858e4c4b // ldr z11, [x2, #115, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x858e504a // ldr z10, [x2, #116, MUL VL]                 
+    WORD $0x858e544b // ldr z11, [x2, #117, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x858e584a // ldr z10, [x2, #118, MUL VL]                 
+    WORD $0x858e5c4b // ldr z11, [x2, #119, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x858f404a // ldr z10, [x2, #120, MUL VL]                 
+    WORD $0x858f444b // ldr z11, [x2, #121, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x858f484a // ldr z10, [x2, #122, MUL VL]                 
+    WORD $0x858f4c4b // ldr z11, [x2, #123, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x858f504a // ldr z10, [x2, #124, MUL VL]                 
+    WORD $0x858f544b // ldr z11, [x2, #125, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x9_store
+
+    // Load and process 32 bytes from input 7 to 9 outputs
+    WORD $0x8580418c // ldr z12, [x12]                              
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x858f584a // ldr z10, [x2, #126, MUL VL]                 
+    WORD $0x858f5c4b // ldr z11, [x2, #127, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8590404a // ldr z10, [x2, #128, MUL VL]                 
+    WORD $0x8590444b // ldr z11, [x2, #129, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8590484a // ldr z10, [x2, #130, MUL VL]                 
+    WORD $0x85904c4b // ldr z11, [x2, #131, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8590504a // ldr z10, [x2, #132, MUL VL]                 
+    WORD $0x8590544b // ldr z11, [x2, #133, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x8590584a // ldr z10, [x2, #134, MUL VL]                 
+    WORD $0x85905c4b // ldr z11, [x2, #135, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x8591404a // ldr z10, [x2, #136, MUL VL]                 
+    WORD $0x8591444b // ldr z11, [x2, #137, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x8591484a // ldr z10, [x2, #138, MUL VL]                 
+    WORD $0x85914c4b // ldr z11, [x2, #139, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x8591504a // ldr z10, [x2, #140, MUL VL]                 
+    WORD $0x8591544b // ldr z11, [x2, #141, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x8591584a // ldr z10, [x2, #142, MUL VL]                 
+    WORD $0x85915c4b // ldr z11, [x2, #143, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x9_store
+
+    // Load and process 32 bytes from input 8 to 9 outputs
+    WORD $0x858041ac // ldr z12, [x13]                              
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x8592404a // ldr z10, [x2, #144, MUL VL]                 
+    WORD $0x8592444b // ldr z11, [x2, #145, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8592484a // ldr z10, [x2, #146, MUL VL]                 
+    WORD $0x85924c4b // ldr z11, [x2, #147, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8592504a // ldr z10, [x2, #148, MUL VL]                 
+    WORD $0x8592544b // ldr z11, [x2, #149, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8592584a // ldr z10, [x2, #150, MUL VL]                 
+    WORD $0x85925c4b // ldr z11, [x2, #151, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x8593404a // ldr z10, [x2, #152, MUL VL]                 
+    WORD $0x8593444b // ldr z11, [x2, #153, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x8593484a // ldr z10, [x2, #154, MUL VL]                 
+    WORD $0x85934c4b // ldr z11, [x2, #155, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x8593504a // ldr z10, [x2, #156, MUL VL]                 
+    WORD $0x8593544b // ldr z11, [x2, #157, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x8593584a // ldr z10, [x2, #158, MUL VL]                 
+    WORD $0x85935c4b // ldr z11, [x2, #159, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x8594404a // ldr z10, [x2, #160, MUL VL]                 
+    WORD $0x8594444b // ldr z11, [x2, #161, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x9_store
+
+    // Load and process 32 bytes from input 9 to 9 outputs
+    WORD $0x8580406c // ldr z12, [x3]                               
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x8594484a // ldr z10, [x2, #162, MUL VL]                 
+    WORD $0x85944c4b // ldr z11, [x2, #163, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8594504a // ldr z10, [x2, #164, MUL VL]                 
+    WORD $0x8594544b // ldr z11, [x2, #165, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8594584a // ldr z10, [x2, #166, MUL VL]                 
+    WORD $0x85945c4b // ldr z11, [x2, #167, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8595404a // ldr z10, [x2, #168, MUL VL]                 
+    WORD $0x8595444b // ldr z11, [x2, #169, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x8595484a // ldr z10, [x2, #170, MUL VL]                 
+    WORD $0x85954c4b // ldr z11, [x2, #171, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x8595504a // ldr z10, [x2, #172, MUL VL]                 
+    WORD $0x8595544b // ldr z11, [x2, #173, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x8595584a // ldr z10, [x2, #174, MUL VL]                 
+    WORD $0x85955c4b // ldr z11, [x2, #175, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x8596404a // ldr z10, [x2, #176, MUL VL]                 
+    WORD $0x8596444b // ldr z11, [x2, #177, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x8596484a // ldr z10, [x2, #178, MUL VL]                 
+    WORD $0x85964c4b // ldr z11, [x2, #179, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+
+mulSve_10x9_store:
+    // Store 9 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+    MOVD 96(R14), R6
+    WORD $0xe5ef40c4 // st1d { z4.d }, p0, [x6, x15, lsl #3]        
+    MOVD 120(R14), R6
+    WORD $0xe5ef40c5 // st1d { z5.d }, p0, [x6, x15, lsl #3]        
+    MOVD 144(R14), R6
+    WORD $0xe5ef40c6 // st1d { z6.d }, p0, [x6, x15, lsl #3]        
+    MOVD 168(R14), R6
+    WORD $0xe5ef40c7 // st1d { z7.d }, p0, [x6, x15, lsl #3]        
+    MOVD 192(R14), R6
+    WORD $0xe5ef40c8 // st1d { z8.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x9_loop
+
+mulSve_10x9_end:
+    RET
+
+// func mulSve_10x9Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x9Xor(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 194 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x9Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038c9 // mov z9.d, x6                                
+    WORD $0x05212129 // dup z9.b, z9.b[0]                           
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x9Xor_loop:
+    // Load and process 32 bytes from input 0 to 9 outputs
+    WORD $0x8580402c // ldr z12, [x1]                               
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    MOVD (R14), R6
+    WORD $0xa5ef40c0 // ld1d { z0.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8580404a // ldr z10, [x2]                               
+    WORD $0x8580444b // ldr z11, [x2, #1, MUL VL]                   
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    MOVD 24(R14), R6
+    WORD $0xa5ef40c1 // ld1d { z1.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8580484a // ldr z10, [x2, #2, MUL VL]                   
+    WORD $0x85804c4b // ldr z11, [x2, #3, MUL VL]                   
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    MOVD 48(R14), R6
+    WORD $0xa5ef40c2 // ld1d { z2.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8580504a // ldr z10, [x2, #4, MUL VL]                   
+    WORD $0x8580544b // ldr z11, [x2, #5, MUL VL]                   
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    MOVD 72(R14), R6
+    WORD $0xa5ef40c3 // ld1d { z3.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8580584a // ldr z10, [x2, #6, MUL VL]                   
+    WORD $0x85805c4b // ldr z11, [x2, #7, MUL VL]                   
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    MOVD 96(R14), R6
+    WORD $0xa5ef40c4 // ld1d { z4.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8581404a // ldr z10, [x2, #8, MUL VL]                   
+    WORD $0x8581444b // ldr z11, [x2, #9, MUL VL]                   
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    MOVD 120(R14), R6
+    WORD $0xa5ef40c5 // ld1d { z5.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8581484a // ldr z10, [x2, #10, MUL VL]                  
+    WORD $0x85814c4b // ldr z11, [x2, #11, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    MOVD 144(R14), R6
+    WORD $0xa5ef40c6 // ld1d { z6.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8581504a // ldr z10, [x2, #12, MUL VL]                  
+    WORD $0x8581544b // ldr z11, [x2, #13, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    MOVD 168(R14), R6
+    WORD $0xa5ef40c7 // ld1d { z7.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8581584a // ldr z10, [x2, #14, MUL VL]                  
+    WORD $0x85815c4b // ldr z11, [x2, #15, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    MOVD 192(R14), R6
+    WORD $0xa5ef40c8 // ld1d { z8.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8582404a // ldr z10, [x2, #16, MUL VL]                  
+    WORD $0x8582444b // ldr z11, [x2, #17, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x9Xor_store
+
+    // Load and process 32 bytes from input 1 to 9 outputs
+    WORD $0x8580408c // ldr z12, [x4]                               
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x8582484a // ldr z10, [x2, #18, MUL VL]                  
+    WORD $0x85824c4b // ldr z11, [x2, #19, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8582504a // ldr z10, [x2, #20, MUL VL]                  
+    WORD $0x8582544b // ldr z11, [x2, #21, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8582584a // ldr z10, [x2, #22, MUL VL]                  
+    WORD $0x85825c4b // ldr z11, [x2, #23, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8583404a // ldr z10, [x2, #24, MUL VL]                  
+    WORD $0x8583444b // ldr z11, [x2, #25, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x8583484a // ldr z10, [x2, #26, MUL VL]                  
+    WORD $0x85834c4b // ldr z11, [x2, #27, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x8583504a // ldr z10, [x2, #28, MUL VL]                  
+    WORD $0x8583544b // ldr z11, [x2, #29, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x8583584a // ldr z10, [x2, #30, MUL VL]                  
+    WORD $0x85835c4b // ldr z11, [x2, #31, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x8584404a // ldr z10, [x2, #32, MUL VL]                  
+    WORD $0x8584444b // ldr z11, [x2, #33, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x8584484a // ldr z10, [x2, #34, MUL VL]                  
+    WORD $0x85844c4b // ldr z11, [x2, #35, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x9Xor_store
+
+    // Load and process 32 bytes from input 2 to 9 outputs
+    WORD $0x858040ac // ldr z12, [x5]                               
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x8584504a // ldr z10, [x2, #36, MUL VL]                  
+    WORD $0x8584544b // ldr z11, [x2, #37, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8584584a // ldr z10, [x2, #38, MUL VL]                  
+    WORD $0x85845c4b // ldr z11, [x2, #39, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8585404a // ldr z10, [x2, #40, MUL VL]                  
+    WORD $0x8585444b // ldr z11, [x2, #41, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8585484a // ldr z10, [x2, #42, MUL VL]                  
+    WORD $0x85854c4b // ldr z11, [x2, #43, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x8585504a // ldr z10, [x2, #44, MUL VL]                  
+    WORD $0x8585544b // ldr z11, [x2, #45, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x8585584a // ldr z10, [x2, #46, MUL VL]                  
+    WORD $0x85855c4b // ldr z11, [x2, #47, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x8586404a // ldr z10, [x2, #48, MUL VL]                  
+    WORD $0x8586444b // ldr z11, [x2, #49, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x8586484a // ldr z10, [x2, #50, MUL VL]                  
+    WORD $0x85864c4b // ldr z11, [x2, #51, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x8586504a // ldr z10, [x2, #52, MUL VL]                  
+    WORD $0x8586544b // ldr z11, [x2, #53, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x9Xor_store
+
+    // Load and process 32 bytes from input 3 to 9 outputs
+    WORD $0x8580410c // ldr z12, [x8]                               
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x8586584a // ldr z10, [x2, #54, MUL VL]                  
+    WORD $0x85865c4b // ldr z11, [x2, #55, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8587404a // ldr z10, [x2, #56, MUL VL]                  
+    WORD $0x8587444b // ldr z11, [x2, #57, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8587484a // ldr z10, [x2, #58, MUL VL]                  
+    WORD $0x85874c4b // ldr z11, [x2, #59, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8587504a // ldr z10, [x2, #60, MUL VL]                  
+    WORD $0x8587544b // ldr z11, [x2, #61, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x8587584a // ldr z10, [x2, #62, MUL VL]                  
+    WORD $0x85875c4b // ldr z11, [x2, #63, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x8588404a // ldr z10, [x2, #64, MUL VL]                  
+    WORD $0x8588444b // ldr z11, [x2, #65, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x8588484a // ldr z10, [x2, #66, MUL VL]                  
+    WORD $0x85884c4b // ldr z11, [x2, #67, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x8588504a // ldr z10, [x2, #68, MUL VL]                  
+    WORD $0x8588544b // ldr z11, [x2, #69, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x8588584a // ldr z10, [x2, #70, MUL VL]                  
+    WORD $0x85885c4b // ldr z11, [x2, #71, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x9Xor_store
+
+    // Load and process 32 bytes from input 4 to 9 outputs
+    WORD $0x8580412c // ldr z12, [x9]                               
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x8589404a // ldr z10, [x2, #72, MUL VL]                  
+    WORD $0x8589444b // ldr z11, [x2, #73, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8589484a // ldr z10, [x2, #74, MUL VL]                  
+    WORD $0x85894c4b // ldr z11, [x2, #75, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8589504a // ldr z10, [x2, #76, MUL VL]                  
+    WORD $0x8589544b // ldr z11, [x2, #77, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8589584a // ldr z10, [x2, #78, MUL VL]                  
+    WORD $0x85895c4b // ldr z11, [x2, #79, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x858a404a // ldr z10, [x2, #80, MUL VL]                  
+    WORD $0x858a444b // ldr z11, [x2, #81, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x858a484a // ldr z10, [x2, #82, MUL VL]                  
+    WORD $0x858a4c4b // ldr z11, [x2, #83, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x858a504a // ldr z10, [x2, #84, MUL VL]                  
+    WORD $0x858a544b // ldr z11, [x2, #85, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x858a584a // ldr z10, [x2, #86, MUL VL]                  
+    WORD $0x858a5c4b // ldr z11, [x2, #87, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x858b404a // ldr z10, [x2, #88, MUL VL]                  
+    WORD $0x858b444b // ldr z11, [x2, #89, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x9Xor_store
+
+    // Load and process 32 bytes from input 5 to 9 outputs
+    WORD $0x8580414c // ldr z12, [x10]                              
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x858b484a // ldr z10, [x2, #90, MUL VL]                  
+    WORD $0x858b4c4b // ldr z11, [x2, #91, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x858b504a // ldr z10, [x2, #92, MUL VL]                  
+    WORD $0x858b544b // ldr z11, [x2, #93, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x858b584a // ldr z10, [x2, #94, MUL VL]                  
+    WORD $0x858b5c4b // ldr z11, [x2, #95, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x858c404a // ldr z10, [x2, #96, MUL VL]                  
+    WORD $0x858c444b // ldr z11, [x2, #97, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x858c484a // ldr z10, [x2, #98, MUL VL]                  
+    WORD $0x858c4c4b // ldr z11, [x2, #99, MUL VL]                  
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x858c504a // ldr z10, [x2, #100, MUL VL]                 
+    WORD $0x858c544b // ldr z11, [x2, #101, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x858c584a // ldr z10, [x2, #102, MUL VL]                 
+    WORD $0x858c5c4b // ldr z11, [x2, #103, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x858d404a // ldr z10, [x2, #104, MUL VL]                 
+    WORD $0x858d444b // ldr z11, [x2, #105, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x858d484a // ldr z10, [x2, #106, MUL VL]                 
+    WORD $0x858d4c4b // ldr z11, [x2, #107, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x9Xor_store
+
+    // Load and process 32 bytes from input 6 to 9 outputs
+    WORD $0x8580416c // ldr z12, [x11]                              
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x858d504a // ldr z10, [x2, #108, MUL VL]                 
+    WORD $0x858d544b // ldr z11, [x2, #109, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x858d584a // ldr z10, [x2, #110, MUL VL]                 
+    WORD $0x858d5c4b // ldr z11, [x2, #111, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x858e404a // ldr z10, [x2, #112, MUL VL]                 
+    WORD $0x858e444b // ldr z11, [x2, #113, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x858e484a // ldr z10, [x2, #114, MUL VL]                 
+    WORD $0x858e4c4b // ldr z11, [x2, #115, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x858e504a // ldr z10, [x2, #116, MUL VL]                 
+    WORD $0x858e544b // ldr z11, [x2, #117, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x858e584a // ldr z10, [x2, #118, MUL VL]                 
+    WORD $0x858e5c4b // ldr z11, [x2, #119, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x858f404a // ldr z10, [x2, #120, MUL VL]                 
+    WORD $0x858f444b // ldr z11, [x2, #121, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x858f484a // ldr z10, [x2, #122, MUL VL]                 
+    WORD $0x858f4c4b // ldr z11, [x2, #123, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x858f504a // ldr z10, [x2, #124, MUL VL]                 
+    WORD $0x858f544b // ldr z11, [x2, #125, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x9Xor_store
+
+    // Load and process 32 bytes from input 7 to 9 outputs
+    WORD $0x8580418c // ldr z12, [x12]                              
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x858f584a // ldr z10, [x2, #126, MUL VL]                 
+    WORD $0x858f5c4b // ldr z11, [x2, #127, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8590404a // ldr z10, [x2, #128, MUL VL]                 
+    WORD $0x8590444b // ldr z11, [x2, #129, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8590484a // ldr z10, [x2, #130, MUL VL]                 
+    WORD $0x85904c4b // ldr z11, [x2, #131, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8590504a // ldr z10, [x2, #132, MUL VL]                 
+    WORD $0x8590544b // ldr z11, [x2, #133, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x8590584a // ldr z10, [x2, #134, MUL VL]                 
+    WORD $0x85905c4b // ldr z11, [x2, #135, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x8591404a // ldr z10, [x2, #136, MUL VL]                 
+    WORD $0x8591444b // ldr z11, [x2, #137, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x8591484a // ldr z10, [x2, #138, MUL VL]                 
+    WORD $0x85914c4b // ldr z11, [x2, #139, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x8591504a // ldr z10, [x2, #140, MUL VL]                 
+    WORD $0x8591544b // ldr z11, [x2, #141, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x8591584a // ldr z10, [x2, #142, MUL VL]                 
+    WORD $0x85915c4b // ldr z11, [x2, #143, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x9Xor_store
+
+    // Load and process 32 bytes from input 8 to 9 outputs
+    WORD $0x858041ac // ldr z12, [x13]                              
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x8592404a // ldr z10, [x2, #144, MUL VL]                 
+    WORD $0x8592444b // ldr z11, [x2, #145, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8592484a // ldr z10, [x2, #146, MUL VL]                 
+    WORD $0x85924c4b // ldr z11, [x2, #147, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8592504a // ldr z10, [x2, #148, MUL VL]                 
+    WORD $0x8592544b // ldr z11, [x2, #149, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8592584a // ldr z10, [x2, #150, MUL VL]                 
+    WORD $0x85925c4b // ldr z11, [x2, #151, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x8593404a // ldr z10, [x2, #152, MUL VL]                 
+    WORD $0x8593444b // ldr z11, [x2, #153, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x8593484a // ldr z10, [x2, #154, MUL VL]                 
+    WORD $0x85934c4b // ldr z11, [x2, #155, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x8593504a // ldr z10, [x2, #156, MUL VL]                 
+    WORD $0x8593544b // ldr z11, [x2, #157, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x8593584a // ldr z10, [x2, #158, MUL VL]                 
+    WORD $0x85935c4b // ldr z11, [x2, #159, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x8594404a // ldr z10, [x2, #160, MUL VL]                 
+    WORD $0x8594444b // ldr z11, [x2, #161, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x9Xor_store
+
+    // Load and process 32 bytes from input 9 to 9 outputs
+    WORD $0x8580406c // ldr z12, [x3]                               
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc958d // lsr z13.d, z12.d, #4                        
+    WORD $0x0429318c // and z12.d, z12.d, z9.d                      
+    WORD $0x042931ad // and z13.d, z13.d, z9.d                      
+    WORD $0x8594484a // ldr z10, [x2, #162, MUL VL]                 
+    WORD $0x85944c4b // ldr z11, [x2, #163, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3000 // eor z0.d, z0.d, z10.d                       
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x8594504a // ldr z10, [x2, #164, MUL VL]                 
+    WORD $0x8594544b // ldr z11, [x2, #165, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3021 // eor z1.d, z1.d, z10.d                       
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x8594584a // ldr z10, [x2, #166, MUL VL]                 
+    WORD $0x85945c4b // ldr z11, [x2, #167, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3042 // eor z2.d, z2.d, z10.d                       
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x8595404a // ldr z10, [x2, #168, MUL VL]                 
+    WORD $0x8595444b // ldr z11, [x2, #169, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3063 // eor z3.d, z3.d, z10.d                       
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x8595484a // ldr z10, [x2, #170, MUL VL]                 
+    WORD $0x85954c4b // ldr z11, [x2, #171, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3084 // eor z4.d, z4.d, z10.d                       
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x8595504a // ldr z10, [x2, #172, MUL VL]                 
+    WORD $0x8595544b // ldr z11, [x2, #173, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30a5 // eor z5.d, z5.d, z10.d                       
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x8595584a // ldr z10, [x2, #174, MUL VL]                 
+    WORD $0x85955c4b // ldr z11, [x2, #175, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30c6 // eor z6.d, z6.d, z10.d                       
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x8596404a // ldr z10, [x2, #176, MUL VL]                 
+    WORD $0x8596444b // ldr z11, [x2, #177, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa30e7 // eor z7.d, z7.d, z10.d                       
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x8596484a // ldr z10, [x2, #178, MUL VL]                 
+    WORD $0x85964c4b // ldr z11, [x2, #179, MUL VL]                 
+    WORD $0x052c314a // tbl z10.b, z10.b, z12.b                     
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x04aa3108 // eor z8.d, z8.d, z10.d                       
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+
+mulSve_10x9Xor_store:
+    // Store 9 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+    MOVD 96(R14), R6
+    WORD $0xe5ef40c4 // st1d { z4.d }, p0, [x6, x15, lsl #3]        
+    MOVD 120(R14), R6
+    WORD $0xe5ef40c5 // st1d { z5.d }, p0, [x6, x15, lsl #3]        
+    MOVD 144(R14), R6
+    WORD $0xe5ef40c6 // st1d { z6.d }, p0, [x6, x15, lsl #3]        
+    MOVD 168(R14), R6
+    WORD $0xe5ef40c7 // st1d { z7.d }, p0, [x6, x15, lsl #3]        
+    MOVD 192(R14), R6
+    WORD $0xe5ef40c8 // st1d { z8.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x9Xor_loop
+
+mulSve_10x9Xor_end:
+    RET
+
+// func mulSve_10x10(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x10(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 215 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x10_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038ca // mov z10.d, x6                               
+    WORD $0x0521214a // dup z10.b, z10.b[0]                         
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x10_loop:
+    // Load and process 32 bytes from input 0 to 10 outputs
+    WORD $0x8580402d // ldr z13, [x1]                               
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x8580404b // ldr z11, [x2]                               
+    WORD $0x8580444c // ldr z12, [x2, #1, MUL VL]                   
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3180 // eor z0.d, z12.d, z11.d                      
+    WORD $0x8580484b // ldr z11, [x2, #2, MUL VL]                   
+    WORD $0x85804c4c // ldr z12, [x2, #3, MUL VL]                   
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3181 // eor z1.d, z12.d, z11.d                      
+    WORD $0x8580504b // ldr z11, [x2, #4, MUL VL]                   
+    WORD $0x8580544c // ldr z12, [x2, #5, MUL VL]                   
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3182 // eor z2.d, z12.d, z11.d                      
+    WORD $0x8580584b // ldr z11, [x2, #6, MUL VL]                   
+    WORD $0x85805c4c // ldr z12, [x2, #7, MUL VL]                   
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3183 // eor z3.d, z12.d, z11.d                      
+    WORD $0x8581404b // ldr z11, [x2, #8, MUL VL]                   
+    WORD $0x8581444c // ldr z12, [x2, #9, MUL VL]                   
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3184 // eor z4.d, z12.d, z11.d                      
+    WORD $0x8581484b // ldr z11, [x2, #10, MUL VL]                  
+    WORD $0x85814c4c // ldr z12, [x2, #11, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3185 // eor z5.d, z12.d, z11.d                      
+    WORD $0x8581504b // ldr z11, [x2, #12, MUL VL]                  
+    WORD $0x8581544c // ldr z12, [x2, #13, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3186 // eor z6.d, z12.d, z11.d                      
+    WORD $0x8581584b // ldr z11, [x2, #14, MUL VL]                  
+    WORD $0x85815c4c // ldr z12, [x2, #15, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3187 // eor z7.d, z12.d, z11.d                      
+    WORD $0x8582404b // ldr z11, [x2, #16, MUL VL]                  
+    WORD $0x8582444c // ldr z12, [x2, #17, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3188 // eor z8.d, z12.d, z11.d                      
+    WORD $0x8582484b // ldr z11, [x2, #18, MUL VL]                  
+    WORD $0x85824c4c // ldr z12, [x2, #19, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3189 // eor z9.d, z12.d, z11.d                      
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x10_store
+
+    // Load and process 32 bytes from input 1 to 10 outputs
+    WORD $0x8580408d // ldr z13, [x4]                               
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x8582504b // ldr z11, [x2, #20, MUL VL]                  
+    WORD $0x8582544c // ldr z12, [x2, #21, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x8582584b // ldr z11, [x2, #22, MUL VL]                  
+    WORD $0x85825c4c // ldr z12, [x2, #23, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x8583404b // ldr z11, [x2, #24, MUL VL]                  
+    WORD $0x8583444c // ldr z12, [x2, #25, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x8583484b // ldr z11, [x2, #26, MUL VL]                  
+    WORD $0x85834c4c // ldr z12, [x2, #27, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8583504b // ldr z11, [x2, #28, MUL VL]                  
+    WORD $0x8583544c // ldr z12, [x2, #29, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8583584b // ldr z11, [x2, #30, MUL VL]                  
+    WORD $0x85835c4c // ldr z12, [x2, #31, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8584404b // ldr z11, [x2, #32, MUL VL]                  
+    WORD $0x8584444c // ldr z12, [x2, #33, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8584484b // ldr z11, [x2, #34, MUL VL]                  
+    WORD $0x85844c4c // ldr z12, [x2, #35, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8584504b // ldr z11, [x2, #36, MUL VL]                  
+    WORD $0x8584544c // ldr z12, [x2, #37, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8584584b // ldr z11, [x2, #38, MUL VL]                  
+    WORD $0x85845c4c // ldr z12, [x2, #39, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x10_store
+
+    // Load and process 32 bytes from input 2 to 10 outputs
+    WORD $0x858040ad // ldr z13, [x5]                               
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x8585404b // ldr z11, [x2, #40, MUL VL]                  
+    WORD $0x8585444c // ldr z12, [x2, #41, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x8585484b // ldr z11, [x2, #42, MUL VL]                  
+    WORD $0x85854c4c // ldr z12, [x2, #43, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x8585504b // ldr z11, [x2, #44, MUL VL]                  
+    WORD $0x8585544c // ldr z12, [x2, #45, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x8585584b // ldr z11, [x2, #46, MUL VL]                  
+    WORD $0x85855c4c // ldr z12, [x2, #47, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8586404b // ldr z11, [x2, #48, MUL VL]                  
+    WORD $0x8586444c // ldr z12, [x2, #49, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8586484b // ldr z11, [x2, #50, MUL VL]                  
+    WORD $0x85864c4c // ldr z12, [x2, #51, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8586504b // ldr z11, [x2, #52, MUL VL]                  
+    WORD $0x8586544c // ldr z12, [x2, #53, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8586584b // ldr z11, [x2, #54, MUL VL]                  
+    WORD $0x85865c4c // ldr z12, [x2, #55, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8587404b // ldr z11, [x2, #56, MUL VL]                  
+    WORD $0x8587444c // ldr z12, [x2, #57, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8587484b // ldr z11, [x2, #58, MUL VL]                  
+    WORD $0x85874c4c // ldr z12, [x2, #59, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x10_store
+
+    // Load and process 32 bytes from input 3 to 10 outputs
+    WORD $0x8580410d // ldr z13, [x8]                               
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x8587504b // ldr z11, [x2, #60, MUL VL]                  
+    WORD $0x8587544c // ldr z12, [x2, #61, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x8587584b // ldr z11, [x2, #62, MUL VL]                  
+    WORD $0x85875c4c // ldr z12, [x2, #63, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x8588404b // ldr z11, [x2, #64, MUL VL]                  
+    WORD $0x8588444c // ldr z12, [x2, #65, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x8588484b // ldr z11, [x2, #66, MUL VL]                  
+    WORD $0x85884c4c // ldr z12, [x2, #67, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8588504b // ldr z11, [x2, #68, MUL VL]                  
+    WORD $0x8588544c // ldr z12, [x2, #69, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8588584b // ldr z11, [x2, #70, MUL VL]                  
+    WORD $0x85885c4c // ldr z12, [x2, #71, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8589404b // ldr z11, [x2, #72, MUL VL]                  
+    WORD $0x8589444c // ldr z12, [x2, #73, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8589484b // ldr z11, [x2, #74, MUL VL]                  
+    WORD $0x85894c4c // ldr z12, [x2, #75, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8589504b // ldr z11, [x2, #76, MUL VL]                  
+    WORD $0x8589544c // ldr z12, [x2, #77, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8589584b // ldr z11, [x2, #78, MUL VL]                  
+    WORD $0x85895c4c // ldr z12, [x2, #79, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x10_store
+
+    // Load and process 32 bytes from input 4 to 10 outputs
+    WORD $0x8580412d // ldr z13, [x9]                               
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x858a404b // ldr z11, [x2, #80, MUL VL]                  
+    WORD $0x858a444c // ldr z12, [x2, #81, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x858a484b // ldr z11, [x2, #82, MUL VL]                  
+    WORD $0x858a4c4c // ldr z12, [x2, #83, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x858a504b // ldr z11, [x2, #84, MUL VL]                  
+    WORD $0x858a544c // ldr z12, [x2, #85, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x858a584b // ldr z11, [x2, #86, MUL VL]                  
+    WORD $0x858a5c4c // ldr z12, [x2, #87, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x858b404b // ldr z11, [x2, #88, MUL VL]                  
+    WORD $0x858b444c // ldr z12, [x2, #89, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x858b484b // ldr z11, [x2, #90, MUL VL]                  
+    WORD $0x858b4c4c // ldr z12, [x2, #91, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x858b504b // ldr z11, [x2, #92, MUL VL]                  
+    WORD $0x858b544c // ldr z12, [x2, #93, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x858b584b // ldr z11, [x2, #94, MUL VL]                  
+    WORD $0x858b5c4c // ldr z12, [x2, #95, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x858c404b // ldr z11, [x2, #96, MUL VL]                  
+    WORD $0x858c444c // ldr z12, [x2, #97, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x858c484b // ldr z11, [x2, #98, MUL VL]                  
+    WORD $0x858c4c4c // ldr z12, [x2, #99, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x10_store
+
+    // Load and process 32 bytes from input 5 to 10 outputs
+    WORD $0x8580414d // ldr z13, [x10]                              
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x858c504b // ldr z11, [x2, #100, MUL VL]                 
+    WORD $0x858c544c // ldr z12, [x2, #101, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x858c584b // ldr z11, [x2, #102, MUL VL]                 
+    WORD $0x858c5c4c // ldr z12, [x2, #103, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x858d404b // ldr z11, [x2, #104, MUL VL]                 
+    WORD $0x858d444c // ldr z12, [x2, #105, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x858d484b // ldr z11, [x2, #106, MUL VL]                 
+    WORD $0x858d4c4c // ldr z12, [x2, #107, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x858d504b // ldr z11, [x2, #108, MUL VL]                 
+    WORD $0x858d544c // ldr z12, [x2, #109, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x858d584b // ldr z11, [x2, #110, MUL VL]                 
+    WORD $0x858d5c4c // ldr z12, [x2, #111, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x858e404b // ldr z11, [x2, #112, MUL VL]                 
+    WORD $0x858e444c // ldr z12, [x2, #113, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x858e484b // ldr z11, [x2, #114, MUL VL]                 
+    WORD $0x858e4c4c // ldr z12, [x2, #115, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x858e504b // ldr z11, [x2, #116, MUL VL]                 
+    WORD $0x858e544c // ldr z12, [x2, #117, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x858e584b // ldr z11, [x2, #118, MUL VL]                 
+    WORD $0x858e5c4c // ldr z12, [x2, #119, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x10_store
+
+    // Load and process 32 bytes from input 6 to 10 outputs
+    WORD $0x8580416d // ldr z13, [x11]                              
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x858f404b // ldr z11, [x2, #120, MUL VL]                 
+    WORD $0x858f444c // ldr z12, [x2, #121, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x858f484b // ldr z11, [x2, #122, MUL VL]                 
+    WORD $0x858f4c4c // ldr z12, [x2, #123, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x858f504b // ldr z11, [x2, #124, MUL VL]                 
+    WORD $0x858f544c // ldr z12, [x2, #125, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x858f584b // ldr z11, [x2, #126, MUL VL]                 
+    WORD $0x858f5c4c // ldr z12, [x2, #127, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8590404b // ldr z11, [x2, #128, MUL VL]                 
+    WORD $0x8590444c // ldr z12, [x2, #129, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8590484b // ldr z11, [x2, #130, MUL VL]                 
+    WORD $0x85904c4c // ldr z12, [x2, #131, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8590504b // ldr z11, [x2, #132, MUL VL]                 
+    WORD $0x8590544c // ldr z12, [x2, #133, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8590584b // ldr z11, [x2, #134, MUL VL]                 
+    WORD $0x85905c4c // ldr z12, [x2, #135, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8591404b // ldr z11, [x2, #136, MUL VL]                 
+    WORD $0x8591444c // ldr z12, [x2, #137, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8591484b // ldr z11, [x2, #138, MUL VL]                 
+    WORD $0x85914c4c // ldr z12, [x2, #139, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x10_store
+
+    // Load and process 32 bytes from input 7 to 10 outputs
+    WORD $0x8580418d // ldr z13, [x12]                              
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x8591504b // ldr z11, [x2, #140, MUL VL]                 
+    WORD $0x8591544c // ldr z12, [x2, #141, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x8591584b // ldr z11, [x2, #142, MUL VL]                 
+    WORD $0x85915c4c // ldr z12, [x2, #143, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x8592404b // ldr z11, [x2, #144, MUL VL]                 
+    WORD $0x8592444c // ldr z12, [x2, #145, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x8592484b // ldr z11, [x2, #146, MUL VL]                 
+    WORD $0x85924c4c // ldr z12, [x2, #147, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8592504b // ldr z11, [x2, #148, MUL VL]                 
+    WORD $0x8592544c // ldr z12, [x2, #149, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8592584b // ldr z11, [x2, #150, MUL VL]                 
+    WORD $0x85925c4c // ldr z12, [x2, #151, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8593404b // ldr z11, [x2, #152, MUL VL]                 
+    WORD $0x8593444c // ldr z12, [x2, #153, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8593484b // ldr z11, [x2, #154, MUL VL]                 
+    WORD $0x85934c4c // ldr z12, [x2, #155, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8593504b // ldr z11, [x2, #156, MUL VL]                 
+    WORD $0x8593544c // ldr z12, [x2, #157, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8593584b // ldr z11, [x2, #158, MUL VL]                 
+    WORD $0x85935c4c // ldr z12, [x2, #159, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x10_store
+
+    // Load and process 32 bytes from input 8 to 10 outputs
+    WORD $0x858041ad // ldr z13, [x13]                              
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x8594404b // ldr z11, [x2, #160, MUL VL]                 
+    WORD $0x8594444c // ldr z12, [x2, #161, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x8594484b // ldr z11, [x2, #162, MUL VL]                 
+    WORD $0x85944c4c // ldr z12, [x2, #163, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x8594504b // ldr z11, [x2, #164, MUL VL]                 
+    WORD $0x8594544c // ldr z12, [x2, #165, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x8594584b // ldr z11, [x2, #166, MUL VL]                 
+    WORD $0x85945c4c // ldr z12, [x2, #167, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8595404b // ldr z11, [x2, #168, MUL VL]                 
+    WORD $0x8595444c // ldr z12, [x2, #169, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8595484b // ldr z11, [x2, #170, MUL VL]                 
+    WORD $0x85954c4c // ldr z12, [x2, #171, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8595504b // ldr z11, [x2, #172, MUL VL]                 
+    WORD $0x8595544c // ldr z12, [x2, #173, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8595584b // ldr z11, [x2, #174, MUL VL]                 
+    WORD $0x85955c4c // ldr z12, [x2, #175, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8596404b // ldr z11, [x2, #176, MUL VL]                 
+    WORD $0x8596444c // ldr z12, [x2, #177, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8596484b // ldr z11, [x2, #178, MUL VL]                 
+    WORD $0x85964c4c // ldr z12, [x2, #179, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x10_store
+
+    // Load and process 32 bytes from input 9 to 10 outputs
+    WORD $0x8580406d // ldr z13, [x3]                               
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x8596504b // ldr z11, [x2, #180, MUL VL]                 
+    WORD $0x8596544c // ldr z12, [x2, #181, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x8596584b // ldr z11, [x2, #182, MUL VL]                 
+    WORD $0x85965c4c // ldr z12, [x2, #183, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x8597404b // ldr z11, [x2, #184, MUL VL]                 
+    WORD $0x8597444c // ldr z12, [x2, #185, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x8597484b // ldr z11, [x2, #186, MUL VL]                 
+    WORD $0x85974c4c // ldr z12, [x2, #187, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8597504b // ldr z11, [x2, #188, MUL VL]                 
+    WORD $0x8597544c // ldr z12, [x2, #189, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8597584b // ldr z11, [x2, #190, MUL VL]                 
+    WORD $0x85975c4c // ldr z12, [x2, #191, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8598404b // ldr z11, [x2, #192, MUL VL]                 
+    WORD $0x8598444c // ldr z12, [x2, #193, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8598484b // ldr z11, [x2, #194, MUL VL]                 
+    WORD $0x85984c4c // ldr z12, [x2, #195, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8598504b // ldr z11, [x2, #196, MUL VL]                 
+    WORD $0x8598544c // ldr z12, [x2, #197, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8598584b // ldr z11, [x2, #198, MUL VL]                 
+    WORD $0x85985c4c // ldr z12, [x2, #199, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+
+mulSve_10x10_store:
+    // Store 10 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+    MOVD 96(R14), R6
+    WORD $0xe5ef40c4 // st1d { z4.d }, p0, [x6, x15, lsl #3]        
+    MOVD 120(R14), R6
+    WORD $0xe5ef40c5 // st1d { z5.d }, p0, [x6, x15, lsl #3]        
+    MOVD 144(R14), R6
+    WORD $0xe5ef40c6 // st1d { z6.d }, p0, [x6, x15, lsl #3]        
+    MOVD 168(R14), R6
+    WORD $0xe5ef40c7 // st1d { z7.d }, p0, [x6, x15, lsl #3]        
+    MOVD 192(R14), R6
+    WORD $0xe5ef40c8 // st1d { z8.d }, p0, [x6, x15, lsl #3]        
+    MOVD 216(R14), R6
+    WORD $0xe5ef40c9 // st1d { z9.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x10_loop
+
+mulSve_10x10_end:
+    RET
+
+// func mulSve_10x10Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: SVE
+TEXT ·mulSve_10x10Xor(SB), NOSPLIT, $8-88
+    WORD $0x25d8e3e0 // ptrue p0.d
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 215 YMM used
+    MOVD n+80(FP), R0
+    MOVD matrix_base+0(FP), R2
+    WORD $0xd345fc00 // lsr x0, x0, #5                              
+    WORD $0xea00001f // tst x0, x0                                  
+    BEQ    mulSve_10x10Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    WORD $0x8b0f0021 // add x1, x1, x15                             
+    WORD $0x8b0f0084 // add x4, x4, x15                             
+    WORD $0x8b0f00a5 // add x5, x5, x15                             
+    WORD $0x8b0f0108 // add x8, x8, x15                             
+    WORD $0x8b0f0129 // add x9, x9, x15                             
+    WORD $0x8b0f014a // add x10, x10, x15                           
+    WORD $0x8b0f016b // add x11, x11, x15                           
+    WORD $0x8b0f018c // add x12, x12, x15                           
+    WORD $0x8b0f01ad // add x13, x13, x15                           
+    WORD $0x8b0f0063 // add x3, x3, x15                             
+    WORD $0xd343fdef // lsr x15, x15, #3                            
+    WORD $0xd28001e6 // mov x6, #15                                 
+    WORD $0x05e038ca // mov z10.d, x6                               
+    WORD $0x0521214a // dup z10.b, z10.b[0]                         
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulSve_10x10Xor_loop:
+    // Load and process 32 bytes from input 0 to 10 outputs
+    WORD $0x8580402d // ldr z13, [x1]                               
+    WORD $0x91008021 // add x1, x1, #32                             
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    MOVD (R14), R6
+    WORD $0xa5ef40c0 // ld1d { z0.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8580404b // ldr z11, [x2]                               
+    WORD $0x8580444c // ldr z12, [x2, #1, MUL VL]                   
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    MOVD 24(R14), R6
+    WORD $0xa5ef40c1 // ld1d { z1.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8580484b // ldr z11, [x2, #2, MUL VL]                   
+    WORD $0x85804c4c // ldr z12, [x2, #3, MUL VL]                   
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    MOVD 48(R14), R6
+    WORD $0xa5ef40c2 // ld1d { z2.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8580504b // ldr z11, [x2, #4, MUL VL]                   
+    WORD $0x8580544c // ldr z12, [x2, #5, MUL VL]                   
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    MOVD 72(R14), R6
+    WORD $0xa5ef40c3 // ld1d { z3.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8580584b // ldr z11, [x2, #6, MUL VL]                   
+    WORD $0x85805c4c // ldr z12, [x2, #7, MUL VL]                   
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    MOVD 96(R14), R6
+    WORD $0xa5ef40c4 // ld1d { z4.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8581404b // ldr z11, [x2, #8, MUL VL]                   
+    WORD $0x8581444c // ldr z12, [x2, #9, MUL VL]                   
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    MOVD 120(R14), R6
+    WORD $0xa5ef40c5 // ld1d { z5.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8581484b // ldr z11, [x2, #10, MUL VL]                  
+    WORD $0x85814c4c // ldr z12, [x2, #11, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    MOVD 144(R14), R6
+    WORD $0xa5ef40c6 // ld1d { z6.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8581504b // ldr z11, [x2, #12, MUL VL]                  
+    WORD $0x8581544c // ldr z12, [x2, #13, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    MOVD 168(R14), R6
+    WORD $0xa5ef40c7 // ld1d { z7.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8581584b // ldr z11, [x2, #14, MUL VL]                  
+    WORD $0x85815c4c // ldr z12, [x2, #15, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    MOVD 192(R14), R6
+    WORD $0xa5ef40c8 // ld1d { z8.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8582404b // ldr z11, [x2, #16, MUL VL]                  
+    WORD $0x8582444c // ldr z12, [x2, #17, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    MOVD 216(R14), R6
+    WORD $0xa5ef40c9 // ld1d { z9.d }, p0/z, [x6, x15, lsl #3]      
+    WORD $0x8582484b // ldr z11, [x2, #18, MUL VL]                  
+    WORD $0x85824c4c // ldr z12, [x2, #19, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulSve_10x10Xor_store
+
+    // Load and process 32 bytes from input 1 to 10 outputs
+    WORD $0x8580408d // ldr z13, [x4]                               
+    WORD $0x91008084 // add x4, x4, #32                             
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x8582504b // ldr z11, [x2, #20, MUL VL]                  
+    WORD $0x8582544c // ldr z12, [x2, #21, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x8582584b // ldr z11, [x2, #22, MUL VL]                  
+    WORD $0x85825c4c // ldr z12, [x2, #23, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x8583404b // ldr z11, [x2, #24, MUL VL]                  
+    WORD $0x8583444c // ldr z12, [x2, #25, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x8583484b // ldr z11, [x2, #26, MUL VL]                  
+    WORD $0x85834c4c // ldr z12, [x2, #27, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8583504b // ldr z11, [x2, #28, MUL VL]                  
+    WORD $0x8583544c // ldr z12, [x2, #29, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8583584b // ldr z11, [x2, #30, MUL VL]                  
+    WORD $0x85835c4c // ldr z12, [x2, #31, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8584404b // ldr z11, [x2, #32, MUL VL]                  
+    WORD $0x8584444c // ldr z12, [x2, #33, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8584484b // ldr z11, [x2, #34, MUL VL]                  
+    WORD $0x85844c4c // ldr z12, [x2, #35, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8584504b // ldr z11, [x2, #36, MUL VL]                  
+    WORD $0x8584544c // ldr z12, [x2, #37, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8584584b // ldr z11, [x2, #38, MUL VL]                  
+    WORD $0x85845c4c // ldr z12, [x2, #39, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulSve_10x10Xor_store
+
+    // Load and process 32 bytes from input 2 to 10 outputs
+    WORD $0x858040ad // ldr z13, [x5]                               
+    WORD $0x910080a5 // add x5, x5, #32                             
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x8585404b // ldr z11, [x2, #40, MUL VL]                  
+    WORD $0x8585444c // ldr z12, [x2, #41, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x8585484b // ldr z11, [x2, #42, MUL VL]                  
+    WORD $0x85854c4c // ldr z12, [x2, #43, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x8585504b // ldr z11, [x2, #44, MUL VL]                  
+    WORD $0x8585544c // ldr z12, [x2, #45, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x8585584b // ldr z11, [x2, #46, MUL VL]                  
+    WORD $0x85855c4c // ldr z12, [x2, #47, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8586404b // ldr z11, [x2, #48, MUL VL]                  
+    WORD $0x8586444c // ldr z12, [x2, #49, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8586484b // ldr z11, [x2, #50, MUL VL]                  
+    WORD $0x85864c4c // ldr z12, [x2, #51, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8586504b // ldr z11, [x2, #52, MUL VL]                  
+    WORD $0x8586544c // ldr z12, [x2, #53, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8586584b // ldr z11, [x2, #54, MUL VL]                  
+    WORD $0x85865c4c // ldr z12, [x2, #55, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8587404b // ldr z11, [x2, #56, MUL VL]                  
+    WORD $0x8587444c // ldr z12, [x2, #57, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8587484b // ldr z11, [x2, #58, MUL VL]                  
+    WORD $0x85874c4c // ldr z12, [x2, #59, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulSve_10x10Xor_store
+
+    // Load and process 32 bytes from input 3 to 10 outputs
+    WORD $0x8580410d // ldr z13, [x8]                               
+    WORD $0x91008108 // add x8, x8, #32                             
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x8587504b // ldr z11, [x2, #60, MUL VL]                  
+    WORD $0x8587544c // ldr z12, [x2, #61, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x8587584b // ldr z11, [x2, #62, MUL VL]                  
+    WORD $0x85875c4c // ldr z12, [x2, #63, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x8588404b // ldr z11, [x2, #64, MUL VL]                  
+    WORD $0x8588444c // ldr z12, [x2, #65, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x8588484b // ldr z11, [x2, #66, MUL VL]                  
+    WORD $0x85884c4c // ldr z12, [x2, #67, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8588504b // ldr z11, [x2, #68, MUL VL]                  
+    WORD $0x8588544c // ldr z12, [x2, #69, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8588584b // ldr z11, [x2, #70, MUL VL]                  
+    WORD $0x85885c4c // ldr z12, [x2, #71, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8589404b // ldr z11, [x2, #72, MUL VL]                  
+    WORD $0x8589444c // ldr z12, [x2, #73, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8589484b // ldr z11, [x2, #74, MUL VL]                  
+    WORD $0x85894c4c // ldr z12, [x2, #75, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8589504b // ldr z11, [x2, #76, MUL VL]                  
+    WORD $0x8589544c // ldr z12, [x2, #77, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8589584b // ldr z11, [x2, #78, MUL VL]                  
+    WORD $0x85895c4c // ldr z12, [x2, #79, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulSve_10x10Xor_store
+
+    // Load and process 32 bytes from input 4 to 10 outputs
+    WORD $0x8580412d // ldr z13, [x9]                               
+    WORD $0x91008129 // add x9, x9, #32                             
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x858a404b // ldr z11, [x2, #80, MUL VL]                  
+    WORD $0x858a444c // ldr z12, [x2, #81, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x858a484b // ldr z11, [x2, #82, MUL VL]                  
+    WORD $0x858a4c4c // ldr z12, [x2, #83, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x858a504b // ldr z11, [x2, #84, MUL VL]                  
+    WORD $0x858a544c // ldr z12, [x2, #85, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x858a584b // ldr z11, [x2, #86, MUL VL]                  
+    WORD $0x858a5c4c // ldr z12, [x2, #87, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x858b404b // ldr z11, [x2, #88, MUL VL]                  
+    WORD $0x858b444c // ldr z12, [x2, #89, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x858b484b // ldr z11, [x2, #90, MUL VL]                  
+    WORD $0x858b4c4c // ldr z12, [x2, #91, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x858b504b // ldr z11, [x2, #92, MUL VL]                  
+    WORD $0x858b544c // ldr z12, [x2, #93, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x858b584b // ldr z11, [x2, #94, MUL VL]                  
+    WORD $0x858b5c4c // ldr z12, [x2, #95, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x858c404b // ldr z11, [x2, #96, MUL VL]                  
+    WORD $0x858c444c // ldr z12, [x2, #97, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x858c484b // ldr z11, [x2, #98, MUL VL]                  
+    WORD $0x858c4c4c // ldr z12, [x2, #99, MUL VL]                  
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulSve_10x10Xor_store
+
+    // Load and process 32 bytes from input 5 to 10 outputs
+    WORD $0x8580414d // ldr z13, [x10]                              
+    WORD $0x9100814a // add x10, x10, #32                           
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x858c504b // ldr z11, [x2, #100, MUL VL]                 
+    WORD $0x858c544c // ldr z12, [x2, #101, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x858c584b // ldr z11, [x2, #102, MUL VL]                 
+    WORD $0x858c5c4c // ldr z12, [x2, #103, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x858d404b // ldr z11, [x2, #104, MUL VL]                 
+    WORD $0x858d444c // ldr z12, [x2, #105, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x858d484b // ldr z11, [x2, #106, MUL VL]                 
+    WORD $0x858d4c4c // ldr z12, [x2, #107, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x858d504b // ldr z11, [x2, #108, MUL VL]                 
+    WORD $0x858d544c // ldr z12, [x2, #109, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x858d584b // ldr z11, [x2, #110, MUL VL]                 
+    WORD $0x858d5c4c // ldr z12, [x2, #111, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x858e404b // ldr z11, [x2, #112, MUL VL]                 
+    WORD $0x858e444c // ldr z12, [x2, #113, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x858e484b // ldr z11, [x2, #114, MUL VL]                 
+    WORD $0x858e4c4c // ldr z12, [x2, #115, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x858e504b // ldr z11, [x2, #116, MUL VL]                 
+    WORD $0x858e544c // ldr z12, [x2, #117, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x858e584b // ldr z11, [x2, #118, MUL VL]                 
+    WORD $0x858e5c4c // ldr z12, [x2, #119, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulSve_10x10Xor_store
+
+    // Load and process 32 bytes from input 6 to 10 outputs
+    WORD $0x8580416d // ldr z13, [x11]                              
+    WORD $0x9100816b // add x11, x11, #32                           
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x858f404b // ldr z11, [x2, #120, MUL VL]                 
+    WORD $0x858f444c // ldr z12, [x2, #121, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x858f484b // ldr z11, [x2, #122, MUL VL]                 
+    WORD $0x858f4c4c // ldr z12, [x2, #123, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x858f504b // ldr z11, [x2, #124, MUL VL]                 
+    WORD $0x858f544c // ldr z12, [x2, #125, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x858f584b // ldr z11, [x2, #126, MUL VL]                 
+    WORD $0x858f5c4c // ldr z12, [x2, #127, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8590404b // ldr z11, [x2, #128, MUL VL]                 
+    WORD $0x8590444c // ldr z12, [x2, #129, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8590484b // ldr z11, [x2, #130, MUL VL]                 
+    WORD $0x85904c4c // ldr z12, [x2, #131, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8590504b // ldr z11, [x2, #132, MUL VL]                 
+    WORD $0x8590544c // ldr z12, [x2, #133, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8590584b // ldr z11, [x2, #134, MUL VL]                 
+    WORD $0x85905c4c // ldr z12, [x2, #135, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8591404b // ldr z11, [x2, #136, MUL VL]                 
+    WORD $0x8591444c // ldr z12, [x2, #137, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8591484b // ldr z11, [x2, #138, MUL VL]                 
+    WORD $0x85914c4c // ldr z12, [x2, #139, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulSve_10x10Xor_store
+
+    // Load and process 32 bytes from input 7 to 10 outputs
+    WORD $0x8580418d // ldr z13, [x12]                              
+    WORD $0x9100818c // add x12, x12, #32                           
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x8591504b // ldr z11, [x2, #140, MUL VL]                 
+    WORD $0x8591544c // ldr z12, [x2, #141, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x8591584b // ldr z11, [x2, #142, MUL VL]                 
+    WORD $0x85915c4c // ldr z12, [x2, #143, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x8592404b // ldr z11, [x2, #144, MUL VL]                 
+    WORD $0x8592444c // ldr z12, [x2, #145, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x8592484b // ldr z11, [x2, #146, MUL VL]                 
+    WORD $0x85924c4c // ldr z12, [x2, #147, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8592504b // ldr z11, [x2, #148, MUL VL]                 
+    WORD $0x8592544c // ldr z12, [x2, #149, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8592584b // ldr z11, [x2, #150, MUL VL]                 
+    WORD $0x85925c4c // ldr z12, [x2, #151, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8593404b // ldr z11, [x2, #152, MUL VL]                 
+    WORD $0x8593444c // ldr z12, [x2, #153, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8593484b // ldr z11, [x2, #154, MUL VL]                 
+    WORD $0x85934c4c // ldr z12, [x2, #155, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8593504b // ldr z11, [x2, #156, MUL VL]                 
+    WORD $0x8593544c // ldr z12, [x2, #157, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8593584b // ldr z11, [x2, #158, MUL VL]                 
+    WORD $0x85935c4c // ldr z12, [x2, #159, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulSve_10x10Xor_store
+
+    // Load and process 32 bytes from input 8 to 10 outputs
+    WORD $0x858041ad // ldr z13, [x13]                              
+    WORD $0x910081ad // add x13, x13, #32                           
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x8594404b // ldr z11, [x2, #160, MUL VL]                 
+    WORD $0x8594444c // ldr z12, [x2, #161, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x8594484b // ldr z11, [x2, #162, MUL VL]                 
+    WORD $0x85944c4c // ldr z12, [x2, #163, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x8594504b // ldr z11, [x2, #164, MUL VL]                 
+    WORD $0x8594544c // ldr z12, [x2, #165, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x8594584b // ldr z11, [x2, #166, MUL VL]                 
+    WORD $0x85945c4c // ldr z12, [x2, #167, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8595404b // ldr z11, [x2, #168, MUL VL]                 
+    WORD $0x8595444c // ldr z12, [x2, #169, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8595484b // ldr z11, [x2, #170, MUL VL]                 
+    WORD $0x85954c4c // ldr z12, [x2, #171, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8595504b // ldr z11, [x2, #172, MUL VL]                 
+    WORD $0x8595544c // ldr z12, [x2, #173, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8595584b // ldr z11, [x2, #174, MUL VL]                 
+    WORD $0x85955c4c // ldr z12, [x2, #175, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8596404b // ldr z11, [x2, #176, MUL VL]                 
+    WORD $0x8596444c // ldr z12, [x2, #177, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8596484b // ldr z11, [x2, #178, MUL VL]                 
+    WORD $0x85964c4c // ldr z12, [x2, #179, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulSve_10x10Xor_store
+
+    // Load and process 32 bytes from input 9 to 10 outputs
+    WORD $0x8580406d // ldr z13, [x3]                               
+    WORD $0x91008063 // add x3, x3, #32                             
+    WORD $0x04fc95ae // lsr z14.d, z13.d, #4                        
+    WORD $0x042a31ad // and z13.d, z13.d, z10.d                     
+    WORD $0x042a31ce // and z14.d, z14.d, z10.d                     
+    WORD $0x8596504b // ldr z11, [x2, #180, MUL VL]                 
+    WORD $0x8596544c // ldr z12, [x2, #181, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3000 // eor z0.d, z0.d, z11.d                       
+    WORD $0x04ac3000 // eor z0.d, z0.d, z12.d                       
+    WORD $0x8596584b // ldr z11, [x2, #182, MUL VL]                 
+    WORD $0x85965c4c // ldr z12, [x2, #183, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3021 // eor z1.d, z1.d, z11.d                       
+    WORD $0x04ac3021 // eor z1.d, z1.d, z12.d                       
+    WORD $0x8597404b // ldr z11, [x2, #184, MUL VL]                 
+    WORD $0x8597444c // ldr z12, [x2, #185, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3042 // eor z2.d, z2.d, z11.d                       
+    WORD $0x04ac3042 // eor z2.d, z2.d, z12.d                       
+    WORD $0x8597484b // ldr z11, [x2, #186, MUL VL]                 
+    WORD $0x85974c4c // ldr z12, [x2, #187, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3063 // eor z3.d, z3.d, z11.d                       
+    WORD $0x04ac3063 // eor z3.d, z3.d, z12.d                       
+    WORD $0x8597504b // ldr z11, [x2, #188, MUL VL]                 
+    WORD $0x8597544c // ldr z12, [x2, #189, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3084 // eor z4.d, z4.d, z11.d                       
+    WORD $0x04ac3084 // eor z4.d, z4.d, z12.d                       
+    WORD $0x8597584b // ldr z11, [x2, #190, MUL VL]                 
+    WORD $0x85975c4c // ldr z12, [x2, #191, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30a5 // eor z5.d, z5.d, z11.d                       
+    WORD $0x04ac30a5 // eor z5.d, z5.d, z12.d                       
+    WORD $0x8598404b // ldr z11, [x2, #192, MUL VL]                 
+    WORD $0x8598444c // ldr z12, [x2, #193, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30c6 // eor z6.d, z6.d, z11.d                       
+    WORD $0x04ac30c6 // eor z6.d, z6.d, z12.d                       
+    WORD $0x8598484b // ldr z11, [x2, #194, MUL VL]                 
+    WORD $0x85984c4c // ldr z12, [x2, #195, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab30e7 // eor z7.d, z7.d, z11.d                       
+    WORD $0x04ac30e7 // eor z7.d, z7.d, z12.d                       
+    WORD $0x8598504b // ldr z11, [x2, #196, MUL VL]                 
+    WORD $0x8598544c // ldr z12, [x2, #197, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3108 // eor z8.d, z8.d, z11.d                       
+    WORD $0x04ac3108 // eor z8.d, z8.d, z12.d                       
+    WORD $0x8598584b // ldr z11, [x2, #198, MUL VL]                 
+    WORD $0x85985c4c // ldr z12, [x2, #199, MUL VL]                 
+    WORD $0x052d316b // tbl z11.b, z11.b, z13.b                     
+    WORD $0x052e318c // tbl z12.b, z12.b, z14.b                     
+    WORD $0x04ab3129 // eor z9.d, z9.d, z11.d                       
+    WORD $0x04ac3129 // eor z9.d, z9.d, z12.d                       
+
+mulSve_10x10Xor_store:
+    // Store 10 outputs
+    MOVD (R14), R6
+    WORD $0xe5ef40c0 // st1d { z0.d }, p0, [x6, x15, lsl #3]        
+    MOVD 24(R14), R6
+    WORD $0xe5ef40c1 // st1d { z1.d }, p0, [x6, x15, lsl #3]        
+    MOVD 48(R14), R6
+    WORD $0xe5ef40c2 // st1d { z2.d }, p0, [x6, x15, lsl #3]        
+    MOVD 72(R14), R6
+    WORD $0xe5ef40c3 // st1d { z3.d }, p0, [x6, x15, lsl #3]        
+    MOVD 96(R14), R6
+    WORD $0xe5ef40c4 // st1d { z4.d }, p0, [x6, x15, lsl #3]        
+    MOVD 120(R14), R6
+    WORD $0xe5ef40c5 // st1d { z5.d }, p0, [x6, x15, lsl #3]        
+    MOVD 144(R14), R6
+    WORD $0xe5ef40c6 // st1d { z6.d }, p0, [x6, x15, lsl #3]        
+    MOVD 168(R14), R6
+    WORD $0xe5ef40c7 // st1d { z7.d }, p0, [x6, x15, lsl #3]        
+    MOVD 192(R14), R6
+    WORD $0xe5ef40c8 // st1d { z8.d }, p0, [x6, x15, lsl #3]        
+    MOVD 216(R14), R6
+    WORD $0xe5ef40c9 // st1d { z9.d }, p0, [x6, x15, lsl #3]        
+
+    // Prepare for next loop
+    WORD $0x910011ef // add x15, x15, #4                            
+    WORD $0xf1000400 // subs x0, x0, #1                             
+    BNE  mulSve_10x10Xor_loop
+
+mulSve_10x10Xor_end:
+    RET
+
+// func mulNeon_10x1_64(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x1_64(SB), $0-88
+    // Loading no tables to registers
+    // Destination kept in GP registers
+    // Full registers estimated 46 YMM used
+    MOVD n+80(FP), R0
+    LSR  $6, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x1_64_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD (R14), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to output
+    ADD    R15, R14
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    MOVD   $15, R15
+    VMOV   R15, V4.B[0]
+    VDUP   V4.B[0], V4.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x1_64_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 64 bytes from input 0 to 1 outputs
+    VLD1.P 32(R1), [V12.B16, V13.B16]
+    VLD1.P 32(R1), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V8.B16, V0.B16
+    VEOR   V7.B16, V9.B16, V1.B16
+    VEOR   V10.B16, V12.B16, V2.B16
+    VEOR   V11.B16, V13.B16, V3.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x1_64_store
+
+    // Load and process 64 bytes from input 1 to 1 outputs
+    VLD1.P 32(R4), [V12.B16, V13.B16]
+    VLD1.P 32(R4), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x1_64_store
+
+    // Load and process 64 bytes from input 2 to 1 outputs
+    VLD1.P 32(R5), [V12.B16, V13.B16]
+    VLD1.P 32(R5), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x1_64_store
+
+    // Load and process 64 bytes from input 3 to 1 outputs
+    VLD1.P 32(R8), [V12.B16, V13.B16]
+    VLD1.P 32(R8), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x1_64_store
+
+    // Load and process 64 bytes from input 4 to 1 outputs
+    VLD1.P 32(R9), [V12.B16, V13.B16]
+    VLD1.P 32(R9), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x1_64_store
+
+    // Load and process 64 bytes from input 5 to 1 outputs
+    VLD1.P 32(R10), [V12.B16, V13.B16]
+    VLD1.P 32(R10), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x1_64_store
+
+    // Load and process 64 bytes from input 6 to 1 outputs
+    VLD1.P 32(R11), [V12.B16, V13.B16]
+    VLD1.P 32(R11), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x1_64_store
+
+    // Load and process 64 bytes from input 7 to 1 outputs
+    VLD1.P 32(R12), [V12.B16, V13.B16]
+    VLD1.P 32(R12), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x1_64_store
+
+    // Load and process 64 bytes from input 8 to 1 outputs
+    VLD1.P 32(R13), [V12.B16, V13.B16]
+    VLD1.P 32(R13), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x1_64_store
+
+    // Load and process 64 bytes from input 9 to 1 outputs
+    VLD1.P 32(R3), [V12.B16, V13.B16]
+    VLD1.P 32(R3), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+
+mulNeon_10x1_64_store:
+    // Store 1 outputs
+    VST1.P [V0.D2, V1.D2], 32(R14)
+    VST1.P [V2.D2, V3.D2], 32(R14)
+
+    // Prepare for next loop
+    SUBS $1, R0
+    BNE  mulNeon_10x1_64_loop
+
+mulNeon_10x1_64_end:
+    RET
+
+// func mulNeon_10x1_64Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x1_64Xor(SB), $0-88
+    // Loading no tables to registers
+    // Destination kept in GP registers
+    // Full registers estimated 46 YMM used
+    MOVD n+80(FP), R0
+    LSR  $6, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x1_64Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD (R14), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to output
+    ADD    R15, R14
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    MOVD   $15, R15
+    VMOV   R15, V4.B[0]
+    VDUP   V4.B[0], V4.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x1_64Xor_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load 1 outputs
+    VLD1.P 32(R14), [V0.B16, V1.B16]
+    VLD1.P 32(R14), [V2.B16, V3.B16]
+
+    // Load and process 64 bytes from input 0 to 1 outputs
+    VLD1.P 32(R1), [V12.B16, V13.B16]
+    VLD1.P 32(R1), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 1 to 1 outputs
+    VLD1.P 32(R4), [V12.B16, V13.B16]
+    VLD1.P 32(R4), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 2 to 1 outputs
+    VLD1.P 32(R5), [V12.B16, V13.B16]
+    VLD1.P 32(R5), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 3 to 1 outputs
+    VLD1.P 32(R8), [V12.B16, V13.B16]
+    VLD1.P 32(R8), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 4 to 1 outputs
+    VLD1.P 32(R9), [V12.B16, V13.B16]
+    VLD1.P 32(R9), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 5 to 1 outputs
+    VLD1.P 32(R10), [V12.B16, V13.B16]
+    VLD1.P 32(R10), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 6 to 1 outputs
+    VLD1.P 32(R11), [V12.B16, V13.B16]
+    VLD1.P 32(R11), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 7 to 1 outputs
+    VLD1.P 32(R12), [V12.B16, V13.B16]
+    VLD1.P 32(R12), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 8 to 1 outputs
+    VLD1.P 32(R13), [V12.B16, V13.B16]
+    VLD1.P 32(R13), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x1_64Xor_store
+
+    // Load and process 64 bytes from input 9 to 1 outputs
+    VLD1.P 32(R3), [V12.B16, V13.B16]
+    VLD1.P 32(R3), [V10.B16, V11.B16]
+    VUSHR  $4, V12.B16, V14.B16
+    VUSHR  $4, V13.B16, V15.B16
+    VUSHR  $4, V10.B16, V16.B16
+    VUSHR  $4, V11.B16, V17.B16
+    VAND   V4.B16, V12.B16, V12.B16
+    VAND   V4.B16, V13.B16, V13.B16
+    VAND   V4.B16, V10.B16, V10.B16
+    VAND   V4.B16, V11.B16, V11.B16
+    VAND   V4.B16, V14.B16, V14.B16
+    VAND   V4.B16, V15.B16, V15.B16
+    VAND   V4.B16, V16.B16, V16.B16
+    VAND   V4.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V8.B16, V9.B16]
+    VTBL   V10.B16, [V6.B16], V10.B16
+    VTBL   V11.B16, [V7.B16], V11.B16
+    VTBL   V12.B16, [V6.B16], V6.B16
+    VTBL   V13.B16, [V7.B16], V7.B16
+    VTBL   V16.B16, [V8.B16], V12.B16
+    VTBL   V17.B16, [V9.B16], V13.B16
+    VTBL   V14.B16, [V8.B16], V8.B16
+    VTBL   V15.B16, [V9.B16], V9.B16
+    VEOR   V6.B16, V0.B16, V0.B16
+    VEOR   V7.B16, V1.B16, V1.B16
+    VEOR   V8.B16, V0.B16, V0.B16
+    VEOR   V9.B16, V1.B16, V1.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+
+mulNeon_10x1_64Xor_store:
+    // Store 1 outputs
+    SUB    $64, R14
+    VST1.P [V0.D2, V1.D2], 32(R14)
+    VST1.P [V2.D2, V3.D2], 32(R14)
+
+    // Prepare for next loop
+    SUBS $1, R0
+    BNE  mulNeon_10x1_64Xor_loop
+
+mulNeon_10x1_64Xor_end:
+    RET
+
+// func mulNeon_10x2_64(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x2_64(SB), $8-88
+    // Loading no tables to registers
+    // Destination kept in GP registers
+    // Full registers estimated 89 YMM used
+    MOVD n+80(FP), R0
+    LSR  $6, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x2_64_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD (R14), R15
+    MOVD 24(R14), R14
+    MOVD start+72(FP), R6
+
+    // Add start offset to output
+    ADD    R6, R15
+    ADD    R6, R14
+
+    // Add start offset to input
+    ADD    R6, R1
+    ADD    R6, R4
+    ADD    R6, R5
+    ADD    R6, R8
+    ADD    R6, R9
+    ADD    R6, R10
+    ADD    R6, R11
+    ADD    R6, R12
+    ADD    R6, R13
+    ADD    R6, R3
+    MOVD   $15, R6
+    VMOV   R6, V8.B[0]
+    VDUP   V8.B[0], V8.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x2_64_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 64 bytes from input 0 to 2 outputs
+    VLD1.P 32(R1), [V18.B16, V19.B16]
+    VLD1.P 32(R1), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V12.B16, V0.B16
+    VEOR   V11.B16, V13.B16, V1.B16
+    VEOR   V14.B16, V16.B16, V2.B16
+    VEOR   V15.B16, V17.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V12.B16, V4.B16
+    VEOR   V11.B16, V13.B16, V5.B16
+    VEOR   V14.B16, V16.B16, V6.B16
+    VEOR   V15.B16, V17.B16, V7.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x2_64_store
+
+    // Load and process 64 bytes from input 1 to 2 outputs
+    VLD1.P 32(R4), [V18.B16, V19.B16]
+    VLD1.P 32(R4), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x2_64_store
+
+    // Load and process 64 bytes from input 2 to 2 outputs
+    VLD1.P 32(R5), [V18.B16, V19.B16]
+    VLD1.P 32(R5), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x2_64_store
+
+    // Load and process 64 bytes from input 3 to 2 outputs
+    VLD1.P 32(R8), [V18.B16, V19.B16]
+    VLD1.P 32(R8), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x2_64_store
+
+    // Load and process 64 bytes from input 4 to 2 outputs
+    VLD1.P 32(R9), [V18.B16, V19.B16]
+    VLD1.P 32(R9), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x2_64_store
+
+    // Load and process 64 bytes from input 5 to 2 outputs
+    VLD1.P 32(R10), [V18.B16, V19.B16]
+    VLD1.P 32(R10), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x2_64_store
+
+    // Load and process 64 bytes from input 6 to 2 outputs
+    VLD1.P 32(R11), [V18.B16, V19.B16]
+    VLD1.P 32(R11), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x2_64_store
+
+    // Load and process 64 bytes from input 7 to 2 outputs
+    VLD1.P 32(R12), [V18.B16, V19.B16]
+    VLD1.P 32(R12), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x2_64_store
+
+    // Load and process 64 bytes from input 8 to 2 outputs
+    VLD1.P 32(R13), [V18.B16, V19.B16]
+    VLD1.P 32(R13), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x2_64_store
+
+    // Load and process 64 bytes from input 9 to 2 outputs
+    VLD1.P 32(R3), [V18.B16, V19.B16]
+    VLD1.P 32(R3), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+
+mulNeon_10x2_64_store:
+    // Store 2 outputs
+    VST1.P [V0.D2, V1.D2], 32(R15)
+    VST1.P [V2.D2, V3.D2], 32(R15)
+    VST1.P [V4.D2, V5.D2], 32(R14)
+    VST1.P [V6.D2, V7.D2], 32(R14)
+
+    // Prepare for next loop
+    SUBS $1, R0
+    BNE  mulNeon_10x2_64_loop
+
+mulNeon_10x2_64_end:
+    RET
+
+// func mulNeon_10x2_64Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x2_64Xor(SB), $8-88
+    // Loading no tables to registers
+    // Destination kept in GP registers
+    // Full registers estimated 89 YMM used
+    MOVD n+80(FP), R0
+    LSR  $6, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x2_64Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD (R14), R15
+    MOVD 24(R14), R14
+    MOVD start+72(FP), R6
+
+    // Add start offset to output
+    ADD    R6, R15
+    ADD    R6, R14
+
+    // Add start offset to input
+    ADD    R6, R1
+    ADD    R6, R4
+    ADD    R6, R5
+    ADD    R6, R8
+    ADD    R6, R9
+    ADD    R6, R10
+    ADD    R6, R11
+    ADD    R6, R12
+    ADD    R6, R13
+    ADD    R6, R3
+    MOVD   $15, R6
+    VMOV   R6, V8.B[0]
+    VDUP   V8.B[0], V8.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x2_64Xor_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load 2 outputs
+    VLD1.P 32(R15), [V0.B16, V1.B16]
+    VLD1.P 32(R15), [V2.B16, V3.B16]
+    VLD1.P 32(R14), [V4.B16, V5.B16]
+    VLD1.P 32(R14), [V6.B16, V7.B16]
+
+    // Load and process 64 bytes from input 0 to 2 outputs
+    VLD1.P 32(R1), [V18.B16, V19.B16]
+    VLD1.P 32(R1), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 1 to 2 outputs
+    VLD1.P 32(R4), [V18.B16, V19.B16]
+    VLD1.P 32(R4), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 2 to 2 outputs
+    VLD1.P 32(R5), [V18.B16, V19.B16]
+    VLD1.P 32(R5), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 3 to 2 outputs
+    VLD1.P 32(R8), [V18.B16, V19.B16]
+    VLD1.P 32(R8), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 4 to 2 outputs
+    VLD1.P 32(R9), [V18.B16, V19.B16]
+    VLD1.P 32(R9), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 5 to 2 outputs
+    VLD1.P 32(R10), [V18.B16, V19.B16]
+    VLD1.P 32(R10), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 6 to 2 outputs
+    VLD1.P 32(R11), [V18.B16, V19.B16]
+    VLD1.P 32(R11), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 7 to 2 outputs
+    VLD1.P 32(R12), [V18.B16, V19.B16]
+    VLD1.P 32(R12), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 8 to 2 outputs
+    VLD1.P 32(R13), [V18.B16, V19.B16]
+    VLD1.P 32(R13), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x2_64Xor_store
+
+    // Load and process 64 bytes from input 9 to 2 outputs
+    VLD1.P 32(R3), [V18.B16, V19.B16]
+    VLD1.P 32(R3), [V22.B16, V23.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V8.B16, V18.B16, V18.B16
+    VAND   V8.B16, V19.B16, V19.B16
+    VAND   V8.B16, V22.B16, V22.B16
+    VAND   V8.B16, V23.B16, V23.B16
+    VAND   V8.B16, V20.B16, V20.B16
+    VAND   V8.B16, V21.B16, V21.B16
+    VAND   V8.B16, V24.B16, V24.B16
+    VAND   V8.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V22.B16, [V10.B16], V14.B16
+    VTBL   V23.B16, [V11.B16], V15.B16
+    VTBL   V18.B16, [V10.B16], V10.B16
+    VTBL   V19.B16, [V11.B16], V11.B16
+    VTBL   V24.B16, [V12.B16], V16.B16
+    VTBL   V25.B16, [V13.B16], V17.B16
+    VTBL   V20.B16, [V12.B16], V12.B16
+    VTBL   V21.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+
+mulNeon_10x2_64Xor_store:
+    // Store 2 outputs
+    SUB    $64, R15
+    VST1.P [V0.D2, V1.D2], 32(R15)
+    VST1.P [V2.D2, V3.D2], 32(R15)
+    SUB    $64, R14
+    VST1.P [V4.D2, V5.D2], 32(R14)
+    VST1.P [V6.D2, V7.D2], 32(R14)
+
+    // Prepare for next loop
+    SUBS $1, R0
+    BNE  mulNeon_10x2_64Xor_loop
+
+mulNeon_10x2_64Xor_end:
+    RET
+
+// func mulNeon_10x3_64(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x3_64(SB), $8-88
+    // Loading no tables to registers
+    // Destination kept in GP registers
+    // Full registers estimated 130 YMM used
+    MOVD n+80(FP), R0
+    LSR  $6, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x3_64_end
+    MOVD in_base+24(FP), R0
+    MOVD (R0), R3
+    MOVD 24(R0), R1
+    MOVD 48(R0), R4
+    MOVD 72(R0), R5
+    MOVD 96(R0), R8
+    MOVD 120(R0), R9
+    MOVD 144(R0), R10
+    MOVD 168(R0), R11
+    MOVD 192(R0), R12
+    MOVD 216(R0), R0
+    MOVD out_base+48(FP), R13
+    MOVD (R13), R14
+    MOVD 24(R13), R15
+    MOVD 48(R13), R13
+    MOVD start+72(FP), R6
+
+    // Add start offset to output
+    ADD    R6, R14
+    ADD    R6, R15
+    ADD    R6, R13
+
+    // Add start offset to input
+    ADD    R6, R3
+    ADD    R6, R1
+    ADD    R6, R4
+    ADD    R6, R5
+    ADD    R6, R8
+    ADD    R6, R9
+    ADD    R6, R10
+    ADD    R6, R11
+    ADD    R6, R12
+    ADD    R6, R0
+    MOVD   $15, R6
+    VMOV   R6, V12.B[0]
+    VDUP   V12.B[0], V12.B16
+
+    // Reload length to save a register
+    MOVD n+80(FP), R6
+    LSR  $6, R6
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x3_64_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 64 bytes from input 0 to 3 outputs
+    VLD1.P 32(R3), [V22.B16, V23.B16]
+    VLD1.P 32(R3), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V16.B16, V0.B16
+    VEOR   V15.B16, V17.B16, V1.B16
+    VEOR   V18.B16, V20.B16, V2.B16
+    VEOR   V19.B16, V21.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V16.B16, V4.B16
+    VEOR   V15.B16, V17.B16, V5.B16
+    VEOR   V18.B16, V20.B16, V6.B16
+    VEOR   V19.B16, V21.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V16.B16, V8.B16
+    VEOR   V15.B16, V17.B16, V9.B16
+    VEOR   V18.B16, V20.B16, V10.B16
+    VEOR   V19.B16, V21.B16, V11.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x3_64_store
+
+    // Load and process 64 bytes from input 1 to 3 outputs
+    VLD1.P 32(R1), [V22.B16, V23.B16]
+    VLD1.P 32(R1), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x3_64_store
+
+    // Load and process 64 bytes from input 2 to 3 outputs
+    VLD1.P 32(R4), [V22.B16, V23.B16]
+    VLD1.P 32(R4), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x3_64_store
+
+    // Load and process 64 bytes from input 3 to 3 outputs
+    VLD1.P 32(R5), [V22.B16, V23.B16]
+    VLD1.P 32(R5), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x3_64_store
+
+    // Load and process 64 bytes from input 4 to 3 outputs
+    VLD1.P 32(R8), [V22.B16, V23.B16]
+    VLD1.P 32(R8), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x3_64_store
+
+    // Load and process 64 bytes from input 5 to 3 outputs
+    VLD1.P 32(R9), [V22.B16, V23.B16]
+    VLD1.P 32(R9), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x3_64_store
+
+    // Load and process 64 bytes from input 6 to 3 outputs
+    VLD1.P 32(R10), [V22.B16, V23.B16]
+    VLD1.P 32(R10), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x3_64_store
+
+    // Load and process 64 bytes from input 7 to 3 outputs
+    VLD1.P 32(R11), [V22.B16, V23.B16]
+    VLD1.P 32(R11), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x3_64_store
+
+    // Load and process 64 bytes from input 8 to 3 outputs
+    VLD1.P 32(R12), [V22.B16, V23.B16]
+    VLD1.P 32(R12), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x3_64_store
+
+    // Load and process 64 bytes from input 9 to 3 outputs
+    VLD1.P 32(R0), [V22.B16, V23.B16]
+    VLD1.P 32(R0), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+
+mulNeon_10x3_64_store:
+    // Store 3 outputs
+    VST1.P [V0.D2, V1.D2], 32(R14)
+    VST1.P [V2.D2, V3.D2], 32(R14)
+    VST1.P [V4.D2, V5.D2], 32(R15)
+    VST1.P [V6.D2, V7.D2], 32(R15)
+    VST1.P [V8.D2, V9.D2], 32(R13)
+    VST1.P [V10.D2, V11.D2], 32(R13)
+
+    // Prepare for next loop
+    SUBS $1, R6
+    BNE  mulNeon_10x3_64_loop
+
+mulNeon_10x3_64_end:
+    RET
+
+// func mulNeon_10x3_64Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x3_64Xor(SB), $8-88
+    // Loading no tables to registers
+    // Destination kept in GP registers
+    // Full registers estimated 130 YMM used
+    MOVD n+80(FP), R0
+    LSR  $6, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x3_64Xor_end
+    MOVD in_base+24(FP), R0
+    MOVD (R0), R3
+    MOVD 24(R0), R1
+    MOVD 48(R0), R4
+    MOVD 72(R0), R5
+    MOVD 96(R0), R8
+    MOVD 120(R0), R9
+    MOVD 144(R0), R10
+    MOVD 168(R0), R11
+    MOVD 192(R0), R12
+    MOVD 216(R0), R0
+    MOVD out_base+48(FP), R13
+    MOVD (R13), R14
+    MOVD 24(R13), R15
+    MOVD 48(R13), R13
+    MOVD start+72(FP), R6
+
+    // Add start offset to output
+    ADD    R6, R14
+    ADD    R6, R15
+    ADD    R6, R13
+
+    // Add start offset to input
+    ADD    R6, R3
+    ADD    R6, R1
+    ADD    R6, R4
+    ADD    R6, R5
+    ADD    R6, R8
+    ADD    R6, R9
+    ADD    R6, R10
+    ADD    R6, R11
+    ADD    R6, R12
+    ADD    R6, R0
+    MOVD   $15, R6
+    VMOV   R6, V12.B[0]
+    VDUP   V12.B[0], V12.B16
+
+    // Reload length to save a register
+    MOVD n+80(FP), R6
+    LSR  $6, R6
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x3_64Xor_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load 3 outputs
+    VLD1.P 32(R14), [V0.B16, V1.B16]
+    VLD1.P 32(R14), [V2.B16, V3.B16]
+    VLD1.P 32(R15), [V4.B16, V5.B16]
+    VLD1.P 32(R15), [V6.B16, V7.B16]
+    VLD1.P 32(R13), [V8.B16, V9.B16]
+    VLD1.P 32(R13), [V10.B16, V11.B16]
+
+    // Load and process 64 bytes from input 0 to 3 outputs
+    VLD1.P 32(R3), [V22.B16, V23.B16]
+    VLD1.P 32(R3), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 1 to 3 outputs
+    VLD1.P 32(R1), [V22.B16, V23.B16]
+    VLD1.P 32(R1), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 2 to 3 outputs
+    VLD1.P 32(R4), [V22.B16, V23.B16]
+    VLD1.P 32(R4), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 3 to 3 outputs
+    VLD1.P 32(R5), [V22.B16, V23.B16]
+    VLD1.P 32(R5), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 4 to 3 outputs
+    VLD1.P 32(R8), [V22.B16, V23.B16]
+    VLD1.P 32(R8), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 5 to 3 outputs
+    VLD1.P 32(R9), [V22.B16, V23.B16]
+    VLD1.P 32(R9), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 6 to 3 outputs
+    VLD1.P 32(R10), [V22.B16, V23.B16]
+    VLD1.P 32(R10), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 7 to 3 outputs
+    VLD1.P 32(R11), [V22.B16, V23.B16]
+    VLD1.P 32(R11), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 8 to 3 outputs
+    VLD1.P 32(R12), [V22.B16, V23.B16]
+    VLD1.P 32(R12), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x3_64Xor_store
+
+    // Load and process 64 bytes from input 9 to 3 outputs
+    VLD1.P 32(R0), [V22.B16, V23.B16]
+    VLD1.P 32(R0), [V26.B16, V27.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V12.B16, V22.B16, V22.B16
+    VAND   V12.B16, V23.B16, V23.B16
+    VAND   V12.B16, V26.B16, V26.B16
+    VAND   V12.B16, V27.B16, V27.B16
+    VAND   V12.B16, V24.B16, V24.B16
+    VAND   V12.B16, V25.B16, V25.B16
+    VAND   V12.B16, V28.B16, V28.B16
+    VAND   V12.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V26.B16, [V14.B16], V18.B16
+    VTBL   V27.B16, [V15.B16], V19.B16
+    VTBL   V22.B16, [V14.B16], V14.B16
+    VTBL   V23.B16, [V15.B16], V15.B16
+    VTBL   V28.B16, [V16.B16], V20.B16
+    VTBL   V29.B16, [V17.B16], V21.B16
+    VTBL   V24.B16, [V16.B16], V16.B16
+    VTBL   V25.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+
+mulNeon_10x3_64Xor_store:
+    // Store 3 outputs
+    SUB    $64, R14
+    VST1.P [V0.D2, V1.D2], 32(R14)
+    VST1.P [V2.D2, V3.D2], 32(R14)
+    SUB    $64, R15
+    VST1.P [V4.D2, V5.D2], 32(R15)
+    VST1.P [V6.D2, V7.D2], 32(R15)
+    SUB    $64, R13
+    VST1.P [V8.D2, V9.D2], 32(R13)
+    VST1.P [V10.D2, V11.D2], 32(R13)
+
+    // Prepare for next loop
+    SUBS $1, R6
+    BNE  mulNeon_10x3_64Xor_loop
+
+mulNeon_10x3_64Xor_end:
+    RET
+
+// func mulNeon_10x4(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x4(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 89 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x4_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V8.B[0]
+    VDUP   V8.B[0], V8.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x4_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 4 outputs
+    VLD1.P 32(R1), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V12.B16, V0.B16
+    VEOR   V11.B16, V13.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V12.B16, V2.B16
+    VEOR   V11.B16, V13.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V12.B16, V4.B16
+    VEOR   V11.B16, V13.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V12.B16, V6.B16
+    VEOR   V11.B16, V13.B16, V7.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x4_store
+
+    // Load and process 32 bytes from input 1 to 4 outputs
+    VLD1.P 32(R4), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x4_store
+
+    // Load and process 32 bytes from input 2 to 4 outputs
+    VLD1.P 32(R5), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x4_store
+
+    // Load and process 32 bytes from input 3 to 4 outputs
+    VLD1.P 32(R8), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x4_store
+
+    // Load and process 32 bytes from input 4 to 4 outputs
+    VLD1.P 32(R9), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x4_store
+
+    // Load and process 32 bytes from input 5 to 4 outputs
+    VLD1.P 32(R10), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x4_store
+
+    // Load and process 32 bytes from input 6 to 4 outputs
+    VLD1.P 32(R11), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x4_store
+
+    // Load and process 32 bytes from input 7 to 4 outputs
+    VLD1.P 32(R12), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x4_store
+
+    // Load and process 32 bytes from input 8 to 4 outputs
+    VLD1.P 32(R13), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x4_store
+
+    // Load and process 32 bytes from input 9 to 4 outputs
+    VLD1.P 32(R3), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+
+mulNeon_10x4_store:
+    // Store 4 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x4_loop
+
+mulNeon_10x4_end:
+    RET
+
+// func mulNeon_10x4Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x4Xor(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 89 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x4Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V8.B[0]
+    VDUP   V8.B[0], V8.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x4Xor_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 4 outputs
+    VLD1.P 32(R1), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V0.B16, V1.B16]
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V2.B16, V3.B16]
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V4.B16, V5.B16]
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x4Xor_store
+
+    // Load and process 32 bytes from input 1 to 4 outputs
+    VLD1.P 32(R4), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x4Xor_store
+
+    // Load and process 32 bytes from input 2 to 4 outputs
+    VLD1.P 32(R5), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x4Xor_store
+
+    // Load and process 32 bytes from input 3 to 4 outputs
+    VLD1.P 32(R8), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x4Xor_store
+
+    // Load and process 32 bytes from input 4 to 4 outputs
+    VLD1.P 32(R9), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x4Xor_store
+
+    // Load and process 32 bytes from input 5 to 4 outputs
+    VLD1.P 32(R10), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x4Xor_store
+
+    // Load and process 32 bytes from input 6 to 4 outputs
+    VLD1.P 32(R11), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x4Xor_store
+
+    // Load and process 32 bytes from input 7 to 4 outputs
+    VLD1.P 32(R12), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x4Xor_store
+
+    // Load and process 32 bytes from input 8 to 4 outputs
+    VLD1.P 32(R13), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x4Xor_store
+
+    // Load and process 32 bytes from input 9 to 4 outputs
+    VLD1.P 32(R3), [V14.B16, V15.B16]
+    VUSHR  $4, V14.B16, V16.B16
+    VUSHR  $4, V15.B16, V17.B16
+    VAND   V8.B16, V14.B16, V14.B16
+    VAND   V8.B16, V15.B16, V15.B16
+    VAND   V8.B16, V16.B16, V16.B16
+    VAND   V8.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V0.B16, V0.B16
+    VEOR   V11.B16, V1.B16, V1.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V2.B16, V2.B16
+    VEOR   V11.B16, V3.B16, V3.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V4.B16, V4.B16
+    VEOR   V11.B16, V5.B16, V5.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VTBL   V14.B16, [V10.B16], V10.B16
+    VTBL   V15.B16, [V11.B16], V11.B16
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VEOR   V10.B16, V6.B16, V6.B16
+    VEOR   V11.B16, V7.B16, V7.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+
+mulNeon_10x4Xor_store:
+    // Store 4 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x4Xor_loop
+
+mulNeon_10x4Xor_end:
+    RET
+
+// func mulNeon_10x5(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x5(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 110 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x5_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V10.B[0]
+    VDUP   V10.B[0], V10.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x5_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 5 outputs
+    VLD1.P 32(R1), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V14.B16, V0.B16
+    VEOR   V13.B16, V15.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V14.B16, V2.B16
+    VEOR   V13.B16, V15.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V14.B16, V4.B16
+    VEOR   V13.B16, V15.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V14.B16, V6.B16
+    VEOR   V13.B16, V15.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V14.B16, V8.B16
+    VEOR   V13.B16, V15.B16, V9.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x5_store
+
+    // Load and process 32 bytes from input 1 to 5 outputs
+    VLD1.P 32(R4), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x5_store
+
+    // Load and process 32 bytes from input 2 to 5 outputs
+    VLD1.P 32(R5), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x5_store
+
+    // Load and process 32 bytes from input 3 to 5 outputs
+    VLD1.P 32(R8), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x5_store
+
+    // Load and process 32 bytes from input 4 to 5 outputs
+    VLD1.P 32(R9), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x5_store
+
+    // Load and process 32 bytes from input 5 to 5 outputs
+    VLD1.P 32(R10), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x5_store
+
+    // Load and process 32 bytes from input 6 to 5 outputs
+    VLD1.P 32(R11), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x5_store
+
+    // Load and process 32 bytes from input 7 to 5 outputs
+    VLD1.P 32(R12), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x5_store
+
+    // Load and process 32 bytes from input 8 to 5 outputs
+    VLD1.P 32(R13), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x5_store
+
+    // Load and process 32 bytes from input 9 to 5 outputs
+    VLD1.P 32(R3), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+
+mulNeon_10x5_store:
+    // Store 5 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V8.D2, V9.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x5_loop
+
+mulNeon_10x5_end:
+    RET
+
+// func mulNeon_10x5Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x5Xor(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 110 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x5Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V10.B[0]
+    VDUP   V10.B[0], V10.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x5Xor_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 5 outputs
+    VLD1.P 32(R1), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V0.B16, V1.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V2.B16, V3.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V4.B16, V5.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V8.B16, V9.B16]
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x5Xor_store
+
+    // Load and process 32 bytes from input 1 to 5 outputs
+    VLD1.P 32(R4), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x5Xor_store
+
+    // Load and process 32 bytes from input 2 to 5 outputs
+    VLD1.P 32(R5), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x5Xor_store
+
+    // Load and process 32 bytes from input 3 to 5 outputs
+    VLD1.P 32(R8), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x5Xor_store
+
+    // Load and process 32 bytes from input 4 to 5 outputs
+    VLD1.P 32(R9), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x5Xor_store
+
+    // Load and process 32 bytes from input 5 to 5 outputs
+    VLD1.P 32(R10), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x5Xor_store
+
+    // Load and process 32 bytes from input 6 to 5 outputs
+    VLD1.P 32(R11), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x5Xor_store
+
+    // Load and process 32 bytes from input 7 to 5 outputs
+    VLD1.P 32(R12), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x5Xor_store
+
+    // Load and process 32 bytes from input 8 to 5 outputs
+    VLD1.P 32(R13), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x5Xor_store
+
+    // Load and process 32 bytes from input 9 to 5 outputs
+    VLD1.P 32(R3), [V16.B16, V17.B16]
+    VUSHR  $4, V16.B16, V18.B16
+    VUSHR  $4, V17.B16, V19.B16
+    VAND   V10.B16, V16.B16, V16.B16
+    VAND   V10.B16, V17.B16, V17.B16
+    VAND   V10.B16, V18.B16, V18.B16
+    VAND   V10.B16, V19.B16, V19.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V0.B16, V0.B16
+    VEOR   V13.B16, V1.B16, V1.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V2.B16, V2.B16
+    VEOR   V13.B16, V3.B16, V3.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V4.B16, V4.B16
+    VEOR   V13.B16, V5.B16, V5.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V6.B16, V6.B16
+    VEOR   V13.B16, V7.B16, V7.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VTBL   V16.B16, [V12.B16], V12.B16
+    VTBL   V17.B16, [V13.B16], V13.B16
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VEOR   V12.B16, V8.B16, V8.B16
+    VEOR   V13.B16, V9.B16, V9.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+
+mulNeon_10x5Xor_store:
+    // Store 5 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V8.D2, V9.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x5Xor_loop
+
+mulNeon_10x5Xor_end:
+    RET
+
+// func mulNeon_10x6(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x6(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 131 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x6_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V12.B[0]
+    VDUP   V12.B[0], V12.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x6_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 6 outputs
+    VLD1.P 32(R1), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V16.B16, V0.B16
+    VEOR   V15.B16, V17.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V16.B16, V2.B16
+    VEOR   V15.B16, V17.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V16.B16, V4.B16
+    VEOR   V15.B16, V17.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V16.B16, V6.B16
+    VEOR   V15.B16, V17.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V16.B16, V8.B16
+    VEOR   V15.B16, V17.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V16.B16, V10.B16
+    VEOR   V15.B16, V17.B16, V11.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x6_store
+
+    // Load and process 32 bytes from input 1 to 6 outputs
+    VLD1.P 32(R4), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x6_store
+
+    // Load and process 32 bytes from input 2 to 6 outputs
+    VLD1.P 32(R5), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x6_store
+
+    // Load and process 32 bytes from input 3 to 6 outputs
+    VLD1.P 32(R8), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x6_store
+
+    // Load and process 32 bytes from input 4 to 6 outputs
+    VLD1.P 32(R9), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x6_store
+
+    // Load and process 32 bytes from input 5 to 6 outputs
+    VLD1.P 32(R10), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x6_store
+
+    // Load and process 32 bytes from input 6 to 6 outputs
+    VLD1.P 32(R11), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x6_store
+
+    // Load and process 32 bytes from input 7 to 6 outputs
+    VLD1.P 32(R12), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x6_store
+
+    // Load and process 32 bytes from input 8 to 6 outputs
+    VLD1.P 32(R13), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x6_store
+
+    // Load and process 32 bytes from input 9 to 6 outputs
+    VLD1.P 32(R3), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+
+mulNeon_10x6_store:
+    // Store 6 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V8.D2, V9.D2], (R6)
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V10.D2, V11.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x6_loop
+
+mulNeon_10x6_end:
+    RET
+
+// func mulNeon_10x6Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x6Xor(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 131 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x6Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V12.B[0]
+    VDUP   V12.B[0], V12.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x6Xor_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 6 outputs
+    VLD1.P 32(R1), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V0.B16, V1.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V2.B16, V3.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V4.B16, V5.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V8.B16, V9.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x6Xor_store
+
+    // Load and process 32 bytes from input 1 to 6 outputs
+    VLD1.P 32(R4), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x6Xor_store
+
+    // Load and process 32 bytes from input 2 to 6 outputs
+    VLD1.P 32(R5), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x6Xor_store
+
+    // Load and process 32 bytes from input 3 to 6 outputs
+    VLD1.P 32(R8), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x6Xor_store
+
+    // Load and process 32 bytes from input 4 to 6 outputs
+    VLD1.P 32(R9), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x6Xor_store
+
+    // Load and process 32 bytes from input 5 to 6 outputs
+    VLD1.P 32(R10), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x6Xor_store
+
+    // Load and process 32 bytes from input 6 to 6 outputs
+    VLD1.P 32(R11), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x6Xor_store
+
+    // Load and process 32 bytes from input 7 to 6 outputs
+    VLD1.P 32(R12), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x6Xor_store
+
+    // Load and process 32 bytes from input 8 to 6 outputs
+    VLD1.P 32(R13), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x6Xor_store
+
+    // Load and process 32 bytes from input 9 to 6 outputs
+    VLD1.P 32(R3), [V18.B16, V19.B16]
+    VUSHR  $4, V18.B16, V20.B16
+    VUSHR  $4, V19.B16, V21.B16
+    VAND   V12.B16, V18.B16, V18.B16
+    VAND   V12.B16, V19.B16, V19.B16
+    VAND   V12.B16, V20.B16, V20.B16
+    VAND   V12.B16, V21.B16, V21.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V0.B16, V0.B16
+    VEOR   V15.B16, V1.B16, V1.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V2.B16, V2.B16
+    VEOR   V15.B16, V3.B16, V3.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V4.B16, V4.B16
+    VEOR   V15.B16, V5.B16, V5.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V6.B16, V6.B16
+    VEOR   V15.B16, V7.B16, V7.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V8.B16, V8.B16
+    VEOR   V15.B16, V9.B16, V9.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VTBL   V18.B16, [V14.B16], V14.B16
+    VTBL   V19.B16, [V15.B16], V15.B16
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VEOR   V14.B16, V10.B16, V10.B16
+    VEOR   V15.B16, V11.B16, V11.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+
+mulNeon_10x6Xor_store:
+    // Store 6 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V8.D2, V9.D2], (R6)
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V10.D2, V11.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x6Xor_loop
+
+mulNeon_10x6Xor_end:
+    RET
+
+// func mulNeon_10x7(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x7(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 152 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x7_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V14.B[0]
+    VDUP   V14.B[0], V14.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x7_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 7 outputs
+    VLD1.P 32(R1), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V18.B16, V0.B16
+    VEOR   V17.B16, V19.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V18.B16, V2.B16
+    VEOR   V17.B16, V19.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V18.B16, V4.B16
+    VEOR   V17.B16, V19.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V18.B16, V6.B16
+    VEOR   V17.B16, V19.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V18.B16, V8.B16
+    VEOR   V17.B16, V19.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V18.B16, V10.B16
+    VEOR   V17.B16, V19.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V18.B16, V12.B16
+    VEOR   V17.B16, V19.B16, V13.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x7_store
+
+    // Load and process 32 bytes from input 1 to 7 outputs
+    VLD1.P 32(R4), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x7_store
+
+    // Load and process 32 bytes from input 2 to 7 outputs
+    VLD1.P 32(R5), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x7_store
+
+    // Load and process 32 bytes from input 3 to 7 outputs
+    VLD1.P 32(R8), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x7_store
+
+    // Load and process 32 bytes from input 4 to 7 outputs
+    VLD1.P 32(R9), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x7_store
+
+    // Load and process 32 bytes from input 5 to 7 outputs
+    VLD1.P 32(R10), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x7_store
+
+    // Load and process 32 bytes from input 6 to 7 outputs
+    VLD1.P 32(R11), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x7_store
+
+    // Load and process 32 bytes from input 7 to 7 outputs
+    VLD1.P 32(R12), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x7_store
+
+    // Load and process 32 bytes from input 8 to 7 outputs
+    VLD1.P 32(R13), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x7_store
+
+    // Load and process 32 bytes from input 9 to 7 outputs
+    VLD1.P 32(R3), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+
+mulNeon_10x7_store:
+    // Store 7 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V8.D2, V9.D2], (R6)
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V10.D2, V11.D2], (R6)
+    MOVD 144(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V12.D2, V13.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x7_loop
+
+mulNeon_10x7_end:
+    RET
+
+// func mulNeon_10x7Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x7Xor(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 152 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x7Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V14.B[0]
+    VDUP   V14.B[0], V14.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x7Xor_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 7 outputs
+    VLD1.P 32(R1), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V0.B16, V1.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V2.B16, V3.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V4.B16, V5.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V8.B16, V9.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    MOVD 144(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x7Xor_store
+
+    // Load and process 32 bytes from input 1 to 7 outputs
+    VLD1.P 32(R4), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x7Xor_store
+
+    // Load and process 32 bytes from input 2 to 7 outputs
+    VLD1.P 32(R5), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x7Xor_store
+
+    // Load and process 32 bytes from input 3 to 7 outputs
+    VLD1.P 32(R8), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x7Xor_store
+
+    // Load and process 32 bytes from input 4 to 7 outputs
+    VLD1.P 32(R9), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x7Xor_store
+
+    // Load and process 32 bytes from input 5 to 7 outputs
+    VLD1.P 32(R10), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x7Xor_store
+
+    // Load and process 32 bytes from input 6 to 7 outputs
+    VLD1.P 32(R11), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x7Xor_store
+
+    // Load and process 32 bytes from input 7 to 7 outputs
+    VLD1.P 32(R12), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x7Xor_store
+
+    // Load and process 32 bytes from input 8 to 7 outputs
+    VLD1.P 32(R13), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x7Xor_store
+
+    // Load and process 32 bytes from input 9 to 7 outputs
+    VLD1.P 32(R3), [V20.B16, V21.B16]
+    VUSHR  $4, V20.B16, V22.B16
+    VUSHR  $4, V21.B16, V23.B16
+    VAND   V14.B16, V20.B16, V20.B16
+    VAND   V14.B16, V21.B16, V21.B16
+    VAND   V14.B16, V22.B16, V22.B16
+    VAND   V14.B16, V23.B16, V23.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V0.B16, V0.B16
+    VEOR   V17.B16, V1.B16, V1.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V2.B16, V2.B16
+    VEOR   V17.B16, V3.B16, V3.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V4.B16, V4.B16
+    VEOR   V17.B16, V5.B16, V5.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V6.B16, V6.B16
+    VEOR   V17.B16, V7.B16, V7.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V8.B16, V8.B16
+    VEOR   V17.B16, V9.B16, V9.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V10.B16, V10.B16
+    VEOR   V17.B16, V11.B16, V11.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VTBL   V20.B16, [V16.B16], V16.B16
+    VTBL   V21.B16, [V17.B16], V17.B16
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VEOR   V16.B16, V12.B16, V12.B16
+    VEOR   V17.B16, V13.B16, V13.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+
+mulNeon_10x7Xor_store:
+    // Store 7 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V8.D2, V9.D2], (R6)
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V10.D2, V11.D2], (R6)
+    MOVD 144(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V12.D2, V13.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x7Xor_loop
+
+mulNeon_10x7Xor_end:
+    RET
+
+// func mulNeon_10x8(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x8(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 173 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x8_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V16.B[0]
+    VDUP   V16.B[0], V16.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x8_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 8 outputs
+    VLD1.P 32(R1), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V20.B16, V0.B16
+    VEOR   V19.B16, V21.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V20.B16, V2.B16
+    VEOR   V19.B16, V21.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V20.B16, V4.B16
+    VEOR   V19.B16, V21.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V20.B16, V6.B16
+    VEOR   V19.B16, V21.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V20.B16, V8.B16
+    VEOR   V19.B16, V21.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V20.B16, V10.B16
+    VEOR   V19.B16, V21.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V20.B16, V12.B16
+    VEOR   V19.B16, V21.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V20.B16, V14.B16
+    VEOR   V19.B16, V21.B16, V15.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x8_store
+
+    // Load and process 32 bytes from input 1 to 8 outputs
+    VLD1.P 32(R4), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x8_store
+
+    // Load and process 32 bytes from input 2 to 8 outputs
+    VLD1.P 32(R5), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x8_store
+
+    // Load and process 32 bytes from input 3 to 8 outputs
+    VLD1.P 32(R8), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x8_store
+
+    // Load and process 32 bytes from input 4 to 8 outputs
+    VLD1.P 32(R9), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x8_store
+
+    // Load and process 32 bytes from input 5 to 8 outputs
+    VLD1.P 32(R10), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x8_store
+
+    // Load and process 32 bytes from input 6 to 8 outputs
+    VLD1.P 32(R11), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x8_store
+
+    // Load and process 32 bytes from input 7 to 8 outputs
+    VLD1.P 32(R12), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x8_store
+
+    // Load and process 32 bytes from input 8 to 8 outputs
+    VLD1.P 32(R13), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x8_store
+
+    // Load and process 32 bytes from input 9 to 8 outputs
+    VLD1.P 32(R3), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+
+mulNeon_10x8_store:
+    // Store 8 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V8.D2, V9.D2], (R6)
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V10.D2, V11.D2], (R6)
+    MOVD 144(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V12.D2, V13.D2], (R6)
+    MOVD 168(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V14.D2, V15.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x8_loop
+
+mulNeon_10x8_end:
+    RET
+
+// func mulNeon_10x8Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x8Xor(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 173 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x8Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V16.B[0]
+    VDUP   V16.B[0], V16.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x8Xor_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 8 outputs
+    VLD1.P 32(R1), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V0.B16, V1.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V2.B16, V3.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V4.B16, V5.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V8.B16, V9.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    MOVD 144(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    MOVD 168(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x8Xor_store
+
+    // Load and process 32 bytes from input 1 to 8 outputs
+    VLD1.P 32(R4), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x8Xor_store
+
+    // Load and process 32 bytes from input 2 to 8 outputs
+    VLD1.P 32(R5), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x8Xor_store
+
+    // Load and process 32 bytes from input 3 to 8 outputs
+    VLD1.P 32(R8), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x8Xor_store
+
+    // Load and process 32 bytes from input 4 to 8 outputs
+    VLD1.P 32(R9), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x8Xor_store
+
+    // Load and process 32 bytes from input 5 to 8 outputs
+    VLD1.P 32(R10), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x8Xor_store
+
+    // Load and process 32 bytes from input 6 to 8 outputs
+    VLD1.P 32(R11), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x8Xor_store
+
+    // Load and process 32 bytes from input 7 to 8 outputs
+    VLD1.P 32(R12), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x8Xor_store
+
+    // Load and process 32 bytes from input 8 to 8 outputs
+    VLD1.P 32(R13), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x8Xor_store
+
+    // Load and process 32 bytes from input 9 to 8 outputs
+    VLD1.P 32(R3), [V22.B16, V23.B16]
+    VUSHR  $4, V22.B16, V24.B16
+    VUSHR  $4, V23.B16, V25.B16
+    VAND   V16.B16, V22.B16, V22.B16
+    VAND   V16.B16, V23.B16, V23.B16
+    VAND   V16.B16, V24.B16, V24.B16
+    VAND   V16.B16, V25.B16, V25.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V0.B16, V0.B16
+    VEOR   V19.B16, V1.B16, V1.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V2.B16, V2.B16
+    VEOR   V19.B16, V3.B16, V3.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V4.B16, V4.B16
+    VEOR   V19.B16, V5.B16, V5.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V6.B16, V6.B16
+    VEOR   V19.B16, V7.B16, V7.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V8.B16, V8.B16
+    VEOR   V19.B16, V9.B16, V9.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V10.B16, V10.B16
+    VEOR   V19.B16, V11.B16, V11.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V12.B16, V12.B16
+    VEOR   V19.B16, V13.B16, V13.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VTBL   V22.B16, [V18.B16], V18.B16
+    VTBL   V23.B16, [V19.B16], V19.B16
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VEOR   V18.B16, V14.B16, V14.B16
+    VEOR   V19.B16, V15.B16, V15.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+
+mulNeon_10x8Xor_store:
+    // Store 8 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V8.D2, V9.D2], (R6)
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V10.D2, V11.D2], (R6)
+    MOVD 144(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V12.D2, V13.D2], (R6)
+    MOVD 168(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V14.D2, V15.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x8Xor_loop
+
+mulNeon_10x8Xor_end:
+    RET
+
+// func mulNeon_10x9(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x9(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 194 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x9_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V18.B[0]
+    VDUP   V18.B[0], V18.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x9_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 9 outputs
+    VLD1.P 32(R1), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V22.B16, V0.B16
+    VEOR   V21.B16, V23.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V22.B16, V2.B16
+    VEOR   V21.B16, V23.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V22.B16, V4.B16
+    VEOR   V21.B16, V23.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V22.B16, V6.B16
+    VEOR   V21.B16, V23.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V22.B16, V8.B16
+    VEOR   V21.B16, V23.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V22.B16, V10.B16
+    VEOR   V21.B16, V23.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V22.B16, V12.B16
+    VEOR   V21.B16, V23.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V22.B16, V14.B16
+    VEOR   V21.B16, V23.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V22.B16, V16.B16
+    VEOR   V21.B16, V23.B16, V17.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x9_store
+
+    // Load and process 32 bytes from input 1 to 9 outputs
+    VLD1.P 32(R4), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x9_store
+
+    // Load and process 32 bytes from input 2 to 9 outputs
+    VLD1.P 32(R5), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x9_store
+
+    // Load and process 32 bytes from input 3 to 9 outputs
+    VLD1.P 32(R8), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x9_store
+
+    // Load and process 32 bytes from input 4 to 9 outputs
+    VLD1.P 32(R9), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x9_store
+
+    // Load and process 32 bytes from input 5 to 9 outputs
+    VLD1.P 32(R10), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x9_store
+
+    // Load and process 32 bytes from input 6 to 9 outputs
+    VLD1.P 32(R11), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x9_store
+
+    // Load and process 32 bytes from input 7 to 9 outputs
+    VLD1.P 32(R12), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x9_store
+
+    // Load and process 32 bytes from input 8 to 9 outputs
+    VLD1.P 32(R13), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x9_store
+
+    // Load and process 32 bytes from input 9 to 9 outputs
+    VLD1.P 32(R3), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+
+mulNeon_10x9_store:
+    // Store 9 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V8.D2, V9.D2], (R6)
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V10.D2, V11.D2], (R6)
+    MOVD 144(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V12.D2, V13.D2], (R6)
+    MOVD 168(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V14.D2, V15.D2], (R6)
+    MOVD 192(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V16.D2, V17.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x9_loop
+
+mulNeon_10x9_end:
+    RET
+
+// func mulNeon_10x9Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x9Xor(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 194 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x9Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V18.B[0]
+    VDUP   V18.B[0], V18.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x9Xor_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 9 outputs
+    VLD1.P 32(R1), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V0.B16, V1.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V2.B16, V3.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V4.B16, V5.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V8.B16, V9.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    MOVD 144(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    MOVD 168(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    MOVD 192(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x9Xor_store
+
+    // Load and process 32 bytes from input 1 to 9 outputs
+    VLD1.P 32(R4), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x9Xor_store
+
+    // Load and process 32 bytes from input 2 to 9 outputs
+    VLD1.P 32(R5), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x9Xor_store
+
+    // Load and process 32 bytes from input 3 to 9 outputs
+    VLD1.P 32(R8), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x9Xor_store
+
+    // Load and process 32 bytes from input 4 to 9 outputs
+    VLD1.P 32(R9), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x9Xor_store
+
+    // Load and process 32 bytes from input 5 to 9 outputs
+    VLD1.P 32(R10), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x9Xor_store
+
+    // Load and process 32 bytes from input 6 to 9 outputs
+    VLD1.P 32(R11), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x9Xor_store
+
+    // Load and process 32 bytes from input 7 to 9 outputs
+    VLD1.P 32(R12), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x9Xor_store
+
+    // Load and process 32 bytes from input 8 to 9 outputs
+    VLD1.P 32(R13), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x9Xor_store
+
+    // Load and process 32 bytes from input 9 to 9 outputs
+    VLD1.P 32(R3), [V24.B16, V25.B16]
+    VUSHR  $4, V24.B16, V26.B16
+    VUSHR  $4, V25.B16, V27.B16
+    VAND   V18.B16, V24.B16, V24.B16
+    VAND   V18.B16, V25.B16, V25.B16
+    VAND   V18.B16, V26.B16, V26.B16
+    VAND   V18.B16, V27.B16, V27.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V0.B16, V0.B16
+    VEOR   V21.B16, V1.B16, V1.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V2.B16, V2.B16
+    VEOR   V21.B16, V3.B16, V3.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V4.B16, V4.B16
+    VEOR   V21.B16, V5.B16, V5.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V6.B16, V6.B16
+    VEOR   V21.B16, V7.B16, V7.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V8.B16, V8.B16
+    VEOR   V21.B16, V9.B16, V9.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V10.B16, V10.B16
+    VEOR   V21.B16, V11.B16, V11.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V12.B16, V12.B16
+    VEOR   V21.B16, V13.B16, V13.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V14.B16, V14.B16
+    VEOR   V21.B16, V15.B16, V15.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V20.B16, V21.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VTBL   V24.B16, [V20.B16], V20.B16
+    VTBL   V25.B16, [V21.B16], V21.B16
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VEOR   V20.B16, V16.B16, V16.B16
+    VEOR   V21.B16, V17.B16, V17.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+
+mulNeon_10x9Xor_store:
+    // Store 9 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V8.D2, V9.D2], (R6)
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V10.D2, V11.D2], (R6)
+    MOVD 144(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V12.D2, V13.D2], (R6)
+    MOVD 168(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V14.D2, V15.D2], (R6)
+    MOVD 192(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V16.D2, V17.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x9Xor_loop
+
+mulNeon_10x9Xor_end:
+    RET
+
+// func mulNeon_10x10(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x10(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 215 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x10_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V20.B[0]
+    VDUP   V20.B[0], V20.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x10_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 10 outputs
+    VLD1.P 32(R1), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V24.B16, V0.B16
+    VEOR   V23.B16, V25.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V24.B16, V2.B16
+    VEOR   V23.B16, V25.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V24.B16, V4.B16
+    VEOR   V23.B16, V25.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V24.B16, V6.B16
+    VEOR   V23.B16, V25.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V24.B16, V8.B16
+    VEOR   V23.B16, V25.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V24.B16, V10.B16
+    VEOR   V23.B16, V25.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V24.B16, V12.B16
+    VEOR   V23.B16, V25.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V24.B16, V14.B16
+    VEOR   V23.B16, V25.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V24.B16, V16.B16
+    VEOR   V23.B16, V25.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V24.B16, V18.B16
+    VEOR   V23.B16, V25.B16, V19.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x10_store
+
+    // Load and process 32 bytes from input 1 to 10 outputs
+    VLD1.P 32(R4), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x10_store
+
+    // Load and process 32 bytes from input 2 to 10 outputs
+    VLD1.P 32(R5), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x10_store
+
+    // Load and process 32 bytes from input 3 to 10 outputs
+    VLD1.P 32(R8), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x10_store
+
+    // Load and process 32 bytes from input 4 to 10 outputs
+    VLD1.P 32(R9), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x10_store
+
+    // Load and process 32 bytes from input 5 to 10 outputs
+    VLD1.P 32(R10), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x10_store
+
+    // Load and process 32 bytes from input 6 to 10 outputs
+    VLD1.P 32(R11), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x10_store
+
+    // Load and process 32 bytes from input 7 to 10 outputs
+    VLD1.P 32(R12), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x10_store
+
+    // Load and process 32 bytes from input 8 to 10 outputs
+    VLD1.P 32(R13), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x10_store
+
+    // Load and process 32 bytes from input 9 to 10 outputs
+    VLD1.P 32(R3), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+
+mulNeon_10x10_store:
+    // Store 10 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V8.D2, V9.D2], (R6)
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V10.D2, V11.D2], (R6)
+    MOVD 144(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V12.D2, V13.D2], (R6)
+    MOVD 168(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V14.D2, V15.D2], (R6)
+    MOVD 192(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V16.D2, V17.D2], (R6)
+    MOVD 216(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V18.D2, V19.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x10_loop
+
+mulNeon_10x10_end:
+    RET
+
+// func mulNeon_10x10Xor(matrix []byte, in [][]byte, out [][]byte, start int, n int)
+// Requires: NEON
+TEXT ·mulNeon_10x10Xor(SB), NOSPLIT, $8-88
+    // Loading no tables to registers
+    // Destination kept on stack
+    // Full registers estimated 215 YMM used
+    MOVD n+80(FP), R0
+    LSR  $5, R0
+    TST  R0, R0
+    BEQ    mulNeon_10x10Xor_end
+    MOVD in_base+24(FP), R3
+    MOVD (R3), R1
+    MOVD 24(R3), R4
+    MOVD 48(R3), R5
+    MOVD 72(R3), R8
+    MOVD 96(R3), R9
+    MOVD 120(R3), R10
+    MOVD 144(R3), R11
+    MOVD 168(R3), R12
+    MOVD 192(R3), R13
+    MOVD 216(R3), R3
+    MOVD out_base+48(FP), R14
+    MOVD start+72(FP), R15
+
+    // Add start offset to input
+    ADD    R15, R1
+    ADD    R15, R4
+    ADD    R15, R5
+    ADD    R15, R8
+    ADD    R15, R9
+    ADD    R15, R10
+    ADD    R15, R11
+    ADD    R15, R12
+    ADD    R15, R13
+    ADD    R15, R3
+    LSR  $3, R15
+    MOVD   $15, R6
+    VMOV   R6, V20.B[0]
+    VDUP   V20.B[0], V20.B16
+
+    // Load number of input shards
+    MOVD   in_len+32(FP), R16
+
+mulNeon_10x10Xor_loop:
+    MOVD matrix_base+0(FP), R2
+    // Load and process 32 bytes from input 0 to 10 outputs
+    VLD1.P 32(R1), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V0.B16, V1.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V2.B16, V3.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V4.B16, V5.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V6.B16, V7.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V8.B16, V9.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V10.B16, V11.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    MOVD 144(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V12.B16, V13.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    MOVD 168(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V14.B16, V15.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    MOVD 192(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V16.B16, V17.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    MOVD 216(R14), R6
+    ADD    R15<<3, R6
+    VLD1   (R6), [V18.B16, V19.B16]
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $1, R16
+    BEQ    mulNeon_10x10Xor_store
+
+    // Load and process 32 bytes from input 1 to 10 outputs
+    VLD1.P 32(R4), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $2, R16
+    BEQ    mulNeon_10x10Xor_store
+
+    // Load and process 32 bytes from input 2 to 10 outputs
+    VLD1.P 32(R5), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $3, R16
+    BEQ    mulNeon_10x10Xor_store
+
+    // Load and process 32 bytes from input 3 to 10 outputs
+    VLD1.P 32(R8), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $4, R16
+    BEQ    mulNeon_10x10Xor_store
+
+    // Load and process 32 bytes from input 4 to 10 outputs
+    VLD1.P 32(R9), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $5, R16
+    BEQ    mulNeon_10x10Xor_store
+
+    // Load and process 32 bytes from input 5 to 10 outputs
+    VLD1.P 32(R10), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $6, R16
+    BEQ    mulNeon_10x10Xor_store
+
+    // Load and process 32 bytes from input 6 to 10 outputs
+    VLD1.P 32(R11), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $7, R16
+    BEQ    mulNeon_10x10Xor_store
+
+    // Load and process 32 bytes from input 7 to 10 outputs
+    VLD1.P 32(R12), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $8, R16
+    BEQ    mulNeon_10x10Xor_store
+
+    // Load and process 32 bytes from input 8 to 10 outputs
+    VLD1.P 32(R13), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+    // Check for early termination
+    CMP    $9, R16
+    BEQ    mulNeon_10x10Xor_store
+
+    // Load and process 32 bytes from input 9 to 10 outputs
+    VLD1.P 32(R3), [V26.B16, V27.B16]
+    VUSHR  $4, V26.B16, V28.B16
+    VUSHR  $4, V27.B16, V29.B16
+    VAND   V20.B16, V26.B16, V26.B16
+    VAND   V20.B16, V27.B16, V27.B16
+    VAND   V20.B16, V28.B16, V28.B16
+    VAND   V20.B16, V29.B16, V29.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V0.B16, V0.B16
+    VEOR   V23.B16, V1.B16, V1.B16
+    VEOR   V24.B16, V0.B16, V0.B16
+    VEOR   V25.B16, V1.B16, V1.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V2.B16, V2.B16
+    VEOR   V23.B16, V3.B16, V3.B16
+    VEOR   V24.B16, V2.B16, V2.B16
+    VEOR   V25.B16, V3.B16, V3.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V4.B16, V4.B16
+    VEOR   V23.B16, V5.B16, V5.B16
+    VEOR   V24.B16, V4.B16, V4.B16
+    VEOR   V25.B16, V5.B16, V5.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V6.B16, V6.B16
+    VEOR   V23.B16, V7.B16, V7.B16
+    VEOR   V24.B16, V6.B16, V6.B16
+    VEOR   V25.B16, V7.B16, V7.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V8.B16, V8.B16
+    VEOR   V23.B16, V9.B16, V9.B16
+    VEOR   V24.B16, V8.B16, V8.B16
+    VEOR   V25.B16, V9.B16, V9.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V10.B16, V10.B16
+    VEOR   V23.B16, V11.B16, V11.B16
+    VEOR   V24.B16, V10.B16, V10.B16
+    VEOR   V25.B16, V11.B16, V11.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V12.B16, V12.B16
+    VEOR   V23.B16, V13.B16, V13.B16
+    VEOR   V24.B16, V12.B16, V12.B16
+    VEOR   V25.B16, V13.B16, V13.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V14.B16, V14.B16
+    VEOR   V23.B16, V15.B16, V15.B16
+    VEOR   V24.B16, V14.B16, V14.B16
+    VEOR   V25.B16, V15.B16, V15.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V16.B16, V16.B16
+    VEOR   V23.B16, V17.B16, V17.B16
+    VEOR   V24.B16, V16.B16, V16.B16
+    VEOR   V25.B16, V17.B16, V17.B16
+    VLD1.P 32(R2), [V22.B16, V23.B16]
+    VLD1.P 32(R2), [V24.B16, V25.B16]
+    VTBL   V26.B16, [V22.B16], V22.B16
+    VTBL   V27.B16, [V23.B16], V23.B16
+    VTBL   V28.B16, [V24.B16], V24.B16
+    VTBL   V29.B16, [V25.B16], V25.B16
+    VEOR   V22.B16, V18.B16, V18.B16
+    VEOR   V23.B16, V19.B16, V19.B16
+    VEOR   V24.B16, V18.B16, V18.B16
+    VEOR   V25.B16, V19.B16, V19.B16
+
+mulNeon_10x10Xor_store:
+    // Store 10 outputs
+    MOVD (R14), R6
+    ADD    R15<<3, R6
+    VST1   [V0.D2, V1.D2], (R6)
+    MOVD 24(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V2.D2, V3.D2], (R6)
+    MOVD 48(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V4.D2, V5.D2], (R6)
+    MOVD 72(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V6.D2, V7.D2], (R6)
+    MOVD 96(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V8.D2, V9.D2], (R6)
+    MOVD 120(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V10.D2, V11.D2], (R6)
+    MOVD 144(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V12.D2, V13.D2], (R6)
+    MOVD 168(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V14.D2, V15.D2], (R6)
+    MOVD 192(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V16.D2, V17.D2], (R6)
+    MOVD 216(R14), R6
+    ADD    R15<<3, R6
+    VST1   [V18.D2, V19.D2], (R6)
+
+    // Prepare for next loop
+    ADD    $4, R15
+    SUBS $1, R0
+    BNE  mulNeon_10x10Xor_loop
+
+mulNeon_10x10Xor_end:
+    RET
+
diff --git a/vendor/github.com/klauspost/reedsolomon/galois_gen_none.go b/vendor/github.com/klauspost/reedsolomon/galois_gen_none.go
index 1bb268a3..3e258986 100644
--- a/vendor/github.com/klauspost/reedsolomon/galois_gen_none.go
+++ b/vendor/github.com/klauspost/reedsolomon/galois_gen_none.go
@@ -1,33 +1,19 @@
-//go:build !amd64 || noasm || appengine || gccgo || nogen
+//go:build !(amd64 || arm64) || noasm || appengine || gccgo || nogen
 
 package reedsolomon
 
-const maxAvx2Inputs = 1
-const maxAvx2Outputs = 1
-const minAvx2Size = 1
-const avxSizeMask = 0
-const avx2CodeGen = false
+const (
+	codeGen              = false
+	codeGenMaxGoroutines = 8
+	codeGenMaxInputs     = 1
+	codeGenMaxOutputs    = 1
+	minCodeGenSize       = 1
+)
 
-func galMulSlicesAvx2(matrix []byte, in, out [][]byte, start, stop int) int {
-	panic("codegen not available")
+func (r *reedSolomon) hasCodeGen(int, int, int) (_, _ *func(matrix []byte, in, out [][]byte, start, stop int) int, ok bool) {
+	return nil, nil, false
 }
 
-func galMulSlicesAvx2Xor(matrix []byte, in, out [][]byte, start, stop int) int {
-	panic("codegen not available")
-}
-
-func galMulSlicesGFNI(matrix []uint64, in, out [][]byte, start, stop int) int {
-	panic("codegen not available")
-}
-
-func galMulSlicesGFNIXor(matrix []uint64, in, out [][]byte, start, stop int) int {
-	panic("codegen not available")
-}
-
-func galMulSlicesAvxGFNI(matrix []uint64, in, out [][]byte, start, stop int) int {
-	panic("codegen not available")
-}
-
-func galMulSlicesAvxGFNIXor(matrix []uint64, in, out [][]byte, start, stop int) int {
-	panic("codegen not available")
+func (r *reedSolomon) canGFNI(int, int, int) (_, _ *func(matrix []uint64, in, out [][]byte, start, stop int) int, ok bool) {
+	return nil, nil, false
 }
diff --git a/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_amd64.go b/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_amd64.go
index 429e2c20..d4f46ea2 100644
--- a/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_amd64.go
+++ b/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_amd64.go
@@ -10,12 +10,39 @@ import (
 )
 
 const (
-	avx2CodeGen    = true
-	maxAvx2Inputs  = 10
-	maxAvx2Outputs = 10
-	minAvx2Size    = 64
+	codeGen              = true
+	codeGenMaxGoroutines = 8
+	codeGenMaxInputs     = 10
+	codeGenMaxOutputs    = 10
+	minCodeGenSize       = 64
 )
 
+var (
+	fAvx2       = galMulSlicesAvx2
+	fAvx2Xor    = galMulSlicesAvx2Xor
+	fGFNI       = galMulSlicesGFNI
+	fGFNIXor    = galMulSlicesGFNIXor
+	fAvxGFNI    = galMulSlicesAvxGFNI
+	fAvxGFNIXor = galMulSlicesAvxGFNIXor
+)
+
+func (r *reedSolomon) hasCodeGen(byteCount int, inputs, outputs int) (_, _ *func(matrix []byte, in, out [][]byte, start, stop int) int, ok bool) {
+	return &fAvx2, &fAvx2Xor, codeGen && pshufb && r.o.useAVX2 &&
+		byteCount >= codeGenMinSize && inputs+outputs >= codeGenMinShards &&
+		inputs <= codeGenMaxInputs && outputs <= codeGenMaxOutputs
+}
+
+func (r *reedSolomon) canGFNI(byteCount int, inputs, outputs int) (_, _ *func(matrix []uint64, in, out [][]byte, start, stop int) int, ok bool) {
+	if r.o.useAvx512GFNI {
+		return &fGFNI, &fGFNIXor, codeGen &&
+			byteCount >= codeGenMinSize && inputs+outputs >= codeGenMinShards &&
+			inputs <= codeGenMaxInputs && outputs <= codeGenMaxOutputs
+	}
+	return &fAvxGFNI, &fAvxGFNIXor, codeGen && r.o.useAvxGNFI &&
+		byteCount >= codeGenMinSize && inputs+outputs >= codeGenMinShards &&
+		inputs <= codeGenMaxInputs && outputs <= codeGenMaxOutputs
+}
+
 func galMulSlicesAvx2(matrix []byte, in, out [][]byte, start, stop int) int {
 	n := stop - start
 
diff --git a/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_arm64.go b/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_arm64.go
new file mode 100644
index 00000000..ff2541b8
--- /dev/null
+++ b/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_arm64.go
@@ -0,0 +1,195 @@
+//go:build !appengine && !noasm && gc && !nogen && !nopshufb
+// +build !appengine,!noasm,gc,!nogen,!nopshufb
+
+package reedsolomon
+
+import (
+	"fmt"
+)
+
+const (
+	codeGen              = true
+	codeGenMaxGoroutines = 16
+	codeGenMaxInputs     = 10
+	codeGenMaxOutputs    = 10
+	minCodeGenSize       = 64
+)
+
+var (
+	fSve     = galMulSlicesSve
+	fSveXor  = galMulSlicesSveXor
+	fNeon    = galMulSlicesNeon
+	fNeonXor = galMulSlicesNeonXor
+)
+
+func (r *reedSolomon) hasCodeGen(byteCount int, inputs, outputs int) (_, _ *func(matrix []byte, in, out [][]byte, start, stop int) int, ok bool) {
+	if r.o.useSVE {
+		return &fSve, &fSveXor, codeGen && pshufb &&
+			byteCount >= codeGenMinSize && inputs+outputs >= codeGenMinShards &&
+			inputs <= codeGenMaxInputs && outputs <= codeGenMaxOutputs
+	}
+	return &fNeon, &fNeonXor, codeGen && pshufb && r.o.useNEON &&
+		byteCount >= codeGenMinSize && inputs+outputs >= codeGenMinShards &&
+		inputs <= codeGenMaxInputs && outputs <= codeGenMaxOutputs
+}
+
+func (r *reedSolomon) canGFNI(byteCount int, inputs, outputs int) (_, _ *func(matrix []uint64, in, out [][]byte, start, stop int) int, ok bool) {
+	return nil, nil, false
+}
+
+// galMulSlicesSve
+func galMulSlicesSve(matrix []byte, in, out [][]byte, start, stop int) int {
+	n := stop - start
+
+	// fmt.Println(len(in), len(out))
+	switch len(out) {
+	case 1:
+		mulSve_10x1_64(matrix, in, out, start, n)
+		return n & (maxInt - 63)
+	case 2:
+		mulSve_10x2_64(matrix, in, out, start, n)
+		return n & (maxInt - 63)
+	case 3:
+		mulSve_10x3_64(matrix, in, out, start, n)
+		return n & (maxInt - 63)
+	case 4:
+		mulSve_10x4(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 5:
+		mulSve_10x5(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 6:
+		mulSve_10x6(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 7:
+		mulSve_10x7(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 8:
+		mulSve_10x8(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 9:
+		mulSve_10x9(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 10:
+		mulSve_10x10(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	}
+	panic(fmt.Sprintf("ARM SVE: unhandled size: %dx%d", len(in), len(out)))
+}
+
+// galMulSlicesSveXor
+func galMulSlicesSveXor(matrix []byte, in, out [][]byte, start, stop int) int {
+	n := (stop - start)
+
+	switch len(out) {
+	case 1:
+		mulSve_10x1_64Xor(matrix, in, out, start, n)
+		return n & (maxInt - 63)
+	case 2:
+		mulSve_10x2_64Xor(matrix, in, out, start, n)
+		return n & (maxInt - 63)
+	case 3:
+		mulSve_10x3_64Xor(matrix, in, out, start, n)
+		return n & (maxInt - 63)
+	case 4:
+		mulSve_10x4Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 5:
+		mulSve_10x5Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 6:
+		mulSve_10x6Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 7:
+		mulSve_10x7Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 8:
+		mulSve_10x8Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 9:
+		mulSve_10x9Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 10:
+		mulSve_10x10Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	}
+	panic(fmt.Sprintf("ARM SVE: unhandled size: %dx%d", len(in), len(out)))
+}
+
+// galMulSlicesNeon
+func galMulSlicesNeon(matrix []byte, in, out [][]byte, start, stop int) int {
+	n := stop - start
+
+	switch len(out) {
+	case 1:
+		mulNeon_10x1_64(matrix, in, out, start, n)
+		return n & (maxInt - 63)
+	case 2:
+		mulNeon_10x2_64(matrix, in, out, start, n)
+		return n & (maxInt - 63)
+	case 3:
+		mulNeon_10x3_64(matrix, in, out, start, n)
+		return n & (maxInt - 63)
+	case 4:
+		mulNeon_10x4(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 5:
+		mulNeon_10x5(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 6:
+		mulNeon_10x6(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 7:
+		mulNeon_10x7(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 8:
+		mulNeon_10x8(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 9:
+		mulNeon_10x9(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 10:
+		mulNeon_10x10(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	}
+	panic(fmt.Sprintf("ARM NEON: unhandled size: %dx%d", len(in), len(out)))
+}
+
+// galMulSlicesNeonXor
+func galMulSlicesNeonXor(matrix []byte, in, out [][]byte, start, stop int) int {
+	n := (stop - start)
+
+	switch len(out) {
+	case 1:
+		mulNeon_10x1_64Xor(matrix, in, out, start, n)
+		return n & (maxInt - 63)
+	case 2:
+		mulNeon_10x2_64Xor(matrix, in, out, start, n)
+		return n & (maxInt - 63)
+	case 3:
+		mulNeon_10x3_64Xor(matrix, in, out, start, n)
+		return n & (maxInt - 63)
+	case 4:
+		mulNeon_10x4Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 5:
+		mulNeon_10x5Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 6:
+		mulNeon_10x6Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 7:
+		mulNeon_10x7Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 8:
+		mulNeon_10x8Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 9:
+		mulNeon_10x9Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	case 10:
+		mulNeon_10x10Xor(matrix, in, out, start, n)
+		return n & (maxInt - 31)
+	}
+	panic(fmt.Sprintf("ARM NEON: unhandled size: %dx%d", len(in), len(out)))
+}
diff --git a/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_nopshufb_amd64.go b/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_nopshufb_amd64.go
index 1ba08b5e..66bab8a0 100644
--- a/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_nopshufb_amd64.go
+++ b/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_nopshufb_amd64.go
@@ -10,12 +10,35 @@ import (
 )
 
 const (
-	avx2CodeGen    = true
-	maxAvx2Inputs  = 10
-	maxAvx2Outputs = 10
-	minAvx2Size    = 64
+	codeGen              = true
+	codeGenMaxGoroutines = 8
+	codeGenMaxInputs     = 10
+	codeGenMaxOutputs    = 10
+	minCodeGenSize       = 64
 )
 
+var (
+	fGFNI       = galMulSlicesGFNI
+	fGFNIXor    = galMulSlicesGFNIXor
+	fAvxGFNI    = galMulSlicesAvxGFNI
+	fAvxGFNIXor = galMulSlicesAvxGFNIXor
+)
+
+func (r *reedSolomon) hasCodeGen(byteCount int, inputs, outputs int) (_, _ *func(matrix []byte, in, out [][]byte, start, stop int) int, ok bool) {
+	return nil, nil, false // no code generation for generic case (only GFNI cases)
+}
+
+func (r *reedSolomon) canGFNI(byteCount int, inputs, outputs int) (_, _ *func(matrix []uint64, in, out [][]byte, start, stop int) int, ok bool) {
+	if r.o.useAvx512GFNI {
+		return &fGFNI, &fGFNIXor, codeGen &&
+			byteCount >= codeGenMinSize && inputs+outputs >= codeGenMinShards &&
+			inputs <= codeGenMaxInputs && outputs <= codeGenMaxOutputs
+	}
+	return &fAvxGFNI, &fAvxGFNIXor, codeGen && r.o.useAvxGNFI &&
+		byteCount >= codeGenMinSize && inputs+outputs >= codeGenMinShards &&
+		inputs <= codeGenMaxInputs && outputs <= codeGenMaxOutputs
+}
+
 func galMulSlicesAvx2(matrix []byte, in, out [][]byte, start, stop int) int    { panic(`no pshufb`) }
 func galMulSlicesAvx2Xor(matrix []byte, in, out [][]byte, start, stop int) int { panic(`no pshufb`) }
 
diff --git a/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_nopshufb_arm64.go b/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_nopshufb_arm64.go
new file mode 100644
index 00000000..db2aaa61
--- /dev/null
+++ b/vendor/github.com/klauspost/reedsolomon/galois_gen_switch_nopshufb_arm64.go
@@ -0,0 +1,22 @@
+// Code generated by command: go generate gen.go. DO NOT EDIT.
+
+//go:build !appengine && !noasm && gc && !nogen && nopshufb
+// +build !appengine,!noasm,gc,!nogen,nopshufb
+
+package reedsolomon
+
+const (
+	codeGen              = false
+	codeGenMaxGoroutines = 16
+	codeGenMaxInputs     = 10
+	codeGenMaxOutputs    = 10
+	minCodeGenSize       = 64
+)
+
+func (r *reedSolomon) hasCodeGen(byteCount int, inputs, outputs int) (_, _ *func(matrix []byte, in, out [][]byte, start, stop int) int, ok bool) {
+	return nil, nil, false
+}
+
+func (r *reedSolomon) canGFNI(byteCount int, inputs, outputs int) (_, _ *func(matrix []uint64, in, out [][]byte, start, stop int) int, ok bool) {
+	return nil, nil, false
+}
diff --git a/vendor/github.com/klauspost/reedsolomon/galois_notamd64.go b/vendor/github.com/klauspost/reedsolomon/galois_notamd64.go
deleted file mode 100644
index f98bfed1..00000000
--- a/vendor/github.com/klauspost/reedsolomon/galois_notamd64.go
+++ /dev/null
@@ -1,13 +0,0 @@
-//go:build !amd64 || noasm || appengine || gccgo || pshufb
-
-// Copyright 2020, Klaus Post, see LICENSE for details.
-
-package reedsolomon
-
-func (r *reedSolomon) codeSomeShardsAvx512(matrixRows, inputs, outputs [][]byte, byteCount int) {
-	panic("codeSomeShardsAvx512 should not be called if built without asm")
-}
-
-func (r *reedSolomon) codeSomeShardsAvx512P(matrixRows, inputs, outputs [][]byte, byteCount int) {
-	panic("codeSomeShardsAvx512P should not be called if built without asm")
-}
diff --git a/vendor/github.com/klauspost/reedsolomon/leopard.go b/vendor/github.com/klauspost/reedsolomon/leopard.go
index 6b4c8018..adf72c8f 100644
--- a/vendor/github.com/klauspost/reedsolomon/leopard.go
+++ b/vendor/github.com/klauspost/reedsolomon/leopard.go
@@ -451,13 +451,13 @@ func (r *leopardFF16) reconstruct(shards [][]byte, recoverAll bool) error {
 	}
 
 	// Evaluate error locator polynomial
-	fwht(&errLocs, order, m+r.dataShards)
+	fwht(&errLocs, m+r.dataShards)
 
 	for i := 0; i < order; i++ {
 		errLocs[i] = ffe((uint(errLocs[i]) * uint(logWalsh[i])) % modulus)
 	}
 
-	fwht(&errLocs, order, order)
+	fwht(&errLocs, order)
 
 	var work [][]byte
 	if w, ok := r.workPool.Get().([][]byte); ok {
@@ -863,11 +863,11 @@ func ceilPow2(n int) int {
 // Decimation in time (DIT) Fast Walsh-Hadamard Transform
 // Unrolls pairs of layers to perform cross-layer operations in registers
 // mtrunc: Number of elements that are non-zero at the front of data
-func fwht(data *[order]ffe, m, mtrunc int) {
+func fwht(data *[order]ffe, mtrunc int) {
 	// Decimation in time: Unroll 2 layers at a time
 	dist := 1
 	dist4 := 4
-	for dist4 <= m {
+	for dist4 <= order {
 		// For each set of dist*4 elements:
 		for r := 0; r < mtrunc; r += dist4 {
 			// For each set of dist elements:
@@ -898,14 +898,6 @@ func fwht(data *[order]ffe, m, mtrunc int) {
 		dist = dist4
 		dist4 <<= 2
 	}
-
-	// If there is one layer left:
-	if dist < m {
-		dist := uint16(dist)
-		for i := uint16(0); i < dist; i++ {
-			fwht2(&data[i], &data[i+dist])
-		}
-	}
 }
 
 func fwht4(data []ffe, s int) {
@@ -1036,7 +1028,7 @@ func initFFTSkew() {
 	}
 	logWalsh[0] = 0
 
-	fwht(logWalsh, order, order)
+	fwht(logWalsh, order)
 }
 
 func initMul16LUT() {
diff --git a/vendor/github.com/klauspost/reedsolomon/leopard8.go b/vendor/github.com/klauspost/reedsolomon/leopard8.go
index cd863a13..cd0a23ee 100644
--- a/vendor/github.com/klauspost/reedsolomon/leopard8.go
+++ b/vendor/github.com/klauspost/reedsolomon/leopard8.go
@@ -509,13 +509,13 @@ func (r *leopardFF8) reconstruct(shards [][]byte, recoverAll bool) error {
 		}
 
 		// Evaluate error locator polynomial8
-		fwht8(&errLocs, order8, m+r.dataShards)
+		fwht8(&errLocs, m+r.dataShards)
 
 		for i := 0; i < order8; i++ {
 			errLocs[i] = ffe8((uint(errLocs[i]) * uint(logWalsh8[i])) % modulus8)
 		}
 
-		fwht8(&errLocs, order8, order8)
+		fwht8(&errLocs, order8)
 
 		if r.inversion != nil {
 			c := leopardGF8cache{
@@ -943,11 +943,11 @@ func subMod8(a, b ffe8) ffe8 {
 // Decimation in time (DIT) Fast Walsh-Hadamard Transform
 // Unrolls pairs of layers to perform cross-layer operations in registers
 // mtrunc: Number of elements that are non-zero at the front of data
-func fwht8(data *[order8]ffe8, m, mtrunc int) {
+func fwht8(data *[order8]ffe8, mtrunc int) {
 	// Decimation in time: Unroll 2 layers at a time
 	dist := 1
 	dist4 := 4
-	for dist4 <= m {
+	for dist4 <= order8 {
 		// For each set of dist*4 elements:
 		for r := 0; r < mtrunc; r += dist4 {
 			// For each set of dist elements:
@@ -978,14 +978,6 @@ func fwht8(data *[order8]ffe8, m, mtrunc int) {
 		dist = dist4
 		dist4 <<= 2
 	}
-
-	// If there is one layer left:
-	if dist < m {
-		dist := uint16(dist)
-		for i := uint16(0); i < dist; i++ {
-			fwht28(&data[i], &data[i+dist])
-		}
-	}
 }
 
 func fwht48(data []ffe8, s int) {
@@ -1113,7 +1105,7 @@ func initFFTSkew8() {
 	}
 	logWalsh8[0] = 0
 
-	fwht8(logWalsh8, order8, order8)
+	fwht8(logWalsh8, order8)
 }
 
 func initMul8LUT() {
diff --git a/vendor/github.com/klauspost/reedsolomon/options.go b/vendor/github.com/klauspost/reedsolomon/options.go
index 73cc7d6d..377137ef 100644
--- a/vendor/github.com/klauspost/reedsolomon/options.go
+++ b/vendor/github.com/klauspost/reedsolomon/options.go
@@ -21,7 +21,9 @@ type options struct {
 	useAVX512,
 	useAVX2,
 	useSSSE3,
-	useSSE2 bool
+	useSSE2,
+	useNEON,
+	useSVE bool
 
 	useJerasureMatrix    bool
 	usePAR1Matrix        bool
@@ -51,6 +53,8 @@ var defaultOptions = options{
 	useAVX512:     cpuid.CPU.Supports(cpuid.AVX512F, cpuid.AVX512BW, cpuid.AVX512VL),
 	useAvx512GFNI: cpuid.CPU.Supports(cpuid.AVX512F, cpuid.GFNI, cpuid.AVX512DQ),
 	useAvxGNFI:    cpuid.CPU.Supports(cpuid.AVX, cpuid.GFNI),
+	useNEON:       cpuid.CPU.Supports(cpuid.ASIMD),
+	useSVE:        cpuid.CPU.Supports(cpuid.SVE),
 }
 
 // leopardMode controls the use of leopard GF in encoding and decoding.
@@ -316,6 +320,11 @@ func (o *options) cpuOptions() string {
 	if o.useAvxGNFI {
 		res = append(res, "AVX+GFNI")
 	}
+	if o.useSVE {
+		res = append(res, "ARM+SVE")
+	} else if o.useNEON {
+		res = append(res, "ARM+NEON")
+	}
 	if len(res) == 0 {
 		return "pure Go"
 	}
diff --git a/vendor/github.com/klauspost/reedsolomon/reedsolomon.go b/vendor/github.com/klauspost/reedsolomon/reedsolomon.go
index bebba044..3b6f5b78 100644
--- a/vendor/github.com/klauspost/reedsolomon/reedsolomon.go
+++ b/vendor/github.com/klauspost/reedsolomon/reedsolomon.go
@@ -153,9 +153,8 @@ type Extensions interface {
 }
 
 const (
-	avx2CodeGenMinSize       = 64
-	avx2CodeGenMinShards     = 3
-	avx2CodeGenMaxGoroutines = 8
+	codeGenMinSize           = 64
+	codeGenMinShards         = 3
 	gfniCodeGenMaxGoroutines = 4
 
 	intSize = 32 << (^uint(0) >> 63) // 32 or 64
@@ -482,21 +481,23 @@ func New(dataShards, parityShards int, opts ...Option) (Encoder, error) {
 		r.o.perRound = 128 << 10
 	}
 
+	_, _, useCodeGen := r.hasCodeGen(codeGenMinSize, codeGenMaxInputs, codeGenMaxOutputs)
+
 	divide := parityShards + 1
-	if avx2CodeGen && r.o.useAVX2 && (dataShards > maxAvx2Inputs || parityShards > maxAvx2Outputs) {
+	if codeGen && useCodeGen && (dataShards > codeGenMaxInputs || parityShards > codeGenMaxOutputs) {
 		// Base on L1 cache if we have many inputs.
 		r.o.perRound = cpuid.CPU.Cache.L1D
 		if r.o.perRound < 32<<10 {
 			r.o.perRound = 32 << 10
 		}
 		divide = 0
-		if dataShards > maxAvx2Inputs {
-			divide += maxAvx2Inputs
+		if dataShards > codeGenMaxInputs {
+			divide += codeGenMaxInputs
 		} else {
 			divide += dataShards
 		}
-		if parityShards > maxAvx2Inputs {
-			divide += maxAvx2Outputs
+		if parityShards > codeGenMaxInputs {
+			divide += codeGenMaxOutputs
 		} else {
 			divide += parityShards
 		}
@@ -555,11 +556,11 @@ func New(dataShards, parityShards int, opts ...Option) (Encoder, error) {
 
 	// Generated AVX2 does not need data to stay in L1 cache between runs.
 	// We will be purely limited by RAM speed.
-	if r.canAVX2C(avx2CodeGenMinSize, maxAvx2Inputs, maxAvx2Outputs) && r.o.maxGoroutines > avx2CodeGenMaxGoroutines {
-		r.o.maxGoroutines = avx2CodeGenMaxGoroutines
+	if useCodeGen && r.o.maxGoroutines > codeGenMaxGoroutines {
+		r.o.maxGoroutines = codeGenMaxGoroutines
 	}
 
-	if r.canGFNI(avx2CodeGenMinSize, maxAvx2Inputs, maxAvx2Outputs) && r.o.maxGoroutines > gfniCodeGenMaxGoroutines {
+	if _, _, useGFNI := r.canGFNI(codeGenMinSize, codeGenMaxInputs, codeGenMaxOutputs); useGFNI && r.o.maxGoroutines > gfniCodeGenMaxGoroutines {
 		r.o.maxGoroutines = gfniCodeGenMaxGoroutines
 	}
 
@@ -577,7 +578,7 @@ func New(dataShards, parityShards int, opts ...Option) (Encoder, error) {
 		r.parity[i] = r.m[dataShards+i]
 	}
 
-	if avx2CodeGen && r.o.useAVX2 {
+	if codeGen /* && r.o.useAVX2 */ {
 		sz := r.dataShards * r.parityShards * 2 * 32
 		r.mPool.New = func() interface{} {
 			return AllocAligned(1, sz)[0]
@@ -653,15 +654,15 @@ func (r *reedSolomon) EncodeIdx(dataShard []byte, idx int, parity [][]byte) erro
 		return ErrShardSize
 	}
 
-	if avx2CodeGen && len(dataShard) >= r.o.perRound && len(parity) >= avx2CodeGenMinShards && ((pshufb && r.o.useAVX2) || r.o.useAvx512GFNI || r.o.useAvxGNFI) {
+	if codeGen && len(dataShard) >= r.o.perRound && len(parity) >= codeGenMinShards && (pshufb || r.o.useAvx512GFNI || r.o.useAvxGNFI) {
 		m := make([][]byte, r.parityShards)
 		for iRow := range m {
 			m[iRow] = r.parity[iRow][idx : idx+1]
 		}
 		if r.o.useAvx512GFNI || r.o.useAvxGNFI {
-			r.codeSomeShardsGFNI(m, [][]byte{dataShard}, parity, len(dataShard), false)
+			r.codeSomeShardsGFNI(m, [][]byte{dataShard}, parity, len(dataShard), false, nil, nil)
 		} else {
-			r.codeSomeShardsAVXP(m, [][]byte{dataShard}, parity, len(dataShard), false)
+			r.codeSomeShardsAVXP(m, [][]byte{dataShard}, parity, len(dataShard), false, nil, nil)
 		}
 		return nil
 	}
@@ -803,18 +804,6 @@ func (r *reedSolomon) Verify(shards [][]byte) (bool, error) {
 	return r.checkSomeShards(r.parity, shards[:r.dataShards], toCheck[:r.parityShards], len(shards[0])), nil
 }
 
-func (r *reedSolomon) canAVX2C(byteCount int, inputs, outputs int) bool {
-	return avx2CodeGen && pshufb && r.o.useAVX2 &&
-		byteCount >= avx2CodeGenMinSize && inputs+outputs >= avx2CodeGenMinShards &&
-		inputs <= maxAvx2Inputs && outputs <= maxAvx2Outputs
-}
-
-func (r *reedSolomon) canGFNI(byteCount int, inputs, outputs int) bool {
-	return avx2CodeGen && (r.o.useAvx512GFNI || r.o.useAvxGNFI) &&
-		byteCount >= avx2CodeGenMinSize && inputs+outputs >= avx2CodeGenMinShards &&
-		inputs <= maxAvx2Inputs && outputs <= maxAvx2Outputs
-}
-
 // Multiplies a subset of rows from a coding matrix by a full set of
 // input totalShards to produce some output totalShards.
 // 'matrixRows' is The rows from the matrix to use.
@@ -838,22 +827,18 @@ func (r *reedSolomon) codeSomeShards(matrixRows, inputs, outputs [][]byte, byteC
 	if end > len(inputs[0]) {
 		end = len(inputs[0])
 	}
-	if r.canGFNI(byteCount, len(inputs), len(outputs)) {
-		var gfni [maxAvx2Inputs * maxAvx2Outputs]uint64
+	if galMulGFNI, galMulGFNIXor, useGFNI := r.canGFNI(byteCount, len(inputs), len(outputs)); useGFNI {
+		var gfni [codeGenMaxInputs * codeGenMaxOutputs]uint64
 		m := genGFNIMatrix(matrixRows, len(inputs), 0, len(outputs), gfni[:])
-		if r.o.useAvx512GFNI {
-			start += galMulSlicesGFNI(m, inputs, outputs, 0, byteCount)
-		} else {
-			start += galMulSlicesAvxGFNI(m, inputs, outputs, 0, byteCount)
-		}
+		start += (*galMulGFNI)(m, inputs, outputs, 0, byteCount)
 		end = len(inputs[0])
-	} else if r.canAVX2C(byteCount, len(inputs), len(outputs)) {
-		m := genAvx2Matrix(matrixRows, len(inputs), 0, len(outputs), r.getTmpSlice())
-		start += galMulSlicesAvx2(m, inputs, outputs, 0, byteCount)
+	} else if galMulGen, _, ok := r.hasCodeGen(byteCount, len(inputs), len(outputs)); ok {
+		m := genCodeGenMatrix(matrixRows, len(inputs), 0, len(outputs), r.getTmpSlice())
+		start += (*galMulGen)(m, inputs, outputs, 0, byteCount)
 		r.putTmpSlice(m)
 		end = len(inputs[0])
-	} else if len(inputs)+len(outputs) > avx2CodeGenMinShards && r.canAVX2C(byteCount, maxAvx2Inputs, maxAvx2Outputs) {
-		var gfni [maxAvx2Inputs * maxAvx2Outputs]uint64
+	} else if galMulGen, galMulGenXor, ok := r.hasCodeGen(byteCount, codeGenMaxInputs, codeGenMaxOutputs); len(inputs)+len(outputs) > codeGenMinShards && ok {
+		var gfni [codeGenMaxInputs * codeGenMaxOutputs]uint64
 		end = len(inputs[0])
 		inIdx := 0
 		m := r.getTmpSlice()
@@ -861,36 +846,29 @@ func (r *reedSolomon) codeSomeShards(matrixRows, inputs, outputs [][]byte, byteC
 		ins := inputs
 		for len(ins) > 0 {
 			inPer := ins
-			if len(inPer) > maxAvx2Inputs {
-				inPer = inPer[:maxAvx2Inputs]
+			if len(inPer) > codeGenMaxInputs {
+				inPer = inPer[:codeGenMaxInputs]
 			}
 			outs := outputs
 			outIdx := 0
 			for len(outs) > 0 {
 				outPer := outs
-				if len(outPer) > maxAvx2Outputs {
-					outPer = outPer[:maxAvx2Outputs]
+				if len(outPer) > codeGenMaxOutputs {
+					outPer = outPer[:codeGenMaxOutputs]
 				}
-				if r.o.useAvx512GFNI {
-					m := genGFNIMatrix(matrixRows[outIdx:], len(inPer), inIdx, len(outPer), gfni[:])
-					if inIdx == 0 {
-						start = galMulSlicesGFNI(m, inPer, outPer, 0, byteCount)
-					} else {
-						start = galMulSlicesGFNIXor(m, inPer, outPer, 0, byteCount)
-					}
-				} else if r.o.useAvxGNFI {
+				if useGFNI {
 					m := genGFNIMatrix(matrixRows[outIdx:], len(inPer), inIdx, len(outPer), gfni[:])
 					if inIdx == 0 {
-						start = galMulSlicesAvxGFNI(m, inPer, outPer, 0, byteCount)
+						start = (*galMulGFNI)(m, inPer, outPer, 0, byteCount)
 					} else {
-						start = galMulSlicesAvxGFNIXor(m, inPer, outPer, 0, byteCount)
+						start = (*galMulGFNIXor)(m, inPer, outPer, 0, byteCount)
 					}
 				} else {
-					m = genAvx2Matrix(matrixRows[outIdx:], len(inPer), inIdx, len(outPer), m)
+					m = genCodeGenMatrix(matrixRows[outIdx:], len(inPer), inIdx, len(outPer), m)
 					if inIdx == 0 {
-						start = galMulSlicesAvx2(m, inPer, outPer, 0, byteCount)
+						start = (*galMulGen)(m, inPer, outPer, 0, byteCount)
 					} else {
-						start = galMulSlicesAvx2Xor(m, inPer, outPer, 0, byteCount)
+						start = (*galMulGenXor)(m, inPer, outPer, 0, byteCount)
 					}
 				}
 				outIdx += len(outPer)
@@ -928,27 +906,27 @@ func (r *reedSolomon) codeSomeShardsP(matrixRows, inputs, outputs [][]byte, byte
 	var wg sync.WaitGroup
 	gor := r.o.maxGoroutines
 
-	var avx2Matrix []byte
+	var genMatrix []byte
 	var gfniMatrix []uint64
-	useAvx2 := r.canAVX2C(byteCount, len(inputs), len(outputs))
-	useGFNI := r.canGFNI(byteCount, len(inputs), len(outputs))
+	galMulGen, _, useCodeGen := r.hasCodeGen(byteCount, len(inputs), len(outputs))
+	galMulGFNI, _, useGFNI := r.canGFNI(byteCount, len(inputs), len(outputs))
 	if useGFNI {
-		var tmp [maxAvx2Inputs * maxAvx2Outputs]uint64
+		var tmp [codeGenMaxInputs * codeGenMaxOutputs]uint64
 		gfniMatrix = genGFNIMatrix(matrixRows, len(inputs), 0, len(outputs), tmp[:])
-	} else if useAvx2 {
-		avx2Matrix = genAvx2Matrix(matrixRows, len(inputs), 0, len(outputs), r.getTmpSlice())
-		defer r.putTmpSlice(avx2Matrix)
-	} else if (r.o.useAvx512GFNI || r.o.useAvxGNFI) && byteCount < 10<<20 && len(inputs)+len(outputs) > avx2CodeGenMinShards &&
-		r.canGFNI(byteCount/4, maxAvx2Inputs, maxAvx2Outputs) {
+	} else if useCodeGen {
+		genMatrix = genCodeGenMatrix(matrixRows, len(inputs), 0, len(outputs), r.getTmpSlice())
+		defer r.putTmpSlice(genMatrix)
+	} else if galMulGFNI, galMulGFNIXor, useGFNI := r.canGFNI(byteCount/4, codeGenMaxInputs, codeGenMaxOutputs); useGFNI &&
+		byteCount < 10<<20 && len(inputs)+len(outputs) > codeGenMinShards {
 		// It appears there is a switchover point at around 10MB where
 		// Regular processing is faster...
-		r.codeSomeShardsGFNI(matrixRows, inputs, outputs, byteCount, true)
+		r.codeSomeShardsGFNI(matrixRows, inputs, outputs, byteCount, true, galMulGFNI, galMulGFNIXor)
 		return
-	} else if r.o.useAVX2 && byteCount < 10<<20 && len(inputs)+len(outputs) > avx2CodeGenMinShards &&
-		r.canAVX2C(byteCount/4, maxAvx2Inputs, maxAvx2Outputs) {
+	} else if galMulGen, galMulGenXor, ok := r.hasCodeGen(byteCount/4, codeGenMaxInputs, codeGenMaxOutputs); ok &&
+		byteCount < 10<<20 && len(inputs)+len(outputs) > codeGenMinShards {
 		// It appears there is a switchover point at around 10MB where
 		// Regular processing is faster...
-		r.codeSomeShardsAVXP(matrixRows, inputs, outputs, byteCount, true)
+		r.codeSomeShardsAVXP(matrixRows, inputs, outputs, byteCount, true, galMulGen, galMulGenXor)
 		return
 	}
 
@@ -960,13 +938,9 @@ func (r *reedSolomon) codeSomeShardsP(matrixRows, inputs, outputs [][]byte, byte
 	exec := func(start, stop int) {
 		if stop-start >= 64 {
 			if useGFNI {
-				if r.o.useAvx512GFNI {
-					start += galMulSlicesGFNI(gfniMatrix, inputs, outputs, start, stop)
-				} else {
-					start += galMulSlicesAvxGFNI(gfniMatrix, inputs, outputs, start, stop)
-				}
-			} else if useAvx2 {
-				start += galMulSlicesAvx2(avx2Matrix, inputs, outputs, start, stop)
+				start += (*galMulGFNI)(gfniMatrix, inputs, outputs, start, stop)
+			} else if useCodeGen {
+				start += (*galMulGen)(genMatrix, inputs, outputs, start, stop)
 			}
 		}
 
@@ -1017,7 +991,7 @@ func (r *reedSolomon) codeSomeShardsP(matrixRows, inputs, outputs [][]byte, byte
 // Perform the same as codeSomeShards, but split the workload into
 // several goroutines.
 // If clear is set, the first write will overwrite the output.
-func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, byteCount int, clear bool) {
+func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, byteCount int, clear bool, galMulGen, galMulGenXor *func(matrix []byte, in [][]byte, out [][]byte, start int, stop int) int) {
 	var wg sync.WaitGroup
 	gor := r.o.maxGoroutines
 
@@ -1028,7 +1002,7 @@ func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, b
 		first  bool
 	}
 	// Make a plan...
-	plan := make([]state, 0, ((len(inputs)+maxAvx2Inputs-1)/maxAvx2Inputs)*((len(outputs)+maxAvx2Outputs-1)/maxAvx2Outputs))
+	plan := make([]state, 0, ((len(inputs)+codeGenMaxInputs-1)/codeGenMaxInputs)*((len(outputs)+codeGenMaxOutputs-1)/codeGenMaxOutputs))
 
 	tmp := r.getTmpSlice()
 	defer r.putTmpSlice(tmp)
@@ -1040,18 +1014,18 @@ func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, b
 		ins := inputs
 		for len(ins) > 0 {
 			inPer := ins
-			if len(inPer) > maxAvx2Inputs {
-				inPer = inPer[:maxAvx2Inputs]
+			if len(inPer) > codeGenMaxInputs {
+				inPer = inPer[:codeGenMaxInputs]
 			}
 			outs := outputs
 			outIdx := 0
 			for len(outs) > 0 {
 				outPer := outs
-				if len(outPer) > maxAvx2Outputs {
-					outPer = outPer[:maxAvx2Outputs]
+				if len(outPer) > codeGenMaxOutputs {
+					outPer = outPer[:codeGenMaxOutputs]
 				}
 				// Generate local matrix
-				m := genAvx2Matrix(matrixRows[outIdx:], len(inPer), inIdx, len(outPer), tmp)
+				m := genCodeGenMatrix(matrixRows[outIdx:], len(inPer), inIdx, len(outPer), tmp)
 				tmp = tmp[len(m):]
 				plan = append(plan, state{
 					input:  inPer,
@@ -1070,19 +1044,19 @@ func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, b
 		outIdx := 0
 		for len(outs) > 0 {
 			outPer := outs
-			if len(outPer) > maxAvx2Outputs {
-				outPer = outPer[:maxAvx2Outputs]
+			if len(outPer) > codeGenMaxOutputs {
+				outPer = outPer[:codeGenMaxOutputs]
 			}
 
 			inIdx := 0
 			ins := inputs
 			for len(ins) > 0 {
 				inPer := ins
-				if len(inPer) > maxAvx2Inputs {
-					inPer = inPer[:maxAvx2Inputs]
+				if len(inPer) > codeGenMaxInputs {
+					inPer = inPer[:codeGenMaxInputs]
 				}
 				// Generate local matrix
-				m := genAvx2Matrix(matrixRows[outIdx:], len(inPer), inIdx, len(outPer), tmp)
+				m := genCodeGenMatrix(matrixRows[outIdx:], len(inPer), inIdx, len(outPer), tmp)
 				tmp = tmp[len(m):]
 				//fmt.Println("bytes:", len(inPer)*r.o.perRound, "out:", len(outPer)*r.o.perRound)
 				plan = append(plan, state{
@@ -1111,14 +1085,14 @@ func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, b
 			lstop = stop
 		}
 		for lstart < stop {
-			if lstop-lstart >= minAvx2Size {
+			if galMulGen != nil && galMulGenXor != nil && lstop-lstart >= minCodeGenSize {
 				// Execute plan...
 				var n int
 				for _, p := range plan {
 					if p.first {
-						n = galMulSlicesAvx2(p.m, p.input, p.output, lstart, lstop)
+						n = (*galMulGen)(p.m, p.input, p.output, lstart, lstop)
 					} else {
-						n = galMulSlicesAvx2Xor(p.m, p.input, p.output, lstart, lstop)
+						n = (*galMulGenXor)(p.m, p.input, p.output, lstart, lstop)
 					}
 				}
 				lstart += n
@@ -1172,7 +1146,7 @@ func (r *reedSolomon) codeSomeShardsAVXP(matrixRows, inputs, outputs [][]byte, b
 // Perform the same as codeSomeShards, but split the workload into
 // several goroutines.
 // If clear is set, the first write will overwrite the output.
-func (r *reedSolomon) codeSomeShardsGFNI(matrixRows, inputs, outputs [][]byte, byteCount int, clear bool) {
+func (r *reedSolomon) codeSomeShardsGFNI(matrixRows, inputs, outputs [][]byte, byteCount int, clear bool, galMulGFNI, galMulGFNIXor *func(matrix []uint64, in, out [][]byte, start, stop int) int) {
 	var wg sync.WaitGroup
 	gor := r.o.maxGoroutines
 
@@ -1183,7 +1157,7 @@ func (r *reedSolomon) codeSomeShardsGFNI(matrixRows, inputs, outputs [][]byte, b
 		first  bool
 	}
 	// Make a plan...
-	plan := make([]state, 0, ((len(inputs)+maxAvx2Inputs-1)/maxAvx2Inputs)*((len(outputs)+maxAvx2Outputs-1)/maxAvx2Outputs))
+	plan := make([]state, 0, ((len(inputs)+codeGenMaxInputs-1)/codeGenMaxInputs)*((len(outputs)+codeGenMaxOutputs-1)/codeGenMaxOutputs))
 
 	// Flips between input first to output first.
 	// We put the smallest data load in the inner loop.
@@ -1192,15 +1166,15 @@ func (r *reedSolomon) codeSomeShardsGFNI(matrixRows, inputs, outputs [][]byte, b
 		ins := inputs
 		for len(ins) > 0 {
 			inPer := ins
-			if len(inPer) > maxAvx2Inputs {
-				inPer = inPer[:maxAvx2Inputs]
+			if len(inPer) > codeGenMaxInputs {
+				inPer = inPer[:codeGenMaxInputs]
 			}
 			outs := outputs
 			outIdx := 0
 			for len(outs) > 0 {
 				outPer := outs
-				if len(outPer) > maxAvx2Outputs {
-					outPer = outPer[:maxAvx2Outputs]
+				if len(outPer) > codeGenMaxOutputs {
+					outPer = outPer[:codeGenMaxOutputs]
 				}
 				// Generate local matrix
 				m := genGFNIMatrix(matrixRows[outIdx:], len(inPer), inIdx, len(outPer), make([]uint64, len(inPer)*len(outPer)))
@@ -1221,16 +1195,16 @@ func (r *reedSolomon) codeSomeShardsGFNI(matrixRows, inputs, outputs [][]byte, b
 		outIdx := 0
 		for len(outs) > 0 {
 			outPer := outs
-			if len(outPer) > maxAvx2Outputs {
-				outPer = outPer[:maxAvx2Outputs]
+			if len(outPer) > codeGenMaxOutputs {
+				outPer = outPer[:codeGenMaxOutputs]
 			}
 
 			inIdx := 0
 			ins := inputs
 			for len(ins) > 0 {
 				inPer := ins
-				if len(inPer) > maxAvx2Inputs {
-					inPer = inPer[:maxAvx2Inputs]
+				if len(inPer) > codeGenMaxInputs {
+					inPer = inPer[:codeGenMaxInputs]
 				}
 				// Generate local matrix
 				m := genGFNIMatrix(matrixRows[outIdx:], len(inPer), inIdx, len(outPer), make([]uint64, len(inPer)*len(outPer)))
@@ -1261,24 +1235,14 @@ func (r *reedSolomon) codeSomeShardsGFNI(matrixRows, inputs, outputs [][]byte, b
 			lstop = stop
 		}
 		for lstart < stop {
-			if lstop-lstart >= minAvx2Size {
+			if galMulGFNI != nil && galMulGFNIXor != nil && lstop-lstart >= minCodeGenSize {
 				// Execute plan...
 				var n int
-				if r.o.useAvx512GFNI {
-					for _, p := range plan {
-						if p.first {
-							n = galMulSlicesGFNI(p.m, p.input, p.output, lstart, lstop)
-						} else {
-							n = galMulSlicesGFNIXor(p.m, p.input, p.output, lstart, lstop)
-						}
-					}
-				} else {
-					for _, p := range plan {
-						if p.first {
-							n = galMulSlicesAvxGFNI(p.m, p.input, p.output, lstart, lstop)
-						} else {
-							n = galMulSlicesAvxGFNIXor(p.m, p.input, p.output, lstart, lstop)
-						}
+				for _, p := range plan {
+					if p.first {
+						n = (*galMulGFNI)(p.m, p.input, p.output, lstart, lstop)
+					} else {
+						n = (*galMulGFNIXor)(p.m, p.input, p.output, lstart, lstop)
 					}
 				}
 				lstart += n
diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go
index d569c0c9..d0ea68f4 100644
--- a/vendor/github.com/mattn/go-isatty/isatty_bsd.go
+++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go
@@ -1,6 +1,7 @@
-//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine
+//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine && !tinygo
 // +build darwin freebsd openbsd netbsd dragonfly hurd
 // +build !appengine
+// +build !tinygo
 
 package isatty
 
diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go
index 31503226..7402e061 100644
--- a/vendor/github.com/mattn/go-isatty/isatty_others.go
+++ b/vendor/github.com/mattn/go-isatty/isatty_others.go
@@ -1,5 +1,6 @@
-//go:build appengine || js || nacl || wasm
-// +build appengine js nacl wasm
+//go:build (appengine || js || nacl || tinygo || wasm) && !windows
+// +build appengine js nacl tinygo wasm
+// +build !windows
 
 package isatty
 
diff --git a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go
index 67787657..0337d8cf 100644
--- a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go
+++ b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go
@@ -1,6 +1,7 @@
-//go:build (linux || aix || zos) && !appengine
+//go:build (linux || aix || zos) && !appengine && !tinygo
 // +build linux aix zos
 // +build !appengine
+// +build !tinygo
 
 package isatty
 
diff --git a/vendor/github.com/pion/datachannel/.gitignore b/vendor/github.com/pion/datachannel/.gitignore
index f977e748..6e2f206a 100644
--- a/vendor/github.com/pion/datachannel/.gitignore
+++ b/vendor/github.com/pion/datachannel/.gitignore
@@ -1,3 +1,6 @@
+# SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+# SPDX-License-Identifier: MIT
+
 ### JetBrains IDE ###
 #####################
 .idea/
diff --git a/vendor/github.com/pion/datachannel/.golangci.yml b/vendor/github.com/pion/datachannel/.golangci.yml
index d7a88eca..e06de4d3 100644
--- a/vendor/github.com/pion/datachannel/.golangci.yml
+++ b/vendor/github.com/pion/datachannel/.golangci.yml
@@ -1,6 +1,10 @@
+# SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+# SPDX-License-Identifier: MIT
+
 linters-settings:
   govet:
-    check-shadowing: true
+    enable:
+      - shadow
   misspell:
     locale: US
   exhaustive:
@@ -10,7 +14,14 @@ linters-settings:
       modules:
         - github.com/pkg/errors:
             recommendations:
-            - errors
+              - errors
+  forbidigo:
+    forbid:
+      - ^fmt.Print(f|ln)?$
+      - ^log.(Panic|Fatal|Print)(f|ln)?$
+      - ^os.Exit$
+      - ^panic$
+      - ^print(ln)?$
 
 linters:
   enable:
@@ -18,9 +29,7 @@ linters:
     - bidichk          # Checks for dangerous unicode character sequences
     - bodyclose        # checks whether HTTP response body is closed successfully
     - contextcheck     # check the function whether use a non-inherited context
-    - deadcode         # Finds unused code
     - decorder         # check declaration order and count of types, constants, variables and functions
-    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - dogsled          # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
     - dupl             # Tool for code clone detection
     - durationcheck    # check for two durations multiplied together
@@ -30,6 +39,7 @@ linters:
     - errorlint        # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
     - exhaustive       # check exhaustiveness of enum switch statements
     - exportloopref    # checks for pointers to enclosing loop variables
+    - forbidigo        # Forbids identifiers
     - forcetypeassert  # finds forced type assertions
     - gci              # Gci control golang package import order and make it always deterministic.
     - gochecknoglobals # Checks that no globals are present in Go code
@@ -53,14 +63,12 @@ linters:
     - importas         # Enforces consistent import aliases
     - ineffassign      # Detects when assignments to existing variables are not used
     - misspell         # Finds commonly misspelled English words in comments
-    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nilerr           # Finds the code that returns nil even if it checks that the error is not nil.
     - nilnil           # Checks that there is no simultaneous return of `nil` error and an invalid value.
     - noctx            # noctx finds sending http request without context.Context
     - predeclared      # find code that shadows one of Go's predeclared identifiers
     - revive           # golint replacement, finds style mistakes
     - staticcheck      # Staticcheck is a go vet on steroids, applying a ton of static analysis checks
-    - structcheck      # Finds unused struct fields
     - stylecheck       # Stylecheck is a replacement for golint
     - tagliatelle      # Checks the struct tags.
     - tenv             # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17
@@ -69,14 +77,13 @@ linters:
     - unconvert        # Remove unnecessary type conversions
     - unparam          # Reports unused function parameters
     - unused           # Checks Go code for unused constants, variables, functions and types
-    - varcheck         # Finds unused global variables and constants
     - wastedassign     # wastedassign finds wasted assignment statements
     - whitespace       # Tool for detection of leading and trailing whitespace
   disable:
+    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - containedctx     # containedctx is a linter that detects struct contained context.Context field
     - cyclop           # checks function and package cyclomatic complexity
     - exhaustivestruct # Checks if all struct's fields are initialized
-    - forbidigo        # Forbids identifiers
     - funlen           # Tool for detection of long functions
     - gocyclo          # Computes and checks the cyclomatic complexity of functions
     - godot            # Check if comments end in a period
@@ -87,6 +94,7 @@ linters:
     - maintidx         # maintidx measures the maintainability index of each function.
     - makezero         # Finds slice declarations with non-zero initial length
     - maligned         # Tool to detect Go structs that would take less memory if their fields were sorted
+    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nestif           # Reports deeply nested if statements
     - nlreturn         # nlreturn checks for a new line before return and branch statements to increase code clarity
     - nolintlint       # Reports ill-formed or insufficient nolint directives
@@ -103,17 +111,15 @@ linters:
 
 issues:
   exclude-use-default: false
+  exclude-dirs-use-default: false
   exclude-rules:
-    # Allow complex tests, better to be self contained
-    - path: _test\.go
+    # Allow complex tests and examples, better to be self contained
+    - path: (examples|main\.go|_test\.go)
       linters:
+        - forbidigo
         - gocognit
 
-    # Allow complex main function in examples
-    - path: examples
-      text: "of func `main` is high"
+    # Allow forbidden identifiers in CLI commands
+    - path: cmd
       linters:
-        - gocognit
-
-run:
-  skip-dirs-use-default: false
+        - forbidigo
diff --git a/vendor/github.com/pion/datachannel/.goreleaser.yml b/vendor/github.com/pion/datachannel/.goreleaser.yml
new file mode 100644
index 00000000..30093e9d
--- /dev/null
+++ b/vendor/github.com/pion/datachannel/.goreleaser.yml
@@ -0,0 +1,5 @@
+# SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+# SPDX-License-Identifier: MIT
+
+builds:
+- skip: true
diff --git a/vendor/github.com/pion/datachannel/AUTHORS.txt b/vendor/github.com/pion/datachannel/AUTHORS.txt
deleted file mode 100644
index c5d9d8d3..00000000
--- a/vendor/github.com/pion/datachannel/AUTHORS.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-# Thank you to everyone that made Pion possible. If you are interested in contributing
-# we would love to have you https://github.com/pion/webrtc/wiki/Contributing
-#
-# This file is auto generated, using git to list all individuals contributors.
-# see `.github/generate-authors.sh` for the scripting
-Atsushi Watanabe <atsushi.w@ieee.org>
-backkem <mail@backkem.me>
-Benny Daon <benny@tuzig.com>
-Chinmay Kousik <chinmaykousik1@gmail.com>
-Eric Daniels <eric@erdaniels.com>
-Hugo Arregui <hugo.arregui@gmail.com>
-Hugo Arregui <hugo@decentraland.org>
-John Bradley <jrb@turrettech.com>
-Norman Rasmussen <norman@rasmussen.co.za>
-Sean DuBois <seaduboi@amazon.com>
-Sean DuBois <sean@siobud.com>
-Yutaka Takeda <yt0916@gmail.com>
diff --git a/vendor/github.com/pion/datachannel/DESIGN.md b/vendor/github.com/pion/datachannel/DESIGN.md
deleted file mode 100644
index 55d6c8ff..00000000
--- a/vendor/github.com/pion/datachannel/DESIGN.md
+++ /dev/null
@@ -1,20 +0,0 @@
-<h1 align="center">
-  Design
-</h1>
-
-### Portable
-Pion Data Channels is written in Go and extremely portable. Anywhere Golang runs, Pion Data Channels should work as well! Instead of dealing with complicated
-cross-compiling of multiple libraries, you now can run anywhere with one `go build`
-
-### Simple API
-The API is based on an io.ReadWriteCloser.
-
-### Readable
-If code comes from an RFC we try to make sure everything is commented with a link to the spec.
-This makes learning and debugging easier, this library was written to also serve as a guide for others.
-
-### Tested
-Every commit is tested via travis-ci Go provides fantastic facilities for testing, and more will be added as time goes on.
-
-### Shared libraries
-Every pion product is built using shared libraries, allowing others to review and reuse our libraries.
diff --git a/vendor/github.com/pion/datachannel/LICENSE b/vendor/github.com/pion/datachannel/LICENSE
index ab602974..491caf6b 100644
--- a/vendor/github.com/pion/datachannel/LICENSE
+++ b/vendor/github.com/pion/datachannel/LICENSE
@@ -1,21 +1,9 @@
 MIT License
 
-Copyright (c) 2018 
+Copyright (c) 2023 The Pion community <https://pion.ly>
 
-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:
+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 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.
+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/pion/datachannel/README.md b/vendor/github.com/pion/datachannel/README.md
index 7be311da..c68be942 100644
--- a/vendor/github.com/pion/datachannel/README.md
+++ b/vendor/github.com/pion/datachannel/README.md
@@ -6,32 +6,29 @@
 <h4 align="center">A Go implementation of WebRTC Data Channels</h4>
 <p align="center">
   <a href="https://pion.ly"><img src="https://img.shields.io/badge/pion-datachannel-gray.svg?longCache=true&colorB=brightgreen" alt="Pion Data Channels"></a>
-  <!--<a href="https://sourcegraph.com/github.com/pion/webrtc?badge"><img src="https://sourcegraph.com/github.com/pion/webrtc/-/badge.svg" alt="Sourcegraph Widget"></a>-->
   <a href="https://pion.ly/slack"><img src="https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen" alt="Slack Widget"></a>
   <br>
-  <a href="https://travis-ci.org/pion/datachannel"><img src="https://travis-ci.org/pion/datachannel.svg?branch=master" alt="Build Status"></a>
-  <a href="https://pkg.go.dev/github.com/pion/datachannel"><img src="https://godoc.org/github.com/pion/datachannel?status.svg" alt="GoDoc"></a>
+  <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/pion/datachannel/test.yaml">
+  <a href="https://pkg.go.dev/github.com/pion/datachannel"><img src="https://pkg.go.dev/badge/github.com/pion/datachannel.svg" alt="Go Reference"></a>
   <a href="https://codecov.io/gh/pion/datachannel"><img src="https://codecov.io/gh/pion/datachannel/branch/master/graph/badge.svg" alt="Coverage Status"></a>
   <a href="https://goreportcard.com/report/github.com/pion/datachannel"><img src="https://goreportcard.com/badge/github.com/pion/datachannel" alt="Go Report Card"></a>
-  <!--<a href="https://www.codacy.com/app/Sean-Der/webrtc"><img src="https://api.codacy.com/project/badge/Grade/18f4aec384894e6aac0b94effe51961d" alt="Codacy Badge"></a>-->
   <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
 </p>
 <br>
 
-See [DESIGN.md](DESIGN.md) for an overview of features and future goals.
-
 ### Roadmap
 The library is used as a part of our WebRTC implementation. Please refer to that [roadmap](https://github.com/pion/webrtc/issues/9) to track our major milestones.
 
 ### Community
-Pion has an active community on the [Golang Slack](https://invite.slack.golangbridge.org/). Sign up and join the **#pion** channel for discussions and support. You can also use [Pion mailing list](https://groups.google.com/forum/#!forum/pion).
+Pion has an active community on the [Slack](https://pion.ly/slack).
 
-We are always looking to support **your projects**. Please reach out if you have something to build!
+Follow the [Pion Twitter](https://twitter.com/_pion) for project updates and important WebRTC news.
 
+We are always looking to support **your projects**. Please reach out if you have something to build!
 If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly)
 
 ### Contributing
-Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contributing)** to join the group of amazing people making this project possible:
+Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible
 
 ### License
 MIT License - see [LICENSE](LICENSE) for full text
diff --git a/vendor/github.com/pion/datachannel/codecov.yml b/vendor/github.com/pion/datachannel/codecov.yml
index 085200a4..263e4d45 100644
--- a/vendor/github.com/pion/datachannel/codecov.yml
+++ b/vendor/github.com/pion/datachannel/codecov.yml
@@ -3,6 +3,8 @@
 #
 # It is automatically copied from https://github.com/pion/.goassets repository.
 #
+# SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+# SPDX-License-Identifier: MIT
 
 coverage:
   status:
diff --git a/vendor/github.com/pion/datachannel/datachannel.go b/vendor/github.com/pion/datachannel/datachannel.go
index 0b125d66..0050185c 100644
--- a/vendor/github.com/pion/datachannel/datachannel.go
+++ b/vendor/github.com/pion/datachannel/datachannel.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 // Package datachannel implements WebRTC Data Channels
 package datachannel
 
@@ -71,12 +74,12 @@ type Config struct {
 	LoggerFactory        logging.LoggerFactory
 }
 
-func newDataChannel(stream *sctp.Stream, config *Config) (*DataChannel, error) {
+func newDataChannel(stream *sctp.Stream, config *Config) *DataChannel {
 	return &DataChannel{
 		Config: *config,
 		stream: stream,
 		log:    config.LoggerFactory.NewLogger("datachannel"),
-	}, nil
+	}
 }
 
 // Dial opens a data channels over SCTP
@@ -115,7 +118,12 @@ func Client(stream *sctp.Stream, config *Config) (*DataChannel, error) {
 			return nil, fmt.Errorf("failed to send ChannelOpen %w", err)
 		}
 	}
-	return newDataChannel(stream, config)
+	dc := newDataChannel(stream, config)
+
+	if err := dc.commitReliabilityParams(); err != nil {
+		return nil, err
+	}
+	return dc, nil
 }
 
 // Accept is used to accept incoming data channels over SCTP
@@ -164,10 +172,7 @@ func Server(stream *sctp.Stream, config *Config) (*DataChannel, error) {
 	config.Label = string(openMsg.Label)
 	config.Protocol = string(openMsg.Protocol)
 
-	dataChannel, err := newDataChannel(stream, config)
-	if err != nil {
-		return nil, err
-	}
+	dataChannel := newDataChannel(stream, config)
 
 	err = dataChannel.writeDataChannelAck()
 	if err != nil {
@@ -280,13 +285,9 @@ func (c *DataChannel) handleDCEP(data []byte) error {
 
 	switch msg := msg.(type) {
 	case *channelAck:
-		c.log.Debug("Received DATA_CHANNEL_ACK")
-		if err = c.commitReliabilityParams(); err != nil {
-			return err
-		}
 		c.onOpenComplete()
 	default:
-		return fmt.Errorf("%w %v", ErrInvalidMessageType, msg)
+		return fmt.Errorf("%w, wanted ACK got %v", ErrUnexpectedDataChannelType, msg)
 	}
 
 	return nil
diff --git a/vendor/github.com/pion/datachannel/errors.go b/vendor/github.com/pion/datachannel/errors.go
index f7aeecc0..2f98bf84 100644
--- a/vendor/github.com/pion/datachannel/errors.go
+++ b/vendor/github.com/pion/datachannel/errors.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package datachannel
 
 import "errors"
diff --git a/vendor/github.com/pion/datachannel/message.go b/vendor/github.com/pion/datachannel/message.go
index 27848c77..53f221b1 100644
--- a/vendor/github.com/pion/datachannel/message.go
+++ b/vendor/github.com/pion/datachannel/message.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package datachannel
 
 import (
@@ -8,6 +11,7 @@ import (
 type message interface {
 	Marshal() ([]byte, error)
 	Unmarshal([]byte) error
+	String() string
 }
 
 // messageType is the first byte in a DataChannel message that specifies type
diff --git a/vendor/github.com/pion/datachannel/message_channel_ack.go b/vendor/github.com/pion/datachannel/message_channel_ack.go
index fd207579..8fe396f8 100644
--- a/vendor/github.com/pion/datachannel/message_channel_ack.go
+++ b/vendor/github.com/pion/datachannel/message_channel_ack.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package datachannel
 
 // channelAck is used to ACK a DataChannel open
@@ -16,7 +19,11 @@ func (c *channelAck) Marshal() ([]byte, error) {
 }
 
 // Unmarshal populates the struct with the given raw data
-func (c *channelAck) Unmarshal(raw []byte) error {
+func (c *channelAck) Unmarshal(_ []byte) error {
 	// Message type already checked in Parse and there is no further data
 	return nil
 }
+
+func (c channelAck) String() string {
+	return "ACK"
+}
diff --git a/vendor/github.com/pion/datachannel/message_channel_open.go b/vendor/github.com/pion/datachannel/message_channel_open.go
index 5eb58633..dac58ff6 100644
--- a/vendor/github.com/pion/datachannel/message_channel_open.go
+++ b/vendor/github.com/pion/datachannel/message_channel_open.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package datachannel
 
 import (
@@ -72,6 +75,23 @@ const (
 	ChannelTypePartialReliableTimedUnordered ChannelType = 0x82
 )
 
+func (c ChannelType) String() string {
+	switch c {
+	case ChannelTypeReliable:
+	case ChannelTypeReliableUnordered:
+		return "ReliableUnordered"
+	case ChannelTypePartialReliableRexmit:
+		return "PartialReliableRexmit"
+	case ChannelTypePartialReliableRexmitUnordered:
+		return "PartialReliableRexmitUnordered"
+	case ChannelTypePartialReliableTimed:
+		return "PartialReliableTimed"
+	case ChannelTypePartialReliableTimedUnordered:
+		return "PartialReliableTimedUnordered"
+	}
+	return "Unknown"
+}
+
 // ChannelPriority enums
 const (
 	ChannelPriorityBelowNormal uint16 = 128
@@ -113,7 +133,7 @@ func (c *channelOpen) Unmarshal(raw []byte) error {
 	labelLength := binary.BigEndian.Uint16(raw[8:])
 	protocolLength := binary.BigEndian.Uint16(raw[10:])
 
-	if expectedLen := int(channelOpenHeaderLength + labelLength + protocolLength); len(raw) != expectedLen {
+	if expectedLen := channelOpenHeaderLength + int(labelLength) + int(protocolLength); len(raw) != expectedLen {
 		return fmt.Errorf("%w expected(%d) actual(%d)", ErrExpectedAndActualLengthMismatch, expectedLen, len(raw))
 	}
 
@@ -121,3 +141,7 @@ func (c *channelOpen) Unmarshal(raw []byte) error {
 	c.Protocol = raw[channelOpenHeaderLength+labelLength : channelOpenHeaderLength+labelLength+protocolLength]
 	return nil
 }
+
+func (c channelOpen) String() string {
+	return fmt.Sprintf("Open ChannelType(%s) Priority(%v) ReliabilityParameter(%d) Label(%s) Protocol(%s)", c.ChannelType, c.Priority, c.ReliabilityParameter, string(c.Label), string(c.Protocol))
+}
diff --git a/vendor/github.com/pion/datachannel/renovate.json b/vendor/github.com/pion/datachannel/renovate.json
index f1614058..f1bb98c6 100644
--- a/vendor/github.com/pion/datachannel/renovate.json
+++ b/vendor/github.com/pion/datachannel/renovate.json
@@ -1,27 +1,6 @@
 {
+  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
   "extends": [
-    "config:base",
-    ":disableDependencyDashboard"
-  ],
-  "postUpdateOptions": [
-    "gomodTidy"
-  ],
-  "commitBody": "Generated by renovateBot",
-  "packageRules": [
-    {
-      "matchUpdateTypes": ["minor", "patch", "pin", "digest"],
-      "automerge": true
-    },
-    {
-      "packagePatterns": ["^golang.org/x/"],
-      "schedule": ["on the first day of the month"]
-    }
-  ],
-  "ignorePaths": [
-    ".github/workflows/generate-authors.yml",
-    ".github/workflows/lint.yaml",
-    ".github/workflows/renovate-go-mod-fix.yaml",
-    ".github/workflows/test.yaml",
-    ".github/workflows/tidy-check.yaml"
+    "github>pion/renovate-config"
   ]
 }
diff --git a/vendor/github.com/pion/dtls/v2/conn.go b/vendor/github.com/pion/dtls/v2/conn.go
index 338f793a..ccea999d 100644
--- a/vendor/github.com/pion/dtls/v2/conn.go
+++ b/vendor/github.com/pion/dtls/v2/conn.go
@@ -34,6 +34,9 @@ const (
 	inboundBufferSize     = 8192
 	// Default replay protection window is specified by RFC 6347 Section 4.1.2.6
 	defaultReplayProtectionWindow = 64
+	// maxAppDataPacketQueueSize is the maximum number of app data packets we will
+	// enqueue before the handshake is completed
+	maxAppDataPacketQueueSize = 100
 )
 
 func invalidKeyingLabels() map[string]bool {
@@ -81,7 +84,7 @@ type Conn struct {
 	replayProtectionWindow uint
 }
 
-func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient bool, initialState *State) (*Conn, error) {
+func createConn(nextConn net.Conn, config *Config, isClient bool) (*Conn, error) {
 	err := validateConfig(config)
 	if err != nil {
 		return nil, err
@@ -91,21 +94,6 @@ func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient
 		return nil, errNilNextConn
 	}
 
-	cipherSuites, err := parseCipherSuites(config.CipherSuites, config.CustomCipherSuites, config.includeCertificateSuites(), config.PSK != nil)
-	if err != nil {
-		return nil, err
-	}
-
-	signatureSchemes, err := signaturehash.ParseSignatureSchemes(config.SignatureSchemes, config.InsecureHashes)
-	if err != nil {
-		return nil, err
-	}
-
-	workerInterval := initialTickerInterval
-	if config.FlightInterval != 0 {
-		workerInterval = config.FlightInterval
-	}
-
 	loggerFactory := config.LoggerFactory
 	if loggerFactory == nil {
 		loggerFactory = logging.NewDefaultLoggerFactory()
@@ -149,6 +137,28 @@ func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient
 
 	c.setRemoteEpoch(0)
 	c.setLocalEpoch(0)
+	return c, nil
+}
+
+func handshakeConn(ctx context.Context, conn *Conn, config *Config, isClient bool, initialState *State) (*Conn, error) {
+	if conn == nil {
+		return nil, errNilNextConn
+	}
+
+	cipherSuites, err := parseCipherSuites(config.CipherSuites, config.CustomCipherSuites, config.includeCertificateSuites(), config.PSK != nil)
+	if err != nil {
+		return nil, err
+	}
+
+	signatureSchemes, err := signaturehash.ParseSignatureSchemes(config.SignatureSchemes, config.InsecureHashes)
+	if err != nil {
+		return nil, err
+	}
+
+	workerInterval := initialTickerInterval
+	if config.FlightInterval != 0 {
+		workerInterval = config.FlightInterval
+	}
 
 	serverName := config.ServerName
 	// Do not allow the use of an IP address literal as an SNI value.
@@ -180,7 +190,7 @@ func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient
 		clientCAs:                   config.ClientCAs,
 		customCipherSuites:          config.CustomCipherSuites,
 		retransmitInterval:          workerInterval,
-		log:                         logger,
+		log:                         conn.log,
 		initialEpoch:                0,
 		keyLogWriter:                config.KeyLogWriter,
 		sessionStore:                config.SessionStore,
@@ -205,16 +215,16 @@ func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient
 	var initialFSMState handshakeState
 
 	if initialState != nil {
-		if c.state.isClient {
+		if conn.state.isClient {
 			initialFlight = flight5
 		} else {
 			initialFlight = flight6
 		}
 		initialFSMState = handshakeFinished
 
-		c.state = *initialState
+		conn.state = *initialState
 	} else {
-		if c.state.isClient {
+		if conn.state.isClient {
 			initialFlight = flight1
 		} else {
 			initialFlight = flight0
@@ -222,13 +232,13 @@ func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient
 		initialFSMState = handshakePreparing
 	}
 	// Do handshake
-	if err := c.handshake(ctx, hsCfg, initialFlight, initialFSMState); err != nil {
+	if err := conn.handshake(ctx, hsCfg, initialFlight, initialFSMState); err != nil {
 		return nil, err
 	}
 
-	c.log.Trace("Handshake Completed")
+	conn.log.Trace("Handshake Completed")
 
-	return c, nil
+	return conn, nil
 }
 
 // Dial connects to the given network address and establishes a DTLS connection on top.
@@ -279,7 +289,12 @@ func ClientWithContext(ctx context.Context, conn net.Conn, config *Config) (*Con
 		return nil, errPSKAndIdentityMustBeSetForClient
 	}
 
-	return createConn(ctx, conn, config, true, nil)
+	dconn, err := createConn(conn, config, true)
+	if err != nil {
+		return nil, err
+	}
+
+	return handshakeConn(ctx, dconn, config, true, nil)
 }
 
 // ServerWithContext listens for incoming DTLS connections.
@@ -287,8 +302,11 @@ func ServerWithContext(ctx context.Context, conn net.Conn, config *Config) (*Con
 	if config == nil {
 		return nil, errNoConfigProvided
 	}
-
-	return createConn(ctx, conn, config, false, nil)
+	dconn, err := createConn(conn, config, false)
+	if err != nil {
+		return nil, err
+	}
+	return handshakeConn(ctx, dconn, config, false, nil)
 }
 
 // Read reads data from the connection.
@@ -607,13 +625,8 @@ func (c *Conn) readAndBuffer(ctx context.Context) error {
 			hasHandshake = true
 		}
 
-		var e *alertError
-		if errors.As(err, &e) {
-			if e.IsFatalOrCloseNotify() {
-				return e
-			}
-		} else if err != nil {
-			return e
+		if err != nil {
+			return err
 		}
 	}
 	if hasHandshake {
@@ -648,12 +661,20 @@ func (c *Conn) handleQueuedPackets(ctx context.Context) error {
 				return e
 			}
 		} else if err != nil {
-			return e
+			return err
 		}
 	}
 	return nil
 }
 
+func (c *Conn) enqueueEncryptedPackets(packet []byte) bool {
+	if len(c.encryptedPackets) < maxAppDataPacketQueueSize {
+		c.encryptedPackets = append(c.encryptedPackets, packet)
+		return true
+	}
+	return false
+}
+
 func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, enqueue bool) (bool, *alert.Alert, error) { //nolint:gocognit
 	h := &recordlayer.Header{}
 	if err := h.Unmarshal(buf); err != nil {
@@ -662,7 +683,6 @@ func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, enqueue boo
 		c.log.Debugf("discarded broken packet: %v", err)
 		return false, nil, nil
 	}
-
 	// Validate epoch
 	remoteEpoch := c.state.getRemoteEpoch()
 	if h.Epoch > remoteEpoch {
@@ -673,8 +693,9 @@ func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, enqueue boo
 			return false, nil, nil
 		}
 		if enqueue {
-			c.log.Debug("received packet of next epoch, queuing packet")
-			c.encryptedPackets = append(c.encryptedPackets, buf)
+			if ok := c.enqueueEncryptedPackets(buf); ok {
+				c.log.Debug("received packet of next epoch, queuing packet")
+			}
 		}
 		return false, nil, nil
 	}
@@ -697,8 +718,9 @@ func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, enqueue boo
 	if h.Epoch != 0 {
 		if c.state.cipherSuite == nil || !c.state.cipherSuite.IsInitialized() {
 			if enqueue {
-				c.encryptedPackets = append(c.encryptedPackets, buf)
-				c.log.Debug("handshake not finished, queuing packet")
+				if ok := c.enqueueEncryptedPackets(buf); ok {
+					c.log.Debug("handshake not finished, queuing packet")
+				}
 			}
 			return false, nil, nil
 		}
@@ -749,8 +771,9 @@ func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, enqueue boo
 	case *protocol.ChangeCipherSpec:
 		if c.state.cipherSuite == nil || !c.state.cipherSuite.IsInitialized() {
 			if enqueue {
-				c.encryptedPackets = append(c.encryptedPackets, buf)
-				c.log.Debugf("CipherSuite not initialized, queuing packet")
+				if ok := c.enqueueEncryptedPackets(buf); ok {
+					c.log.Debugf("CipherSuite not initialized, queuing packet")
+				}
 			}
 			return false, nil, nil
 		}
diff --git a/vendor/github.com/pion/dtls/v2/resume.go b/vendor/github.com/pion/dtls/v2/resume.go
index c470d856..f070d753 100644
--- a/vendor/github.com/pion/dtls/v2/resume.go
+++ b/vendor/github.com/pion/dtls/v2/resume.go
@@ -13,7 +13,11 @@ func Resume(state *State, conn net.Conn, config *Config) (*Conn, error) {
 	if err := state.initCipherSuite(); err != nil {
 		return nil, err
 	}
-	c, err := createConn(context.Background(), conn, config, state.isClient, state)
+	dconn, err := createConn(conn, config, state.isClient)
+	if err != nil {
+		return nil, err
+	}
+	c, err := handshakeConn(context.Background(), dconn, config, state.isClient, state)
 	if err != nil {
 		return nil, err
 	}
diff --git a/vendor/github.com/pion/ice/v2/agent.go b/vendor/github.com/pion/ice/v2/agent.go
index 09b7e628..91d25f12 100644
--- a/vendor/github.com/pion/ice/v2/agent.go
+++ b/vendor/github.com/pion/ice/v2/agent.go
@@ -8,6 +8,7 @@ package ice
 import (
 	"context"
 	"fmt"
+	"math"
 	"net"
 	"strconv"
 	"strings"
@@ -125,12 +126,16 @@ type Agent struct {
 	taskLoopDone chan struct{}
 	err          atomicx.Error
 
+	// Callback that allows user to implement custom behavior
+	// for STUN Binding Requests
+	userBindingRequestHandler func(m *stun.Message, local, remote Candidate, pair *CandidatePair) bool
+
 	gatherCandidateCancel func()
 	gatherCandidateDone   chan struct{}
 
-	chanCandidate     chan Candidate
-	chanCandidatePair chan *CandidatePair
-	chanState         chan ConnectionState
+	connectionStateNotifier       *handlerNotifier
+	candidateNotifier             *handlerNotifier
+	selectedCandidatePairNotifier *handlerNotifier
 
 	loggerFactory logging.LoggerFactory
 	log           logging.LeveledLogger
@@ -227,9 +232,6 @@ func (a *Agent) taskLoop() {
 
 		after()
 
-		close(a.chanState)
-		close(a.chanCandidate)
-		close(a.chanCandidatePair)
 		close(a.taskLoopDone)
 	}()
 
@@ -277,33 +279,30 @@ func NewAgent(config *AgentConfig) (*Agent, error) { //nolint:gocognit
 	startedCtx, startedFn := context.WithCancel(context.Background())
 
 	a := &Agent{
-		chanTask:          make(chan task),
-		chanState:         make(chan ConnectionState),
-		chanCandidate:     make(chan Candidate),
-		chanCandidatePair: make(chan *CandidatePair),
-		tieBreaker:        globalMathRandomGenerator.Uint64(),
-		lite:              config.Lite,
-		gatheringState:    GatheringStateNew,
-		connectionState:   ConnectionStateNew,
-		localCandidates:   make(map[NetworkType][]Candidate),
-		remoteCandidates:  make(map[NetworkType][]Candidate),
-		urls:              config.Urls,
-		networkTypes:      config.NetworkTypes,
-		onConnected:       make(chan struct{}),
-		buf:               packetio.NewBuffer(),
-		done:              make(chan struct{}),
-		taskLoopDone:      make(chan struct{}),
-		startedCh:         startedCtx.Done(),
-		startedFn:         startedFn,
-		portMin:           config.PortMin,
-		portMax:           config.PortMax,
-		loggerFactory:     loggerFactory,
-		log:               log,
-		net:               config.Net,
-		proxyDialer:       config.ProxyDialer,
-		tcpMux:            config.TCPMux,
-		udpMux:            config.UDPMux,
-		udpMuxSrflx:       config.UDPMuxSrflx,
+		chanTask:         make(chan task),
+		tieBreaker:       globalMathRandomGenerator.Uint64(),
+		lite:             config.Lite,
+		gatheringState:   GatheringStateNew,
+		connectionState:  ConnectionStateNew,
+		localCandidates:  make(map[NetworkType][]Candidate),
+		remoteCandidates: make(map[NetworkType][]Candidate),
+		urls:             config.Urls,
+		networkTypes:     config.NetworkTypes,
+		onConnected:      make(chan struct{}),
+		buf:              packetio.NewBuffer(),
+		done:             make(chan struct{}),
+		taskLoopDone:     make(chan struct{}),
+		startedCh:        startedCtx.Done(),
+		startedFn:        startedFn,
+		portMin:          config.PortMin,
+		portMax:          config.PortMax,
+		loggerFactory:    loggerFactory,
+		log:              log,
+		net:              config.Net,
+		proxyDialer:      config.ProxyDialer,
+		tcpMux:           config.TCPMux,
+		udpMux:           config.UDPMux,
+		udpMuxSrflx:      config.UDPMuxSrflx,
 
 		mDNSMode: mDNSMode,
 		mDNSName: mDNSName,
@@ -321,7 +320,12 @@ func NewAgent(config *AgentConfig) (*Agent, error) { //nolint:gocognit
 		includeLoopback: config.IncludeLoopback,
 
 		disableActiveTCP: config.DisableActiveTCP,
+
+		userBindingRequestHandler: config.BindingRequestHandler,
 	}
+	a.connectionStateNotifier = &handlerNotifier{connectionStateFunc: a.onConnectionStateChange, done: make(chan struct{})}
+	a.candidateNotifier = &handlerNotifier{candidateFunc: a.onCandidate, done: make(chan struct{})}
+	a.selectedCandidatePairNotifier = &handlerNotifier{candidatePairFunc: a.onSelectedCandidatePairChange, done: make(chan struct{})}
 
 	if a.net == nil {
 		a.net, err = stdnet.NewNet()
@@ -365,13 +369,6 @@ func NewAgent(config *AgentConfig) (*Agent, error) { //nolint:gocognit
 
 	go a.taskLoop()
 
-	// CandidatePair and ConnectionState are usually changed at once.
-	// Blocking one by the other one causes deadlock.
-	// Hence, we call handlers from independent Goroutines.
-	go a.candidatePairRoutine()
-	go a.connectionStateRoutine()
-	go a.candidateRoutine()
-
 	// Restart is also used to initialize the agent for the first time
 	if err := a.Restart(config.LocalUfrag, config.LocalPwd); err != nil {
 		a.closeMulticastConn()
@@ -456,6 +453,9 @@ func (a *Agent) connectivityChecks() {
 		}
 	}
 
+	t := time.NewTimer(math.MaxInt64)
+	t.Stop()
+
 	for {
 		interval := defaultKeepaliveInterval
 
@@ -476,10 +476,13 @@ func (a *Agent) connectivityChecks() {
 		updateInterval(a.disconnectedTimeout)
 		updateInterval(a.failedTimeout)
 
-		t := time.NewTimer(interval)
+		t.Reset(interval)
+
 		select {
 		case <-a.forceCandidateContact:
-			t.Stop()
+			if !t.Stop() {
+				<-t.C
+			}
 			contact()
 		case <-t.C:
 			contact()
@@ -503,12 +506,7 @@ func (a *Agent) updateConnectionState(newState ConnectionState) {
 
 		a.log.Infof("Setting new connection state: %s", newState)
 		a.connectionState = newState
-
-		// Call handler after finishing current task since we may be holding the agent lock
-		// and the handler may also require it
-		a.afterRun(func(ctx context.Context) {
-			a.chanState <- newState
-		})
+		a.connectionStateNotifier.EnqueueConnectionState(newState)
 	}
 }
 
@@ -527,12 +525,7 @@ func (a *Agent) setSelectedPair(p *CandidatePair) {
 	a.updateConnectionState(ConnectionStateConnected)
 
 	// Notify when the selected pair changes
-	a.afterRun(func(ctx context.Context) {
-		select {
-		case a.chanCandidatePair <- p:
-		case <-ctx.Done():
-		}
-	})
+	a.selectedCandidatePairNotifier.EnqueueSelectedCandidatePair(p)
 
 	// Signal connected
 	a.onConnectedOnce.Do(func() { close(a.onConnected) })
@@ -768,7 +761,7 @@ func (a *Agent) addRemotePassiveTCPCandidate(remoteCandidate Candidate) {
 
 		localCandidate.start(a, conn, a.startedCh)
 		a.localCandidates[localCandidate.NetworkType()] = append(a.localCandidates[localCandidate.NetworkType()], localCandidate)
-		a.chanCandidate <- localCandidate
+		a.candidateNotifier.EnqueueCandidate(localCandidate)
 
 		a.addPair(localCandidate, remoteCandidate)
 	}
@@ -814,7 +807,7 @@ func (a *Agent) addCandidate(ctx context.Context, c Candidate, candidateConn net
 		set := a.localCandidates[c.NetworkType()]
 		for _, candidate := range set {
 			if candidate.Equal(c) {
-				a.log.Debugf("Ignore duplicate candidate: %s", c.String())
+				a.log.Debugf("Ignore duplicate candidate: %s", c)
 				if err := c.close(); err != nil {
 					a.log.Warnf("Failed to close duplicate candidate: %v", err)
 				}
@@ -838,7 +831,7 @@ func (a *Agent) addCandidate(ctx context.Context, c Candidate, candidateConn net
 
 		a.requestConnectivityCheck()
 
-		a.chanCandidate <- c
+		a.candidateNotifier.EnqueueCandidate(c)
 	})
 }
 
@@ -938,6 +931,9 @@ func (a *Agent) Close() error {
 
 	close(a.done)
 	<-a.taskLoopDone
+	a.connectionStateNotifier.Close()
+	a.candidateNotifier.Close()
+	a.selectedCandidatePairNotifier.Close()
 	return nil
 }
 
@@ -981,7 +977,7 @@ func (a *Agent) findRemoteCandidate(networkType NetworkType, addr net.Addr) Cand
 }
 
 func (a *Agent) sendBindingRequest(m *stun.Message, local, remote Candidate) {
-	a.log.Tracef("Ping STUN from %s to %s", local.String(), remote.String())
+	a.log.Tracef("Ping STUN from %s to %s", local, remote)
 
 	a.invalidatePendingBindingRequests(time.Now())
 	a.pendingBindingRequests = append(a.pendingBindingRequests, bindingRequest{
@@ -1096,7 +1092,7 @@ func (a *Agent) handleInbound(m *stun.Message, local Candidate, remote net.Addr)
 
 		a.selector.HandleSuccessResponse(m, local, remoteCandidate, remote)
 	} else if m.Type.Class == stun.ClassRequest {
-		a.log.Tracef("Inbound STUN (Request) from %s to %s, useCandidate: %v", remote.String(), local.String(), m.Contains(stun.AttrUseCandidate))
+		a.log.Tracef("Inbound STUN (Request) from %s to %s, useCandidate: %v", remote, local, m.Contains(stun.AttrUseCandidate))
 
 		if err = stunx.AssertUsername(m, a.localUfrag+":"+a.remoteUfrag); err != nil {
 			a.log.Warnf("Discard message from (%s), %v", remote, err)
@@ -1274,7 +1270,7 @@ func (a *Agent) setGatheringState(newState GatheringState) error {
 	done := make(chan struct{})
 	if err := a.run(a.context(), func(ctx context.Context, agent *Agent) {
 		if a.gatheringState != newState && newState == GatheringStateComplete {
-			a.chanCandidate <- nil
+			a.candidateNotifier.EnqueueCandidate(nil)
 		}
 
 		a.gatheringState = newState
diff --git a/vendor/github.com/pion/ice/v2/agent_config.go b/vendor/github.com/pion/ice/v2/agent_config.go
index 9629fd5a..7f7b67a3 100644
--- a/vendor/github.com/pion/ice/v2/agent_config.go
+++ b/vendor/github.com/pion/ice/v2/agent_config.go
@@ -188,6 +188,13 @@ type AgentConfig struct {
 	// DisableActiveTCP can be used to disable Active TCP candidates. Otherwise when TCP is enabled
 	// Active TCP candidates will be created when a new passive TCP remote candidate is added.
 	DisableActiveTCP bool
+
+	// BindingRequestHandler allows applications to perform logic on incoming STUN Binding Requests
+	// This was implemented to allow users to
+	// * Log incoming Binding Requests for debugging
+	// * Implement draft-thatcher-ice-renomination
+	// * Implement custom CandidatePair switching logic
+	BindingRequestHandler func(m *stun.Message, local, remote Candidate, pair *CandidatePair) bool
 }
 
 // initWithDefaults populates an agent and falls back to defaults if fields are unset
diff --git a/vendor/github.com/pion/ice/v2/agent_handlers.go b/vendor/github.com/pion/ice/v2/agent_handlers.go
index c5a5ec03..7ebfedd1 100644
--- a/vendor/github.com/pion/ice/v2/agent_handlers.go
+++ b/vendor/github.com/pion/ice/v2/agent_handlers.go
@@ -3,6 +3,8 @@
 
 package ice
 
+import "sync"
+
 // OnConnectionStateChange sets a handler that is fired when the connection state changes
 func (a *Agent) OnConnectionStateChange(f func(ConnectionState)) error {
 	a.onConnectionStateChangeHdlr.Store(f)
@@ -41,20 +43,137 @@ func (a *Agent) onConnectionStateChange(s ConnectionState) {
 	}
 }
 
-func (a *Agent) candidatePairRoutine() {
-	for p := range a.chanCandidatePair {
-		a.onSelectedCandidatePairChange(p)
+type handlerNotifier struct {
+	sync.Mutex
+	running   bool
+	notifiers sync.WaitGroup
+
+	connectionStates    []ConnectionState
+	connectionStateFunc func(ConnectionState)
+
+	candidates    []Candidate
+	candidateFunc func(Candidate)
+
+	selectedCandidatePairs []*CandidatePair
+	candidatePairFunc      func(*CandidatePair)
+
+	// State for closing
+	done chan struct{}
+}
+
+func (h *handlerNotifier) Close() {
+	h.Lock()
+
+	select {
+	case <-h.done:
+		h.Unlock()
+		return
+	default:
 	}
+	close(h.done)
+	h.Unlock()
+
+	h.notifiers.Wait()
 }
 
-func (a *Agent) connectionStateRoutine() {
-	for s := range a.chanState {
-		go a.onConnectionStateChange(s)
+func (h *handlerNotifier) EnqueueConnectionState(s ConnectionState) {
+	h.Lock()
+	defer h.Unlock()
+
+	select {
+	case <-h.done:
+		return
+	default:
+	}
+
+	notify := func() {
+		defer h.notifiers.Done()
+		for {
+			h.Lock()
+			if len(h.connectionStates) == 0 {
+				h.running = false
+				h.Unlock()
+				return
+			}
+			notification := h.connectionStates[0]
+			h.connectionStates = h.connectionStates[1:]
+			h.Unlock()
+			h.connectionStateFunc(notification)
+		}
+	}
+
+	h.connectionStates = append(h.connectionStates, s)
+	if !h.running {
+		h.running = true
+		h.notifiers.Add(1)
+		go notify()
 	}
 }
 
-func (a *Agent) candidateRoutine() {
-	for c := range a.chanCandidate {
-		a.onCandidate(c)
+func (h *handlerNotifier) EnqueueCandidate(c Candidate) {
+	h.Lock()
+	defer h.Unlock()
+
+	select {
+	case <-h.done:
+		return
+	default:
+	}
+
+	notify := func() {
+		defer h.notifiers.Done()
+		for {
+			h.Lock()
+			if len(h.candidates) == 0 {
+				h.running = false
+				h.Unlock()
+				return
+			}
+			notification := h.candidates[0]
+			h.candidates = h.candidates[1:]
+			h.Unlock()
+			h.candidateFunc(notification)
+		}
+	}
+
+	h.candidates = append(h.candidates, c)
+	if !h.running {
+		h.running = true
+		h.notifiers.Add(1)
+		go notify()
+	}
+}
+
+func (h *handlerNotifier) EnqueueSelectedCandidatePair(p *CandidatePair) {
+	h.Lock()
+	defer h.Unlock()
+
+	select {
+	case <-h.done:
+		return
+	default:
+	}
+
+	notify := func() {
+		defer h.notifiers.Done()
+		for {
+			h.Lock()
+			if len(h.selectedCandidatePairs) == 0 {
+				h.running = false
+				h.Unlock()
+				return
+			}
+			notification := h.selectedCandidatePairs[0]
+			h.selectedCandidatePairs = h.selectedCandidatePairs[1:]
+			h.Unlock()
+			h.candidatePairFunc(notification)
+		}
+	}
+
+	h.selectedCandidatePairs = append(h.selectedCandidatePairs, p)
+	if !h.running {
+		h.running = true
+		h.notifiers.Add(1)
+		go notify()
 	}
 }
diff --git a/vendor/github.com/pion/ice/v2/candidate_base.go b/vendor/github.com/pion/ice/v2/candidate_base.go
index 63199406..f7259852 100644
--- a/vendor/github.com/pion/ice/v2/candidate_base.go
+++ b/vendor/github.com/pion/ice/v2/candidate_base.go
@@ -447,6 +447,13 @@ func (c *candidateBase) copy() (Candidate, error) {
 	return UnmarshalCandidate(c.Marshal())
 }
 
+func removeZoneIDFromAddress(addr string) string {
+	if i := strings.Index(addr, "%"); i != -1 {
+		return addr[:i]
+	}
+	return addr
+}
+
 // Marshal returns the string representation of the ICECandidate
 func (c *candidateBase) Marshal() string {
 	val := c.Foundation()
@@ -459,7 +466,7 @@ func (c *candidateBase) Marshal() string {
 		c.Component(),
 		c.NetworkType().NetworkShort(),
 		c.Priority(),
-		c.Address(),
+		removeZoneIDFromAddress(c.Address()),
 		c.Port(),
 		c.Type())
 
@@ -509,7 +516,7 @@ func UnmarshalCandidate(raw string) (Candidate, error) {
 	priority := uint32(priorityRaw)
 
 	// Address
-	address := split[4]
+	address := removeZoneIDFromAddress(split[4])
 
 	// Port
 	rawPort, err := strconv.ParseUint(split[5], 10, 16)
diff --git a/vendor/github.com/pion/ice/v2/selection.go b/vendor/github.com/pion/ice/v2/selection.go
index f854581f..69bde40a 100644
--- a/vendor/github.com/pion/ice/v2/selection.go
+++ b/vendor/github.com/pion/ice/v2/selection.go
@@ -59,7 +59,7 @@ func (s *controllingSelector) ContactCandidates() {
 	default:
 		p := s.agent.getBestValidCandidatePair()
 		if p != nil && s.isNominatable(p.Local) && s.isNominatable(p.Remote) {
-			s.log.Tracef("Nominatable pair found, nominating (%s, %s)", p.Local.String(), p.Remote.String())
+			s.log.Tracef("Nominatable pair found, nominating (%s, %s)", p.Local, p.Remote)
 			p.nominated = true
 			s.nominatedPair = p
 			s.nominatePair(p)
@@ -87,7 +87,7 @@ func (s *controllingSelector) nominatePair(pair *CandidatePair) {
 		return
 	}
 
-	s.log.Tracef("Ping STUN (nominate candidate pair) from %s to %s", pair.Local.String(), pair.Remote.String())
+	s.log.Tracef("Ping STUN (nominate candidate pair) from %s to %s", pair.Local, pair.Remote)
 	s.agent.sendBindingRequest(msg, pair.Local, pair.Remote)
 }
 
@@ -106,12 +106,17 @@ func (s *controllingSelector) HandleBindingRequest(m *stun.Message, local, remot
 		if bestPair == nil {
 			s.log.Tracef("No best pair available")
 		} else if bestPair.equal(p) && s.isNominatable(p.Local) && s.isNominatable(p.Remote) {
-			s.log.Tracef("The candidate (%s, %s) is the best candidate available, marking it as nominated",
-				p.Local.String(), p.Remote.String())
+			s.log.Tracef("The candidate (%s, %s) is the best candidate available, marking it as nominated", p.Local, p.Remote)
 			s.nominatedPair = p
 			s.nominatePair(p)
 		}
 	}
+
+	if s.agent.userBindingRequestHandler != nil {
+		if shouldSwitch := s.agent.userBindingRequestHandler(m, local, remote, p); shouldSwitch {
+			s.agent.setSelectedPair(p)
+		}
+	}
 }
 
 func (s *controllingSelector) HandleSuccessResponse(m *stun.Message, local, remote Candidate, remoteAddr net.Addr) {
@@ -130,7 +135,7 @@ func (s *controllingSelector) HandleSuccessResponse(m *stun.Message, local, remo
 		return
 	}
 
-	s.log.Tracef("Inbound STUN (SuccessResponse) from %s to %s", remote.String(), local.String())
+	s.log.Tracef("Inbound STUN (SuccessResponse) from %s to %s", remote, local)
 	p := s.agent.findPair(local, remote)
 
 	if p == nil {
@@ -221,7 +226,7 @@ func (s *controlledSelector) HandleSuccessResponse(m *stun.Message, local, remot
 		return
 	}
 
-	s.log.Tracef("Inbound STUN (SuccessResponse) from %s to %s", remote.String(), local.String())
+	s.log.Tracef("Inbound STUN (SuccessResponse) from %s to %s", remote, local)
 
 	p := s.agent.findPair(local, remote)
 	if p == nil {
@@ -243,14 +248,12 @@ func (s *controlledSelector) HandleSuccessResponse(m *stun.Message, local, remot
 }
 
 func (s *controlledSelector) HandleBindingRequest(m *stun.Message, local, remote Candidate) {
-	useCandidate := m.Contains(stun.AttrUseCandidate)
-
 	p := s.agent.findPair(local, remote)
 	if p == nil {
 		p = s.agent.addPair(local, remote)
 	}
 
-	if useCandidate {
+	if m.Contains(stun.AttrUseCandidate) {
 		// https://tools.ietf.org/html/rfc8445#section-7.3.1.5
 
 		if p.state == CandidatePairStateSucceeded {
@@ -258,8 +261,8 @@ func (s *controlledSelector) HandleBindingRequest(m *stun.Message, local, remote
 			// previously sent by this pair produced a successful response and
 			// generated a valid pair (Section 7.2.5.3.2).  The agent sets the
 			// nominated flag value of the valid pair to true.
-			if selectedPair := s.agent.getSelectedPair(); selectedPair == nil ||
-				(selectedPair != p && selectedPair.priority() <= p.priority()) {
+			selectedPair := s.agent.getSelectedPair()
+			if selectedPair == nil || (selectedPair != p && selectedPair.priority() <= p.priority()) {
 				s.agent.setSelectedPair(p)
 			} else if selectedPair != p {
 				s.log.Tracef("Ignore nominate new pair %s, already nominated pair %s", p, selectedPair)
@@ -279,6 +282,12 @@ func (s *controlledSelector) HandleBindingRequest(m *stun.Message, local, remote
 
 	s.agent.sendBindingSuccess(m, local, remote)
 	s.PingCandidate(local, remote)
+
+	if s.agent.userBindingRequestHandler != nil {
+		if shouldSwitch := s.agent.userBindingRequestHandler(m, local, remote, p); shouldSwitch {
+			s.agent.setSelectedPair(p)
+		}
+	}
 }
 
 type liteSelector struct {
diff --git a/vendor/github.com/pion/ice/v2/tcp_mux.go b/vendor/github.com/pion/ice/v2/tcp_mux.go
index df169be2..ff3afed0 100644
--- a/vendor/github.com/pion/ice/v2/tcp_mux.go
+++ b/vendor/github.com/pion/ice/v2/tcp_mux.go
@@ -10,6 +10,7 @@ import (
 	"net"
 	"strings"
 	"sync"
+	"time"
 
 	"github.com/pion/logging"
 	"github.com/pion/stun"
@@ -52,6 +53,16 @@ type TCPMuxParams struct {
 	// if the write buffer is full, the subsequent write packet will be dropped until it has enough space.
 	// a default 4MB is recommended.
 	WriteBufferSize int
+
+	// A new established connection will be removed if the first STUN binding request is not received within this timeout,
+	// avoiding the client with bad network or attacker to create a lot of empty connections.
+	// Default 30s timeout will be used if not set.
+	FirstStunBindTimeout time.Duration
+
+	// TCPMux will create connection from STUN binding request with an unknown username, if
+	// the connection is not used in the timeout, it will be removed to avoid resource leak / attack.
+	// Default 30s timeout will be used if not set.
+	AliveDurationForConnFromStun time.Duration
 }
 
 // NewTCPMuxDefault creates a new instance of TCPMuxDefault.
@@ -60,6 +71,14 @@ func NewTCPMuxDefault(params TCPMuxParams) *TCPMuxDefault {
 		params.Logger = logging.NewDefaultLoggerFactory().NewLogger("ice")
 	}
 
+	if params.FirstStunBindTimeout == 0 {
+		params.FirstStunBindTimeout = 30 * time.Second
+	}
+
+	if params.AliveDurationForConnFromStun == 0 {
+		params.AliveDurationForConnFromStun = 30 * time.Second
+	}
+
 	m := &TCPMuxDefault{
 		params: &params,
 
@@ -110,13 +129,14 @@ func (m *TCPMuxDefault) GetConnByUfrag(ufrag string, isIPv6 bool, local net.IP)
 	}
 
 	if conn, ok := m.getConn(ufrag, isIPv6, local); ok {
+		conn.ClearAliveTimer()
 		return conn, nil
 	}
 
-	return m.createConn(ufrag, isIPv6, local)
+	return m.createConn(ufrag, isIPv6, local, false)
 }
 
-func (m *TCPMuxDefault) createConn(ufrag string, isIPv6 bool, local net.IP) (*tcpPacketConn, error) {
+func (m *TCPMuxDefault) createConn(ufrag string, isIPv6 bool, local net.IP, fromStun bool) (*tcpPacketConn, error) {
 	addr, ok := m.LocalAddr().(*net.TCPAddr)
 	if !ok {
 		return nil, ErrGetTransportAddress
@@ -124,11 +144,17 @@ func (m *TCPMuxDefault) createConn(ufrag string, isIPv6 bool, local net.IP) (*tc
 	localAddr := *addr
 	localAddr.IP = local
 
+	var alive time.Duration
+	if fromStun {
+		alive = m.params.AliveDurationForConnFromStun
+	}
+
 	conn := newTCPPacketConn(tcpPacketParams{
-		ReadBuffer:  m.params.ReadBufferSize,
-		WriteBuffer: m.params.WriteBufferSize,
-		LocalAddr:   &localAddr,
-		Logger:      m.params.Logger,
+		ReadBuffer:    m.params.ReadBufferSize,
+		WriteBuffer:   m.params.WriteBufferSize,
+		LocalAddr:     &localAddr,
+		Logger:        m.params.Logger,
+		AliveDuration: alive,
 	})
 
 	var conns map[ipAddr]*tcpPacketConn
@@ -163,13 +189,26 @@ func (m *TCPMuxDefault) closeAndLogError(closer io.Closer) {
 }
 
 func (m *TCPMuxDefault) handleConn(conn net.Conn) {
-	buf := make([]byte, receiveMTU)
+	buf := make([]byte, 512)
 
+	if m.params.FirstStunBindTimeout > 0 {
+		if err := conn.SetReadDeadline(time.Now().Add(m.params.FirstStunBindTimeout)); err != nil {
+			m.params.Logger.Warnf("Failed to set read deadline for first STUN message: %s to %s , err: %s", conn.RemoteAddr(), conn.LocalAddr(), err)
+		}
+	}
 	n, err := readStreamingPacket(conn, buf)
 	if err != nil {
-		m.params.Logger.Warnf("Error reading first packet from %s: %s", conn.RemoteAddr().String(), err)
+		if errors.Is(err, io.ErrShortBuffer) {
+			m.params.Logger.Warnf("Buffer too small for first packet from %s: %s", conn.RemoteAddr(), err)
+		} else {
+			m.params.Logger.Warnf("Error reading first packet from %s: %s", conn.RemoteAddr(), err)
+		}
+		m.closeAndLogError(conn)
 		return
 	}
+	if err = conn.SetReadDeadline(time.Time{}); err != nil {
+		m.params.Logger.Warnf("Failed to reset read deadline from %s: %s", conn.RemoteAddr(), err)
+	}
 
 	buf = buf[:n]
 
@@ -204,9 +243,6 @@ func (m *TCPMuxDefault) handleConn(conn net.Conn) {
 	ufrag := strings.Split(string(attr), ":")[0]
 	m.params.Logger.Debugf("Ufrag: %s", ufrag)
 
-	m.mu.Lock()
-	defer m.mu.Unlock()
-
 	host, _, err := net.SplitHostPort(conn.RemoteAddr().String())
 	if err != nil {
 		m.closeAndLogError(conn)
@@ -222,15 +258,18 @@ func (m *TCPMuxDefault) handleConn(conn net.Conn) {
 		m.params.Logger.Warnf("Failed to get local tcp address in STUN message from %s to %s", conn.RemoteAddr(), conn.LocalAddr())
 		return
 	}
+	m.mu.Lock()
 	packetConn, ok := m.getConn(ufrag, isIPv6, localAddr.IP)
 	if !ok {
-		packetConn, err = m.createConn(ufrag, isIPv6, localAddr.IP)
+		packetConn, err = m.createConn(ufrag, isIPv6, localAddr.IP, true)
 		if err != nil {
+			m.mu.Unlock()
 			m.closeAndLogError(conn)
 			m.params.Logger.Warnf("Failed to create packetConn for STUN message from %s to %s", conn.RemoteAddr(), conn.LocalAddr())
 			return
 		}
 	}
+	m.mu.Unlock()
 
 	if err := packetConn.AddConn(conn, buf); err != nil {
 		m.closeAndLogError(conn)
diff --git a/vendor/github.com/pion/ice/v2/tcp_packet_conn.go b/vendor/github.com/pion/ice/v2/tcp_packet_conn.go
index 8329cba8..60ea2c80 100644
--- a/vendor/github.com/pion/ice/v2/tcp_packet_conn.go
+++ b/vendor/github.com/pion/ice/v2/tcp_packet_conn.go
@@ -85,6 +85,7 @@ type tcpPacketConn struct {
 	wg         sync.WaitGroup
 	closedChan chan struct{}
 	closeOnce  sync.Once
+	aliveTimer *time.Timer
 }
 
 type streamingPacket struct {
@@ -94,10 +95,11 @@ type streamingPacket struct {
 }
 
 type tcpPacketParams struct {
-	ReadBuffer  int
-	LocalAddr   net.Addr
-	Logger      logging.LeveledLogger
-	WriteBuffer int
+	ReadBuffer    int
+	LocalAddr     net.Addr
+	Logger        logging.LeveledLogger
+	WriteBuffer   int
+	AliveDuration time.Duration
 }
 
 func newTCPPacketConn(params tcpPacketParams) *tcpPacketConn {
@@ -110,9 +112,24 @@ func newTCPPacketConn(params tcpPacketParams) *tcpPacketConn {
 		closedChan: make(chan struct{}),
 	}
 
+	if params.AliveDuration > 0 {
+		p.aliveTimer = time.AfterFunc(params.AliveDuration, func() {
+			p.params.Logger.Warn("close tcp packet conn by alive timeout")
+			_ = p.Close()
+		})
+	}
+
 	return p
 }
 
+func (t *tcpPacketConn) ClearAliveTimer() {
+	t.mu.Lock()
+	if t.aliveTimer != nil {
+		t.aliveTimer.Stop()
+	}
+	t.mu.Unlock()
+}
+
 func (t *tcpPacketConn) AddConn(conn net.Conn, firstPacketData []byte) error {
 	t.params.Logger.Infof("Added connection: %s remote %s to local %s", conn.RemoteAddr().Network(), conn.RemoteAddr(), conn.LocalAddr())
 
@@ -261,6 +278,9 @@ func (t *tcpPacketConn) Close() error {
 	t.closeOnce.Do(func() {
 		close(t.closedChan)
 		shouldCloseRecvChan = true
+		if t.aliveTimer != nil {
+			t.aliveTimer.Stop()
+		}
 	})
 
 	for _, conn := range t.conns {
diff --git a/vendor/github.com/pion/ice/v2/udp_mux.go b/vendor/github.com/pion/ice/v2/udp_mux.go
index 47084f83..ba2a7e38 100644
--- a/vendor/github.com/pion/ice/v2/udp_mux.go
+++ b/vendor/github.com/pion/ice/v2/udp_mux.go
@@ -36,7 +36,7 @@ type UDPMuxDefault struct {
 	connsIPv4, connsIPv6 map[string]*udpMuxedConn
 
 	addressMapMu sync.RWMutex
-	addressMap   map[string]*udpMuxedConn
+	addressMap   map[udpMuxedConnAddr]*udpMuxedConn
 
 	// Buffer pool to recycle buffers for net.UDPAddr encodes/decodes
 	pool *sync.Pool
@@ -47,8 +47,6 @@ type UDPMuxDefault struct {
 	localAddrsForUnspecified []net.Addr
 }
 
-const maxAddrSize = 512
-
 // UDPMuxParams are parameters for UDPMux.
 type UDPMuxParams struct {
 	Logger  logging.LeveledLogger
@@ -105,7 +103,7 @@ func NewUDPMuxDefault(params UDPMuxParams) *UDPMuxDefault {
 	}
 
 	m := &UDPMuxDefault{
-		addressMap: map[string]*udpMuxedConn{},
+		addressMap: map[udpMuxedConnAddr]*udpMuxedConn{},
 		params:     params,
 		connsIPv4:  make(map[string]*udpMuxedConn),
 		connsIPv6:  make(map[string]*udpMuxedConn),
@@ -113,7 +111,7 @@ func NewUDPMuxDefault(params UDPMuxParams) *UDPMuxDefault {
 		pool: &sync.Pool{
 			New: func() interface{} {
 				// Big enough buffer to fit both packet and address
-				return newBufferHolder(receiveMTU + maxAddrSize)
+				return newBufferHolder(receiveMTU)
 			},
 		},
 		localAddrsForUnspecified: localAddrsForUnspecified,
@@ -246,7 +244,7 @@ func (m *UDPMuxDefault) writeTo(buf []byte, rAddr net.Addr) (n int, err error) {
 	return m.params.UDPConn.WriteTo(buf, rAddr)
 }
 
-func (m *UDPMuxDefault) registerConnForAddress(conn *udpMuxedConn, addr string) {
+func (m *UDPMuxDefault) registerConnForAddress(conn *udpMuxedConn, addr udpMuxedConnAddr) {
 	if m.IsClosed() {
 		return
 	}
@@ -304,7 +302,7 @@ func (m *UDPMuxDefault) connWorker() {
 
 		// If we have already seen this address dispatch to the appropriate destination
 		m.addressMapMu.Lock()
-		destinationConn := m.addressMap[addr.String()]
+		destinationConn := m.addressMap[newUDPMuxedConnAddr(udpAddr)]
 		m.addressMapMu.Unlock()
 
 		// If we haven't seen this address before but is a STUN packet lookup by ufrag
@@ -333,7 +331,7 @@ func (m *UDPMuxDefault) connWorker() {
 		}
 
 		if destinationConn == nil {
-			m.params.Logger.Tracef("Dropping packet from %s, addr: %s", udpAddr.String(), addr.String())
+			m.params.Logger.Tracef("Dropping packet from %s, addr: %s", udpAddr, addr)
 			continue
 		}
 
@@ -353,7 +351,9 @@ func (m *UDPMuxDefault) getConn(ufrag string, isIPv6 bool) (val *udpMuxedConn, o
 }
 
 type bufferHolder struct {
-	buf []byte
+	next *bufferHolder
+	buf  []byte
+	addr *net.UDPAddr
 }
 
 func newBufferHolder(size int) *bufferHolder {
@@ -361,3 +361,8 @@ func newBufferHolder(size int) *bufferHolder {
 		buf: make([]byte, size),
 	}
 }
+
+func (b *bufferHolder) reset() {
+	b.next = nil
+	b.addr = nil
+}
diff --git a/vendor/github.com/pion/ice/v2/udp_muxed_conn.go b/vendor/github.com/pion/ice/v2/udp_muxed_conn.go
index 09e4b3a8..322d0207 100644
--- a/vendor/github.com/pion/ice/v2/udp_muxed_conn.go
+++ b/vendor/github.com/pion/ice/v2/udp_muxed_conn.go
@@ -4,16 +4,33 @@
 package ice
 
 import (
-	"encoding/binary"
 	"io"
 	"net"
 	"sync"
 	"time"
 
 	"github.com/pion/logging"
-	"github.com/pion/transport/v2/packetio"
 )
 
+type udpMuxedConnState int
+
+const (
+	udpMuxedConnOpen udpMuxedConnState = iota
+	udpMuxedConnWaiting
+	udpMuxedConnClosed
+)
+
+type udpMuxedConnAddr struct {
+	ip   [16]byte
+	port uint16
+}
+
+func newUDPMuxedConnAddr(addr *net.UDPAddr) (a udpMuxedConnAddr) {
+	copy(a.ip[:], addr.IP.To16())
+	a.port = uint16(addr.Port)
+	return a
+}
+
 type udpMuxedConnParams struct {
 	Mux       *UDPMuxDefault
 	AddrPool  *sync.Pool
@@ -26,54 +43,63 @@ type udpMuxedConnParams struct {
 type udpMuxedConn struct {
 	params *udpMuxedConnParams
 	// Remote addresses that we have sent to on this conn
-	addresses []string
+	addresses []udpMuxedConnAddr
 
-	// Channel holding incoming packets
-	buf        *packetio.Buffer
-	closedChan chan struct{}
-	closeOnce  sync.Once
-	mu         sync.Mutex
+	// FIFO queue holding incoming packets
+	bufHead, bufTail *bufferHolder
+	notify           chan struct{}
+	closedChan       chan struct{}
+	state            udpMuxedConnState
+	mu               sync.Mutex
 }
 
 func newUDPMuxedConn(params *udpMuxedConnParams) *udpMuxedConn {
-	p := &udpMuxedConn{
+	return &udpMuxedConn{
 		params:     params,
-		buf:        packetio.NewBuffer(),
+		notify:     make(chan struct{}, 1),
 		closedChan: make(chan struct{}),
 	}
-
-	return p
 }
 
 func (c *udpMuxedConn) ReadFrom(b []byte) (n int, rAddr net.Addr, err error) {
-	buf := c.params.AddrPool.Get().(*bufferHolder) //nolint:forcetypeassert
-	defer c.params.AddrPool.Put(buf)
-
-	// Read address
-	total, err := c.buf.Read(buf.buf)
-	if err != nil {
-		return 0, nil, err
-	}
-
-	dataLen := int(binary.LittleEndian.Uint16(buf.buf[:2]))
-	if dataLen > total || dataLen > len(b) {
-		return 0, nil, io.ErrShortBuffer
-	}
+	for {
+		c.mu.Lock()
+		if c.bufTail != nil {
+			pkt := c.bufTail
+			c.bufTail = pkt.next
+
+			if pkt == c.bufHead {
+				c.bufHead = nil
+			}
+			c.mu.Unlock()
+
+			if len(b) < len(pkt.buf) {
+				err = io.ErrShortBuffer
+			} else {
+				n = copy(b, pkt.buf)
+				rAddr = pkt.addr
+			}
+
+			pkt.reset()
+			c.params.AddrPool.Put(pkt)
+
+			return
+		}
 
-	// Read data and then address
-	offset := 2
-	copy(b, buf.buf[offset:offset+dataLen])
-	offset += dataLen
+		if c.state == udpMuxedConnClosed {
+			c.mu.Unlock()
+			return 0, nil, io.EOF
+		}
 
-	// Read address len & decode address
-	addrLen := int(binary.LittleEndian.Uint16(buf.buf[offset : offset+2]))
-	offset += 2
+		c.state = udpMuxedConnWaiting
+		c.mu.Unlock()
 
-	if rAddr, err = decodeUDPAddr(buf.buf[offset : offset+addrLen]); err != nil {
-		return 0, nil, err
+		select {
+		case <-c.notify:
+		case <-c.closedChan:
+			return 0, nil, io.EOF
+		}
 	}
-
-	return dataLen, rAddr, nil
 }
 
 func (c *udpMuxedConn) WriteTo(buf []byte, rAddr net.Addr) (n int, err error) {
@@ -81,7 +107,7 @@ func (c *udpMuxedConn) WriteTo(buf []byte, rAddr net.Addr) (n int, err error) {
 		return 0, io.ErrClosedPipe
 	}
 	// Each time we write to a new address, we'll register it with the mux
-	addr := rAddr.String()
+	addr := newUDPMuxedConnAddr(rAddr.(*net.UDPAddr))
 	if !c.containsAddress(addr) {
 		c.addAddress(addr)
 	}
@@ -110,32 +136,41 @@ func (c *udpMuxedConn) CloseChannel() <-chan struct{} {
 }
 
 func (c *udpMuxedConn) Close() error {
-	var err error
-	c.closeOnce.Do(func() {
-		err = c.buf.Close()
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	if c.state != udpMuxedConnClosed {
+		for pkt := c.bufTail; pkt != nil; {
+			next := pkt.next
+
+			pkt.reset()
+			c.params.AddrPool.Put(pkt)
+
+			pkt = next
+		}
+		c.bufHead = nil
+		c.bufTail = nil
+
+		c.state = udpMuxedConnClosed
 		close(c.closedChan)
-	})
-	return err
+	}
+	return nil
 }
 
 func (c *udpMuxedConn) isClosed() bool {
-	select {
-	case <-c.closedChan:
-		return true
-	default:
-		return false
-	}
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	return c.state == udpMuxedConnClosed
 }
 
-func (c *udpMuxedConn) getAddresses() []string {
+func (c *udpMuxedConn) getAddresses() []udpMuxedConnAddr {
 	c.mu.Lock()
 	defer c.mu.Unlock()
-	addresses := make([]string, len(c.addresses))
+	addresses := make([]udpMuxedConnAddr, len(c.addresses))
 	copy(addresses, c.addresses)
 	return addresses
 }
 
-func (c *udpMuxedConn) addAddress(addr string) {
+func (c *udpMuxedConn) addAddress(addr udpMuxedConnAddr) {
 	c.mu.Lock()
 	c.addresses = append(c.addresses, addr)
 	c.mu.Unlock()
@@ -144,11 +179,11 @@ func (c *udpMuxedConn) addAddress(addr string) {
 	c.params.Mux.registerConnForAddress(c, addr)
 }
 
-func (c *udpMuxedConn) removeAddress(addr string) {
+func (c *udpMuxedConn) removeAddress(addr udpMuxedConnAddr) {
 	c.mu.Lock()
 	defer c.mu.Unlock()
 
-	newAddresses := make([]string, 0, len(c.addresses))
+	newAddresses := make([]udpMuxedConnAddr, 0, len(c.addresses))
 	for _, a := range c.addresses {
 		if a != addr {
 			newAddresses = append(newAddresses, a)
@@ -158,7 +193,7 @@ func (c *udpMuxedConn) removeAddress(addr string) {
 	c.addresses = newAddresses
 }
 
-func (c *udpMuxedConn) containsAddress(addr string) bool {
+func (c *udpMuxedConn) containsAddress(addr udpMuxedConnAddr) bool {
 	c.mu.Lock()
 	defer c.mu.Unlock()
 	for _, a := range c.addresses {
@@ -170,77 +205,44 @@ func (c *udpMuxedConn) containsAddress(addr string) bool {
 }
 
 func (c *udpMuxedConn) writePacket(data []byte, addr *net.UDPAddr) error {
-	// Write two packets, address and data
-	buf := c.params.AddrPool.Get().(*bufferHolder) //nolint:forcetypeassert
-	defer c.params.AddrPool.Put(buf)
-
-	// Format of buffer | data len | data bytes | addr len | addr bytes |
-	if len(buf.buf) < len(data)+maxAddrSize {
+	pkt := c.params.AddrPool.Get().(*bufferHolder) //nolint:forcetypeassert
+	if cap(pkt.buf) < len(data) {
+		c.params.AddrPool.Put(pkt)
 		return io.ErrShortBuffer
 	}
-	// Data length
-	binary.LittleEndian.PutUint16(buf.buf, uint16(len(data)))
-	offset := 2
-
-	// Data
-	copy(buf.buf[offset:], data)
-	offset += len(data)
-
-	// Write address first, leaving room for its length
-	n, err := encodeUDPAddr(addr, buf.buf[offset+2:])
-	if err != nil {
-		return err
-	}
-	total := offset + n + 2
 
-	// Address len
-	binary.LittleEndian.PutUint16(buf.buf[offset:], uint16(n))
+	pkt.buf = append(pkt.buf[:0], data...)
+	pkt.addr = addr
 
-	if _, err := c.buf.Write(buf.buf[:total]); err != nil {
-		return err
-	}
-	return nil
-}
+	c.mu.Lock()
+	if c.state == udpMuxedConnClosed {
+		c.mu.Unlock()
+
+		pkt.reset()
+		c.params.AddrPool.Put(pkt)
 
-func encodeUDPAddr(addr *net.UDPAddr, buf []byte) (int, error) {
-	ipData, err := addr.IP.MarshalText()
-	if err != nil {
-		return 0, err
+		return io.ErrClosedPipe
 	}
-	total := 2 + len(ipData) + 2 + len(addr.Zone)
-	if total > len(buf) {
-		return 0, io.ErrShortBuffer
+
+	if c.bufHead != nil {
+		c.bufHead.next = pkt
 	}
+	c.bufHead = pkt
 
-	binary.LittleEndian.PutUint16(buf, uint16(len(ipData)))
-	offset := 2
-	n := copy(buf[offset:], ipData)
-	offset += n
-	binary.LittleEndian.PutUint16(buf[offset:], uint16(addr.Port))
-	offset += 2
-	copy(buf[offset:], addr.Zone)
-	return total, nil
-}
-
-func decodeUDPAddr(buf []byte) (*net.UDPAddr, error) {
-	addr := net.UDPAddr{}
-
-	offset := 0
-	ipLen := int(binary.LittleEndian.Uint16(buf[:2]))
-	offset += 2
-	// Basic bounds checking
-	if ipLen+offset > len(buf) {
-		return nil, io.ErrShortBuffer
+	if c.bufTail == nil {
+		c.bufTail = pkt
 	}
-	if err := addr.IP.UnmarshalText(buf[offset : offset+ipLen]); err != nil {
-		return nil, err
+
+	state := c.state
+	c.state = udpMuxedConnOpen
+	c.mu.Unlock()
+
+	if state == udpMuxedConnWaiting {
+		select {
+		case c.notify <- struct{}{}:
+		default:
+		}
 	}
-	offset += ipLen
-	addr.Port = int(binary.LittleEndian.Uint16(buf[offset : offset+2]))
-	offset += 2
-	zone := make([]byte, len(buf[offset:]))
-	copy(zone, buf[offset:])
-	addr.Zone = string(zone)
-
-	return &addr, nil
+
+	return nil
 }
diff --git a/vendor/github.com/pion/interceptor/.golangci.yml b/vendor/github.com/pion/interceptor/.golangci.yml
index 4e3eddf4..e06de4d3 100644
--- a/vendor/github.com/pion/interceptor/.golangci.yml
+++ b/vendor/github.com/pion/interceptor/.golangci.yml
@@ -3,7 +3,8 @@
 
 linters-settings:
   govet:
-    check-shadowing: true
+    enable:
+      - shadow
   misspell:
     locale: US
   exhaustive:
@@ -29,7 +30,6 @@ linters:
     - bodyclose        # checks whether HTTP response body is closed successfully
     - contextcheck     # check the function whether use a non-inherited context
     - decorder         # check declaration order and count of types, constants, variables and functions
-    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - dogsled          # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
     - dupl             # Tool for code clone detection
     - durationcheck    # check for two durations multiplied together
@@ -63,7 +63,6 @@ linters:
     - importas         # Enforces consistent import aliases
     - ineffassign      # Detects when assignments to existing variables are not used
     - misspell         # Finds commonly misspelled English words in comments
-    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nilerr           # Finds the code that returns nil even if it checks that the error is not nil.
     - nilnil           # Checks that there is no simultaneous return of `nil` error and an invalid value.
     - noctx            # noctx finds sending http request without context.Context
@@ -81,6 +80,7 @@ linters:
     - wastedassign     # wastedassign finds wasted assignment statements
     - whitespace       # Tool for detection of leading and trailing whitespace
   disable:
+    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - containedctx     # containedctx is a linter that detects struct contained context.Context field
     - cyclop           # checks function and package cyclomatic complexity
     - exhaustivestruct # Checks if all struct's fields are initialized
@@ -94,6 +94,7 @@ linters:
     - maintidx         # maintidx measures the maintainability index of each function.
     - makezero         # Finds slice declarations with non-zero initial length
     - maligned         # Tool to detect Go structs that would take less memory if their fields were sorted
+    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nestif           # Reports deeply nested if statements
     - nlreturn         # nlreturn checks for a new line before return and branch statements to increase code clarity
     - nolintlint       # Reports ill-formed or insufficient nolint directives
@@ -110,28 +111,15 @@ linters:
 
 issues:
   exclude-use-default: false
+  exclude-dirs-use-default: false
   exclude-rules:
-    # Allow complex tests, better to be self contained
-    - path: _test\.go
+    # Allow complex tests and examples, better to be self contained
+    - path: (examples|main\.go|_test\.go)
       linters:
-        - gocognit
         - forbidigo
-
-    # Allow complex main function in examples
-    - path: examples
-      text: "of func `main` is high"
-      linters:
         - gocognit
-    
-    # Allow forbidden identifiers in examples
-    - path: examples
-      linters:
-        - forbidigo
 
     # Allow forbidden identifiers in CLI commands
     - path: cmd
       linters:
         - forbidigo
-
-run:
-  skip-dirs-use-default: false
diff --git a/vendor/github.com/pion/interceptor/AUTHORS.txt b/vendor/github.com/pion/interceptor/AUTHORS.txt
deleted file mode 100644
index 54863555..00000000
--- a/vendor/github.com/pion/interceptor/AUTHORS.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-# Thank you to everyone that made Pion possible. If you are interested in contributing
-# we would love to have you https://github.com/pion/webrtc/wiki/Contributing
-#
-# This file is auto generated, using git to list all individuals contributors.
-# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting
-Aaron Boushley <boushley@gmail.com>
-Adam Kiss <masterada@gmail.com>
-adamroach <adam@nostrum.com>
-Aditya Kumar <k.aditya00@gmail.com>
-Adrian Cable <6544927+adriancable@users.noreply.github.com>
-aler9 <46489434+aler9@users.noreply.github.com>
-Antoine Baché <antoine@tenten.app>
-Atsushi Watanabe <atsushi.w@ieee.org>
-Bobby Peck <rpeck@mux.com>
-boks1971 <raja.gobi@tutanota.com>
-cptpcrd <31829097+cptpcrd@users.noreply.github.com>
-David Zhao <david@davidzhao.com>
-Jonathan Müller <jonathan@fotokite.com>
-Kevin Caffrey <kcaffrey@gmail.com>
-Maksim Nesterov <msnesterov@avito.ru>
-Mathis Engelbart <mathis.engelbart@gmail.com>
-Miroslav <sedivy.miro@gmail.com>
-Miroslav Šedivý <sedivy.miro@gmail.com>
-Quentin Renard <contact@asticode.com>
-Rayleigh Li <rayleigh.li@zoom.us>
-Sean DuBois <sean@siobud.com>
-Steffen Vogel <post@steffenvogel.de>
-treyhakanson <treyhakanson@gmail.com>
-XLPolar <guangjin_pan@163.com>
-ypothoma <thomas.pougetabadie@gmail.com>
-ziminghua <565209960@qq.com>
-
-# List of contributors not appearing in Git history
-
diff --git a/vendor/github.com/pion/interceptor/README.md b/vendor/github.com/pion/interceptor/README.md
index dcc856f1..5db5d441 100644
--- a/vendor/github.com/pion/interceptor/README.md
+++ b/vendor/github.com/pion/interceptor/README.md
@@ -78,7 +78,7 @@ We are always looking to support **your projects**. Please reach out if you have
 If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly)
 
 ### Contributing
-Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt)
+Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible
 
 ### License
 MIT License - see [LICENSE](LICENSE) for full text
diff --git a/vendor/github.com/pion/interceptor/pkg/report/receiver_interceptor.go b/vendor/github.com/pion/interceptor/pkg/report/receiver_interceptor.go
index c126f9ab..0afbd08f 100644
--- a/vendor/github.com/pion/interceptor/pkg/report/receiver_interceptor.go
+++ b/vendor/github.com/pion/interceptor/pkg/report/receiver_interceptor.go
@@ -100,7 +100,7 @@ func (r *ReceiverInterceptor) loop(rtcpWriter interceptor.RTCPWriter) {
 		select {
 		case <-ticker.C:
 			now := r.now()
-			r.streams.Range(func(key, value interface{}) bool {
+			r.streams.Range(func(_, value interface{}) bool {
 				if stream, ok := value.(*receiverStream); !ok {
 					r.log.Warnf("failed to cast ReceiverInterceptor stream")
 				} else if _, err := rtcpWriter.Write([]rtcp.Packet{stream.generateReport(now)}, interceptor.Attributes{}); err != nil {
@@ -142,8 +142,8 @@ func (r *ReceiverInterceptor) BindRemoteStream(info *interceptor.StreamInfo, rea
 	})
 }
 
-// UnbindLocalStream is called when the Stream is removed. It can be used to clean up any data related to that track.
-func (r *ReceiverInterceptor) UnbindLocalStream(info *interceptor.StreamInfo) {
+// UnbindRemoteStream is called when the Stream is removed. It can be used to clean up any data related to that track.
+func (r *ReceiverInterceptor) UnbindRemoteStream(info *interceptor.StreamInfo) {
 	r.streams.Delete(info.SSRC)
 }
 
diff --git a/vendor/github.com/pion/interceptor/pkg/report/sender_interceptor.go b/vendor/github.com/pion/interceptor/pkg/report/sender_interceptor.go
index 087838e7..1b6f4b25 100644
--- a/vendor/github.com/pion/interceptor/pkg/report/sender_interceptor.go
+++ b/vendor/github.com/pion/interceptor/pkg/report/sender_interceptor.go
@@ -116,7 +116,7 @@ func (s *SenderInterceptor) loop(rtcpWriter interceptor.RTCPWriter) {
 		select {
 		case <-ticker.Ch():
 			now := s.now()
-			s.streams.Range(func(key, value interface{}) bool {
+			s.streams.Range(func(_, value interface{}) bool {
 				if stream, ok := value.(*senderStream); !ok {
 					s.log.Warnf("failed to cast SenderInterceptor stream")
 				} else if _, err := rtcpWriter.Write([]rtcp.Packet{stream.generateReport(now)}, interceptor.Attributes{}); err != nil {
@@ -144,3 +144,8 @@ func (s *SenderInterceptor) BindLocalStream(info *interceptor.StreamInfo, writer
 		return writer.Write(header, payload, a)
 	})
 }
+
+// UnbindLocalStream is called when the Stream is removed. It can be used to clean up any data related to that track.
+func (s *SenderInterceptor) UnbindLocalStream(info *interceptor.StreamInfo) {
+	s.streams.Delete(info.SSRC)
+}
diff --git a/vendor/github.com/pion/mdns/.golangci.yml b/vendor/github.com/pion/mdns/.golangci.yml
index 4e3eddf4..6dd80c80 100644
--- a/vendor/github.com/pion/mdns/.golangci.yml
+++ b/vendor/github.com/pion/mdns/.golangci.yml
@@ -29,7 +29,6 @@ linters:
     - bodyclose        # checks whether HTTP response body is closed successfully
     - contextcheck     # check the function whether use a non-inherited context
     - decorder         # check declaration order and count of types, constants, variables and functions
-    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - dogsled          # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
     - dupl             # Tool for code clone detection
     - durationcheck    # check for two durations multiplied together
@@ -63,7 +62,6 @@ linters:
     - importas         # Enforces consistent import aliases
     - ineffassign      # Detects when assignments to existing variables are not used
     - misspell         # Finds commonly misspelled English words in comments
-    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nilerr           # Finds the code that returns nil even if it checks that the error is not nil.
     - nilnil           # Checks that there is no simultaneous return of `nil` error and an invalid value.
     - noctx            # noctx finds sending http request without context.Context
@@ -81,6 +79,7 @@ linters:
     - wastedassign     # wastedassign finds wasted assignment statements
     - whitespace       # Tool for detection of leading and trailing whitespace
   disable:
+    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - containedctx     # containedctx is a linter that detects struct contained context.Context field
     - cyclop           # checks function and package cyclomatic complexity
     - exhaustivestruct # Checks if all struct's fields are initialized
@@ -94,6 +93,7 @@ linters:
     - maintidx         # maintidx measures the maintainability index of each function.
     - makezero         # Finds slice declarations with non-zero initial length
     - maligned         # Tool to detect Go structs that would take less memory if their fields were sorted
+    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nestif           # Reports deeply nested if statements
     - nlreturn         # nlreturn checks for a new line before return and branch statements to increase code clarity
     - nolintlint       # Reports ill-formed or insufficient nolint directives
@@ -111,22 +111,11 @@ linters:
 issues:
   exclude-use-default: false
   exclude-rules:
-    # Allow complex tests, better to be self contained
-    - path: _test\.go
+    # Allow complex tests and examples, better to be self contained
+    - path: (examples|main\.go|_test\.go)
       linters:
-        - gocognit
         - forbidigo
-
-    # Allow complex main function in examples
-    - path: examples
-      text: "of func `main` is high"
-      linters:
         - gocognit
-    
-    # Allow forbidden identifiers in examples
-    - path: examples
-      linters:
-        - forbidigo
 
     # Allow forbidden identifiers in CLI commands
     - path: cmd
diff --git a/vendor/github.com/pion/mdns/AUTHORS.txt b/vendor/github.com/pion/mdns/AUTHORS.txt
deleted file mode 100644
index 1585819f..00000000
--- a/vendor/github.com/pion/mdns/AUTHORS.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# Thank you to everyone that made Pion possible. If you are interested in contributing
-# we would love to have you https://github.com/pion/webrtc/wiki/Contributing
-#
-# This file is auto generated, using git to list all individuals contributors.
-# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting
-Atsushi Watanabe <atsushi.w@ieee.org>
-Benjamin Dahlmanns <bendahl@users.noreply.github.com>
-Bjørn Remseth <la3lma@gmail.com>
-Doug Cone <nullvariable@users.noreply.github.com>
-Eric Daniels <eric@erdaniels.com>
-Hugo Arregui <hugo.arregui@gmail.com>
-Javier Peletier <jm@epiclabs.io>
-Jonas van den Berg <24623262+vonas@users.noreply.github.com>
-Konstantin Itskov <konstantin.itskov@kovits.com>
-Sean DuBois <seaduboi@amazon.com>
-Sean DuBois <sean@siobud.com>
-Steffen Vogel <post@steffenvogel.de>
-
-# List of contributors not appearing in Git history
-
diff --git a/vendor/github.com/pion/mdns/README.md b/vendor/github.com/pion/mdns/README.md
index cfd90b21..70b48818 100644
--- a/vendor/github.com/pion/mdns/README.md
+++ b/vendor/github.com/pion/mdns/README.md
@@ -66,7 +66,7 @@ We are always looking to support **your projects**. Please reach out if you have
 If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly)
 
 ### Contributing
-Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt)
+Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible
 
 ### License
 MIT License - see [LICENSE](LICENSE) for full text
\ No newline at end of file
diff --git a/vendor/github.com/pion/mdns/config.go b/vendor/github.com/pion/mdns/config.go
index 936b0b64..34fc8fe7 100644
--- a/vendor/github.com/pion/mdns/config.go
+++ b/vendor/github.com/pion/mdns/config.go
@@ -32,4 +32,10 @@ type Config struct {
 	LocalAddress net.IP
 
 	LoggerFactory logging.LoggerFactory
+
+	// IncludeLoopback will include loopback interfaces to be eligble for queries and answers.
+	IncludeLoopback bool
+
+	// Interfaces will override the interfaces used for queries and answers.
+	Interfaces []net.Interface
 }
diff --git a/vendor/github.com/pion/mdns/conn.go b/vendor/github.com/pion/mdns/conn.go
index ddff48ae..1f146072 100644
--- a/vendor/github.com/pion/mdns/conn.go
+++ b/vendor/github.com/pion/mdns/conn.go
@@ -6,7 +6,7 @@ package mdns
 import (
 	"context"
 	"errors"
-	"math/big"
+	"fmt"
 	"net"
 	"sync"
 	"time"
@@ -26,7 +26,7 @@ type Conn struct {
 
 	queryInterval time.Duration
 	localNames    []string
-	queries       []query
+	queries       []*query
 	ifaces        []net.Interface
 
 	closed chan interface{}
@@ -47,26 +47,42 @@ const (
 	destinationAddress   = "224.0.0.251:5353"
 	maxMessageRecords    = 3
 	responseTTL          = 120
+	// maxPacketSize is the maximum size of a mdns packet.
+	// From RFC 6762:
+	// Even when fragmentation is used, a Multicast DNS packet, including IP
+	// and UDP headers, MUST NOT exceed 9000 bytes.
+	// https://datatracker.ietf.org/doc/html/rfc6762#section-17
+	maxPacketSize = 9000
 )
 
 var errNoPositiveMTUFound = errors.New("no positive MTU found")
 
-// Server establishes a mDNS connection over an existing conn
+// Server establishes a mDNS connection over an existing conn.
+//
+// Currently, the server only supports listening on an IPv4 connection, but internally
+// it supports answering with IPv6 AAAA records if this were ever to change.
 func Server(conn *ipv4.PacketConn, config *Config) (*Conn, error) {
 	if config == nil {
 		return nil, errNilConfig
 	}
 
-	ifaces, err := net.Interfaces()
-	if err != nil {
-		return nil, err
+	ifaces := config.Interfaces
+	if ifaces == nil {
+		var err error
+		ifaces, err = net.Interfaces()
+		if err != nil {
+			return nil, err
+		}
 	}
 
 	inboundBufferSize := 0
 	joinErrCount := 0
 	ifacesToUse := make([]net.Interface, 0, len(ifaces))
 	for i, ifc := range ifaces {
-		if err = conn.JoinGroup(&ifaces[i], &net.UDPAddr{IP: net.IPv4(224, 0, 0, 251)}); err != nil {
+		if !config.IncludeLoopback && ifc.Flags&net.FlagLoopback == net.FlagLoopback {
+			continue
+		}
+		if err := conn.JoinGroup(&ifaces[i], &net.UDPAddr{IP: net.IPv4(224, 0, 0, 251)}); err != nil {
 			joinErrCount++
 			continue
 		}
@@ -81,6 +97,9 @@ func Server(conn *ipv4.PacketConn, config *Config) (*Conn, error) {
 	if inboundBufferSize == 0 {
 		return nil, errNoPositiveMTUFound
 	}
+	if inboundBufferSize > maxPacketSize {
+		inboundBufferSize = maxPacketSize
+	}
 	if joinErrCount >= len(ifaces) {
 		return nil, errJoiningMulticastGroup
 	}
@@ -102,7 +121,7 @@ func Server(conn *ipv4.PacketConn, config *Config) (*Conn, error) {
 
 	c := &Conn{
 		queryInterval: defaultQueryInterval,
-		queries:       []query{},
+		queries:       []*query{},
 		socket:        conn,
 		dstAddr:       dstAddr,
 		localNames:    localNames,
@@ -118,6 +137,14 @@ func Server(conn *ipv4.PacketConn, config *Config) (*Conn, error) {
 		c.log.Warnf("Failed to SetControlMessage on PacketConn %v", err)
 	}
 
+	if config.IncludeLoopback {
+		// this is an efficient way for us to send ourselves a message faster instead of it going
+		// further out into the network stack.
+		if err := conn.SetMulticastLoopback(true); err != nil {
+			c.log.Warnf("Failed to SetMulticastLoopback(true) on PacketConn %v; this may cause inefficient network path communications", err)
+		}
+	}
+
 	// https://www.rfc-editor.org/rfc/rfc6762.html#section-17
 	// Multicast DNS messages carried by UDP may be up to the IP MTU of the
 	// physical interface, less the space required for the IP header (20
@@ -154,11 +181,22 @@ func (c *Conn) Query(ctx context.Context, name string) (dnsmessage.ResourceHeade
 	nameWithSuffix := name + "."
 
 	queryChan := make(chan queryResult, 1)
+	query := &query{nameWithSuffix, queryChan}
 	c.mu.Lock()
-	c.queries = append(c.queries, query{nameWithSuffix, queryChan})
-	ticker := time.NewTicker(c.queryInterval)
+	c.queries = append(c.queries, query)
 	c.mu.Unlock()
 
+	defer func() {
+		c.mu.Lock()
+		defer c.mu.Unlock()
+		for i := len(c.queries) - 1; i >= 0; i-- {
+			if c.queries[i] == query {
+				c.queries = append(c.queries[:i], c.queries[i+1:]...)
+			}
+		}
+	}()
+
+	ticker := time.NewTicker(c.queryInterval)
 	defer ticker.Stop()
 
 	c.sendQuestion(nameWithSuffix)
@@ -169,6 +207,11 @@ func (c *Conn) Query(ctx context.Context, name string) (dnsmessage.ResourceHeade
 		case <-c.closed:
 			return dnsmessage.ResourceHeader{}, nil, errConnectionClosed
 		case res := <-queryChan:
+			// Given https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-mdns-ice-candidates#section-3.2.2-2
+			// An ICE agent SHOULD ignore candidates where the hostname resolution returns more than one IP address.
+			//
+			// We will take the first we receive which could result in a race between two suitable addresses where
+			// one is better than the other (e.g. localhost vs LAN).
 			return res.answer, res.addr, nil
 		case <-ctx.Done():
 			return dnsmessage.ResourceHeader{}, nil, errContextElapsed
@@ -176,16 +219,37 @@ func (c *Conn) Query(ctx context.Context, name string) (dnsmessage.ResourceHeade
 	}
 }
 
-func ipToBytes(ip net.IP) (out [4]byte) {
+type ipToBytesError struct {
+	ip           net.IP
+	expectedType string
+}
+
+func (err ipToBytesError) Error() string {
+	return fmt.Sprintf("ip (%s) is not %s", err.ip, err.expectedType)
+}
+
+func ipv4ToBytes(ip net.IP) ([4]byte, error) {
 	rawIP := ip.To4()
 	if rawIP == nil {
-		return
+		return [4]byte{}, ipToBytesError{ip, "IPv4"}
 	}
 
-	ipInt := big.NewInt(0)
-	ipInt.SetBytes(rawIP)
-	copy(out[:], ipInt.Bytes())
-	return
+	// net.IPs are stored in big endian / network byte order
+	var out [4]byte
+	copy(out[:], rawIP[:])
+	return out, nil
+}
+
+func ipv6ToBytes(ip net.IP) ([16]byte, error) {
+	rawIP := ip.To16()
+	if rawIP == nil {
+		return [16]byte{}, ipToBytesError{ip, "IPv6"}
+	}
+
+	// net.IPs are stored in big endian / network byte order
+	var out [16]byte
+	copy(out[:], rawIP[:])
+	return out, nil
 }
 
 func interfaceForRemote(remote string) (net.IP, error) {
@@ -233,14 +297,14 @@ func (c *Conn) sendQuestion(name string) {
 	c.writeToSocket(0, rawQuery, false)
 }
 
-func (c *Conn) writeToSocket(ifIndex int, b []byte, onlyLooback bool) {
+func (c *Conn) writeToSocket(ifIndex int, b []byte, srcIfcIsLoopback bool) {
 	if ifIndex != 0 {
 		ifc, err := net.InterfaceByIndex(ifIndex)
 		if err != nil {
-			c.log.Warnf("Failed to get interface interface for %d: %v", ifIndex, err)
+			c.log.Warnf("Failed to get interface for %d: %v", ifIndex, err)
 			return
 		}
-		if onlyLooback && ifc.Flags&net.FlagLoopback == 0 {
+		if srcIfcIsLoopback && ifc.Flags&net.FlagLoopback == 0 {
 			// avoid accidentally tricking the destination that itself is the same as us
 			c.log.Warnf("Interface is not loopback %d", ifIndex)
 			return
@@ -255,7 +319,7 @@ func (c *Conn) writeToSocket(ifIndex int, b []byte, onlyLooback bool) {
 		return
 	}
 	for ifcIdx := range c.ifaces {
-		if onlyLooback && c.ifaces[ifcIdx].Flags&net.FlagLoopback == 0 {
+		if srcIfcIsLoopback && c.ifaces[ifcIdx].Flags&net.FlagLoopback == 0 {
 			// avoid accidentally tricking the destination that itself is the same as us
 			continue
 		}
@@ -269,11 +333,10 @@ func (c *Conn) writeToSocket(ifIndex int, b []byte, onlyLooback bool) {
 	}
 }
 
-func (c *Conn) sendAnswer(name string, ifIndex int, dst net.IP) {
+func createAnswer(name string, addr net.IP) (dnsmessage.Message, error) {
 	packedName, err := dnsmessage.NewName(name)
 	if err != nil {
-		c.log.Warnf("Failed to construct mDNS packet %v", err)
-		return
+		return dnsmessage.Message{}, err
 	}
 
 	msg := dnsmessage.Message{
@@ -289,20 +352,45 @@ func (c *Conn) sendAnswer(name string, ifIndex int, dst net.IP) {
 					Name:  packedName,
 					TTL:   responseTTL,
 				},
-				Body: &dnsmessage.AResource{
-					A: ipToBytes(dst),
-				},
 			},
 		},
 	}
 
-	rawAnswer, err := msg.Pack()
+	if ip4 := addr.To4(); ip4 != nil {
+		ipBuf, err := ipv4ToBytes(addr)
+		if err != nil {
+			return dnsmessage.Message{}, err
+		}
+		msg.Answers[0].Body = &dnsmessage.AResource{
+			A: ipBuf,
+		}
+	} else {
+		ipBuf, err := ipv6ToBytes(addr)
+		if err != nil {
+			return dnsmessage.Message{}, err
+		}
+		msg.Answers[0].Body = &dnsmessage.AAAAResource{
+			AAAA: ipBuf,
+		}
+	}
+
+	return msg, nil
+}
+
+func (c *Conn) sendAnswer(name string, ifIndex int, addr net.IP) {
+	answer, err := createAnswer(name, addr)
+	if err != nil {
+		c.log.Warnf("Failed to create mDNS answer %v", err)
+		return
+	}
+
+	rawAnswer, err := answer.Pack()
 	if err != nil {
 		c.log.Warnf("Failed to construct mDNS packet %v", err)
 		return
 	}
 
-	c.writeToSocket(ifIndex, rawAnswer, dst.IsLoopback())
+	c.writeToSocket(ifIndex, rawAnswer, addr.IsLoopback())
 }
 
 func (c *Conn) start(inboundBufferSize int, config *Config) { //nolint gocognit
@@ -328,6 +416,17 @@ func (c *Conn) start(inboundBufferSize int, config *Config) { //nolint gocognit
 		if cm != nil {
 			ifIndex = cm.IfIndex
 		}
+		var srcIP net.IP
+		switch addr := src.(type) {
+		case *net.UDPAddr:
+			srcIP = addr.IP
+		case *net.TCPAddr:
+			srcIP = addr.IP
+		default:
+			c.log.Warnf("Failed to determine address type %T for source address %s", src, src)
+			continue
+		}
+		srcIsIPv4 := srcIP.To4() != nil
 
 		func() {
 			c.mu.RLock()
@@ -352,10 +451,70 @@ func (c *Conn) start(inboundBufferSize int, config *Config) { //nolint gocognit
 						if config.LocalAddress != nil {
 							c.sendAnswer(q.Name.String(), ifIndex, config.LocalAddress)
 						} else {
-							localAddress, err := interfaceForRemote(src.String())
-							if err != nil {
-								c.log.Warnf("Failed to get local interface to communicate with %s: %v", src.String(), err)
-								continue
+							var localAddress net.IP
+
+							// prefer the address of the interface if we know its index, but otherwise
+							// derive it from the address we read from. We do this because even if
+							// multicast loopback is in use or we send from a loopback interface,
+							// there are still cases where the IP packet will contain the wrong
+							// source IP (e.g. a LAN interface).
+							// For example, we can have a packet that has:
+							// Source: 192.168.65.3
+							// Destination: 224.0.0.251
+							// Interface Index: 1
+							// Interface Addresses @ 1: [127.0.0.1/8 ::1/128]
+							if ifIndex != 0 {
+								ifc, netErr := net.InterfaceByIndex(ifIndex)
+								if netErr != nil {
+									c.log.Warnf("Failed to get interface for %d: %v", ifIndex, netErr)
+									continue
+								}
+								addrs, addrsErr := ifc.Addrs()
+								if addrsErr != nil {
+									c.log.Warnf("Failed to get addresses for interface %d: %v", ifIndex, addrsErr)
+									continue
+								}
+								if len(addrs) == 0 {
+									c.log.Warnf("Expected more than one address for interface %d", ifIndex)
+									continue
+								}
+								var selectedIP net.IP
+								for _, addr := range addrs {
+									var ip net.IP
+									switch addr := addr.(type) {
+									case *net.IPNet:
+										ip = addr.IP
+									case *net.IPAddr:
+										ip = addr.IP
+									default:
+										c.log.Warnf("Failed to determine address type %T from interface %d", addr, ifIndex)
+										continue
+									}
+
+									// match up respective IP types
+									if ipv4 := ip.To4(); ipv4 == nil {
+										if srcIsIPv4 {
+											continue
+										} else if !isSupportedIPv6(ip) {
+											continue
+										}
+									} else if !srcIsIPv4 {
+										continue
+									}
+									selectedIP = ip
+									break
+								}
+								if selectedIP == nil {
+									c.log.Warnf("Failed to find suitable IP for interface %d; deriving address from source address instead", ifIndex)
+								} else {
+									localAddress = selectedIP
+								}
+							} else if ifIndex == 0 || localAddress == nil {
+								localAddress, err = interfaceForRemote(src.String())
+								if err != nil {
+									c.log.Warnf("Failed to get local interface to communicate with %s: %v", src.String(), err)
+									continue
+								}
 							}
 
 							c.sendAnswer(q.Name.String(), ifIndex, localAddress)
@@ -403,7 +562,7 @@ func ipFromAnswerHeader(a dnsmessage.ResourceHeader, p dnsmessage.Parser) (ip []
 		if err != nil {
 			return nil, err
 		}
-		ip = net.IP(resource.A[:])
+		ip = resource.A[:]
 	} else {
 		resource, err := p.AAAAResource()
 		if err != nil {
@@ -414,3 +573,25 @@ func ipFromAnswerHeader(a dnsmessage.ResourceHeader, p dnsmessage.Parser) (ip []
 
 	return
 }
+
+// The conditions of invalidation written below are defined in
+// https://tools.ietf.org/html/rfc8445#section-5.1.1.1
+func isSupportedIPv6(ip net.IP) bool {
+	if len(ip) != net.IPv6len ||
+		isZeros(ip[0:12]) || // !(IPv4-compatible IPv6)
+		ip[0] == 0xfe && ip[1]&0xc0 == 0xc0 || // !(IPv6 site-local unicast)
+		ip.IsLinkLocalUnicast() ||
+		ip.IsLinkLocalMulticast() {
+		return false
+	}
+	return true
+}
+
+func isZeros(ip net.IP) bool {
+	for i := 0; i < len(ip); i++ {
+		if ip[i] != 0 {
+			return false
+		}
+	}
+	return true
+}
diff --git a/vendor/github.com/pion/rtcp/.golangci.yml b/vendor/github.com/pion/rtcp/.golangci.yml
index 4e3eddf4..6dd80c80 100644
--- a/vendor/github.com/pion/rtcp/.golangci.yml
+++ b/vendor/github.com/pion/rtcp/.golangci.yml
@@ -29,7 +29,6 @@ linters:
     - bodyclose        # checks whether HTTP response body is closed successfully
     - contextcheck     # check the function whether use a non-inherited context
     - decorder         # check declaration order and count of types, constants, variables and functions
-    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - dogsled          # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
     - dupl             # Tool for code clone detection
     - durationcheck    # check for two durations multiplied together
@@ -63,7 +62,6 @@ linters:
     - importas         # Enforces consistent import aliases
     - ineffassign      # Detects when assignments to existing variables are not used
     - misspell         # Finds commonly misspelled English words in comments
-    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nilerr           # Finds the code that returns nil even if it checks that the error is not nil.
     - nilnil           # Checks that there is no simultaneous return of `nil` error and an invalid value.
     - noctx            # noctx finds sending http request without context.Context
@@ -81,6 +79,7 @@ linters:
     - wastedassign     # wastedassign finds wasted assignment statements
     - whitespace       # Tool for detection of leading and trailing whitespace
   disable:
+    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - containedctx     # containedctx is a linter that detects struct contained context.Context field
     - cyclop           # checks function and package cyclomatic complexity
     - exhaustivestruct # Checks if all struct's fields are initialized
@@ -94,6 +93,7 @@ linters:
     - maintidx         # maintidx measures the maintainability index of each function.
     - makezero         # Finds slice declarations with non-zero initial length
     - maligned         # Tool to detect Go structs that would take less memory if their fields were sorted
+    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nestif           # Reports deeply nested if statements
     - nlreturn         # nlreturn checks for a new line before return and branch statements to increase code clarity
     - nolintlint       # Reports ill-formed or insufficient nolint directives
@@ -111,22 +111,11 @@ linters:
 issues:
   exclude-use-default: false
   exclude-rules:
-    # Allow complex tests, better to be self contained
-    - path: _test\.go
+    # Allow complex tests and examples, better to be self contained
+    - path: (examples|main\.go|_test\.go)
       linters:
-        - gocognit
         - forbidigo
-
-    # Allow complex main function in examples
-    - path: examples
-      text: "of func `main` is high"
-      linters:
         - gocognit
-    
-    # Allow forbidden identifiers in examples
-    - path: examples
-      linters:
-        - forbidigo
 
     # Allow forbidden identifiers in CLI commands
     - path: cmd
diff --git a/vendor/github.com/pion/rtcp/AUTHORS.txt b/vendor/github.com/pion/rtcp/AUTHORS.txt
deleted file mode 100644
index 5f55cf2c..00000000
--- a/vendor/github.com/pion/rtcp/AUTHORS.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-# Thank you to everyone that made Pion possible. If you are interested in contributing
-# we would love to have you https://github.com/pion/webrtc/wiki/Contributing
-#
-# This file is auto generated, using git to list all individuals contributors.
-# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting
-Adam Roach <adam@caffeine.tv>
-adwpc <adwpc@hotmail.com>
-aggresss <aggresss@163.com>
-Atsushi Watanabe <atsushi.w@ieee.org>
-cnderrauber <zengjie9004@gmail.com>
-Gabor Pongracz <gabor.pongracz@proemergotech.com>
-Hugo Arregui <hugo.arregui@gmail.com>
-Hugo Arregui <hugo@decentraland.org>
-Juho Nurminen <juhonurm@gmail.com>
-Juliusz Chroboczek <jch@irif.fr>
-Kevin Wang <kevmo314@gmail.com>
-lllf <littlelightlittlefire@gmail.com>
-Luke Curley <kixelated@gmail.com>
-Mathis Engelbart <mathis.engelbart@gmail.com>
-Max Hawkins <maxhawkins@gmail.com>
-Sean <sean@siobud.com>
-Sean DuBois <seaduboi@amazon.com>
-Sean DuBois <sean@siobud.com>
-Simone Gotti <simone.gotti@gmail.com>
-Steffen Vogel <post@steffenvogel.de>
-tanghao <tanghao1996.seu@gmail.com>
-tanghao <tanghao@bilibili.com>
-Woodrow Douglass <wdouglass@carnegierobotics.com>
-
-# List of contributors not appearing in Git history
-
diff --git a/vendor/github.com/pion/rtcp/README.md b/vendor/github.com/pion/rtcp/README.md
index 6641d94b..063574aa 100644
--- a/vendor/github.com/pion/rtcp/README.md
+++ b/vendor/github.com/pion/rtcp/README.md
@@ -31,7 +31,7 @@ We are always looking to support **your projects**. Please reach out if you have
 If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly)
 
 ### Contributing
-Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt)
+Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible
 
 ### License
 MIT License - see [LICENSE](LICENSE) for full text
diff --git a/vendor/github.com/pion/rtcp/extended_report.go b/vendor/github.com/pion/rtcp/extended_report.go
index db7ca41d..0f9ee2cc 100644
--- a/vendor/github.com/pion/rtcp/extended_report.go
+++ b/vendor/github.com/pion/rtcp/extended_report.go
@@ -646,7 +646,8 @@ func (x *ExtendedReport) Unmarshal(b []byte) error {
 
 // DestinationSSRC returns an array of SSRC values that this packet refers to.
 func (x *ExtendedReport) DestinationSSRC() []uint32 {
-	ssrc := make([]uint32, 0)
+	ssrc := make([]uint32, 0, len(x.Reports)+1)
+	ssrc = append(ssrc, x.SenderSSRC)
 	for _, p := range x.Reports {
 		ssrc = append(ssrc, p.DestinationSSRC()...)
 	}
diff --git a/vendor/github.com/pion/rtp/.golangci.yml b/vendor/github.com/pion/rtp/.golangci.yml
index 4e3eddf4..e06de4d3 100644
--- a/vendor/github.com/pion/rtp/.golangci.yml
+++ b/vendor/github.com/pion/rtp/.golangci.yml
@@ -3,7 +3,8 @@
 
 linters-settings:
   govet:
-    check-shadowing: true
+    enable:
+      - shadow
   misspell:
     locale: US
   exhaustive:
@@ -29,7 +30,6 @@ linters:
     - bodyclose        # checks whether HTTP response body is closed successfully
     - contextcheck     # check the function whether use a non-inherited context
     - decorder         # check declaration order and count of types, constants, variables and functions
-    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - dogsled          # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
     - dupl             # Tool for code clone detection
     - durationcheck    # check for two durations multiplied together
@@ -63,7 +63,6 @@ linters:
     - importas         # Enforces consistent import aliases
     - ineffassign      # Detects when assignments to existing variables are not used
     - misspell         # Finds commonly misspelled English words in comments
-    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nilerr           # Finds the code that returns nil even if it checks that the error is not nil.
     - nilnil           # Checks that there is no simultaneous return of `nil` error and an invalid value.
     - noctx            # noctx finds sending http request without context.Context
@@ -81,6 +80,7 @@ linters:
     - wastedassign     # wastedassign finds wasted assignment statements
     - whitespace       # Tool for detection of leading and trailing whitespace
   disable:
+    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - containedctx     # containedctx is a linter that detects struct contained context.Context field
     - cyclop           # checks function and package cyclomatic complexity
     - exhaustivestruct # Checks if all struct's fields are initialized
@@ -94,6 +94,7 @@ linters:
     - maintidx         # maintidx measures the maintainability index of each function.
     - makezero         # Finds slice declarations with non-zero initial length
     - maligned         # Tool to detect Go structs that would take less memory if their fields were sorted
+    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nestif           # Reports deeply nested if statements
     - nlreturn         # nlreturn checks for a new line before return and branch statements to increase code clarity
     - nolintlint       # Reports ill-formed or insufficient nolint directives
@@ -110,28 +111,15 @@ linters:
 
 issues:
   exclude-use-default: false
+  exclude-dirs-use-default: false
   exclude-rules:
-    # Allow complex tests, better to be self contained
-    - path: _test\.go
+    # Allow complex tests and examples, better to be self contained
+    - path: (examples|main\.go|_test\.go)
       linters:
-        - gocognit
         - forbidigo
-
-    # Allow complex main function in examples
-    - path: examples
-      text: "of func `main` is high"
-      linters:
         - gocognit
-    
-    # Allow forbidden identifiers in examples
-    - path: examples
-      linters:
-        - forbidigo
 
     # Allow forbidden identifiers in CLI commands
     - path: cmd
       linters:
         - forbidigo
-
-run:
-  skip-dirs-use-default: false
diff --git a/vendor/github.com/pion/rtp/AUTHORS.txt b/vendor/github.com/pion/rtp/AUTHORS.txt
deleted file mode 100644
index f8dbb32a..00000000
--- a/vendor/github.com/pion/rtp/AUTHORS.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-# Thank you to everyone that made Pion possible. If you are interested in contributing
-# we would love to have you https://github.com/pion/webrtc/wiki/Contributing
-#
-# This file is auto generated, using git to list all individuals contributors.
-# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting
-Aaron Boushley <boushley@pretzelaux.com>
-adwpc <adwpc@hotmail.com>
-aler9 <46489434+aler9@users.noreply.github.com>
-Antoine Baché <antoine.bache@epitech.eu>
-Antoine Baché <antoine@tenten.app>
-Atsushi Watanabe <atsushi.w@ieee.org>
-baiyufei <baiyufei@outlook.com>
-Bao Nguyen <bao@n4n.dev>
-boks1971 <raja.gobi@tutanota.com>
-debiandebiandebian <debiandebiandebiandebian@gmail.com>
-ffmiyo <leffmiyo@gmail.com>
-Guilherme <gqgs@protonmail.com>
-Haiyang Wang <ocean2811@outlook.com>
-Hugo Arregui <hugo@decentraland.org>
-John Bradley <jrb@turrettech.com>
-Juho Nurminen <juhonurm@gmail.com>
-Juliusz Chroboczek <jch@irif.fr>
-kawaway <kawawa.y@gmail.com>
-Kazuyuki Honda <hakobera@gmail.com>
-Kevin Wang <kevmo314@gmail.com>
-Luke Curley <kixelated@gmail.com>
-lxb <xiangbing.li@uama.com.cn>
-Michael MacDonald <github@macdonald.cx>
-Michael MacDonald <mike.macdonald@savantsystems.com>
-Michael Uti <utimichael9@gmail.com>
-Raphael Derosso Pereira <raphaelpereira@gmail.com>
-Rob Lofthouse <ri.lofthouse@gmail.com>
-Robin Raymond <robin@goheadroom.com>
-Sean <sean@pion.ly>
-Sean <sean@siobud.com>
-Sean DuBois <duboisea@twitch.tv>
-Sean DuBois <seaduboi@amazon.com>
-Sean DuBois <sean@pion.ly>
-Sean DuBois <sean@siobud.com>
-Simone Gotti <simone.gotti@gmail.com>
-Steffen Vogel <post@steffenvogel.de>
-Tarrence van As <tarrence13@gmail.com>
-wangzixiang <wangzixiang@onething.net>
-Woodrow Douglass <wdouglass@carnegierobotics.com>
-訾明华 <565209960@qq.com>
-
-# List of contributors not appearing in Git history
-
diff --git a/vendor/github.com/pion/rtp/README.md b/vendor/github.com/pion/rtp/README.md
index 37b7cc0e..c84621c0 100644
--- a/vendor/github.com/pion/rtp/README.md
+++ b/vendor/github.com/pion/rtp/README.md
@@ -29,7 +29,7 @@ We are always looking to support **your projects**. Please reach out if you have
 If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly)
 
 ### Contributing
-Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt)
+Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible
 
 ### License
-MIT License - see [LICENSE](LICENSE) for full text
\ No newline at end of file
+MIT License - see [LICENSE](LICENSE) for full text
diff --git a/vendor/github.com/pion/rtp/abscapturetimeextension.go b/vendor/github.com/pion/rtp/abscapturetimeextension.go
index 56b783df..5e96cffb 100644
--- a/vendor/github.com/pion/rtp/abscapturetimeextension.go
+++ b/vendor/github.com/pion/rtp/abscapturetimeextension.go
@@ -66,7 +66,15 @@ func (t AbsCaptureTimeExtension) EstimatedCaptureClockOffsetDuration() *time.Dur
 		return nil
 	}
 	offset := *t.EstimatedCaptureClockOffset
+	negative := false
+	if offset < 0 {
+		offset = -offset
+		negative = true
+	}
 	duration := time.Duration(offset/(1<<32))*time.Second + time.Duration((offset&0xFFFFFFFF)*1e9/(1<<32))*time.Nanosecond
+	if negative {
+		duration = -duration
+	}
 	return &duration
 }
 
@@ -80,9 +88,17 @@ func NewAbsCaptureTimeExtension(captureTime time.Time) *AbsCaptureTimeExtension
 // NewAbsCaptureTimeExtensionWithCaptureClockOffset makes new AbsCaptureTimeExtension from time.Time and a clock offset.
 func NewAbsCaptureTimeExtensionWithCaptureClockOffset(captureTime time.Time, captureClockOffset time.Duration) *AbsCaptureTimeExtension {
 	ns := captureClockOffset.Nanoseconds()
+	negative := false
+	if ns < 0 {
+		ns = -ns
+		negative = true
+	}
 	lsb := (ns / 1e9) & 0xFFFFFFFF
 	msb := (((ns % 1e9) * (1 << 32)) / 1e9) & 0xFFFFFFFF
 	offset := (lsb << 32) | msb
+	if negative {
+		offset = -offset
+	}
 	return &AbsCaptureTimeExtension{
 		Timestamp:                   toNtpTime(captureTime),
 		EstimatedCaptureClockOffset: &offset,
diff --git a/vendor/github.com/pion/rtp/codecs/av1/obu/leb128.go b/vendor/github.com/pion/rtp/codecs/av1/obu/leb128.go
index 38ce0909..f5fcbf65 100644
--- a/vendor/github.com/pion/rtp/codecs/av1/obu/leb128.go
+++ b/vendor/github.com/pion/rtp/codecs/av1/obu/leb128.go
@@ -67,3 +67,19 @@ func ReadLeb128(in []byte) (uint, uint, error) {
 
 	return 0, 0, ErrFailedToReadLEB128
 }
+
+// WriteToLeb128 writes a uint to a LEB128 encoded byte slice.
+func WriteToLeb128(in uint) []byte {
+	b := make([]byte, 10)
+
+	for i := 0; i < len(b); i++ {
+		b[i] = byte(in & 0x7f)
+		in >>= 7
+		if in == 0 {
+			return b[:i+1]
+		}
+		b[i] |= 0x80
+	}
+
+	return b // unreachable
+}
diff --git a/vendor/github.com/pion/rtp/codecs/av1_packet.go b/vendor/github.com/pion/rtp/codecs/av1_packet.go
index 3a78b90e..bcea6905 100644
--- a/vendor/github.com/pion/rtp/codecs/av1_packet.go
+++ b/vendor/github.com/pion/rtp/codecs/av1_packet.go
@@ -134,6 +134,8 @@ type AV1Packet struct {
 	// Each AV1 RTP Packet is a collection of OBU Elements. Each OBU Element may be a full OBU, or just a fragment of one.
 	// AV1Frame provides the tools to construct a collection of OBUs from a collection of OBU Elements
 	OBUElements [][]byte
+
+	videoDepacketizer
 }
 
 // Unmarshal parses the passed byte slice and stores the result in the AV1Packet this method is called upon
@@ -153,13 +155,26 @@ func (p *AV1Packet) Unmarshal(payload []byte) ([]byte, error) {
 		return nil, errIsKeyframeAndFragment
 	}
 
-	currentIndex := uint(1)
-	p.OBUElements = [][]byte{}
+	if !p.zeroAllocation {
+		obuElements, err := p.parseBody(payload[1:])
+		if err != nil {
+			return nil, err
+		}
+		p.OBUElements = obuElements
+	}
+
+	return payload[1:], nil
+}
+
+func (p *AV1Packet) parseBody(payload []byte) ([][]byte, error) {
+	if p.OBUElements != nil {
+		return p.OBUElements, nil
+	}
+
+	obuElements := [][]byte{}
 
-	var (
-		obuElementLength, bytesRead uint
-		err                         error
-	)
+	var obuElementLength, bytesRead uint
+	currentIndex := uint(0)
 	for i := 1; ; i++ {
 		if currentIndex == uint(len(payload)) {
 			break
@@ -170,6 +185,7 @@ func (p *AV1Packet) Unmarshal(payload []byte) ([]byte, error) {
 			bytesRead = 0
 			obuElementLength = uint(len(payload)) - currentIndex
 		} else {
+			var err error
 			obuElementLength, bytesRead, err = obu.ReadLeb128(payload[currentIndex:])
 			if err != nil {
 				return nil, err
@@ -180,9 +196,9 @@ func (p *AV1Packet) Unmarshal(payload []byte) ([]byte, error) {
 		if uint(len(payload)) < currentIndex+obuElementLength {
 			return nil, errShortPacket
 		}
-		p.OBUElements = append(p.OBUElements, payload[currentIndex:currentIndex+obuElementLength])
+		obuElements = append(obuElements, payload[currentIndex:currentIndex+obuElementLength])
 		currentIndex += obuElementLength
 	}
 
-	return payload[1:], nil
+	return obuElements, nil
 }
diff --git a/vendor/github.com/pion/rtp/codecs/common.go b/vendor/github.com/pion/rtp/codecs/common.go
index 5da8aaf6..e807a0ac 100644
--- a/vendor/github.com/pion/rtp/codecs/common.go
+++ b/vendor/github.com/pion/rtp/codecs/common.go
@@ -22,8 +22,18 @@ func (d *audioDepacketizer) IsPartitionHead(_ []byte) bool {
 }
 
 // videoDepacketizer is a mixin for video codec depacketizers
-type videoDepacketizer struct{}
+type videoDepacketizer struct {
+	zeroAllocation bool
+}
 
 func (d *videoDepacketizer) IsPartitionTail(marker bool, _ []byte) bool {
 	return marker
 }
+
+// SetZeroAllocation enables Zero Allocation mode for the depacketizer
+// By default the Depacketizers will allocate as they parse. These allocations
+// are needed for Metadata and other optional values. If you don't need this information
+// enabling SetZeroAllocation gives you higher performance at a reduced feature set.
+func (d *videoDepacketizer) SetZeroAllocation(zeroAllocation bool) {
+	d.zeroAllocation = zeroAllocation
+}
diff --git a/vendor/github.com/pion/rtp/codecs/h264_packet.go b/vendor/github.com/pion/rtp/codecs/h264_packet.go
index 583e1892..3021fc0f 100644
--- a/vendor/github.com/pion/rtp/codecs/h264_packet.go
+++ b/vendor/github.com/pion/rtp/codecs/h264_packet.go
@@ -188,14 +188,16 @@ type H264Packet struct {
 	videoDepacketizer
 }
 
-func (p *H264Packet) doPackaging(nalu []byte) []byte {
+func (p *H264Packet) doPackaging(buf, nalu []byte) []byte {
 	if p.IsAVC {
-		naluLength := make([]byte, 4)
-		binary.BigEndian.PutUint32(naluLength, uint32(len(nalu)))
-		return append(naluLength, nalu...)
+		buf = binary.BigEndian.AppendUint32(buf, uint32(len(nalu)))
+		buf = append(buf, nalu...)
+		return buf
 	}
 
-	return append(annexbNALUStartCode, nalu...)
+	buf = append(buf, annexbNALUStartCode...)
+	buf = append(buf, nalu...)
+	return buf
 }
 
 // IsDetectedFinalPacketInSequence returns true of the packet passed in has the
@@ -206,6 +208,14 @@ func (p *H264Packet) IsDetectedFinalPacketInSequence(rtpPacketMarketBit bool) bo
 
 // Unmarshal parses the passed byte slice and stores the result in the H264Packet this method is called upon
 func (p *H264Packet) Unmarshal(payload []byte) ([]byte, error) {
+	if p.zeroAllocation {
+		return payload, nil
+	}
+
+	return p.parseBody(payload)
+}
+
+func (p *H264Packet) parseBody(payload []byte) ([]byte, error) {
 	if len(payload) == 0 {
 		return nil, fmt.Errorf("%w: %d <=0", errShortPacket, len(payload))
 	}
@@ -215,7 +225,7 @@ func (p *H264Packet) Unmarshal(payload []byte) ([]byte, error) {
 	naluType := payload[0] & naluTypeBitmask
 	switch {
 	case naluType > 0 && naluType < 24:
-		return p.doPackaging(payload), nil
+		return p.doPackaging(nil, payload), nil
 
 	case naluType == stapaNALUType:
 		currOffset := int(stapaHeaderSize)
@@ -228,7 +238,7 @@ func (p *H264Packet) Unmarshal(payload []byte) ([]byte, error) {
 				return nil, fmt.Errorf("%w STAP-A declared size(%d) is larger than buffer(%d)", errShortPacket, naluSize, len(payload)-currOffset)
 			}
 
-			result = append(result, p.doPackaging(payload[currOffset:currOffset+naluSize])...)
+			result = p.doPackaging(result, payload[currOffset:currOffset+naluSize])
 			currOffset += naluSize
 		}
 		return result, nil
@@ -251,7 +261,7 @@ func (p *H264Packet) Unmarshal(payload []byte) ([]byte, error) {
 			nalu := append([]byte{}, naluRefIdc|fragmentedNaluType)
 			nalu = append(nalu, p.fuaBuffer...)
 			p.fuaBuffer = nil
-			return p.doPackaging(nalu), nil
+			return p.doPackaging(nil, nalu), nil
 		}
 
 		return []byte{}, nil
diff --git a/vendor/github.com/pion/rtp/codecs/vp8_packet.go b/vendor/github.com/pion/rtp/codecs/vp8_packet.go
index 5d0a6540..4ddd15bc 100644
--- a/vendor/github.com/pion/rtp/codecs/vp8_packet.go
+++ b/vendor/github.com/pion/rtp/codecs/vp8_packet.go
@@ -123,7 +123,7 @@ type VP8Packet struct {
 }
 
 // Unmarshal parses the passed byte slice and stores the result in the VP8Packet this method is called upon
-func (p *VP8Packet) Unmarshal(payload []byte) ([]byte, error) {
+func (p *VP8Packet) Unmarshal(payload []byte) ([]byte, error) { //nolint: gocognit
 	if payload == nil {
 		return nil, errNilPacket
 	}
@@ -163,6 +163,9 @@ func (p *VP8Packet) Unmarshal(payload []byte) ([]byte, error) {
 			return nil, errShortPacket
 		}
 		if payload[payloadIndex]&0x80 > 0 { // M == 1, PID is 16bit
+			if payloadIndex+1 >= payloadLen {
+				return nil, errShortPacket
+			}
 			p.PictureID = (uint16(payload[payloadIndex]&0x7F) << 8) | uint16(payload[payloadIndex+1])
 			payloadIndex += 2
 		} else {
diff --git a/vendor/github.com/pion/rtp/depacketizer.go b/vendor/github.com/pion/rtp/depacketizer.go
index 0439a531..d10ad89b 100644
--- a/vendor/github.com/pion/rtp/depacketizer.go
+++ b/vendor/github.com/pion/rtp/depacketizer.go
@@ -5,11 +5,15 @@ package rtp
 
 // Depacketizer depacketizes a RTP payload, removing any RTP specific data from the payload
 type Depacketizer interface {
+	// Unmarshal parses the RTP payload and returns media.
+	// Metadata may be stored on the Depacketizer itself
 	Unmarshal(packet []byte) ([]byte, error)
+
 	// Checks if the packet is at the beginning of a partition.  This
 	// should return false if the result could not be determined, in
 	// which case the caller will detect timestamp discontinuities.
 	IsPartitionHead(payload []byte) bool
+
 	// Checks if the packet is at the end of a partition.  This should
 	// return false if the result could not be determined.
 	IsPartitionTail(marker bool, payload []byte) bool
diff --git a/vendor/github.com/pion/rtp/packetizer.go b/vendor/github.com/pion/rtp/packetizer.go
index 7ecebde6..7a6a46db 100644
--- a/vendor/github.com/pion/rtp/packetizer.go
+++ b/vendor/github.com/pion/rtp/packetizer.go
@@ -15,6 +15,7 @@ type Payloader interface {
 // Packetizer packetizes a payload
 type Packetizer interface {
 	Packetize(payload []byte, samples uint32) []*Packet
+	GeneratePadding(samples uint32) []*Packet
 	EnableAbsSendTime(value int)
 	SkipSamples(skippedSamples uint32)
 }
@@ -98,6 +99,38 @@ func (p *packetizer) Packetize(payload []byte, samples uint32) []*Packet {
 	return packets
 }
 
+// GeneratePadding returns required padding-only packages
+func (p *packetizer) GeneratePadding(samples uint32) []*Packet {
+	// Guard against an empty payload
+	if samples == 0 {
+		return nil
+	}
+
+	packets := make([]*Packet, samples)
+
+	for i := 0; i < int(samples); i++ {
+		pp := make([]byte, 255)
+		pp[254] = 255
+
+		packets[i] = &Packet{
+			Header: Header{
+				Version:        2,
+				Padding:        true,
+				Extension:      false,
+				Marker:         false,
+				PayloadType:    p.PayloadType,
+				SequenceNumber: p.Sequencer.NextSequenceNumber(),
+				Timestamp:      p.Timestamp, // Use latest timestamp
+				SSRC:           p.SSRC,
+				CSRC:           []uint32{},
+			},
+			Payload: pp,
+		}
+	}
+
+	return packets
+}
+
 // SkipSamples causes a gap in sample count between Packetize requests so the
 // RTP payloads produced have a gap in timestamps
 func (p *packetizer) SkipSamples(skippedSamples uint32) {
diff --git a/vendor/github.com/pion/rtp/payload_types.go b/vendor/github.com/pion/rtp/payload_types.go
new file mode 100644
index 00000000..a9bf2272
--- /dev/null
+++ b/vendor/github.com/pion/rtp/payload_types.go
@@ -0,0 +1,68 @@
+// SPDX-FileCopyrightText: 2024 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
+package rtp
+
+// https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml
+// https://en.wikipedia.org/wiki/RTP_payload_formats
+
+// Audio Payload Types as defined in https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml
+const (
+	// PayloadTypePCMU is a payload type for ITU-T G.711 PCM μ-Law audio 64 kbit/s (RFC 3551).
+	PayloadTypePCMU = 0
+	// PayloadTypeGSM is a payload type for European GSM Full Rate audio 13 kbit/s (GSM 06.10).
+	PayloadTypeGSM = 3
+	// PayloadTypeG723 is a payload type for ITU-T G.723.1 audio (RFC 3551).
+	PayloadTypeG723 = 4
+	// PayloadTypeDVI4_8000 is a payload type for IMA ADPCM audio 32 kbit/s (RFC 3551).
+	PayloadTypeDVI4_8000 = 5
+	// PayloadTypeDVI4_16000 is a payload type for IMA ADPCM audio 64 kbit/s (RFC 3551).
+	PayloadTypeDVI4_16000 = 6
+	// PayloadTypeLPC is a payload type for Experimental Linear Predictive Coding audio 5.6 kbit/s (RFC 3551).
+	PayloadTypeLPC = 7
+	// PayloadTypePCMA is a payload type for ITU-T G.711 PCM A-Law audio 64 kbit/s (RFC 3551).
+	PayloadTypePCMA = 8
+	// PayloadTypeG722 is a payload type for ITU-T G.722 audio 64 kbit/s (RFC 3551).
+	PayloadTypeG722 = 9
+	// PayloadTypeL16Stereo is a payload type for Linear PCM 16-bit Stereo audio 1411.2 kbit/s, uncompressed (RFC 3551).
+	PayloadTypeL16Stereo = 10
+	// PayloadTypeL16Mono is a payload type for Linear PCM 16-bit audio 705.6 kbit/s, uncompressed (RFC 3551).
+	PayloadTypeL16Mono = 11
+	// PayloadTypeQCELP is a payload type for Qualcomm Code Excited Linear Prediction (RFC 2658, RFC 3551).
+	PayloadTypeQCELP = 12
+	// PayloadTypeCN is a payload type for Comfort noise (RFC 3389).
+	PayloadTypeCN = 13
+	// PayloadTypeMPA is a payload type for MPEG-1 or MPEG-2 audio only (RFC 3551, RFC 2250).
+	PayloadTypeMPA = 14
+	// PayloadTypeG728 is a payload type for ITU-T G.728 audio 16 kbit/s (RFC 3551).
+	PayloadTypeG728 = 15
+	// PayloadTypeDVI4_11025 is a payload type for IMA ADPCM audio 44.1 kbit/s (RFC 3551).
+	PayloadTypeDVI4_11025 = 16
+	// PayloadTypeDVI4_22050 is a payload type for IMA ADPCM audio 88.2 kbit/s (RFC 3551).
+	PayloadTypeDVI4_22050 = 17
+	// PayloadTypeG729 is a payload type for ITU-T G.729 and G.729a audio 8 kbit/s (RFC 3551, RFC 3555).
+	PayloadTypeG729 = 18
+)
+
+// Video Payload Types as defined in https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml
+const (
+	// PayloadTypeCELLB is a payload type for Sun CellB video (RFC 2029).
+	PayloadTypeCELLB = 25
+	// PayloadTypeJPEG is a payload type for JPEG video (RFC 2435).
+	PayloadTypeJPEG = 26
+	// PayloadTypeNV is a payload type for Xerox PARC's Network Video (nv, RFC 3551).
+	PayloadTypeNV = 28
+	// PayloadTypeH261 is a payload type for ITU-T H.261 video (RFC 4587).
+	PayloadTypeH261 = 31
+	// PayloadTypeMPV is a payload type for MPEG-1 and MPEG-2 video (RFC 2250).
+	PayloadTypeMPV = 32
+	// PayloadTypeMP2T is a payload type for MPEG-2 transport stream (RFC 2250).
+	PayloadTypeMP2T = 33
+	// PayloadTypeH263 is a payload type for H.263 video, first version (1996, RFC 3551, RFC 2190).
+	PayloadTypeH263 = 34
+)
+
+const (
+	// PayloadTypeFirstDynamic is a first non-static payload type.
+	PayloadTypeFirstDynamic = 35
+)
diff --git a/vendor/github.com/pion/rtp/vlaextension.go b/vendor/github.com/pion/rtp/vlaextension.go
new file mode 100644
index 00000000..e10820a3
--- /dev/null
+++ b/vendor/github.com/pion/rtp/vlaextension.go
@@ -0,0 +1,360 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
+package rtp
+
+import (
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"strings"
+
+	"github.com/pion/rtp/codecs/av1/obu"
+)
+
+var (
+	ErrVLATooShort             = errors.New("VLA payload too short")           // ErrVLATooShort is returned when payload is too short
+	ErrVLAInvalidStreamCount   = errors.New("invalid RTP stream count in VLA") // ErrVLAInvalidStreamCount is returned when RTP stream count is invalid
+	ErrVLAInvalidStreamID      = errors.New("invalid RTP stream ID in VLA")    // ErrVLAInvalidStreamID is returned when RTP stream ID is invalid
+	ErrVLAInvalidSpatialID     = errors.New("invalid spatial ID in VLA")       // ErrVLAInvalidSpatialID is returned when spatial ID is invalid
+	ErrVLADuplicateSpatialID   = errors.New("duplicate spatial ID in VLA")     // ErrVLADuplicateSpatialID is returned when spatial ID is invalid
+	ErrVLAInvalidTemporalLayer = errors.New("invalid temporal layer in VLA")   // ErrVLAInvalidTemporalLayer is returned when temporal layer is invalid
+)
+
+// SpatialLayer is a spatial layer in VLA.
+type SpatialLayer struct {
+	RTPStreamID    int
+	SpatialID      int
+	TargetBitrates []int // target bitrates per temporal layer
+
+	// Following members are valid only when HasResolutionAndFramerate is true
+	Width     int
+	Height    int
+	Framerate int
+}
+
+// VLA is a Video Layer Allocation (VLA) extension.
+// See https://webrtc.googlesource.com/src/+/refs/heads/main/docs/native-code/rtp-hdrext/video-layers-allocation00
+type VLA struct {
+	RTPStreamID               int // 0-origin RTP stream ID (RID) this allocation is sent on (0..3)
+	RTPStreamCount            int // Number of RTP streams (1..4)
+	ActiveSpatialLayer        []SpatialLayer
+	HasResolutionAndFramerate bool
+}
+
+type vlaMarshalingContext struct {
+	slMBs                 [4]uint8
+	sls                   [4][4]*SpatialLayer
+	commonSLBM            uint8
+	encodedTargetBitrates [][]byte
+	requiredLen           int
+}
+
+func (v VLA) preprocessForMashaling(ctx *vlaMarshalingContext) error {
+	for i := 0; i < len(v.ActiveSpatialLayer); i++ {
+		sl := v.ActiveSpatialLayer[i]
+		if sl.RTPStreamID < 0 || sl.RTPStreamID >= v.RTPStreamCount {
+			return fmt.Errorf("invalid RTP streamID %d:%w", sl.RTPStreamID, ErrVLAInvalidStreamID)
+		}
+		if sl.SpatialID < 0 || sl.SpatialID >= 4 {
+			return fmt.Errorf("invalid spatial ID %d: %w", sl.SpatialID, ErrVLAInvalidSpatialID)
+		}
+		if len(sl.TargetBitrates) == 0 || len(sl.TargetBitrates) > 4 {
+			return fmt.Errorf("invalid temporal layer count %d: %w", len(sl.TargetBitrates), ErrVLAInvalidTemporalLayer)
+		}
+		ctx.slMBs[sl.RTPStreamID] |= 1 << sl.SpatialID
+		if ctx.sls[sl.RTPStreamID][sl.SpatialID] != nil {
+			return fmt.Errorf("duplicate spatial layer: %w", ErrVLADuplicateSpatialID)
+		}
+		ctx.sls[sl.RTPStreamID][sl.SpatialID] = &sl
+	}
+	return nil
+}
+
+func (v VLA) encodeTargetBitrates(ctx *vlaMarshalingContext) {
+	for rtpStreamID := 0; rtpStreamID < v.RTPStreamCount; rtpStreamID++ {
+		for spatialID := 0; spatialID < 4; spatialID++ {
+			if sl := ctx.sls[rtpStreamID][spatialID]; sl != nil {
+				for _, kbps := range sl.TargetBitrates {
+					leb128 := obu.WriteToLeb128(uint(kbps))
+					ctx.encodedTargetBitrates = append(ctx.encodedTargetBitrates, leb128)
+					ctx.requiredLen += len(leb128)
+				}
+			}
+		}
+	}
+}
+
+func (v VLA) analyzeVLAForMarshaling() (*vlaMarshalingContext, error) {
+	// Validate RTPStreamCount
+	if v.RTPStreamCount <= 0 || v.RTPStreamCount > 4 {
+		return nil, ErrVLAInvalidStreamCount
+	}
+	// Validate RTPStreamID
+	if v.RTPStreamID < 0 || v.RTPStreamID >= v.RTPStreamCount {
+		return nil, ErrVLAInvalidStreamID
+	}
+
+	ctx := &vlaMarshalingContext{}
+	err := v.preprocessForMashaling(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	ctx.commonSLBM = commonSLBMValues(ctx.slMBs[:])
+
+	// RID, NS, sl_bm fields
+	if ctx.commonSLBM != 0 {
+		ctx.requiredLen = 1
+	} else {
+		ctx.requiredLen = 3
+	}
+
+	// #tl fields
+	ctx.requiredLen += (len(v.ActiveSpatialLayer)-1)/4 + 1
+
+	v.encodeTargetBitrates(ctx)
+
+	if v.HasResolutionAndFramerate {
+		ctx.requiredLen += len(v.ActiveSpatialLayer) * 5
+	}
+
+	return ctx, nil
+}
+
+// Marshal encodes VLA into a byte slice.
+func (v VLA) Marshal() ([]byte, error) {
+	ctx, err := v.analyzeVLAForMarshaling()
+	if err != nil {
+		return nil, err
+	}
+
+	payload := make([]byte, ctx.requiredLen)
+	offset := 0
+
+	// RID, NS, sl_bm fields
+	payload[offset] = byte(v.RTPStreamID<<6) | byte(v.RTPStreamCount-1)<<4 | ctx.commonSLBM
+
+	if ctx.commonSLBM == 0 {
+		offset++
+		for streamID := 0; streamID < v.RTPStreamCount; streamID++ {
+			if streamID%2 == 0 {
+				payload[offset+streamID/2] |= ctx.slMBs[streamID] << 4
+			} else {
+				payload[offset+streamID/2] |= ctx.slMBs[streamID]
+			}
+		}
+		offset += (v.RTPStreamCount - 1) / 2
+	}
+
+	// #tl fields
+	offset++
+	var temporalLayerIndex int
+	for rtpStreamID := 0; rtpStreamID < v.RTPStreamCount; rtpStreamID++ {
+		for spatialID := 0; spatialID < 4; spatialID++ {
+			if sl := ctx.sls[rtpStreamID][spatialID]; sl != nil {
+				if temporalLayerIndex >= 4 {
+					temporalLayerIndex = 0
+					offset++
+				}
+				payload[offset] |= byte(len(sl.TargetBitrates)-1) << (2 * (3 - temporalLayerIndex))
+				temporalLayerIndex++
+			}
+		}
+	}
+
+	// Target bitrate fields
+	offset++
+	for _, encodedKbps := range ctx.encodedTargetBitrates {
+		encodedSize := len(encodedKbps)
+		copy(payload[offset:], encodedKbps)
+		offset += encodedSize
+	}
+
+	// Resolution & framerate fields
+	if v.HasResolutionAndFramerate {
+		for _, sl := range v.ActiveSpatialLayer {
+			binary.BigEndian.PutUint16(payload[offset+0:], uint16(sl.Width-1))
+			binary.BigEndian.PutUint16(payload[offset+2:], uint16(sl.Height-1))
+			payload[offset+4] = byte(sl.Framerate)
+			offset += 5
+		}
+	}
+
+	return payload, nil
+}
+
+func commonSLBMValues(slMBs []uint8) uint8 {
+	var common uint8
+	for i := 0; i < len(slMBs); i++ {
+		if slMBs[i] == 0 {
+			continue
+		}
+		if common == 0 {
+			common = slMBs[i]
+			continue
+		}
+		if slMBs[i] != common {
+			return 0
+		}
+	}
+	return common
+}
+
+type vlaUnmarshalingContext struct {
+	payload   []byte
+	offset    int
+	slBMField uint8
+	slBMs     [4]uint8
+}
+
+func (ctx *vlaUnmarshalingContext) checkRemainingLen(requiredLen int) bool {
+	return len(ctx.payload)-ctx.offset >= requiredLen
+}
+
+func (v *VLA) unmarshalSpatialLayers(ctx *vlaUnmarshalingContext) error {
+	if !ctx.checkRemainingLen(1) {
+		return fmt.Errorf("failed to unmarshal VLA (offset=%d): %w", ctx.offset, ErrVLATooShort)
+	}
+	v.RTPStreamID = int(ctx.payload[ctx.offset] >> 6 & 0b11)
+	v.RTPStreamCount = int(ctx.payload[ctx.offset]>>4&0b11) + 1
+
+	// sl_bm fields
+	ctx.slBMField = ctx.payload[ctx.offset] & 0b1111
+	ctx.offset++
+
+	if ctx.slBMField != 0 {
+		for streamID := 0; streamID < v.RTPStreamCount; streamID++ {
+			ctx.slBMs[streamID] = ctx.slBMField
+		}
+	} else {
+		if !ctx.checkRemainingLen((v.RTPStreamCount-1)/2 + 1) {
+			return fmt.Errorf("failed to unmarshal VLA (offset=%d): %w", ctx.offset, ErrVLATooShort)
+		}
+		// slX_bm fields
+		for streamID := 0; streamID < v.RTPStreamCount; streamID++ {
+			var bm uint8
+			if streamID%2 == 0 {
+				bm = ctx.payload[ctx.offset+streamID/2] >> 4 & 0b1111
+			} else {
+				bm = ctx.payload[ctx.offset+streamID/2] & 0b1111
+			}
+			ctx.slBMs[streamID] = bm
+		}
+		ctx.offset += 1 + (v.RTPStreamCount-1)/2
+	}
+
+	return nil
+}
+
+func (v *VLA) unmarshalTemporalLayers(ctx *vlaUnmarshalingContext) error {
+	if !ctx.checkRemainingLen(1) {
+		return fmt.Errorf("failed to unmarshal VLA (offset=%d): %w", ctx.offset, ErrVLATooShort)
+	}
+
+	var temporalLayerIndex int
+	for streamID := 0; streamID < v.RTPStreamCount; streamID++ {
+		for spatialID := 0; spatialID < 4; spatialID++ {
+			if ctx.slBMs[streamID]&(1<<spatialID) == 0 {
+				continue
+			}
+			if temporalLayerIndex >= 4 {
+				temporalLayerIndex = 0
+				ctx.offset++
+				if !ctx.checkRemainingLen(1) {
+					return fmt.Errorf("failed to unmarshal VLA (offset=%d): %w", ctx.offset, ErrVLATooShort)
+				}
+			}
+			tlCount := int(ctx.payload[ctx.offset]>>(2*(3-temporalLayerIndex))&0b11) + 1
+			temporalLayerIndex++
+			sl := SpatialLayer{
+				RTPStreamID:    streamID,
+				SpatialID:      spatialID,
+				TargetBitrates: make([]int, tlCount),
+			}
+			v.ActiveSpatialLayer = append(v.ActiveSpatialLayer, sl)
+		}
+	}
+	ctx.offset++
+
+	// target bitrates
+	for i, sl := range v.ActiveSpatialLayer {
+		for j := range sl.TargetBitrates {
+			kbps, n, err := obu.ReadLeb128(ctx.payload[ctx.offset:])
+			if err != nil {
+				return err
+			}
+			if !ctx.checkRemainingLen(int(n)) {
+				return fmt.Errorf("failed to unmarshal VLA (offset=%d): %w", ctx.offset, ErrVLATooShort)
+			}
+			v.ActiveSpatialLayer[i].TargetBitrates[j] = int(kbps)
+			ctx.offset += int(n)
+		}
+	}
+
+	return nil
+}
+
+func (v *VLA) unmarshalResolutionAndFramerate(ctx *vlaUnmarshalingContext) error {
+	if !ctx.checkRemainingLen(len(v.ActiveSpatialLayer) * 5) {
+		return fmt.Errorf("failed to unmarshal VLA (offset=%d): %w", ctx.offset, ErrVLATooShort)
+	}
+
+	v.HasResolutionAndFramerate = true
+
+	for i := range v.ActiveSpatialLayer {
+		v.ActiveSpatialLayer[i].Width = int(binary.BigEndian.Uint16(ctx.payload[ctx.offset+0:])) + 1
+		v.ActiveSpatialLayer[i].Height = int(binary.BigEndian.Uint16(ctx.payload[ctx.offset+2:])) + 1
+		v.ActiveSpatialLayer[i].Framerate = int(ctx.payload[ctx.offset+4])
+		ctx.offset += 5
+	}
+
+	return nil
+}
+
+// Unmarshal decodes VLA from a byte slice.
+func (v *VLA) Unmarshal(payload []byte) (int, error) {
+	ctx := &vlaUnmarshalingContext{
+		payload: payload,
+	}
+
+	err := v.unmarshalSpatialLayers(ctx)
+	if err != nil {
+		return ctx.offset, err
+	}
+
+	// #tl fields (build the list ActiveSpatialLayer at the same time)
+	err = v.unmarshalTemporalLayers(ctx)
+	if err != nil {
+		return ctx.offset, err
+	}
+
+	if len(ctx.payload) == ctx.offset {
+		return ctx.offset, nil
+	}
+
+	// resolution & framerate (optional)
+	err = v.unmarshalResolutionAndFramerate(ctx)
+	if err != nil {
+		return ctx.offset, err
+	}
+
+	return ctx.offset, nil
+}
+
+// String makes VLA printable.
+func (v VLA) String() string {
+	out := fmt.Sprintf("RID:%d,RTPStreamCount:%d", v.RTPStreamID, v.RTPStreamCount)
+	var slOut []string
+	for _, sl := range v.ActiveSpatialLayer {
+		out2 := fmt.Sprintf("RTPStreamID:%d", sl.RTPStreamID)
+		out2 += fmt.Sprintf(",TargetBitrates:%v", sl.TargetBitrates)
+		if v.HasResolutionAndFramerate {
+			out2 += fmt.Sprintf(",Resolution:(%d,%d)", sl.Width, sl.Height)
+			out2 += fmt.Sprintf(",Framerate:%d", sl.Framerate)
+		}
+		slOut = append(slOut, out2)
+	}
+	out += fmt.Sprintf(",ActiveSpatialLayers:{%s}", strings.Join(slOut, ","))
+	return out
+}
diff --git a/vendor/github.com/pion/sctp/.golangci.yml b/vendor/github.com/pion/sctp/.golangci.yml
index 4e3eddf4..e06de4d3 100644
--- a/vendor/github.com/pion/sctp/.golangci.yml
+++ b/vendor/github.com/pion/sctp/.golangci.yml
@@ -3,7 +3,8 @@
 
 linters-settings:
   govet:
-    check-shadowing: true
+    enable:
+      - shadow
   misspell:
     locale: US
   exhaustive:
@@ -29,7 +30,6 @@ linters:
     - bodyclose        # checks whether HTTP response body is closed successfully
     - contextcheck     # check the function whether use a non-inherited context
     - decorder         # check declaration order and count of types, constants, variables and functions
-    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - dogsled          # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
     - dupl             # Tool for code clone detection
     - durationcheck    # check for two durations multiplied together
@@ -63,7 +63,6 @@ linters:
     - importas         # Enforces consistent import aliases
     - ineffassign      # Detects when assignments to existing variables are not used
     - misspell         # Finds commonly misspelled English words in comments
-    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nilerr           # Finds the code that returns nil even if it checks that the error is not nil.
     - nilnil           # Checks that there is no simultaneous return of `nil` error and an invalid value.
     - noctx            # noctx finds sending http request without context.Context
@@ -81,6 +80,7 @@ linters:
     - wastedassign     # wastedassign finds wasted assignment statements
     - whitespace       # Tool for detection of leading and trailing whitespace
   disable:
+    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - containedctx     # containedctx is a linter that detects struct contained context.Context field
     - cyclop           # checks function and package cyclomatic complexity
     - exhaustivestruct # Checks if all struct's fields are initialized
@@ -94,6 +94,7 @@ linters:
     - maintidx         # maintidx measures the maintainability index of each function.
     - makezero         # Finds slice declarations with non-zero initial length
     - maligned         # Tool to detect Go structs that would take less memory if their fields were sorted
+    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nestif           # Reports deeply nested if statements
     - nlreturn         # nlreturn checks for a new line before return and branch statements to increase code clarity
     - nolintlint       # Reports ill-formed or insufficient nolint directives
@@ -110,28 +111,15 @@ linters:
 
 issues:
   exclude-use-default: false
+  exclude-dirs-use-default: false
   exclude-rules:
-    # Allow complex tests, better to be self contained
-    - path: _test\.go
+    # Allow complex tests and examples, better to be self contained
+    - path: (examples|main\.go|_test\.go)
       linters:
-        - gocognit
         - forbidigo
-
-    # Allow complex main function in examples
-    - path: examples
-      text: "of func `main` is high"
-      linters:
         - gocognit
-    
-    # Allow forbidden identifiers in examples
-    - path: examples
-      linters:
-        - forbidigo
 
     # Allow forbidden identifiers in CLI commands
     - path: cmd
       linters:
         - forbidigo
-
-run:
-  skip-dirs-use-default: false
diff --git a/vendor/github.com/pion/sctp/AUTHORS.txt b/vendor/github.com/pion/sctp/AUTHORS.txt
deleted file mode 100644
index ae88cf02..00000000
--- a/vendor/github.com/pion/sctp/AUTHORS.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-# Thank you to everyone that made Pion possible. If you are interested in contributing
-# we would love to have you https://github.com/pion/webrtc/wiki/Contributing
-#
-# This file is auto generated, using git to list all individuals contributors.
-# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting
-Aaron France <aaron.l.france@gmail.com>
-Adrian Cable <adrian.cable@gmail.com>
-Atsushi Watanabe <atsushi.w@ieee.org>
-backkem <mail@backkem.me>
-Cecylia Bocovich <cohosh@torproject.org>
-chenkaiC4 <chenkaic4@gmail.com>
-Eric Daniels <eric@erdaniels.com>
-Hugo Arregui <hugo.arregui@gmail.com>
-Hugo Arregui <hugo@decentraland.org>
-Jerko Steiner <jerko.steiner@gmail.com>
-Jerry Tao <taojay315@gmail.com>
-John Bradley <jrb@turrettech.com>
-Juliusz Chroboczek <jch@irif.fr>
-Konstantin Itskov <konstantin.itskov@kovits.com>
-Lukas Herman <lherman.cs@gmail.com>
-Luke Curley <lcurley@twitch.tv>
-Michael MacDonald <github@macdonald.cx>
-ronan <ronan.jezequel@gmail.com>
-Sam Lancia <sam@vaion.com>
-Sean DuBois <seaduboi@amazon.com>
-Sean DuBois <sean@siobud.com>
-Steffen <post@steffenvogel.de>
-Steffen Vogel <post@steffenvogel.de>
-Teddy <richardgeorgeoff@gmail.com>
-Will Forcey <wsforc3y@gmail.com>
-Yutaka Takeda <yt0916@gmail.com>
-ZHENK <chengzhenyang@gmail.com>
-
-# List of contributors not appearing in Git history
-
diff --git a/vendor/github.com/pion/sctp/README.md b/vendor/github.com/pion/sctp/README.md
index 3ca23445..a407c46a 100644
--- a/vendor/github.com/pion/sctp/README.md
+++ b/vendor/github.com/pion/sctp/README.md
@@ -28,7 +28,7 @@ We are always looking to support **your projects**. Please reach out if you have
 If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly)
 
 ### Contributing
-Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt)
+Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible
 
 ### License
 MIT License - see [LICENSE](LICENSE) for full text
diff --git a/vendor/github.com/pion/sctp/ack_timer.go b/vendor/github.com/pion/sctp/ack_timer.go
index 3d9b43e0..b6008d18 100644
--- a/vendor/github.com/pion/sctp/ack_timer.go
+++ b/vendor/github.com/pion/sctp/ack_timer.go
@@ -4,6 +4,7 @@
 package sctp
 
 import (
+	"math"
 	"sync"
 	"time"
 )
@@ -17,23 +18,38 @@ type ackTimerObserver interface {
 	onAckTimeout()
 }
 
+type ackTimerState uint8
+
+const (
+	ackTimerStopped ackTimerState = iota
+	ackTimerStarted
+	ackTimerClosed
+)
+
 // ackTimer provides the retnransmission timer conforms with RFC 4960 Sec 6.3.1
 type ackTimer struct {
+	timer    *time.Timer
 	observer ackTimerObserver
-	interval time.Duration
-	stopFunc stopAckTimerLoop
-	closed   bool
-	mutex    sync.RWMutex
+	mutex    sync.Mutex
+	state    ackTimerState
+	pending  uint8
 }
 
-type stopAckTimerLoop func()
-
 // newAckTimer creates a new acknowledgement timer used to enable delayed ack.
 func newAckTimer(observer ackTimerObserver) *ackTimer {
-	return &ackTimer{
-		observer: observer,
-		interval: ackInterval,
+	t := &ackTimer{observer: observer}
+	t.timer = time.AfterFunc(math.MaxInt64, t.timeout)
+	t.timer.Stop()
+	return t
+}
+
+func (t *ackTimer) timeout() {
+	t.mutex.Lock()
+	if t.pending--; t.pending == 0 && t.state == ackTimerStarted {
+		t.state = ackTimerStopped
+		defer t.observer.onAckTimeout()
 	}
+	t.mutex.Unlock()
 }
 
 // start starts the timer.
@@ -41,34 +57,14 @@ func (t *ackTimer) start() bool {
 	t.mutex.Lock()
 	defer t.mutex.Unlock()
 
-	// this timer is already closed
-	if t.closed {
-		return false
-	}
-
-	// this is a noop if the timer is already running
-	if t.stopFunc != nil {
+	// this timer is already closed or already running
+	if t.state != ackTimerStopped {
 		return false
 	}
 
-	cancelCh := make(chan struct{})
-
-	go func() {
-		timer := time.NewTimer(t.interval)
-
-		select {
-		case <-timer.C:
-			t.stop()
-			t.observer.onAckTimeout()
-		case <-cancelCh:
-			timer.Stop()
-		}
-	}()
-
-	t.stopFunc = func() {
-		close(cancelCh)
-	}
-
+	t.state = ackTimerStarted
+	t.pending++
+	t.timer.Reset(ackInterval)
 	return true
 }
 
@@ -78,9 +74,11 @@ func (t *ackTimer) stop() {
 	t.mutex.Lock()
 	defer t.mutex.Unlock()
 
-	if t.stopFunc != nil {
-		t.stopFunc()
-		t.stopFunc = nil
+	if t.state == ackTimerStarted {
+		if t.timer.Stop() {
+			t.pending--
+		}
+		t.state = ackTimerStopped
 	}
 }
 
@@ -90,19 +88,17 @@ func (t *ackTimer) close() {
 	t.mutex.Lock()
 	defer t.mutex.Unlock()
 
-	if t.stopFunc != nil {
-		t.stopFunc()
-		t.stopFunc = nil
+	if t.state == ackTimerStarted && t.timer.Stop() {
+		t.pending--
 	}
-
-	t.closed = true
+	t.state = ackTimerClosed
 }
 
 // isRunning tests if the timer is running.
 // Debug purpose only
 func (t *ackTimer) isRunning() bool {
-	t.mutex.RLock()
-	defer t.mutex.RUnlock()
+	t.mutex.Lock()
+	defer t.mutex.Unlock()
 
-	return (t.stopFunc != nil)
+	return t.state == ackTimerStarted
 }
diff --git a/vendor/github.com/pion/sctp/association.go b/vendor/github.com/pion/sctp/association.go
index ce3725ec..2198fc6f 100644
--- a/vendor/github.com/pion/sctp/association.go
+++ b/vendor/github.com/pion/sctp/association.go
@@ -19,6 +19,12 @@ import (
 	"github.com/pion/randutil"
 )
 
+// Port 5000 shows up in examples for SDPs used by WebRTC. Since this implementation
+// assumes it will be used by DTLS over UDP, the port is only meaningful for de-multiplexing
+// but more-so verification.
+// Example usage: https://www.rfc-editor.org/rfc/rfc8841.html#section-13.1-2
+const defaultSCTPSrcDstPort = 5000
+
 // Use global random generator to properly seed by crypto grade random.
 var globalMathRandomGenerator = randutil.NewMathRandomGenerator() // nolint:gochecknoglobals
 
@@ -44,6 +50,7 @@ var (
 	ErrChunkTypeUnhandled            = errors.New("unhandled chunk type")
 	ErrHandshakeInitAck              = errors.New("handshake failed (INIT ACK)")
 	ErrHandshakeCookieEcho           = errors.New("handshake failed (COOKIE ECHO)")
+	ErrTooManyReconfigRequests       = errors.New("too many outstanding reconfig requests")
 )
 
 const (
@@ -93,6 +100,19 @@ const (
 // other constants
 const (
 	acceptChSize = 16
+	// avgChunkSize is an estimate of the average chunk size. There is no theory behind
+	// this estimate.
+	avgChunkSize = 500
+	// minTSNOffset is the minimum offset over the cummulative TSN that we will enqueue
+	// irrespective of the receive buffer size
+	// see getMaxTSNOffset
+	minTSNOffset = 2000
+	// maxTSNOffset is the maximum offset over the cummulative TSN that we will enqueue
+	// irrespective of the receive buffer size
+	// see getMaxTSNOffset
+	maxTSNOffset = 40000
+	// maxReconfigRequests is the maximum number of reconfig requests we will keep outstanding
+	maxReconfigRequests = 1000
 )
 
 func getAssociationStateString(a uint32) string {
@@ -131,6 +151,8 @@ func getAssociationStateString(a uint32) string {
 //
 // Note: No "CLOSED" state is illustrated since if a
 // association is "CLOSED" its TCB SHOULD be removed.
+// Note: By nature of an Association being constructed with one net.Conn,
+// it is not a multi-home supporting implementation of SCTP.
 type Association struct {
 	bytesReceived uint64
 	bytesSent     uint64
@@ -142,8 +164,8 @@ type Association struct {
 	peerVerificationTag    uint32
 	myVerificationTag      uint32
 	state                  uint32
+	initialTSN             uint32
 	myNextTSN              uint32 // nextTSN
-	peerLastTSN            uint32 // lastRcvdTSN
 	minTSN2MeasureRTT      uint32 // for RTT measurement
 	willSendForwardTSN     bool
 	willRetransmitFast     bool
@@ -167,7 +189,7 @@ type Association struct {
 	myMaxNumInboundStreams  uint16
 	myMaxNumOutboundStreams uint16
 	myCookie                *paramStateCookie
-	payloadQueue            *payloadQueue
+	payloadQueue            *receivePayloadQueue
 	inflightQueue           *payloadQueue
 	pendingQueue            *pendingQueue
 	controlQueue            *controlQueue
@@ -177,6 +199,8 @@ type Association struct {
 	cumulativeTSNAckPoint   uint32
 	advancedPeerTSNAckPoint uint32
 	useForwardTSN           bool
+	sendZeroChecksum        bool
+	recvZeroChecksum        bool
 
 	// Congestion control parameters
 	maxReceiveBufferSize uint32
@@ -230,10 +254,14 @@ type Association struct {
 // Config collects the arguments to createAssociation construction into
 // a single structure
 type Config struct {
+	Name                 string
 	NetConn              net.Conn
 	MaxReceiveBufferSize uint32
 	MaxMessageSize       uint32
+	EnableZeroChecksum   bool
 	LoggerFactory        logging.LoggerFactory
+	// RTOMax is the maximum retransmission timeout in milliseconds
+	RTOMax float64
 }
 
 // Server accepts a SCTP stream over a conn
@@ -254,10 +282,18 @@ func Server(config Config) (*Association, error) {
 
 // Client opens a SCTP stream over a conn
 func Client(config Config) (*Association, error) {
+	return createClientWithContext(context.Background(), config)
+}
+
+func createClientWithContext(ctx context.Context, config Config) (*Association, error) {
 	a := createAssociation(config)
 	a.init(true)
 
 	select {
+	case <-ctx.Done():
+		a.log.Errorf("[%s] client handshake canceled: state=%s", a.name, getAssociationStateString(a.getState()))
+		a.Close() // nolint:errcheck,gosec
+		return nil, ctx.Err()
 	case err := <-a.handshakeCompletedCh:
 		if err != nil {
 			return nil, err
@@ -285,23 +321,30 @@ func createAssociation(config Config) *Association {
 
 	tsn := globalMathRandomGenerator.Uint32()
 	a := &Association{
-		netConn:                 config.NetConn,
-		maxReceiveBufferSize:    maxReceiveBufferSize,
-		maxMessageSize:          maxMessageSize,
+		netConn:              config.NetConn,
+		maxReceiveBufferSize: maxReceiveBufferSize,
+		maxMessageSize:       maxMessageSize,
+
+		// These two max values have us not need to follow
+		// 5.1.1 where this peer may be incapable of supporting
+		// the requested amount of outbound streams from the other
+		// peer.
 		myMaxNumOutboundStreams: math.MaxUint16,
 		myMaxNumInboundStreams:  math.MaxUint16,
-		payloadQueue:            newPayloadQueue(),
+
+		payloadQueue:            newReceivePayloadQueue(getMaxTSNOffset(maxReceiveBufferSize)),
 		inflightQueue:           newPayloadQueue(),
 		pendingQueue:            newPendingQueue(),
 		controlQueue:            newControlQueue(),
 		mtu:                     initialMTU,
 		maxPayloadSize:          initialMTU - (commonHeaderSize + dataChunkHeaderSize),
 		myVerificationTag:       globalMathRandomGenerator.Uint32(),
+		initialTSN:              tsn,
 		myNextTSN:               tsn,
 		myNextRSN:               tsn,
 		minTSN2MeasureRTT:       tsn,
 		state:                   closed,
-		rtoMgr:                  newRTOManager(),
+		rtoMgr:                  newRTOManager(config.RTOMax),
 		streams:                 map[uint16]*Stream{},
 		reconfigs:               map[uint32]*chunkReconfig{},
 		reconfigRequests:        map[uint32]*paramOutgoingResetRequest{},
@@ -312,12 +355,16 @@ func createAssociation(config Config) *Association {
 		handshakeCompletedCh:    make(chan error),
 		cumulativeTSNAckPoint:   tsn - 1,
 		advancedPeerTSNAckPoint: tsn - 1,
+		recvZeroChecksum:        config.EnableZeroChecksum,
 		silentError:             ErrSilentlyDiscard,
 		stats:                   &associationStats{},
 		log:                     config.LoggerFactory.NewLogger("sctp"),
+		name:                    config.Name,
 	}
 
-	a.name = fmt.Sprintf("%p", a)
+	if a.name == "" {
+		a.name = fmt.Sprintf("%p", a)
+	}
 
 	// RFC 4690 Sec 7.2.1
 	//  o  The initial cwnd before DATA transmission or after a sufficiently
@@ -328,11 +375,11 @@ func createAssociation(config Config) *Association {
 		a.name, a.CWND(), a.ssthresh, a.inflightQueue.getNumBytes())
 
 	a.srtt.Store(float64(0))
-	a.t1Init = newRTXTimer(timerT1Init, a, maxInitRetrans)
-	a.t1Cookie = newRTXTimer(timerT1Cookie, a, maxInitRetrans)
-	a.t2Shutdown = newRTXTimer(timerT2Shutdown, a, noMaxRetrans) // retransmit forever
-	a.t3RTX = newRTXTimer(timerT3RTX, a, noMaxRetrans)           // retransmit forever
-	a.tReconfig = newRTXTimer(timerReconfig, a, noMaxRetrans)    // retransmit forever
+	a.t1Init = newRTXTimer(timerT1Init, a, maxInitRetrans, config.RTOMax)
+	a.t1Cookie = newRTXTimer(timerT1Cookie, a, maxInitRetrans, config.RTOMax)
+	a.t2Shutdown = newRTXTimer(timerT2Shutdown, a, noMaxRetrans, config.RTOMax)
+	a.t3RTX = newRTXTimer(timerT3RTX, a, noMaxRetrans, config.RTOMax)
+	a.tReconfig = newRTXTimer(timerReconfig, a, noMaxRetrans, config.RTOMax)
 	a.ackTimer = newAckTimer(a)
 
 	return a
@@ -346,7 +393,6 @@ func (a *Association) init(isClient bool) {
 	go a.writeLoop()
 
 	if isClient {
-		a.setState(cookieWait)
 		init := &chunkInit{}
 		init.initialTSN = a.myNextTSN
 		init.numOutboundStreams = a.myMaxNumOutboundStreams
@@ -354,6 +400,11 @@ func (a *Association) init(isClient bool) {
 		init.initiateTag = a.myVerificationTag
 		init.advertisedReceiverWindowCredit = a.maxReceiveBufferSize
 		setSupportedExtensions(&init.chunkInitCommon)
+
+		if a.recvZeroChecksum {
+			init.params = append(init.params, &paramZeroChecksumAcceptable{edmid: dtlsErrorDetectionMethod})
+		}
+
 		a.storedInit = init
 
 		err := a.sendInit()
@@ -361,6 +412,11 @@ func (a *Association) init(isClient bool) {
 			a.log.Errorf("[%s] failed to send init: %s", a.name, err.Error())
 		}
 
+		// After sending the INIT chunk, "A" starts the T1-init timer and enters the COOKIE-WAIT state.
+		// Note: ideally we would set state after the timer starts but since we don't do this in an atomic
+		// set + timer-start, it's safer to just set the state first so that we don't have a timer expiration
+		// race.
+		a.setState(cookieWait)
 		a.t1Init.start(a.rtoMgr.getRTO())
 	}
 }
@@ -374,8 +430,8 @@ func (a *Association) sendInit() error {
 
 	outbound := &packet{}
 	outbound.verificationTag = a.peerVerificationTag
-	a.sourcePort = 5000      // Spec??
-	a.destinationPort = 5000 // Spec??
+	a.sourcePort = defaultSCTPSrcDstPort
+	a.destinationPort = defaultSCTPSrcDstPort
 	outbound.sourcePort = a.sourcePort
 	outbound.destinationPort = a.destinationPort
 
@@ -451,8 +507,11 @@ func (a *Association) Close() error {
 	<-a.readLoopCloseCh
 
 	a.log.Debugf("[%s] association closed", a.name)
+	a.log.Debugf("[%s] stats nPackets (in) : %d", a.name, a.stats.getNumPacketsReceived())
+	a.log.Debugf("[%s] stats nPackets (out) : %d", a.name, a.stats.getNumPacketsSent())
 	a.log.Debugf("[%s] stats nDATAs (in) : %d", a.name, a.stats.getNumDATAs())
-	a.log.Debugf("[%s] stats nSACKs (in) : %d", a.name, a.stats.getNumSACKs())
+	a.log.Debugf("[%s] stats nSACKs (in) : %d", a.name, a.stats.getNumSACKsReceived())
+	a.log.Debugf("[%s] stats nSACKs (out) : %d\n", a.name, a.stats.getNumSACKsSent())
 	a.log.Debugf("[%s] stats nT3Timeouts : %d", a.name, a.stats.getNumT3Timeouts())
 	a.log.Debugf("[%s] stats nAckTimeouts: %d", a.name, a.stats.getNumAckTimeouts())
 	a.log.Debugf("[%s] stats nFastRetrans: %d", a.name, a.stats.getNumFastRetrans())
@@ -522,7 +581,7 @@ func (a *Association) readLoop() {
 
 		a.log.Debugf("[%s] association closed", a.name)
 		a.log.Debugf("[%s] stats nDATAs (in) : %d", a.name, a.stats.getNumDATAs())
-		a.log.Debugf("[%s] stats nSACKs (in) : %d", a.name, a.stats.getNumSACKs())
+		a.log.Debugf("[%s] stats nSACKs (in) : %d", a.name, a.stats.getNumSACKsReceived())
 		a.log.Debugf("[%s] stats nT3Timeouts : %d", a.name, a.stats.getNumT3Timeouts())
 		a.log.Debugf("[%s] stats nAckTimeouts: %d", a.name, a.stats.getNumAckTimeouts())
 		a.log.Debugf("[%s] stats nFastRetrans: %d", a.name, a.stats.getNumFastRetrans())
@@ -571,6 +630,7 @@ loop:
 				break loop
 			}
 			atomic.AddUint64(&a.bytesSent, uint64(len(raw)))
+			a.stats.incPacketsSent()
 		}
 
 		if !ok {
@@ -610,10 +670,32 @@ func (a *Association) unregisterStream(s *Stream, err error) {
 	s.readNotifier.Broadcast()
 }
 
+func chunkMandatoryChecksum(cc []chunk) bool {
+	for _, c := range cc {
+		switch c.(type) {
+		case *chunkInit, *chunkCookieEcho:
+			return true
+		}
+	}
+	return false
+}
+
+func (a *Association) marshalPacket(p *packet) ([]byte, error) {
+	return p.marshal(!a.sendZeroChecksum || chunkMandatoryChecksum(p.chunks))
+}
+
+func (a *Association) unmarshalPacket(raw []byte) (*packet, error) {
+	p := &packet{}
+	if err := p.unmarshal(!a.recvZeroChecksum, raw); err != nil {
+		return nil, err
+	}
+	return p, nil
+}
+
 // handleInbound parses incoming raw packets
 func (a *Association) handleInbound(raw []byte) error {
-	p := &packet{}
-	if err := p.unmarshal(raw); err != nil {
+	p, err := a.unmarshalPacket(raw)
+	if err != nil {
 		a.log.Warnf("[%s] unable to parse SCTP packet %s", a.name, err)
 		return nil
 	}
@@ -623,7 +705,7 @@ func (a *Association) handleInbound(raw []byte) error {
 		return nil
 	}
 
-	a.handleChunkStart()
+	a.handleChunksStart()
 
 	for _, c := range p.chunks {
 		if err := a.handleChunk(p, c); err != nil {
@@ -631,7 +713,7 @@ func (a *Association) handleInbound(raw []byte) error {
 		}
 	}
 
-	a.handleChunkEnd()
+	a.handleChunksEnd()
 
 	return nil
 }
@@ -639,7 +721,7 @@ func (a *Association) handleInbound(raw []byte) error {
 // The caller should hold the lock
 func (a *Association) gatherDataPacketsToRetransmit(rawPackets [][]byte) [][]byte {
 	for _, p := range a.getDataPacketsToRetransmit() {
-		raw, err := p.marshal()
+		raw, err := a.marshalPacket(p)
 		if err != nil {
 			a.log.Warnf("[%s] failed to serialize a DATA packet to be retransmitted", a.name)
 			continue
@@ -660,7 +742,7 @@ func (a *Association) gatherOutboundDataAndReconfigPackets(rawPackets [][]byte)
 		a.log.Tracef("[%s] T3-rtx timer start (pt1)", a.name)
 		a.t3RTX.start(a.rtoMgr.getRTO())
 		for _, p := range a.bundleDataChunksIntoPackets(chunks) {
-			raw, err := p.marshal()
+			raw, err := a.marshalPacket(p)
 			if err != nil {
 				a.log.Warnf("[%s] failed to serialize a DATA packet", a.name)
 				continue
@@ -675,7 +757,7 @@ func (a *Association) gatherOutboundDataAndReconfigPackets(rawPackets [][]byte)
 			a.log.Debugf("[%s] retransmit %d RECONFIG chunk(s)", a.name, len(a.reconfigs))
 			for _, c := range a.reconfigs {
 				p := a.createPacket([]chunk{c})
-				raw, err := p.marshal()
+				raw, err := a.marshalPacket(p)
 				if err != nil {
 					a.log.Warnf("[%s] failed to serialize a RECONFIG packet to be retransmitted", a.name)
 				} else {
@@ -698,7 +780,7 @@ func (a *Association) gatherOutboundDataAndReconfigPackets(rawPackets [][]byte)
 			a.log.Debugf("[%s] sending RECONFIG: rsn=%d tsn=%d streams=%v",
 				a.name, rsn, a.myNextTSN-1, sisToReset)
 			p := a.createPacket([]chunk{c})
-			raw, err := p.marshal()
+			raw, err := a.marshalPacket(p)
 			if err != nil {
 				a.log.Warnf("[%s] failed to serialize a RECONFIG packet to be transmitted", a.name)
 			} else {
@@ -761,7 +843,7 @@ func (a *Association) gatherOutboundFastRetransmissionPackets(rawPackets [][]byt
 		}
 
 		if len(toFastRetrans) > 0 {
-			raw, err := a.createPacket(toFastRetrans).marshal()
+			raw, err := a.marshalPacket(a.createPacket(toFastRetrans))
 			if err != nil {
 				a.log.Warnf("[%s] failed to serialize a DATA packet to be fast-retransmitted", a.name)
 			} else {
@@ -778,8 +860,9 @@ func (a *Association) gatherOutboundSackPackets(rawPackets [][]byte) [][]byte {
 	if a.ackState == ackStateImmediate {
 		a.ackState = ackStateIdle
 		sack := a.createSelectiveAckChunk()
+		a.stats.incSACKsSent()
 		a.log.Debugf("[%s] sending SACK: %s", a.name, sack)
-		raw, err := a.createPacket([]chunk{sack}).marshal()
+		raw, err := a.marshalPacket(a.createPacket([]chunk{sack}))
 		if err != nil {
 			a.log.Warnf("[%s] failed to serialize a SACK packet", a.name)
 		} else {
@@ -796,7 +879,7 @@ func (a *Association) gatherOutboundForwardTSNPackets(rawPackets [][]byte) [][]b
 		a.willSendForwardTSN = false
 		if sna32GT(a.advancedPeerTSNAckPoint, a.cumulativeTSNAckPoint) {
 			fwdtsn := a.createForwardTSN()
-			raw, err := a.createPacket([]chunk{fwdtsn}).marshal()
+			raw, err := a.marshalPacket(a.createPacket([]chunk{fwdtsn}))
 			if err != nil {
 				a.log.Warnf("[%s] failed to serialize a Forward TSN packet", a.name)
 			} else {
@@ -819,7 +902,7 @@ func (a *Association) gatherOutboundShutdownPackets(rawPackets [][]byte) ([][]by
 			cumulativeTSNAck: a.cumulativeTSNAckPoint,
 		}
 
-		raw, err := a.createPacket([]chunk{shutdown}).marshal()
+		raw, err := a.marshalPacket(a.createPacket([]chunk{shutdown}))
 		if err != nil {
 			a.log.Warnf("[%s] failed to serialize a Shutdown packet", a.name)
 		} else {
@@ -831,7 +914,7 @@ func (a *Association) gatherOutboundShutdownPackets(rawPackets [][]byte) ([][]by
 
 		shutdownAck := &chunkShutdownAck{}
 
-		raw, err := a.createPacket([]chunk{shutdownAck}).marshal()
+		raw, err := a.marshalPacket(a.createPacket([]chunk{shutdownAck}))
 		if err != nil {
 			a.log.Warnf("[%s] failed to serialize a ShutdownAck packet", a.name)
 		} else {
@@ -843,7 +926,7 @@ func (a *Association) gatherOutboundShutdownPackets(rawPackets [][]byte) ([][]by
 
 		shutdownComplete := &chunkShutdownComplete{}
 
-		raw, err := a.createPacket([]chunk{shutdownComplete}).marshal()
+		raw, err := a.marshalPacket(a.createPacket([]chunk{shutdownComplete}))
 		if err != nil {
 			a.log.Warnf("[%s] failed to serialize a ShutdownComplete packet", a.name)
 		} else {
@@ -867,7 +950,7 @@ func (a *Association) gatherAbortPacket() ([]byte, error) {
 		abort.errorCauses = []errorCause{cause}
 	}
 
-	raw, err := a.createPacket([]chunk{abort}).marshal()
+	raw, err := a.marshalPacket(a.createPacket([]chunk{abort}))
 
 	return raw, err
 }
@@ -892,7 +975,7 @@ func (a *Association) gatherOutbound() ([][]byte, bool) {
 
 	if a.controlQueue.size() > 0 {
 		for _, p := range a.controlQueue.popAll() {
-			raw, err := p.marshal()
+			raw, err := a.marshalPacket(p)
 			if err != nil {
 				a.log.Warnf("[%s] failed to serialize a control packet", a.name)
 				continue
@@ -987,6 +1070,11 @@ func min32(a, b uint32) uint32 {
 	return b
 }
 
+// peerLastTSN return last received cumulative TSN
+func (a *Association) peerLastTSN() uint32 {
+	return a.payloadQueue.getcumulativeTSN()
+}
+
 // setState atomically sets the state of the Association.
 // The caller should hold the lock.
 func (a *Association) setState(newState uint32) {
@@ -1042,6 +1130,21 @@ func (a *Association) SRTT() float64 {
 	return a.srtt.Load().(float64) //nolint:forcetypeassert
 }
 
+// getMaxTSNOffset returns the maximum offset over the current cummulative TSN that
+// we are willing to enqueue. This ensures that we keep the bytes utilized in the receive
+// buffer within a small multiple of the user provided max receive buffer size.
+func getMaxTSNOffset(maxReceiveBufferSize uint32) uint32 {
+	// 4 is a magic number here. There is no theory behind this.
+	offset := (maxReceiveBufferSize * 4) / avgChunkSize
+	if offset < minTSNOffset {
+		offset = minTSNOffset
+	}
+	if offset > maxTSNOffset {
+		offset = maxTSNOffset
+	}
+	return offset
+}
+
 func setSupportedExtensions(init *chunkInitCommon) {
 	// nolint:godox
 	// TODO RFC5061 https://tools.ietf.org/html/rfc6525#section-5.2
@@ -1071,7 +1174,10 @@ func (a *Association) handleInit(p *packet, i *chunkInit) ([]*packet, error) {
 		return nil, fmt.Errorf("%w: %s", ErrHandleInitState, getAssociationStateString(state))
 	}
 
-	// Should we be setting any of these permanently until we've ACKed further?
+	// NOTE: Setting these prior to a reception of a COOKIE ECHO chunk containing
+	// our cookie is not compliant with https://www.rfc-editor.org/rfc/rfc9260#section-5.1-2.2.3.
+	// It makes us more vulnerable to resource attacks, albeit minimally so.
+	//  https://www.rfc-editor.org/rfc/rfc9260#sec_handle_stream_parameters
 	a.myMaxNumInboundStreams = min16(i.numInboundStreams, a.myMaxNumInboundStreams)
 	a.myMaxNumOutboundStreams = min16(i.numOutboundStreams, a.myMaxNumOutboundStreams)
 	a.peerVerificationTag = i.initiateTag
@@ -1082,7 +1188,7 @@ func (a *Association) handleInit(p *packet, i *chunkInit) ([]*packet, error) {
 	// is set initially by taking the peer's initial TSN,
 	// received in the INIT or INIT ACK chunk, and
 	// subtracting one from it.
-	a.peerLastTSN = i.initialTSN - 1
+	a.payloadQueue.init(i.initialTSN - 1)
 
 	for _, param := range i.params {
 		switch v := param.(type) { // nolint:gocritic
@@ -1093,8 +1199,11 @@ func (a *Association) handleInit(p *packet, i *chunkInit) ([]*packet, error) {
 					a.useForwardTSN = true
 				}
 			}
+		case *paramZeroChecksumAcceptable:
+			a.sendZeroChecksum = v.edmid == dtlsErrorDetectionMethod
 		}
 	}
+
 	if !a.useForwardTSN {
 		a.log.Warnf("[%s] not using ForwardTSN (on init)", a.name)
 	}
@@ -1105,6 +1214,7 @@ func (a *Association) handleInit(p *packet, i *chunkInit) ([]*packet, error) {
 	outbound.destinationPort = a.destinationPort
 
 	initAck := &chunkInitAck{}
+	a.log.Debug("sending INIT ACK")
 
 	initAck.initialTSN = a.myNextTSN
 	initAck.numOutboundStreams = a.myMaxNumOutboundStreams
@@ -1114,6 +1224,8 @@ func (a *Association) handleInit(p *packet, i *chunkInit) ([]*packet, error) {
 
 	if a.myCookie == nil {
 		var err error
+		// NOTE: This generation process is not compliant with
+		// 5.1.3.  Generating State Cookie (https://www.rfc-editor.org/rfc/rfc4960#section-5.1.3)
 		if a.myCookie, err = newRandomStateCookie(); err != nil {
 			return nil, err
 		}
@@ -1121,6 +1233,11 @@ func (a *Association) handleInit(p *packet, i *chunkInit) ([]*packet, error) {
 
 	initAck.params = []param{a.myCookie}
 
+	if a.recvZeroChecksum {
+		initAck.params = append(initAck.params, &paramZeroChecksumAcceptable{edmid: dtlsErrorDetectionMethod})
+	}
+	a.log.Debugf("[%s] sendZeroChecksum=%t (on init)", a.name, a.sendZeroChecksum)
+
 	setSupportedExtensions(&initAck.chunkInitCommon)
 
 	outbound.chunks = []chunk{initAck}
@@ -1145,7 +1262,7 @@ func (a *Association) handleInitAck(p *packet, i *chunkInitAck) error {
 	a.myMaxNumInboundStreams = min16(i.numInboundStreams, a.myMaxNumInboundStreams)
 	a.myMaxNumOutboundStreams = min16(i.numOutboundStreams, a.myMaxNumOutboundStreams)
 	a.peerVerificationTag = i.initiateTag
-	a.peerLastTSN = i.initialTSN - 1
+	a.payloadQueue.init(i.initialTSN - 1)
 	if a.sourcePort != p.destinationPort ||
 		a.destinationPort != p.sourcePort {
 		a.log.Warnf("[%s] handleInitAck: port mismatch", a.name)
@@ -1178,8 +1295,13 @@ func (a *Association) handleInitAck(p *packet, i *chunkInitAck) error {
 					a.useForwardTSN = true
 				}
 			}
+		case *paramZeroChecksumAcceptable:
+			a.sendZeroChecksum = v.edmid == dtlsErrorDetectionMethod
 		}
 	}
+
+	a.log.Debugf("[%s] sendZeroChecksum=%t (on initAck)", a.name, a.sendZeroChecksum)
+
 	if !a.useForwardTSN {
 		a.log.Warnf("[%s] not using ForwardTSN (on initAck)", a.name)
 	}
@@ -1243,6 +1365,8 @@ func (a *Association) handleCookieEcho(c *chunkCookieEcho) []*packet {
 			return nil
 		}
 
+		// RFC wise, these do not seem to belong here, but removing them
+		// causes TestCookieEchoRetransmission to break
 		a.t1Init.stop()
 		a.storedInit = nil
 
@@ -1250,6 +1374,7 @@ func (a *Association) handleCookieEcho(c *chunkCookieEcho) []*packet {
 		a.storedCookieEcho = nil
 
 		a.setState(established)
+		// Note: This is a future place where the user could be notified (COMMUNICATION UP)
 		a.handshakeCompletedCh <- nil
 	}
 
@@ -1278,6 +1403,7 @@ func (a *Association) handleCookieAck() {
 	a.storedCookieEcho = nil
 
 	a.setState(established)
+	// Note: This is a future place where the user could be notified (COMMUNICATION UP)
 	a.handshakeCompletedCh <- nil
 }
 
@@ -1287,26 +1413,26 @@ func (a *Association) handleData(d *chunkPayloadData) []*packet {
 		a.name, d.tsn, d.immediateSack, len(d.userData))
 	a.stats.incDATAs()
 
-	canPush := a.payloadQueue.canPush(d, a.peerLastTSN)
+	canPush := a.payloadQueue.canPush(d.tsn)
 	if canPush {
 		s := a.getOrCreateStream(d.streamIdentifier, true, PayloadTypeUnknown)
 		if s == nil {
-			// silentely discard the data. (sender will retry on T3-rtx timeout)
+			// silently discard the data. (sender will retry on T3-rtx timeout)
 			// see pion/sctp#30
-			a.log.Debugf("discard %d", d.streamSequenceNumber)
+			a.log.Debugf("[%s] discard %d", a.name, d.streamSequenceNumber)
 			return nil
 		}
 
 		if a.getMyReceiverWindowCredit() > 0 {
 			// Pass the new chunk to stream level as soon as it arrives
-			a.payloadQueue.push(d, a.peerLastTSN)
+			a.payloadQueue.push(d.tsn)
 			s.handleData(d)
 		} else {
 			// Receive buffer is full
 			lastTSN, ok := a.payloadQueue.getLastTSNReceived()
 			if ok && sna32LT(d.tsn, lastTSN) {
 				a.log.Debugf("[%s] receive buffer full, but accepted as this is a missing chunk with tsn=%d ssn=%d", a.name, d.tsn, d.streamSequenceNumber)
-				a.payloadQueue.push(d, a.peerLastTSN)
+				a.payloadQueue.push(d.tsn)
 				s.handleData(d)
 			} else {
 				a.log.Debugf("[%s] receive buffer full. dropping DATA with tsn=%d ssn=%d", a.name, d.tsn, d.streamSequenceNumber)
@@ -1330,10 +1456,9 @@ func (a *Association) handlePeerLastTSNAndAcknowledgement(sackImmediately bool)
 	// Meaning, if peerLastTSN+1 points to a chunk that is received,
 	// advance peerLastTSN until peerLastTSN+1 points to unreceived chunk.
 	for {
-		if _, popOk := a.payloadQueue.pop(a.peerLastTSN + 1); !popOk {
+		if popOk := a.payloadQueue.pop(false); !popOk {
 			break
 		}
-		a.peerLastTSN++
 
 		for _, rstReq := range a.reconfigRequests {
 			resp := a.resetStreamsIfAny(rstReq)
@@ -1346,7 +1471,7 @@ func (a *Association) handlePeerLastTSNAndAcknowledgement(sackImmediately bool)
 
 	hasPacketLoss := (a.payloadQueue.size() > 0)
 	if hasPacketLoss {
-		a.log.Tracef("[%s] packetloss: %s", a.name, a.payloadQueue.getGapAckBlocksString(a.peerLastTSN))
+		a.log.Tracef("[%s] packetloss: %s", a.name, a.payloadQueue.getGapAckBlocksString())
 	}
 
 	if (a.ackState != ackStateImmediate && !sackImmediately && !hasPacketLoss && a.ackMode == ackModeNormal) || a.ackMode == ackModeAlwaysDelay {
@@ -1658,7 +1783,7 @@ func (a *Association) handleSack(d *chunkSelectiveAck) error {
 		return nil
 	}
 
-	a.stats.incSACKs()
+	a.stats.incSACKsReceived()
 
 	if sna32GT(a.cumulativeTSNAckPoint, d.cumulativeTSNAck) {
 		// RFC 4960 sec 6.2.1.  Processing a Received SACK
@@ -1944,8 +2069,8 @@ func (a *Association) handleForwardTSN(c *chunkForwardTSN) []*packet {
 	//   duplicate may indicate the previous SACK was lost in the network.
 
 	a.log.Tracef("[%s] should send ack? newCumTSN=%d peerLastTSN=%d",
-		a.name, c.newCumulativeTSN, a.peerLastTSN)
-	if sna32LTE(c.newCumulativeTSN, a.peerLastTSN) {
+		a.name, c.newCumulativeTSN, a.peerLastTSN())
+	if sna32LTE(c.newCumulativeTSN, a.peerLastTSN()) {
 		a.log.Tracef("[%s] sending ack on Forward TSN", a.name)
 		a.ackState = ackStateImmediate
 		a.ackTimer.stop()
@@ -1964,9 +2089,8 @@ func (a *Association) handleForwardTSN(c *chunkForwardTSN) []*packet {
 	//   chunk,
 
 	// Advance peerLastTSN
-	for sna32LT(a.peerLastTSN, c.newCumulativeTSN) {
-		a.payloadQueue.pop(a.peerLastTSN + 1) // may not exist
-		a.peerLastTSN++
+	for sna32LT(a.peerLastTSN(), c.newCumulativeTSN) {
+		a.payloadQueue.pop(true) // may not exist
 	}
 
 	// Report new peerLastTSN value and abandoned largest SSN value to
@@ -2019,15 +2143,39 @@ func (a *Association) handleReconfigParam(raw param) (*packet, error) {
 	switch p := raw.(type) {
 	case *paramOutgoingResetRequest:
 		a.log.Tracef("[%s] handleReconfigParam (OutgoingResetRequest)", a.name)
+		if a.peerLastTSN() < p.senderLastTSN && len(a.reconfigRequests) >= maxReconfigRequests {
+			// We have too many reconfig requests outstanding. Drop the request and let
+			// the peer retransmit. A well behaved peer should only have 1 outstanding
+			// reconfig request.
+			//
+			// RFC 6525: https://www.rfc-editor.org/rfc/rfc6525.html#section-5.1.1
+			//    At any given time, there MUST NOT be more than one request in flight.
+			//    So, if the Re-configuration Timer is running and the RE-CONFIG chunk
+			//    contains at least one request parameter, the chunk MUST be buffered.
+			// chrome: https://chromium.googlesource.com/external/webrtc/+/refs/heads/main/net/dcsctp/socket/stream_reset_handler.cc#271
+			return nil, fmt.Errorf("%w: %d", ErrTooManyReconfigRequests, len(a.reconfigRequests))
+		}
 		a.reconfigRequests[p.reconfigRequestSequenceNumber] = p
 		resp := a.resetStreamsIfAny(p)
 		if resp != nil {
 			return resp, nil
 		}
 		return nil, nil //nolint:nilnil
-
 	case *paramReconfigResponse:
 		a.log.Tracef("[%s] handleReconfigParam (ReconfigResponse)", a.name)
+		if p.result == reconfigResultInProgress {
+			// RFC 6525: https://www.rfc-editor.org/rfc/rfc6525.html#section-5.2.7
+			//
+			//   If the Result field indicates "In progress", the timer for the
+			//   Re-configuration Request Sequence Number is started again.  If
+			//   the timer runs out, the RE-CONFIG chunk MUST be retransmitted
+			//   but the corresponding error counters MUST NOT be incremented.
+			if _, ok := a.reconfigs[p.reconfigResponseSequenceNumber]; ok {
+				a.tReconfig.stop()
+				a.tReconfig.start(a.rtoMgr.getRTO())
+			}
+			return nil, nil //nolint:nilnil
+		}
 		delete(a.reconfigs, p.reconfigResponseSequenceNumber)
 		if len(a.reconfigs) == 0 {
 			a.tReconfig.stop()
@@ -2041,9 +2189,9 @@ func (a *Association) handleReconfigParam(raw param) (*packet, error) {
 // The caller should hold the lock.
 func (a *Association) resetStreamsIfAny(p *paramOutgoingResetRequest) *packet {
 	result := reconfigResultSuccessPerformed
-	if sna32LTE(p.senderLastTSN, a.peerLastTSN) {
+	if sna32LTE(p.senderLastTSN, a.peerLastTSN()) {
 		a.log.Debugf("[%s] resetStream(): senderLastTSN=%d <= peerLastTSN=%d",
-			a.name, p.senderLastTSN, a.peerLastTSN)
+			a.name, p.senderLastTSN, a.peerLastTSN())
 		for _, id := range p.streamIdentifiers {
 			s, ok := a.streams[id]
 			if !ok {
@@ -2058,7 +2206,7 @@ func (a *Association) resetStreamsIfAny(p *paramOutgoingResetRequest) *packet {
 		delete(a.reconfigRequests, p.reconfigRequestSequenceNumber)
 	} else {
 		a.log.Debugf("[%s] resetStream(): senderLastTSN=%d > peerLastTSN=%d",
-			a.name, p.senderLastTSN, a.peerLastTSN)
+			a.name, p.senderLastTSN, a.peerLastTSN())
 		result = reconfigResultInProgress
 	}
 
@@ -2132,7 +2280,7 @@ func (a *Association) popPendingDataChunksToSend() ([]*chunkPayloadData, []uint1
 				break // would exceeds cwnd
 			}
 
-			if dataLen > a.rwnd {
+			if dataLen > a.RWND() {
 				break // no more rwnd
 			}
 
@@ -2171,14 +2319,15 @@ func (a *Association) bundleDataChunksIntoPackets(chunks []*chunkPayloadData) []
 		//   single packet.  Furthermore, DATA chunks being retransmitted MAY be
 		//   bundled with new DATA chunks, as long as the resulting packet size
 		//   does not exceed the path MTU.
-		if bytesInPacket+len(c.userData) > int(a.MTU()) {
+		chunkSizeInPacket := int(dataChunkHeaderSize) + len(c.userData)
+		chunkSizeInPacket += getPadding(chunkSizeInPacket)
+		if bytesInPacket+chunkSizeInPacket > int(a.MTU()) {
 			packets = append(packets, a.createPacket(chunksToSend))
 			chunksToSend = []chunk{}
 			bytesInPacket = int(commonHeaderSize)
 		}
-
 		chunksToSend = append(chunksToSend, c)
-		bytesInPacket += int(dataChunkHeaderSize) + len(c.userData)
+		bytesInPacket += chunkSizeInPacket
 	}
 
 	if len(chunksToSend) > 0 {
@@ -2305,10 +2454,10 @@ func (a *Association) generateNextRSN() uint32 {
 
 func (a *Association) createSelectiveAckChunk() *chunkSelectiveAck {
 	sack := &chunkSelectiveAck{}
-	sack.cumulativeTSNAck = a.peerLastTSN
+	sack.cumulativeTSNAck = a.peerLastTSN()
 	sack.advertisedReceiverWindowCredit = a.getMyReceiverWindowCredit()
 	sack.duplicateTSN = a.payloadQueue.popDuplicates()
-	sack.gapAckBlocks = a.payloadQueue.getGapAckBlocks(a.peerLastTSN)
+	sack.gapAckBlocks = a.payloadQueue.getGapAckBlocks()
 	return sack
 }
 
@@ -2316,15 +2465,17 @@ func pack(p *packet) []*packet {
 	return []*packet{p}
 }
 
-func (a *Association) handleChunkStart() {
+func (a *Association) handleChunksStart() {
 	a.lock.Lock()
 	defer a.lock.Unlock()
 
+	a.stats.incPacketsReceived()
+
 	a.delayedAckTriggered = false
 	a.immediateAckTriggered = false
 }
 
-func (a *Association) handleChunkEnd() {
+func (a *Association) handleChunksEnd() {
 	a.lock.Lock()
 	defer a.lock.Unlock()
 
@@ -2347,13 +2498,18 @@ func (a *Association) handleChunk(p *packet, c chunk) error {
 	var err error
 
 	if _, err = c.check(); err != nil {
-		a.log.Errorf("[ %s ] failed validating chunk: %s ", a.name, err)
+		a.log.Errorf("[%s] failed validating chunk: %s ", a.name, err)
 		return nil
 	}
 
 	isAbort := false
 
 	switch c := c.(type) {
+	// Note: We do not do the following for chunkInit, chunkInitAck, and chunkCookieEcho:
+	// If an endpoint receives an INIT, INIT ACK, or COOKIE ECHO chunk but decides not to establish the
+	// new association due to missing mandatory parameters in the received INIT or INIT ACK chunk, invalid
+	// parameter values, or lack of local resources, it SHOULD respond with an ABORT chunk.
+
 	case *chunkInit:
 		packets, err = a.handleInit(p, c)
 
@@ -2371,6 +2527,7 @@ func (a *Association) handleChunk(p *packet, c chunk) error {
 		}
 		a.log.Debugf("[%s] Error chunk, with following errors: %s", a.name, errStr)
 
+	// Note: chunkHeartbeatAck not handled?
 	case *chunkHeartbeat:
 		packets = a.handleHeartbeat(c)
 
@@ -2425,6 +2582,12 @@ func (a *Association) onRetransmissionTimeout(id int, nRtos uint) {
 	a.lock.Lock()
 	defer a.lock.Unlock()
 
+	// TSN hasn't been incremented in 3 attempts. Speculatively
+	// toggle ZeroChecksum because old Pion versions had a broken implementation
+	if a.cumulativeTSNAckPoint+1 == a.initialTSN && nRtos%3 == 0 {
+		a.sendZeroChecksum = !a.sendZeroChecksum
+	}
+
 	if id == timerT1Init {
 		err := a.sendInit()
 		if err != nil {
diff --git a/vendor/github.com/pion/sctp/association_stats.go b/vendor/github.com/pion/sctp/association_stats.go
index 60883c47..0e4e581b 100644
--- a/vendor/github.com/pion/sctp/association_stats.go
+++ b/vendor/github.com/pion/sctp/association_stats.go
@@ -8,11 +8,30 @@ import (
 )
 
 type associationStats struct {
-	nDATAs       uint64
-	nSACKs       uint64
-	nT3Timeouts  uint64
-	nAckTimeouts uint64
-	nFastRetrans uint64
+	nPacketsReceived uint64
+	nPacketsSent     uint64
+	nDATAs           uint64
+	nSACKsReceived   uint64
+	nSACKsSent       uint64
+	nT3Timeouts      uint64
+	nAckTimeouts     uint64
+	nFastRetrans     uint64
+}
+
+func (s *associationStats) incPacketsReceived() {
+	atomic.AddUint64(&s.nPacketsReceived, 1)
+}
+
+func (s *associationStats) getNumPacketsReceived() uint64 {
+	return atomic.LoadUint64(&s.nPacketsReceived)
+}
+
+func (s *associationStats) incPacketsSent() {
+	atomic.AddUint64(&s.nPacketsSent, 1)
+}
+
+func (s *associationStats) getNumPacketsSent() uint64 {
+	return atomic.LoadUint64(&s.nPacketsSent)
 }
 
 func (s *associationStats) incDATAs() {
@@ -23,12 +42,20 @@ func (s *associationStats) getNumDATAs() uint64 {
 	return atomic.LoadUint64(&s.nDATAs)
 }
 
-func (s *associationStats) incSACKs() {
-	atomic.AddUint64(&s.nSACKs, 1)
+func (s *associationStats) incSACKsReceived() {
+	atomic.AddUint64(&s.nSACKsReceived, 1)
+}
+
+func (s *associationStats) getNumSACKsReceived() uint64 {
+	return atomic.LoadUint64(&s.nSACKsReceived)
+}
+
+func (s *associationStats) incSACKsSent() {
+	atomic.AddUint64(&s.nSACKsSent, 1)
 }
 
-func (s *associationStats) getNumSACKs() uint64 {
-	return atomic.LoadUint64(&s.nSACKs)
+func (s *associationStats) getNumSACKsSent() uint64 {
+	return atomic.LoadUint64(&s.nSACKsSent)
 }
 
 func (s *associationStats) incT3Timeouts() {
@@ -56,8 +83,11 @@ func (s *associationStats) getNumFastRetrans() uint64 {
 }
 
 func (s *associationStats) reset() {
+	atomic.StoreUint64(&s.nPacketsReceived, 0)
+	atomic.StoreUint64(&s.nPacketsSent, 0)
 	atomic.StoreUint64(&s.nDATAs, 0)
-	atomic.StoreUint64(&s.nSACKs, 0)
+	atomic.StoreUint64(&s.nSACKsReceived, 0)
+	atomic.StoreUint64(&s.nSACKsSent, 0)
 	atomic.StoreUint64(&s.nT3Timeouts, 0)
 	atomic.StoreUint64(&s.nAckTimeouts, 0)
 	atomic.StoreUint64(&s.nFastRetrans, 0)
diff --git a/vendor/github.com/pion/sctp/chunk_init.go b/vendor/github.com/pion/sctp/chunk_init.go
index fb898446..a6a3be31 100644
--- a/vendor/github.com/pion/sctp/chunk_init.go
+++ b/vendor/github.com/pion/sctp/chunk_init.go
@@ -38,6 +38,7 @@ var (
 	ErrInitInboundStreamRequestZero  = errors.New("INIT ACK inbound stream request must be > 0")
 	ErrInitOutboundStreamRequestZero = errors.New("INIT ACK outbound stream request must be > 0")
 	ErrInitAdvertisedReceiver1500    = errors.New("INIT ACK Advertised Receiver Window Credit (a_rwnd) must be >= 1500")
+	ErrInitUnknownParam              = errors.New("INIT with unknown param")
 )
 
 func (i *chunkInit) unmarshal(raw []byte) error {
@@ -89,8 +90,7 @@ func (i *chunkInit) check() (abort bool, err error) {
 	// to be 0, the receiver MUST treat it as an error and close the
 	// association by transmitting an ABORT.
 	if i.initiateTag == 0 {
-		abort = true
-		return abort, ErrChunkTypeInitInitateTagZero
+		return true, ErrChunkTypeInitInitateTagZero
 	}
 
 	// Defines the maximum number of streams the sender of this INIT
@@ -104,8 +104,7 @@ func (i *chunkInit) check() (abort bool, err error) {
 	// Note: A receiver of an INIT with the MIS value of 0 SHOULD abort
 	// the association.
 	if i.numInboundStreams == 0 {
-		abort = true
-		return abort, ErrInitInboundStreamRequestZero
+		return true, ErrInitInboundStreamRequestZero
 	}
 
 	// Defines the number of outbound streams the sender of this INIT
@@ -116,8 +115,7 @@ func (i *chunkInit) check() (abort bool, err error) {
 	// abort the association.
 
 	if i.numOutboundStreams == 0 {
-		abort = true
-		return abort, ErrInitOutboundStreamRequestZero
+		return true, ErrInitOutboundStreamRequestZero
 	}
 
 	// An SCTP receiver MUST be able to receive a minimum of 1500 bytes in
@@ -125,8 +123,14 @@ func (i *chunkInit) check() (abort bool, err error) {
 	// less than 1500 bytes in its initial a_rwnd sent in the INIT or INIT
 	// ACK.
 	if i.advertisedReceiverWindowCredit < 1500 {
-		abort = true
-		return abort, ErrInitAdvertisedReceiver1500
+		return true, ErrInitAdvertisedReceiver1500
+	}
+
+	for _, p := range i.unrecognizedParams {
+		if p.unrecognizedAction == paramHeaderUnrecognizedActionStop ||
+			p.unrecognizedAction == paramHeaderUnrecognizedActionStopAndReport {
+			return true, ErrInitUnknownParam
+		}
 	}
 
 	return false, nil
diff --git a/vendor/github.com/pion/sctp/chunk_init_common.go b/vendor/github.com/pion/sctp/chunk_init_common.go
index 63c70c98..b3f8b845 100644
--- a/vendor/github.com/pion/sctp/chunk_init_common.go
+++ b/vendor/github.com/pion/sctp/chunk_init_common.go
@@ -49,6 +49,7 @@ type chunkInitCommon struct {
 	numInboundStreams              uint16
 	initialTSN                     uint32
 	params                         []param
+	unrecognizedParams             []paramHeader
 }
 
 const (
@@ -59,7 +60,6 @@ const (
 // Init chunk errors
 var (
 	ErrInitChunkParseParamTypeFailed = errors.New("failed to parse param type")
-	ErrInitChunkUnmarshalParam       = errors.New("failed unmarshalling param in Init Chunk")
 	ErrInitAckMarshalParam           = errors.New("unable to marshal parameter for INIT/INITACK")
 )
 
@@ -91,18 +91,21 @@ func (i *chunkInitCommon) unmarshal(raw []byte) error {
 	remaining := len(raw) - offset
 	for remaining > 0 {
 		if remaining > initOptionalVarHeaderLength {
-			pType, err := parseParamType(raw[offset:])
-			if err != nil {
+			var pHeader paramHeader
+			if err := pHeader.unmarshal(raw[offset:]); err != nil {
 				return fmt.Errorf("%w: %v", ErrInitChunkParseParamTypeFailed, err) //nolint:errorlint
 			}
-			p, err := buildParam(pType, raw[offset:])
+
+			p, err := buildParam(pHeader.typ, raw[offset:])
 			if err != nil {
-				return fmt.Errorf("%w: %v", ErrInitChunkUnmarshalParam, err) //nolint:errorlint
+				i.unrecognizedParams = append(i.unrecognizedParams, pHeader)
+			} else {
+				i.params = append(i.params, p)
 			}
-			i.params = append(i.params, p)
-			padding := getPadding(p.length())
-			offset += p.length() + padding
-			remaining -= p.length() + padding
+
+			padding := getPadding(pHeader.length())
+			offset += pHeader.length() + padding
+			remaining -= pHeader.length() + padding
 		} else {
 			break
 		}
diff --git a/vendor/github.com/pion/sctp/chunk_payload_data.go b/vendor/github.com/pion/sctp/chunk_payload_data.go
index b6f1b614..a5a00064 100644
--- a/vendor/github.com/pion/sctp/chunk_payload_data.go
+++ b/vendor/github.com/pion/sctp/chunk_payload_data.go
@@ -132,7 +132,7 @@ func (p *chunkPayloadData) unmarshal(raw []byte) error {
 	p.beginningFragment = p.flags&payloadDataBeginingFragmentBitmask != 0
 	p.endingFragment = p.flags&payloadDataEndingFragmentBitmask != 0
 
-	if len(raw) < payloadDataHeaderSize {
+	if len(p.raw) < payloadDataHeaderSize {
 		return ErrChunkPayloadSmall
 	}
 	p.tsn = binary.BigEndian.Uint32(p.raw[0:])
@@ -206,3 +206,7 @@ func (p *chunkPayloadData) setAllInflight() {
 		}
 	}
 }
+
+func (p *chunkPayloadData) isFragmented() bool {
+	return !(p.head == nil && p.beginningFragment && p.endingFragment)
+}
diff --git a/vendor/github.com/pion/sctp/error_cause_header.go b/vendor/github.com/pion/sctp/error_cause_header.go
index 84ff209d..98c530fb 100644
--- a/vendor/github.com/pion/sctp/error_cause_header.go
+++ b/vendor/github.com/pion/sctp/error_cause_header.go
@@ -5,6 +5,7 @@ package sctp
 
 import (
 	"encoding/binary"
+	"errors"
 )
 
 // errorCauseHeader represents the shared header that is shared by all error causes
@@ -18,6 +19,9 @@ const (
 	errorCauseHeaderLength = 4
 )
 
+// ErrInvalidSCTPChunk is returned when an SCTP chunk is invalid
+var ErrInvalidSCTPChunk = errors.New("invalid SCTP chunk")
+
 func (e *errorCauseHeader) marshal() ([]byte, error) {
 	e.len = uint16(len(e.raw)) + uint16(errorCauseHeaderLength)
 	raw := make([]byte, e.len)
@@ -31,6 +35,9 @@ func (e *errorCauseHeader) marshal() ([]byte, error) {
 func (e *errorCauseHeader) unmarshal(raw []byte) error {
 	e.code = errorCauseCode(binary.BigEndian.Uint16(raw[0:]))
 	e.len = binary.BigEndian.Uint16(raw[2:])
+	if e.len < errorCauseHeaderLength || int(e.len) > len(raw) {
+		return ErrInvalidSCTPChunk
+	}
 	valueLength := e.len - errorCauseHeaderLength
 	e.raw = raw[errorCauseHeaderLength : errorCauseHeaderLength+valueLength]
 	return nil
diff --git a/vendor/github.com/pion/sctp/packet.go b/vendor/github.com/pion/sctp/packet.go
index 2d40d295..72660f3e 100644
--- a/vendor/github.com/pion/sctp/packet.go
+++ b/vendor/github.com/pion/sctp/packet.go
@@ -65,16 +65,35 @@ var (
 	ErrChecksumMismatch            = errors.New("checksum mismatch theirs")
 )
 
-func (p *packet) unmarshal(raw []byte) error {
+func (p *packet) unmarshal(doChecksum bool, raw []byte) error {
 	if len(raw) < packetHeaderSize {
 		return fmt.Errorf("%w: raw only %d bytes, %d is the minimum length", ErrPacketRawTooSmall, len(raw), packetHeaderSize)
 	}
 
+	offset := packetHeaderSize
+
+	// Check if doing CRC32c is required.
+	// Without having SCTP AUTH implemented, this depends only on the type
+	// og the first chunk.
+	if offset+chunkHeaderSize <= len(raw) {
+		switch chunkType(raw[offset]) {
+		case ctInit, ctCookieEcho:
+			doChecksum = true
+		default:
+		}
+	}
+	theirChecksum := binary.LittleEndian.Uint32(raw[8:])
+	if theirChecksum != 0 || doChecksum {
+		ourChecksum := generatePacketChecksum(raw)
+		if theirChecksum != ourChecksum {
+			return fmt.Errorf("%w: %d ours: %d", ErrChecksumMismatch, theirChecksum, ourChecksum)
+		}
+	}
+
 	p.sourcePort = binary.BigEndian.Uint16(raw[0:])
 	p.destinationPort = binary.BigEndian.Uint16(raw[2:])
 	p.verificationTag = binary.BigEndian.Uint32(raw[4:])
 
-	offset := packetHeaderSize
 	for {
 		// Exact match, no more chunks
 		if offset == len(raw) {
@@ -125,15 +144,11 @@ func (p *packet) unmarshal(raw []byte) error {
 		chunkValuePadding := getPadding(c.valueLength())
 		offset += chunkHeaderSize + c.valueLength() + chunkValuePadding
 	}
-	theirChecksum := binary.LittleEndian.Uint32(raw[8:])
-	ourChecksum := generatePacketChecksum(raw)
-	if theirChecksum != ourChecksum {
-		return fmt.Errorf("%w: %d ours: %d", ErrChecksumMismatch, theirChecksum, ourChecksum)
-	}
+
 	return nil
 }
 
-func (p *packet) marshal() ([]byte, error) {
+func (p *packet) marshal(doChecksum bool) ([]byte, error) {
 	raw := make([]byte, packetHeaderSize)
 
 	// Populate static headers
@@ -156,9 +171,16 @@ func (p *packet) marshal() ([]byte, error) {
 		}
 	}
 
-	// Checksum is already in BigEndian
-	// Using LittleEndian.PutUint32 stops it from being flipped
-	binary.LittleEndian.PutUint32(raw[8:], generatePacketChecksum(raw))
+	if doChecksum {
+		// golang CRC32C uses reflected input and reflected output, the
+		// net result of this is to have the bytes flipped compared to
+		// the non reflected variant that the spec expects.
+		//
+		// Use LittleEndian.PutUint32 to avoid flipping the bytes in to
+		// the spec compliant checksum order
+		binary.LittleEndian.PutUint32(raw[8:], generatePacketChecksum(raw))
+	}
+
 	return raw, nil
 }
 
diff --git a/vendor/github.com/pion/sctp/param.go b/vendor/github.com/pion/sctp/param.go
index 8035add3..c28d7a5b 100644
--- a/vendor/github.com/pion/sctp/param.go
+++ b/vendor/github.com/pion/sctp/param.go
@@ -38,6 +38,8 @@ func buildParam(t paramType, rawParam []byte) (param, error) {
 		return (&paramOutgoingResetRequest{}).unmarshal(rawParam)
 	case reconfigResp:
 		return (&paramReconfigResponse{}).unmarshal(rawParam)
+	case zeroChecksumAcceptable:
+		return (&paramZeroChecksumAcceptable{}).unmarshal(rawParam)
 	default:
 		return nil, fmt.Errorf("%w: %v", ErrParamTypeUnhandled, t)
 	}
diff --git a/vendor/github.com/pion/sctp/param_requested_hmac_algorithm.go b/vendor/github.com/pion/sctp/param_requested_hmac_algorithm.go
index ca9b0147..3e98ea71 100644
--- a/vendor/github.com/pion/sctp/param_requested_hmac_algorithm.go
+++ b/vendor/github.com/pion/sctp/param_requested_hmac_algorithm.go
@@ -13,7 +13,7 @@ type hmacAlgorithm uint16
 
 const (
 	hmacResv1  hmacAlgorithm = 0
-	hmacSHA128               = 1
+	hmacSHA128 hmacAlgorithm = 1
 	hmacResv2  hmacAlgorithm = 2
 	hmacSHA256 hmacAlgorithm = 3
 )
@@ -21,6 +21,9 @@ const (
 // ErrInvalidAlgorithmType is returned if unknown auth algorithm is specified.
 var ErrInvalidAlgorithmType = errors.New("invalid algorithm type")
 
+// ErrInvalidChunkLength is returned if the chunk length is invalid.
+var ErrInvalidChunkLength = errors.New("invalid chunk length")
+
 func (c hmacAlgorithm) String() string {
 	switch c {
 	case hmacResv1:
@@ -58,6 +61,9 @@ func (r *paramRequestedHMACAlgorithm) unmarshal(raw []byte) (param, error) {
 	if err != nil {
 		return nil, err
 	}
+	if len(r.raw)%2 == 1 {
+		return nil, ErrInvalidChunkLength
+	}
 
 	i := 0
 	for i < len(r.raw) {
diff --git a/vendor/github.com/pion/sctp/param_zero_checksum.go b/vendor/github.com/pion/sctp/param_zero_checksum.go
new file mode 100644
index 00000000..ddf7c5af
--- /dev/null
+++ b/vendor/github.com/pion/sctp/param_zero_checksum.go
@@ -0,0 +1,56 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
+package sctp
+
+import (
+	"encoding/binary"
+	"errors"
+)
+
+//  This parameter is used to inform the receiver that a sender is willing to
+//  accept zero as checksum if some other error detection method is used
+//  instead.
+//
+//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |   Type = 0x8001 (suggested)   |          Length = 8           |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |           Error Detection Method Identifier (EDMID)           |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+type paramZeroChecksumAcceptable struct {
+	paramHeader
+	// The Error Detection Method Identifier (EDMID) specifies an alternate
+	// error detection method the sender of this parameter is willing to use for
+	// received packets.
+	edmid uint32
+}
+
+// Zero Checksum parameter error
+var (
+	ErrZeroChecksumParamTooShort = errors.New("zero checksum parameter too short")
+)
+
+const (
+	dtlsErrorDetectionMethod uint32 = 1
+)
+
+func (r *paramZeroChecksumAcceptable) marshal() ([]byte, error) {
+	r.typ = zeroChecksumAcceptable
+	r.raw = make([]byte, 4)
+	binary.BigEndian.PutUint32(r.raw, r.edmid)
+	return r.paramHeader.marshal()
+}
+
+func (r *paramZeroChecksumAcceptable) unmarshal(raw []byte) (param, error) {
+	err := r.paramHeader.unmarshal(raw)
+	if err != nil {
+		return nil, err
+	}
+	if len(r.raw) < 4 {
+		return nil, ErrZeroChecksumParamTooShort
+	}
+	r.edmid = binary.BigEndian.Uint32(r.raw)
+	return r, nil
+}
diff --git a/vendor/github.com/pion/sctp/paramheader.go b/vendor/github.com/pion/sctp/paramheader.go
index 5cef07d5..5b694428 100644
--- a/vendor/github.com/pion/sctp/paramheader.go
+++ b/vendor/github.com/pion/sctp/paramheader.go
@@ -10,13 +10,40 @@ import (
 	"fmt"
 )
 
+type paramHeaderUnrecognizedAction byte
+
 type paramHeader struct {
-	typ paramType
-	len int
-	raw []byte
+	typ                paramType
+	unrecognizedAction paramHeaderUnrecognizedAction
+	len                int
+	raw                []byte
 }
 
+/*
+	 The Parameter Types are encoded such that the highest-order 2 bits specify
+	 the action that is taken if the processing endpoint does not recognize the
+	 Parameter Type.
+
+	 00 - Stop processing this parameter and do not process any further parameters within this chunk.
+
+	 01 - Stop processing this parameter, do not process any further parameters within this chunk, and
+		  report the unrecognized parameter, as described in Section 3.2.2.
+
+	 10 - Skip this parameter and continue processing.
+
+	 11 - Skip this parameter and continue processing, but report the unrecognized
+		  parameter, as described in Section 3.2.2.
+
+	 https://www.rfc-editor.org/rfc/rfc9260.html#section-3.2.1
+*/
+
 const (
+	paramHeaderUnrecognizedActionMask                                        = 0b11000000
+	paramHeaderUnrecognizedActionStop          paramHeaderUnrecognizedAction = 0b00000000
+	paramHeaderUnrecognizedActionStopAndReport paramHeaderUnrecognizedAction = 0b01000000
+	paramHeaderUnrecognizedActionSkip          paramHeaderUnrecognizedAction = 0b10000000
+	paramHeaderUnrecognizedActionSkipAndReport paramHeaderUnrecognizedAction = 0b11000000
+
 	paramHeaderLength = 4
 )
 
@@ -57,6 +84,7 @@ func (p *paramHeader) unmarshal(raw []byte) error {
 		return fmt.Errorf("%w: %v", ErrParamHeaderParseFailed, err) //nolint:errorlint
 	}
 	p.typ = typ
+	p.unrecognizedAction = paramHeaderUnrecognizedAction(raw[0] & paramHeaderUnrecognizedActionMask)
 	p.raw = raw[paramHeaderLength:paramLengthPlusHeader]
 	p.len = int(paramLengthPlusHeader)
 
diff --git a/vendor/github.com/pion/sctp/paramtype.go b/vendor/github.com/pion/sctp/paramtype.go
index f0a3da38..de1b3dd9 100644
--- a/vendor/github.com/pion/sctp/paramtype.go
+++ b/vendor/github.com/pion/sctp/paramtype.go
@@ -13,33 +13,34 @@ import (
 type paramType uint16
 
 const (
-	heartbeatInfo      paramType = 1     // Heartbeat Info	[RFC4960]
-	ipV4Addr           paramType = 5     // IPv4 IP	[RFC4960]
-	ipV6Addr           paramType = 6     // IPv6 IP	[RFC4960]
-	stateCookie        paramType = 7     // State Cookie	[RFC4960]
-	unrecognizedParam  paramType = 8     // Unrecognized Parameters	[RFC4960]
-	cookiePreservative paramType = 9     // Cookie Preservative	[RFC4960]
-	hostNameAddr       paramType = 11    // Host Name IP	[RFC4960]
-	supportedAddrTypes paramType = 12    // Supported IP Types	[RFC4960]
-	outSSNResetReq     paramType = 13    // Outgoing SSN Reset Request Parameter	[RFC6525]
-	incSSNResetReq     paramType = 14    // Incoming SSN Reset Request Parameter	[RFC6525]
-	ssnTSNResetReq     paramType = 15    // SSN/TSN Reset Request Parameter	[RFC6525]
-	reconfigResp       paramType = 16    // Re-configuration Response Parameter	[RFC6525]
-	addOutStreamsReq   paramType = 17    // Add Outgoing Streams Request Parameter	[RFC6525]
-	addIncStreamsReq   paramType = 18    // Add Incoming Streams Request Parameter	[RFC6525]
-	ecnCapable         paramType = 32768 // ECN Capable (0x8000)	[RFC2960]
-	random             paramType = 32770 // Random (0x8002)	[RFC4805]
-	chunkList          paramType = 32771 // Chunk List (0x8003)	[RFC4895]
-	reqHMACAlgo        paramType = 32772 // Requested HMAC Algorithm Parameter (0x8004)	[RFC4895]
-	padding            paramType = 32773 // Padding (0x8005)
-	supportedExt       paramType = 32776 // Supported Extensions (0x8008)	[RFC5061]
-	forwardTSNSupp     paramType = 49152 // Forward TSN supported (0xC000)	[RFC3758]
-	addIPAddr          paramType = 49153 // Add IP IP (0xC001)	[RFC5061]
-	delIPAddr          paramType = 49154 // Delete IP IP (0xC002)	[RFC5061]
-	errClauseInd       paramType = 49155 // Error Cause Indication (0xC003)	[RFC5061]
-	setPriAddr         paramType = 49156 // Set Primary IP (0xC004)	[RFC5061]
-	successInd         paramType = 49157 // Success Indication (0xC005)	[RFC5061]
-	adaptLayerInd      paramType = 49158 // Adaptation Layer Indication (0xC006)	[RFC5061]
+	heartbeatInfo          paramType = 1     // Heartbeat Info	[RFC4960]
+	ipV4Addr               paramType = 5     // IPv4 IP	[RFC4960]
+	ipV6Addr               paramType = 6     // IPv6 IP	[RFC4960]
+	stateCookie            paramType = 7     // State Cookie	[RFC4960]
+	unrecognizedParam      paramType = 8     // Unrecognized Parameters	[RFC4960]
+	cookiePreservative     paramType = 9     // Cookie Preservative	[RFC4960]
+	hostNameAddr           paramType = 11    // Host Name IP	[RFC4960]
+	supportedAddrTypes     paramType = 12    // Supported IP Types	[RFC4960]
+	outSSNResetReq         paramType = 13    // Outgoing SSN Reset Request Parameter	[RFC6525]
+	incSSNResetReq         paramType = 14    // Incoming SSN Reset Request Parameter	[RFC6525]
+	ssnTSNResetReq         paramType = 15    // SSN/TSN Reset Request Parameter	[RFC6525]
+	reconfigResp           paramType = 16    // Re-configuration Response Parameter	[RFC6525]
+	addOutStreamsReq       paramType = 17    // Add Outgoing Streams Request Parameter	[RFC6525]
+	addIncStreamsReq       paramType = 18    // Add Incoming Streams Request Parameter	[RFC6525]
+	ecnCapable             paramType = 32768 // ECN Capable (0x8000)	[RFC2960]
+	zeroChecksumAcceptable paramType = 32769 // Zero Checksum Acceptable [draft-ietf-tsvwg-sctp-zero-checksum-00]
+	random                 paramType = 32770 // Random (0x8002)	[RFC4805]
+	chunkList              paramType = 32771 // Chunk List (0x8003)	[RFC4895]
+	reqHMACAlgo            paramType = 32772 // Requested HMAC Algorithm Parameter (0x8004)	[RFC4895]
+	padding                paramType = 32773 // Padding (0x8005)
+	supportedExt           paramType = 32776 // Supported Extensions (0x8008)	[RFC5061]
+	forwardTSNSupp         paramType = 49152 // Forward TSN supported (0xC000)	[RFC3758]
+	addIPAddr              paramType = 49153 // Add IP IP (0xC001)	[RFC5061]
+	delIPAddr              paramType = 49154 // Delete IP IP (0xC002)	[RFC5061]
+	errClauseInd           paramType = 49155 // Error Cause Indication (0xC003)	[RFC5061]
+	setPriAddr             paramType = 49156 // Set Primary IP (0xC004)	[RFC5061]
+	successInd             paramType = 49157 // Success Indication (0xC005)	[RFC5061]
+	adaptLayerInd          paramType = 49158 // Adaptation Layer Indication (0xC006)	[RFC5061]
 )
 
 // Parameter packet errors
@@ -86,6 +87,8 @@ func (p paramType) String() string {
 		return "Add Incoming Streams Request Parameter"
 	case ecnCapable:
 		return "ECN Capable"
+	case zeroChecksumAcceptable:
+		return "Zero Checksum Acceptable"
 	case random:
 		return "Random"
 	case chunkList:
diff --git a/vendor/github.com/pion/sctp/payload_queue.go b/vendor/github.com/pion/sctp/payload_queue.go
index e5925a51..92eacecd 100644
--- a/vendor/github.com/pion/sctp/payload_queue.go
+++ b/vendor/github.com/pion/sctp/payload_queue.go
@@ -3,81 +3,26 @@
 
 package sctp
 
-import (
-	"fmt"
-	"sort"
-)
-
 type payloadQueue struct {
-	chunkMap map[uint32]*chunkPayloadData
-	sorted   []uint32
-	dupTSN   []uint32
-	nBytes   int
+	chunks *queue[*chunkPayloadData]
+	nBytes int
 }
 
 func newPayloadQueue() *payloadQueue {
-	return &payloadQueue{chunkMap: map[uint32]*chunkPayloadData{}}
-}
-
-func (q *payloadQueue) updateSortedKeys() {
-	if q.sorted != nil {
-		return
-	}
-
-	q.sorted = make([]uint32, len(q.chunkMap))
-	i := 0
-	for k := range q.chunkMap {
-		q.sorted[i] = k
-		i++
-	}
-
-	sort.Slice(q.sorted, func(i, j int) bool {
-		return sna32LT(q.sorted[i], q.sorted[j])
-	})
-}
-
-func (q *payloadQueue) canPush(p *chunkPayloadData, cumulativeTSN uint32) bool {
-	_, ok := q.chunkMap[p.tsn]
-	if ok || sna32LTE(p.tsn, cumulativeTSN) {
-		return false
-	}
-	return true
+	return &payloadQueue{chunks: newQueue[*chunkPayloadData](128)}
 }
 
 func (q *payloadQueue) pushNoCheck(p *chunkPayloadData) {
-	q.chunkMap[p.tsn] = p
+	q.chunks.PushBack(p)
 	q.nBytes += len(p.userData)
-	q.sorted = nil
-}
-
-// push pushes a payload data. If the payload data is already in our queue or
-// older than our cumulativeTSN marker, it will be recored as duplications,
-// which can later be retrieved using popDuplicates.
-func (q *payloadQueue) push(p *chunkPayloadData, cumulativeTSN uint32) bool {
-	_, ok := q.chunkMap[p.tsn]
-	if ok || sna32LTE(p.tsn, cumulativeTSN) {
-		// Found the packet, log in dups
-		q.dupTSN = append(q.dupTSN, p.tsn)
-		return false
-	}
-
-	q.chunkMap[p.tsn] = p
-	q.nBytes += len(p.userData)
-	q.sorted = nil
-	return true
 }
 
 // pop pops only if the oldest chunk's TSN matches the given TSN.
 func (q *payloadQueue) pop(tsn uint32) (*chunkPayloadData, bool) {
-	q.updateSortedKeys()
-
-	if len(q.chunkMap) > 0 && tsn == q.sorted[0] {
-		q.sorted = q.sorted[1:]
-		if c, ok := q.chunkMap[tsn]; ok {
-			delete(q.chunkMap, tsn)
-			q.nBytes -= len(c.userData)
-			return c, true
-		}
+	if q.chunks.Len() > 0 && tsn == q.chunks.Front().tsn {
+		c := q.chunks.PopFront()
+		q.nBytes -= len(c.userData)
+		return c, true
 	}
 
 	return nil, false
@@ -85,65 +30,20 @@ func (q *payloadQueue) pop(tsn uint32) (*chunkPayloadData, bool) {
 
 // get returns reference to chunkPayloadData with the given TSN value.
 func (q *payloadQueue) get(tsn uint32) (*chunkPayloadData, bool) {
-	c, ok := q.chunkMap[tsn]
-	return c, ok
-}
-
-// popDuplicates returns an array of TSN values that were found duplicate.
-func (q *payloadQueue) popDuplicates() []uint32 {
-	dups := q.dupTSN
-	q.dupTSN = []uint32{}
-	return dups
-}
-
-func (q *payloadQueue) getGapAckBlocks(cumulativeTSN uint32) (gapAckBlocks []gapAckBlock) {
-	var b gapAckBlock
-
-	if len(q.chunkMap) == 0 {
-		return []gapAckBlock{}
-	}
-
-	q.updateSortedKeys()
-
-	for i, tsn := range q.sorted {
-		if i == 0 {
-			b.start = uint16(tsn - cumulativeTSN)
-			b.end = b.start
-			continue
-		}
-		diff := uint16(tsn - cumulativeTSN)
-		if b.end+1 == diff {
-			b.end++
-		} else {
-			gapAckBlocks = append(gapAckBlocks, gapAckBlock{
-				start: b.start,
-				end:   b.end,
-			})
-			b.start = diff
-			b.end = diff
-		}
+	length := q.chunks.Len()
+	if length == 0 {
+		return nil, false
 	}
-
-	gapAckBlocks = append(gapAckBlocks, gapAckBlock{
-		start: b.start,
-		end:   b.end,
-	})
-
-	return gapAckBlocks
-}
-
-func (q *payloadQueue) getGapAckBlocksString(cumulativeTSN uint32) string {
-	gapAckBlocks := q.getGapAckBlocks(cumulativeTSN)
-	str := fmt.Sprintf("cumTSN=%d", cumulativeTSN)
-	for _, b := range gapAckBlocks {
-		str += fmt.Sprintf(",%d-%d", b.start, b.end)
+	head := q.chunks.Front().tsn
+	if tsn < head || int(tsn-head) >= length {
+		return nil, false
 	}
-	return str
+	return q.chunks.At(int(tsn - head)), true
 }
 
 func (q *payloadQueue) markAsAcked(tsn uint32) int {
 	var nBytesAcked int
-	if c, ok := q.chunkMap[tsn]; ok {
+	if c, ok := q.get(tsn); ok {
 		c.acked = true
 		c.retransmit = false
 		nBytesAcked = len(c.userData)
@@ -154,18 +54,9 @@ func (q *payloadQueue) markAsAcked(tsn uint32) int {
 	return nBytesAcked
 }
 
-func (q *payloadQueue) getLastTSNReceived() (uint32, bool) {
-	q.updateSortedKeys()
-
-	qlen := len(q.sorted)
-	if qlen == 0 {
-		return 0, false
-	}
-	return q.sorted[qlen-1], true
-}
-
 func (q *payloadQueue) markAllToRetrasmit() {
-	for _, c := range q.chunkMap {
+	for i := 0; i < q.chunks.Len(); i++ {
+		c := q.chunks.At(i)
 		if c.acked || c.abandoned() {
 			continue
 		}
@@ -178,5 +69,5 @@ func (q *payloadQueue) getNumBytes() int {
 }
 
 func (q *payloadQueue) size() int {
-	return len(q.chunkMap)
+	return q.chunks.Len()
 }
diff --git a/vendor/github.com/pion/sctp/queue.go b/vendor/github.com/pion/sctp/queue.go
new file mode 100644
index 00000000..a6945caf
--- /dev/null
+++ b/vendor/github.com/pion/sctp/queue.go
@@ -0,0 +1,70 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
+package sctp
+
+type queue[T any] struct {
+	buf   []T
+	head  int
+	tail  int
+	count int
+}
+
+const minCap = 16
+
+func newQueue[T any](capacity int) *queue[T] {
+	queueCap := minCap
+	for queueCap < capacity {
+		queueCap <<= 1
+	}
+
+	return &queue[T]{
+		buf: make([]T, queueCap),
+	}
+}
+
+func (q *queue[T]) Len() int {
+	return q.count
+}
+
+func (q *queue[T]) PushBack(ele T) {
+	q.growIfFull()
+	q.buf[q.tail] = ele
+	q.tail = (q.tail + 1) % len(q.buf)
+	q.count++
+}
+
+func (q *queue[T]) PopFront() T {
+	ele := q.buf[q.head]
+	var zeroVal T
+	q.buf[q.head] = zeroVal
+	q.head = (q.head + 1) % len(q.buf)
+	q.count--
+	return ele
+}
+
+func (q *queue[T]) Front() T {
+	return q.buf[q.head]
+}
+
+func (q *queue[T]) At(i int) T {
+	return q.buf[(q.head+i)%(len(q.buf))]
+}
+
+func (q *queue[T]) growIfFull() {
+	if q.count < len(q.buf) {
+		return
+	}
+
+	newBuf := make([]T, q.count<<1)
+	if q.tail > q.head {
+		copy(newBuf, q.buf[q.head:q.tail])
+	} else {
+		n := copy(newBuf, q.buf[q.head:])
+		copy(newBuf[n:], q.buf[:q.tail])
+	}
+
+	q.head = 0
+	q.tail = q.count
+	q.buf = newBuf
+}
diff --git a/vendor/github.com/pion/sctp/reassembly_queue.go b/vendor/github.com/pion/sctp/reassembly_queue.go
index c23e6991..e0d527c0 100644
--- a/vendor/github.com/pion/sctp/reassembly_queue.go
+++ b/vendor/github.com/pion/sctp/reassembly_queue.go
@@ -155,11 +155,22 @@ func (r *reassemblyQueue) push(chunk *chunkPayloadData) bool {
 		return false
 	}
 
-	// Check if a chunkSet with the SSN already exists
-	for _, set := range r.ordered {
-		if set.ssn == chunk.streamSequenceNumber {
-			cset = set
-			break
+	// Check if a fragmented chunkSet with the fragmented SSN already exists
+	if chunk.isFragmented() {
+		for _, set := range r.ordered {
+			// nolint:godox
+			// TODO: add caution around SSN wrapping here... this helps only a little bit
+			// by ensuring we don't add to an unfragmented cset (1 chunk). There's
+			// a case where if the SSN does wrap around, we may see the same SSN
+			// for a different chunk.
+
+			// nolint:godox
+			// TODO: this slice can get pretty big; it may be worth maintaining a map
+			// for O(1) lookups at the cost of 2x memory.
+			if set.ssn == chunk.streamSequenceNumber && set.chunks[0].isFragmented() {
+				cset = set
+				break
+			}
 		}
 	}
 
diff --git a/vendor/github.com/pion/sctp/receive_payload_queue.go b/vendor/github.com/pion/sctp/receive_payload_queue.go
new file mode 100644
index 00000000..2a4f2bbf
--- /dev/null
+++ b/vendor/github.com/pion/sctp/receive_payload_queue.go
@@ -0,0 +1,186 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
+package sctp
+
+import (
+	"fmt"
+	"math/bits"
+)
+
+type receivePayloadQueue struct {
+	tailTSN      uint32
+	chunkSize    int
+	tsnBitmask   []uint64
+	dupTSN       []uint32
+	maxTSNOffset uint32
+
+	cumulativeTSN uint32
+}
+
+func newReceivePayloadQueue(maxTSNOffset uint32) *receivePayloadQueue {
+	maxTSNOffset = ((maxTSNOffset + 63) / 64) * 64
+	return &receivePayloadQueue{
+		tsnBitmask:   make([]uint64, maxTSNOffset/64),
+		maxTSNOffset: maxTSNOffset,
+	}
+}
+
+func (q *receivePayloadQueue) init(cumulativeTSN uint32) {
+	q.cumulativeTSN = cumulativeTSN
+	q.tailTSN = cumulativeTSN
+	q.chunkSize = 0
+	for i := range q.tsnBitmask {
+		q.tsnBitmask[i] = 0
+	}
+	q.dupTSN = q.dupTSN[:0]
+}
+
+func (q *receivePayloadQueue) hasChunk(tsn uint32) bool {
+	if q.chunkSize == 0 || sna32LTE(tsn, q.cumulativeTSN) || sna32GT(tsn, q.tailTSN) {
+		return false
+	}
+
+	index, offset := int(tsn/64)%len(q.tsnBitmask), tsn%64
+	return q.tsnBitmask[index]&(1<<offset) != 0
+}
+
+func (q *receivePayloadQueue) canPush(tsn uint32) bool {
+	ok := q.hasChunk(tsn)
+	if ok || sna32LTE(tsn, q.cumulativeTSN) || sna32GT(tsn, q.cumulativeTSN+q.maxTSNOffset) {
+		return false
+	}
+	return true
+}
+
+// push pushes a payload data. If the payload data is already in our queue or
+// older than our cumulativeTSN marker, it will be recored as duplications,
+// which can later be retrieved using popDuplicates.
+func (q *receivePayloadQueue) push(tsn uint32) bool {
+	if sna32GT(tsn, q.cumulativeTSN+q.maxTSNOffset) {
+		return false
+	}
+
+	if sna32LTE(tsn, q.cumulativeTSN) || q.hasChunk(tsn) {
+		// Found the packet, log in dups
+		q.dupTSN = append(q.dupTSN, tsn)
+		return false
+	}
+
+	index, offset := int(tsn/64)%len(q.tsnBitmask), tsn%64
+	q.tsnBitmask[index] |= (1 << offset)
+	q.chunkSize++
+	if sna32GT(tsn, q.tailTSN) {
+		q.tailTSN = tsn
+	}
+	return true
+}
+
+// pop advances cumulativeTSN and pops the oldest chunk's TSN if it matches the given TSN or force is true.
+func (q *receivePayloadQueue) pop(force bool) bool {
+	tsn := q.cumulativeTSN + 1
+	if q.hasChunk(tsn) {
+		index, offset := int(tsn/64)%len(q.tsnBitmask), int(tsn%64)
+		q.tsnBitmask[index] &= ^uint64(1 << (offset))
+		q.chunkSize--
+		q.cumulativeTSN++
+		return true
+	}
+	if force {
+		q.cumulativeTSN++
+		if q.chunkSize == 0 {
+			q.tailTSN = q.cumulativeTSN
+		}
+	}
+	return false
+}
+
+// popDuplicates returns an array of TSN values that were found duplicate.
+func (q *receivePayloadQueue) popDuplicates() []uint32 {
+	dups := q.dupTSN
+	q.dupTSN = []uint32{}
+	return dups
+}
+
+func (q *receivePayloadQueue) getGapAckBlocks() (gapAckBlocks []gapAckBlock) {
+	var b gapAckBlock
+
+	if q.chunkSize == 0 {
+		return nil
+	}
+
+	startTSN, endTSN := q.cumulativeTSN+1, q.tailTSN
+	var findEnd bool
+	for tsn := startTSN; sna32LTE(tsn, endTSN); {
+		index, offset := int(tsn/64)%len(q.tsnBitmask), int(tsn%64)
+		if !findEnd {
+			// find first received tsn as start
+			if nonZeroBit, ok := getFirstNonZeroBit(q.tsnBitmask[index], offset, 64); ok {
+				b.start = uint16(tsn + uint32(nonZeroBit-offset) - q.cumulativeTSN)
+				tsn += uint32(nonZeroBit - offset)
+				findEnd = true
+			} else {
+				// no result, find start bits in next uint64 bitmask
+				tsn += uint32(64 - offset)
+			}
+		} else {
+			if zeroBit, ok := getFirstZeroBit(q.tsnBitmask[index], offset, 64); ok {
+				b.end = uint16(tsn + uint32(zeroBit-offset) - 1 - q.cumulativeTSN)
+				tsn += uint32(zeroBit - offset)
+				if sna32LTE(tsn, endTSN) {
+					gapAckBlocks = append(gapAckBlocks, gapAckBlock{
+						start: b.start,
+						end:   b.end,
+					})
+				}
+				findEnd = false
+			} else {
+				tsn += uint32(64 - offset)
+			}
+
+			// no zero bit at the end, close and append the last gap
+			if sna32GT(tsn, endTSN) {
+				b.end = uint16(endTSN - q.cumulativeTSN)
+				gapAckBlocks = append(gapAckBlocks, gapAckBlock{
+					start: b.start,
+					end:   b.end,
+				})
+				break
+			}
+		}
+	}
+	return gapAckBlocks
+}
+
+func (q *receivePayloadQueue) getGapAckBlocksString() string {
+	gapAckBlocks := q.getGapAckBlocks()
+	str := fmt.Sprintf("cumTSN=%d", q.cumulativeTSN)
+	for _, b := range gapAckBlocks {
+		str += fmt.Sprintf(",%d-%d", b.start, b.end)
+	}
+	return str
+}
+
+func (q *receivePayloadQueue) getLastTSNReceived() (uint32, bool) {
+	if q.chunkSize == 0 {
+		return 0, false
+	}
+	return q.tailTSN, true
+}
+
+func (q *receivePayloadQueue) getcumulativeTSN() uint32 {
+	return q.cumulativeTSN
+}
+
+func (q *receivePayloadQueue) size() int {
+	return q.chunkSize
+}
+
+func getFirstNonZeroBit(val uint64, start, end int) (int, bool) {
+	i := bits.TrailingZeros64(val >> uint64(start))
+	return i + start, i+start < end
+}
+
+func getFirstZeroBit(val uint64, start, end int) (int, bool) {
+	return getFirstNonZeroBit(^val, start, end)
+}
diff --git a/vendor/github.com/pion/sctp/rtx_timer.go b/vendor/github.com/pion/sctp/rtx_timer.go
index 8be001c1..1fea3931 100644
--- a/vendor/github.com/pion/sctp/rtx_timer.go
+++ b/vendor/github.com/pion/sctp/rtx_timer.go
@@ -10,14 +10,28 @@ import (
 )
 
 const (
-	rtoInitial     float64 = 3.0 * 1000  // msec
-	rtoMin         float64 = 1.0 * 1000  // msec
-	rtoMax         float64 = 60.0 * 1000 // msec
-	rtoAlpha       float64 = 0.125
-	rtoBeta        float64 = 0.25
-	maxInitRetrans uint    = 8
-	pathMaxRetrans uint    = 5
-	noMaxRetrans   uint    = 0
+	// RTO.Initial in msec
+	rtoInitial float64 = 1.0 * 1000
+
+	// RTO.Min in msec
+	rtoMin float64 = 1.0 * 1000
+
+	// RTO.Max in msec
+	defaultRTOMax float64 = 60.0 * 1000
+
+	// RTO.Alpha
+	rtoAlpha float64 = 0.125
+
+	// RTO.Beta
+	rtoBeta float64 = 0.25
+
+	// Max.Init.Retransmits:
+	maxInitRetrans uint = 8
+
+	// Path.Max.Retrans
+	pathMaxRetrans uint = 5
+
+	noMaxRetrans uint = 0
 )
 
 // rtoManager manages Rtx timeout values.
@@ -28,13 +42,19 @@ type rtoManager struct {
 	rto      float64
 	noUpdate bool
 	mutex    sync.RWMutex
+	rtoMax   float64
 }
 
 // newRTOManager creates a new rtoManager.
-func newRTOManager() *rtoManager {
-	return &rtoManager{
-		rto: rtoInitial,
+func newRTOManager(rtoMax float64) *rtoManager {
+	mgr := rtoManager{
+		rto:    rtoInitial,
+		rtoMax: rtoMax,
 	}
+	if mgr.rtoMax == 0 {
+		mgr.rtoMax = defaultRTOMax
+	}
+	return &mgr
 }
 
 // setNewRTT takes a newly measured RTT then adjust the RTO in msec.
@@ -55,7 +75,7 @@ func (m *rtoManager) setNewRTT(rtt float64) float64 {
 		m.rttvar = (1-rtoBeta)*m.rttvar + rtoBeta*(math.Abs(m.srtt-rtt))
 		m.srtt = (1-rtoAlpha)*m.srtt + rtoAlpha*rtt
 	}
-	m.rto = math.Min(math.Max(m.srtt+4*m.rttvar, rtoMin), rtoMax)
+	m.rto = math.Min(math.Max(m.srtt+4*m.rttvar, rtoMin), m.rtoMax)
 	return m.srtt
 }
 
@@ -98,27 +118,66 @@ type rtxTimerObserver interface {
 	onRetransmissionFailure(timerID int)
 }
 
+type rtxTimerState uint8
+
+const (
+	rtxTimerStopped rtxTimerState = iota
+	rtxTimerStarted
+	rtxTimerClosed
+)
+
 // rtxTimer provides the retnransmission timer conforms with RFC 4960 Sec 6.3.1
 type rtxTimer struct {
-	id         int
+	timer      *time.Timer
 	observer   rtxTimerObserver
+	id         int
 	maxRetrans uint
-	stopFunc   stopTimerLoop
-	closed     bool
-	mutex      sync.RWMutex
+	rtoMax     float64
+	mutex      sync.Mutex
+	rto        float64
+	nRtos      uint
+	state      rtxTimerState
+	pending    uint8
 }
 
-type stopTimerLoop func()
-
 // newRTXTimer creates a new retransmission timer.
 // if maxRetrans is set to 0, it will keep retransmitting until stop() is called.
 // (it will never make onRetransmissionFailure() callback.
-func newRTXTimer(id int, observer rtxTimerObserver, maxRetrans uint) *rtxTimer {
-	return &rtxTimer{
+func newRTXTimer(id int, observer rtxTimerObserver, maxRetrans uint,
+	rtoMax float64,
+) *rtxTimer {
+	timer := rtxTimer{
 		id:         id,
 		observer:   observer,
 		maxRetrans: maxRetrans,
+		rtoMax:     rtoMax,
+	}
+	if timer.rtoMax == 0 {
+		timer.rtoMax = defaultRTOMax
+	}
+	timer.timer = time.AfterFunc(math.MaxInt64, timer.timeout)
+	timer.timer.Stop()
+	return &timer
+}
+
+func (t *rtxTimer) calculateNextTimeout() time.Duration {
+	timeout := calculateNextTimeout(t.rto, t.nRtos, t.rtoMax)
+	return time.Duration(timeout) * time.Millisecond
+}
+
+func (t *rtxTimer) timeout() {
+	t.mutex.Lock()
+	if t.pending--; t.pending == 0 && t.state == rtxTimerStarted {
+		if t.nRtos++; t.maxRetrans == 0 || t.nRtos <= t.maxRetrans {
+			t.timer.Reset(t.calculateNextTimeout())
+			t.pending++
+			defer t.observer.onRetransmissionTimeout(t.id, t.nRtos)
+		} else {
+			t.state = rtxTimerStopped
+			defer t.observer.onRetransmissionFailure(t.id)
+		}
 	}
+	t.mutex.Unlock()
 }
 
 // start starts the timer.
@@ -126,13 +185,8 @@ func (t *rtxTimer) start(rto float64) bool {
 	t.mutex.Lock()
 	defer t.mutex.Unlock()
 
-	// this timer is already closed
-	if t.closed {
-		return false
-	}
-
-	// this is a noop if the timer is always running
-	if t.stopFunc != nil {
+	// this timer is already closed or aleady running
+	if t.state != rtxTimerStopped {
 		return false
 	}
 
@@ -140,37 +194,11 @@ func (t *rtxTimer) start(rto float64) bool {
 	// fast timeout for the tests. Non-test code should pass in the
 	// rto generated by rtoManager getRTO() method which caps the
 	// value at RTO.Min or at RTO.Max.
-	var nRtos uint
-
-	cancelCh := make(chan struct{})
-
-	go func() {
-		canceling := false
-
-		for !canceling {
-			timeout := calculateNextTimeout(rto, nRtos)
-			timer := time.NewTimer(time.Duration(timeout) * time.Millisecond)
-
-			select {
-			case <-timer.C:
-				nRtos++
-				if t.maxRetrans == 0 || nRtos <= t.maxRetrans {
-					t.observer.onRetransmissionTimeout(t.id, nRtos)
-				} else {
-					t.stop()
-					t.observer.onRetransmissionFailure(t.id)
-				}
-			case <-cancelCh:
-				canceling = true
-				timer.Stop()
-			}
-		}
-	}()
-
-	t.stopFunc = func() {
-		close(cancelCh)
-	}
-
+	t.rto = rto
+	t.nRtos = 0
+	t.state = rtxTimerStarted
+	t.pending++
+	t.timer.Reset(t.calculateNextTimeout())
 	return true
 }
 
@@ -179,9 +207,11 @@ func (t *rtxTimer) stop() {
 	t.mutex.Lock()
 	defer t.mutex.Unlock()
 
-	if t.stopFunc != nil {
-		t.stopFunc()
-		t.stopFunc = nil
+	if t.state == rtxTimerStarted {
+		if t.timer.Stop() {
+			t.pending--
+		}
+		t.state = rtxTimerStopped
 	}
 }
 
@@ -191,24 +221,22 @@ func (t *rtxTimer) close() {
 	t.mutex.Lock()
 	defer t.mutex.Unlock()
 
-	if t.stopFunc != nil {
-		t.stopFunc()
-		t.stopFunc = nil
+	if t.state == rtxTimerStarted && t.timer.Stop() {
+		t.pending--
 	}
-
-	t.closed = true
+	t.state = rtxTimerClosed
 }
 
 // isRunning tests if the timer is running.
 // Debug purpose only
 func (t *rtxTimer) isRunning() bool {
-	t.mutex.RLock()
-	defer t.mutex.RUnlock()
+	t.mutex.Lock()
+	defer t.mutex.Unlock()
 
-	return (t.stopFunc != nil)
+	return t.state == rtxTimerStarted
 }
 
-func calculateNextTimeout(rto float64, nRtos uint) float64 {
+func calculateNextTimeout(rto float64, nRtos uint, rtoMax float64) float64 {
 	// RFC 4096 sec 6.3.3.  Handle T3-rtx Expiration
 	//   E2)  For the destination address for which the timer expires, set RTO
 	//        <- RTO * 2 ("back off the timer").  The maximum value discussed
diff --git a/vendor/github.com/pion/sctp/stream.go b/vendor/github.com/pion/sctp/stream.go
index b12bb24c..47e06f35 100644
--- a/vendor/github.com/pion/sctp/stream.go
+++ b/vendor/github.com/pion/sctp/stream.go
@@ -7,7 +7,6 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"math"
 	"os"
 	"sync"
 	"sync/atomic"
@@ -175,6 +174,11 @@ func (s *Stream) SetReadDeadline(deadline time.Time) error {
 				t.Stop()
 				return
 			case <-t.C:
+				select {
+				case <-readTimeoutCancel:
+					return
+				default:
+				}
 				s.lock.Lock()
 				if s.readErr == nil {
 					s.readErr = ErrReadDeadlineExceeded
@@ -261,7 +265,7 @@ func (s *Stream) Write(p []byte) (n int, err error) {
 func (s *Stream) WriteSCTP(p []byte, ppi PayloadProtocolIdentifier) (int, error) {
 	maxMessageSize := s.association.MaxMessageSize()
 	if len(p) > int(maxMessageSize) {
-		return 0, fmt.Errorf("%w: %v", ErrOutboundPacketTooLarge, math.MaxUint16)
+		return 0, fmt.Errorf("%w: %v", ErrOutboundPacketTooLarge, maxMessageSize)
 	}
 
 	if s.State() != StreamStateOpen {
diff --git a/vendor/github.com/pion/sdp/v3/.gitignore b/vendor/github.com/pion/sdp/v3/.gitignore
index f977e748..6e2f206a 100644
--- a/vendor/github.com/pion/sdp/v3/.gitignore
+++ b/vendor/github.com/pion/sdp/v3/.gitignore
@@ -1,3 +1,6 @@
+# SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+# SPDX-License-Identifier: MIT
+
 ### JetBrains IDE ###
 #####################
 .idea/
diff --git a/vendor/github.com/pion/sdp/v3/.golangci.yml b/vendor/github.com/pion/sdp/v3/.golangci.yml
index d7a88eca..6dd80c80 100644
--- a/vendor/github.com/pion/sdp/v3/.golangci.yml
+++ b/vendor/github.com/pion/sdp/v3/.golangci.yml
@@ -1,3 +1,6 @@
+# SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+# SPDX-License-Identifier: MIT
+
 linters-settings:
   govet:
     check-shadowing: true
@@ -10,7 +13,14 @@ linters-settings:
       modules:
         - github.com/pkg/errors:
             recommendations:
-            - errors
+              - errors
+  forbidigo:
+    forbid:
+      - ^fmt.Print(f|ln)?$
+      - ^log.(Panic|Fatal|Print)(f|ln)?$
+      - ^os.Exit$
+      - ^panic$
+      - ^print(ln)?$
 
 linters:
   enable:
@@ -18,9 +28,7 @@ linters:
     - bidichk          # Checks for dangerous unicode character sequences
     - bodyclose        # checks whether HTTP response body is closed successfully
     - contextcheck     # check the function whether use a non-inherited context
-    - deadcode         # Finds unused code
     - decorder         # check declaration order and count of types, constants, variables and functions
-    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - dogsled          # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
     - dupl             # Tool for code clone detection
     - durationcheck    # check for two durations multiplied together
@@ -30,6 +38,7 @@ linters:
     - errorlint        # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
     - exhaustive       # check exhaustiveness of enum switch statements
     - exportloopref    # checks for pointers to enclosing loop variables
+    - forbidigo        # Forbids identifiers
     - forcetypeassert  # finds forced type assertions
     - gci              # Gci control golang package import order and make it always deterministic.
     - gochecknoglobals # Checks that no globals are present in Go code
@@ -53,14 +62,12 @@ linters:
     - importas         # Enforces consistent import aliases
     - ineffassign      # Detects when assignments to existing variables are not used
     - misspell         # Finds commonly misspelled English words in comments
-    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nilerr           # Finds the code that returns nil even if it checks that the error is not nil.
     - nilnil           # Checks that there is no simultaneous return of `nil` error and an invalid value.
     - noctx            # noctx finds sending http request without context.Context
     - predeclared      # find code that shadows one of Go's predeclared identifiers
     - revive           # golint replacement, finds style mistakes
     - staticcheck      # Staticcheck is a go vet on steroids, applying a ton of static analysis checks
-    - structcheck      # Finds unused struct fields
     - stylecheck       # Stylecheck is a replacement for golint
     - tagliatelle      # Checks the struct tags.
     - tenv             # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17
@@ -69,14 +76,13 @@ linters:
     - unconvert        # Remove unnecessary type conversions
     - unparam          # Reports unused function parameters
     - unused           # Checks Go code for unused constants, variables, functions and types
-    - varcheck         # Finds unused global variables and constants
     - wastedassign     # wastedassign finds wasted assignment statements
     - whitespace       # Tool for detection of leading and trailing whitespace
   disable:
+    - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - containedctx     # containedctx is a linter that detects struct contained context.Context field
     - cyclop           # checks function and package cyclomatic complexity
     - exhaustivestruct # Checks if all struct's fields are initialized
-    - forbidigo        # Forbids identifiers
     - funlen           # Tool for detection of long functions
     - gocyclo          # Computes and checks the cyclomatic complexity of functions
     - godot            # Check if comments end in a period
@@ -87,6 +93,7 @@ linters:
     - maintidx         # maintidx measures the maintainability index of each function.
     - makezero         # Finds slice declarations with non-zero initial length
     - maligned         # Tool to detect Go structs that would take less memory if their fields were sorted
+    - nakedret         # Finds naked returns in functions greater than a specified function length
     - nestif           # Reports deeply nested if statements
     - nlreturn         # nlreturn checks for a new line before return and branch statements to increase code clarity
     - nolintlint       # Reports ill-formed or insufficient nolint directives
@@ -104,16 +111,16 @@ linters:
 issues:
   exclude-use-default: false
   exclude-rules:
-    # Allow complex tests, better to be self contained
-    - path: _test\.go
+    # Allow complex tests and examples, better to be self contained
+    - path: (examples|main\.go|_test\.go)
       linters:
+        - forbidigo
         - gocognit
 
-    # Allow complex main function in examples
-    - path: examples
-      text: "of func `main` is high"
+    # Allow forbidden identifiers in CLI commands
+    - path: cmd
       linters:
-        - gocognit
+        - forbidigo
 
 run:
   skip-dirs-use-default: false
diff --git a/vendor/github.com/pion/sdp/v3/.goreleaser.yml b/vendor/github.com/pion/sdp/v3/.goreleaser.yml
new file mode 100644
index 00000000..30093e9d
--- /dev/null
+++ b/vendor/github.com/pion/sdp/v3/.goreleaser.yml
@@ -0,0 +1,5 @@
+# SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+# SPDX-License-Identifier: MIT
+
+builds:
+- skip: true
diff --git a/vendor/github.com/pion/sdp/v3/AUTHORS.txt b/vendor/github.com/pion/sdp/v3/AUTHORS.txt
deleted file mode 100644
index 038e5991..00000000
--- a/vendor/github.com/pion/sdp/v3/AUTHORS.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-# Thank you to everyone that made Pion possible. If you are interested in contributing
-# we would love to have you https://github.com/pion/webrtc/wiki/Contributing
-#
-# This file is auto generated, using git to list all individuals contributors.
-# see `.github/generate-authors.sh` for the scripting
-adwpc <adwpc@hotmail.com>
-Atsushi Watanabe <atsushi.w@ieee.org>
-backkem <mail@backkem.me>
-Brendan Abolivier <babolivier@matrix.org>
-chenkaiC4 <chenkaic4@gmail.com>
-cnderrauber <zengjie9004@gmail.com>
-Daniele Sluijters <daenney@users.noreply.github.com>
-Graham King <graham@gkgk.org>
-Guilherme <gqgs@protonmail.com>
-Hugo Arregui <hugo.arregui@gmail.com>
-Jason <jabrady42@gmail.com>
-Jerko Steiner <jerko.steiner@gmail.com>
-John Bradley <jrb@turrettech.com>
-Konstantin Itskov <konstantin.itskov@kovits.com>
-korymiller1489 <kmiller@unwiredrevolution.com>
-Luke S <luke@street.dev>
-Max Hawkins <maxhawkins@gmail.com>
-Maxim Oransky <maxim.oransky@gmail.com>
-mchlrhw <4028654+mchlrhw@users.noreply.github.com>
-Michael MacDonald <mike.macdonald@savantsystems.com>
-Mustafa Navruz <mustafanavruz@gmail.com>
-Roman Romanenko <romandafe94@gmail.com>
-Sean DuBois <seaduboi@amazon.com>
-Sean DuBois <sean@siobud.com>
-tarrencev <tarrence13@gmail.com>
-Woodrow Douglass <wdouglass@carnegierobotics.com>
-ZHENK <chengzhenyang@gmail.com>
diff --git a/vendor/github.com/pion/sdp/v3/LICENSE b/vendor/github.com/pion/sdp/v3/LICENSE
index ab602974..491caf6b 100644
--- a/vendor/github.com/pion/sdp/v3/LICENSE
+++ b/vendor/github.com/pion/sdp/v3/LICENSE
@@ -1,21 +1,9 @@
 MIT License
 
-Copyright (c) 2018 
+Copyright (c) 2023 The Pion community <https://pion.ly>
 
-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:
+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 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.
+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/pion/sdp/v3/README.md b/vendor/github.com/pion/sdp/v3/README.md
index c29c97f7..1cb8dbd2 100644
--- a/vendor/github.com/pion/sdp/v3/README.md
+++ b/vendor/github.com/pion/sdp/v3/README.md
@@ -9,27 +9,27 @@
   <a href="https://sourcegraph.com/github.com/pion/sdp?badge"><img src="https://sourcegraph.com/github.com/pion/sdp/-/badge.svg" alt="Sourcegraph Widget"></a>
   <a href="https://pion.ly/slack"><img src="https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen" alt="Slack Widget"></a>
   <br>
-  <a href="https://travis-ci.org/pion/sdp"><img src="https://travis-ci.org/pion/sdp.svg?branch=master" alt="Build Status"></a>
-  <a href="https://pkg.go.dev/github.com/pion/sdp/v2"><img src="https://godoc.org/github.com/pion/sdp?status.svg" alt="GoDoc"></a>
+  <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/pion/sdp/test.yaml">
+  <a href="https://pkg.go.dev/github.com/pion/sdp/v2"><img src="https://pkg.go.dev/badge/github.com/pion/sdp/v2.svg" alt="Go Reference"></a>
   <a href="https://codecov.io/gh/pion/sdp"><img src="https://codecov.io/gh/pion/sdp/branch/master/graph/badge.svg" alt="Coverage Status"></a>
   <a href="https://goreportcard.com/report/github.com/pion/sdp"><img src="https://goreportcard.com/badge/github.com/pion/sdp" alt="Go Report Card"></a>
   <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
 </p>
 <br>
 
-
 ### Roadmap
 The library is used as a part of our WebRTC implementation. Please refer to that [roadmap](https://github.com/pion/webrtc/issues/9) to track our major milestones.
 
 ### Community
-Pion has an active community on the [Golang Slack](https://invite.slack.golangbridge.org/). Sign up and join the **#pion** channel for discussions and support. You can also use [Pion mailing list](https://groups.google.com/forum/#!forum/pion).
+Pion has an active community on the [Slack](https://pion.ly/slack).
 
-We are always looking to support **your projects**. Please reach out if you have something to build!
+Follow the [Pion Twitter](https://twitter.com/_pion) for project updates and important WebRTC news.
 
+We are always looking to support **your projects**. Please reach out if you have something to build!
 If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly)
 
 ### Contributing
-Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contributing)** to join the group of amazing people making this project possible:
+Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible
 
 ### License
-MIT License - see [LICENSE](LICENSE) for full text
+MIT License - see [LICENSE](LICENSE) for full text
\ No newline at end of file
diff --git a/vendor/github.com/pion/sdp/v3/base_lexer.go b/vendor/github.com/pion/sdp/v3/base_lexer.go
index f1f2ccd1..edd532a5 100644
--- a/vendor/github.com/pion/sdp/v3/base_lexer.go
+++ b/vendor/github.com/pion/sdp/v3/base_lexer.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package sdp
 
 import (
@@ -22,12 +25,12 @@ func (e syntaxError) Error() string {
 }
 
 type baseLexer struct {
-	value []byte
+	value string
 	pos   int
 }
 
 func (l baseLexer) syntaxError() error {
-	return syntaxError{s: string(l.value), i: l.pos - 1}
+	return syntaxError{s: l.value, i: l.pos - 1}
 }
 
 func (l *baseLexer) unreadByte() error {
@@ -154,7 +157,7 @@ func (l *baseLexer) readField() (string, error) {
 			break
 		}
 	}
-	return string(l.value[start:stop]), nil
+	return l.value[start:stop], nil
 }
 
 // Returns symbols until line end
@@ -170,50 +173,32 @@ func (l *baseLexer) readLine() (string, error) {
 			trim++
 		}
 		if ch == '\n' {
-			return string(l.value[start : l.pos-trim]), nil
-		}
-	}
-}
-
-func (l *baseLexer) readString(until byte) (string, error) {
-	start := l.pos
-	for {
-		ch, err := l.readByte()
-		if err != nil {
-			return "", err
-		}
-		if ch == until {
-			return string(l.value[start:l.pos]), nil
+			return l.value[start : l.pos-trim], nil
 		}
 	}
 }
 
-func (l *baseLexer) readType() (string, error) {
+func (l *baseLexer) readType() (byte, error) {
 	for {
-		b, err := l.readByte()
+		firstByte, err := l.readByte()
 		if err != nil {
-			return "", err
+			return 0, err
 		}
 
-		if isNewline(b) {
+		if isNewline(firstByte) {
 			continue
 		}
 
-		err = l.unreadByte()
-		if err != nil {
-			return "", err
-		}
-
-		key, err := l.readString('=')
+		secondByte, err := l.readByte()
 		if err != nil {
-			return key, err
+			return 0, err
 		}
 
-		if len(key) == 2 {
-			return key, nil
+		if secondByte != '=' {
+			return firstByte, l.syntaxError()
 		}
 
-		return key, l.syntaxError()
+		return firstByte, nil
 	}
 }
 
diff --git a/vendor/github.com/pion/sdp/v3/codecov.yml b/vendor/github.com/pion/sdp/v3/codecov.yml
index 085200a4..263e4d45 100644
--- a/vendor/github.com/pion/sdp/v3/codecov.yml
+++ b/vendor/github.com/pion/sdp/v3/codecov.yml
@@ -3,6 +3,8 @@
 #
 # It is automatically copied from https://github.com/pion/.goassets repository.
 #
+# SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+# SPDX-License-Identifier: MIT
 
 coverage:
   status:
diff --git a/vendor/github.com/pion/sdp/v3/common_description.go b/vendor/github.com/pion/sdp/v3/common_description.go
index 1174be41..9db79036 100644
--- a/vendor/github.com/pion/sdp/v3/common_description.go
+++ b/vendor/github.com/pion/sdp/v3/common_description.go
@@ -1,8 +1,10 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package sdp
 
 import (
 	"strconv"
-	"strings"
 )
 
 // Information describes the "i=" field which provides textual information
@@ -10,7 +12,15 @@ import (
 type Information string
 
 func (i Information) String() string {
-	return string(i)
+	return stringFromMarshal(i.marshalInto, i.marshalSize)
+}
+
+func (i Information) marshalInto(b []byte) []byte {
+	return append(b, i...)
+}
+
+func (i Information) marshalSize() (size int) {
+	return len(i)
 }
 
 // ConnectionInformation defines the representation for the "c=" field
@@ -22,11 +32,29 @@ type ConnectionInformation struct {
 }
 
 func (c ConnectionInformation) String() string {
-	parts := []string{c.NetworkType, c.AddressType}
-	if c.Address != nil && c.Address.String() != "" {
-		parts = append(parts, c.Address.String())
+	return stringFromMarshal(c.marshalInto, c.marshalSize)
+}
+
+func (c ConnectionInformation) marshalInto(b []byte) []byte {
+	b = append(append(b, c.NetworkType...), ' ')
+	b = append(b, c.AddressType...)
+
+	if c.Address != nil {
+		b = append(b, ' ')
+		b = c.Address.marshalInto(b)
+	}
+
+	return b
+}
+
+func (c ConnectionInformation) marshalSize() (size int) {
+	size = len(c.NetworkType)
+	size += 1 + len(c.AddressType)
+	if c.Address != nil {
+		size += 1 + c.Address.marshalSize()
 	}
-	return strings.Join(parts, " ")
+
+	return
 }
 
 // Address desribes a structured address token from within the "c=" field.
@@ -37,17 +65,33 @@ type Address struct {
 }
 
 func (c *Address) String() string {
-	var parts []string
-	parts = append(parts, c.Address)
+	return stringFromMarshal(c.marshalInto, c.marshalSize)
+}
+
+func (c *Address) marshalInto(b []byte) []byte {
+	b = append(b, c.Address...)
 	if c.TTL != nil {
-		parts = append(parts, strconv.Itoa(*c.TTL))
+		b = append(b, '/')
+		b = strconv.AppendInt(b, int64(*c.TTL), 10)
+	}
+	if c.Range != nil {
+		b = append(b, '/')
+		b = strconv.AppendInt(b, int64(*c.Range), 10)
 	}
 
+	return b
+}
+
+func (c Address) marshalSize() (size int) {
+	size = len(c.Address)
+	if c.TTL != nil {
+		size += 1 + lenUint(uint64(*c.TTL))
+	}
 	if c.Range != nil {
-		parts = append(parts, strconv.Itoa(*c.Range))
+		size += 1 + lenUint(uint64(*c.Range))
 	}
 
-	return strings.Join(parts, "/")
+	return
 }
 
 // Bandwidth describes an optional field which denotes the proposed bandwidth
@@ -59,19 +103,39 @@ type Bandwidth struct {
 }
 
 func (b Bandwidth) String() string {
-	var output string
+	return stringFromMarshal(b.marshalInto, b.marshalSize)
+}
+
+func (b Bandwidth) marshalInto(d []byte) []byte {
+	if b.Experimental {
+		d = append(d, "X-"...)
+	}
+	d = append(append(d, b.Type...), ':')
+	return strconv.AppendUint(d, b.Bandwidth, 10)
+}
+
+func (b Bandwidth) marshalSize() (size int) {
 	if b.Experimental {
-		output += "X-"
+		size += 2
 	}
-	output += b.Type + ":" + strconv.FormatUint(b.Bandwidth, 10)
-	return output
+
+	size += len(b.Type) + 1 + lenUint(b.Bandwidth)
+	return
 }
 
 // EncryptionKey describes the "k=" which conveys encryption key information.
 type EncryptionKey string
 
-func (s EncryptionKey) String() string {
-	return string(s)
+func (e EncryptionKey) String() string {
+	return stringFromMarshal(e.marshalInto, e.marshalSize)
+}
+
+func (e EncryptionKey) marshalInto(b []byte) []byte {
+	return append(b, e...)
+}
+
+func (e EncryptionKey) marshalSize() (size int) {
+	return len(e)
 }
 
 // Attribute describes the "a=" field which represents the primary means for
@@ -97,11 +161,25 @@ func NewAttribute(key, value string) Attribute {
 }
 
 func (a Attribute) String() string {
-	output := a.Key
+	return stringFromMarshal(a.marshalInto, a.marshalSize)
+}
+
+func (a Attribute) marshalInto(b []byte) []byte {
+	b = append(b, a.Key...)
+	if len(a.Value) > 0 {
+		b = append(append(b, ':'), a.Value...)
+	}
+
+	return b
+}
+
+func (a Attribute) marshalSize() (size int) {
+	size = len(a.Key)
 	if len(a.Value) > 0 {
-		output += ":" + a.Value
+		size += 1 + len(a.Value)
 	}
-	return output
+
+	return size
 }
 
 // IsICECandidate returns true if the attribute key equals "candidate".
diff --git a/vendor/github.com/pion/sdp/v3/direction.go b/vendor/github.com/pion/sdp/v3/direction.go
index 19ea92db..936130cc 100644
--- a/vendor/github.com/pion/sdp/v3/direction.go
+++ b/vendor/github.com/pion/sdp/v3/direction.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package sdp
 
 import "errors"
diff --git a/vendor/github.com/pion/sdp/v3/extmap.go b/vendor/github.com/pion/sdp/v3/extmap.go
index 1242a8cf..f260c9be 100644
--- a/vendor/github.com/pion/sdp/v3/extmap.go
+++ b/vendor/github.com/pion/sdp/v3/extmap.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package sdp
 
 import (
diff --git a/vendor/github.com/pion/sdp/v3/fuzz.go b/vendor/github.com/pion/sdp/v3/fuzz.go
deleted file mode 100644
index f41ef78c..00000000
--- a/vendor/github.com/pion/sdp/v3/fuzz.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// +build gofuzz
-
-package sdp
-
-// Fuzz implements a randomized fuzz test of the sdp
-// parser using go-fuzz.
-//
-// To run the fuzzer, first download go-fuzz:
-// `go get github.com/dvyukov/go-fuzz/...`
-//
-// Then build the testing package:
-// `go-fuzz-build`
-//
-// And run the fuzzer on the corpus:
-// `go-fuzz`
-func Fuzz(data []byte) int {
-	// Check that unmarshalling any byte slice does not panic.
-	var sd SessionDescription
-	if err := sd.Unmarshal(data); err != nil {
-		return 0
-	}
-	// Check that we can marshal anything we unmarshalled.
-	_, err := sd.Marshal()
-	if err != nil {
-		panic("failed to marshal") // nolint
-	}
-	// It'd be nice to check that if we round trip Marshal then Unmarshal,
-	// we get the original back. Right now, though, we frequently don't,
-	// and we'd need to fix that first.
-	return 1
-}
diff --git a/vendor/github.com/pion/sdp/v3/jsep.go b/vendor/github.com/pion/sdp/v3/jsep.go
index de07d8f3..600acf56 100644
--- a/vendor/github.com/pion/sdp/v3/jsep.go
+++ b/vendor/github.com/pion/sdp/v3/jsep.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package sdp
 
 import (
@@ -56,8 +59,9 @@ func extMapURI() map[int]string {
 // some settings that are required by the JSEP spec.
 //
 // Note: Since v2.4.0, session ID has been fixed to use crypto random according to
-//       JSEP spec, so that NewJSEPSessionDescription now returns error as a second
-//       return value.
+//
+//	JSEP spec, so that NewJSEPSessionDescription now returns error as a second
+//	return value.
 func NewJSEPSessionDescription(identity bool) (*SessionDescription, error) {
 	sid, err := newSessionID()
 	if err != nil {
@@ -120,7 +124,7 @@ func (s *SessionDescription) WithMedia(md *MediaDescription) *SessionDescription
 
 // NewJSEPMediaDescription creates a new MediaName with
 // some settings that are required by the JSEP spec.
-func NewJSEPMediaDescription(codecType string, codecPrefs []string) *MediaDescription {
+func NewJSEPMediaDescription(codecType string, _ []string) *MediaDescription {
 	return &MediaDescription{
 		MediaName: MediaName{
 			Media:  codecType,
diff --git a/vendor/github.com/pion/sdp/v3/marshal.go b/vendor/github.com/pion/sdp/v3/marshal.go
index f029c4e9..43dd738b 100644
--- a/vendor/github.com/pion/sdp/v3/marshal.go
+++ b/vendor/github.com/pion/sdp/v3/marshal.go
@@ -1,136 +1,240 @@
-package sdp
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
 
-import (
-	"strings"
-)
+package sdp
 
 // Marshal takes a SDP struct to text
 // https://tools.ietf.org/html/rfc4566#section-5
 // Session description
-//    v=  (protocol version)
-//    o=  (originator and session identifier)
-//    s=  (session name)
-//    i=* (session information)
-//    u=* (URI of description)
-//    e=* (email address)
-//    p=* (phone number)
-//    c=* (connection information -- not required if included in
-//         all media)
-//    b=* (zero or more bandwidth information lines)
-//    One or more time descriptions ("t=" and "r=" lines; see below)
-//    z=* (time zone adjustments)
-//    k=* (encryption key)
-//    a=* (zero or more session attribute lines)
-//    Zero or more media descriptions
+//
+//	v=  (protocol version)
+//	o=  (originator and session identifier)
+//	s=  (session name)
+//	i=* (session information)
+//	u=* (URI of description)
+//	e=* (email address)
+//	p=* (phone number)
+//	c=* (connection information -- not required if included in
+//	     all media)
+//	b=* (zero or more bandwidth information lines)
+//	One or more time descriptions ("t=" and "r=" lines; see below)
+//	z=* (time zone adjustments)
+//	k=* (encryption key)
+//	a=* (zero or more session attribute lines)
+//	Zero or more media descriptions
 //
 // Time description
-//    t=  (time the session is active)
-//    r=* (zero or more repeat times)
+//
+//	t=  (time the session is active)
+//	r=* (zero or more repeat times)
 //
 // Media description, if present
-//    m=  (media name and transport address)
-//    i=* (media title)
-//    c=* (connection information -- optional if included at
-//         session level)
-//    b=* (zero or more bandwidth information lines)
-//    k=* (encryption key)
-//    a=* (zero or more media attribute lines)
+//
+//	m=  (media name and transport address)
+//	i=* (media title)
+//	c=* (connection information -- optional if included at
+//	     session level)
+//	b=* (zero or more bandwidth information lines)
+//	k=* (encryption key)
+//	a=* (zero or more media attribute lines)
 func (s *SessionDescription) Marshal() ([]byte, error) {
-	m := make(marshaller, 0, 1024)
+	m := make(marshaller, 0, s.MarshalSize())
 
-	m.addKeyValue("v=", s.Version.String())
-	m.addKeyValue("o=", s.Origin.String())
-	m.addKeyValue("s=", s.SessionName.String())
+	m.addKeyValue("v=", s.Version.marshalInto)
+	m.addKeyValue("o=", s.Origin.marshalInto)
+	m.addKeyValue("s=", s.SessionName.marshalInto)
 
 	if s.SessionInformation != nil {
-		m.addKeyValue("i=", s.SessionInformation.String())
+		m.addKeyValue("i=", s.SessionInformation.marshalInto)
 	}
 
 	if s.URI != nil {
-		m.addKeyValue("u=", s.URI.String())
+		m = append(m, "u="...)
+		m = append(m, s.URI.String()...)
+		m = append(m, "\r\n"...)
 	}
 
 	if s.EmailAddress != nil {
-		m.addKeyValue("e=", s.EmailAddress.String())
+		m.addKeyValue("e=", s.EmailAddress.marshalInto)
 	}
 
 	if s.PhoneNumber != nil {
-		m.addKeyValue("p=", s.PhoneNumber.String())
+		m.addKeyValue("p=", s.PhoneNumber.marshalInto)
 	}
 
 	if s.ConnectionInformation != nil {
-		m.addKeyValue("c=", s.ConnectionInformation.String())
+		m.addKeyValue("c=", s.ConnectionInformation.marshalInto)
 	}
 
 	for _, b := range s.Bandwidth {
-		m.addKeyValue("b=", b.String())
+		m.addKeyValue("b=", b.marshalInto)
 	}
 
 	for _, td := range s.TimeDescriptions {
-		m.addKeyValue("t=", td.Timing.String())
+		m.addKeyValue("t=", td.Timing.marshalInto)
 		for _, r := range td.RepeatTimes {
-			m.addKeyValue("r=", r.String())
+			m.addKeyValue("r=", r.marshalInto)
 		}
 	}
 
 	if len(s.TimeZones) > 0 {
-		var b strings.Builder
+		m = append(m, "z="...)
 		for i, z := range s.TimeZones {
 			if i > 0 {
-				b.WriteString(" ")
+				m = append(m, ' ')
 			}
-			b.WriteString(z.String())
+			m = z.marshalInto(m)
 		}
-		m.addKeyValue("z=", b.String())
+		m = append(m, "\r\n"...)
 	}
 
 	if s.EncryptionKey != nil {
-		m.addKeyValue("k=", s.EncryptionKey.String())
+		m.addKeyValue("k=", s.EncryptionKey.marshalInto)
 	}
 
 	for _, a := range s.Attributes {
-		m.addKeyValue("a=", a.String())
+		m.addKeyValue("a=", a.marshalInto)
 	}
 
 	for _, md := range s.MediaDescriptions {
-		m.addKeyValue("m=", md.MediaName.String())
+		m.addKeyValue("m=", md.MediaName.marshalInto)
 
 		if md.MediaTitle != nil {
-			m.addKeyValue("i=", md.MediaTitle.String())
+			m.addKeyValue("i=", md.MediaTitle.marshalInto)
 		}
 
 		if md.ConnectionInformation != nil {
-			m.addKeyValue("c=", md.ConnectionInformation.String())
+			m.addKeyValue("c=", md.ConnectionInformation.marshalInto)
 		}
 
 		for _, b := range md.Bandwidth {
-			m.addKeyValue("b=", b.String())
+			m.addKeyValue("b=", b.marshalInto)
 		}
 
 		if md.EncryptionKey != nil {
-			m.addKeyValue("k=", md.EncryptionKey.String())
+			m.addKeyValue("k=", md.EncryptionKey.marshalInto)
 		}
 
 		for _, a := range md.Attributes {
-			m.addKeyValue("a=", a.String())
+			m.addKeyValue("a=", a.marshalInto)
 		}
 	}
 
-	return m.bytes(), nil
+	return m, nil
+}
+
+// `$type=` and CRLF size
+const lineBaseSize = 4
+
+// MarshalSize returns the size of the SessionDescription once marshaled.
+func (s *SessionDescription) MarshalSize() (marshalSize int) {
+	marshalSize += lineBaseSize + s.Version.marshalSize()
+	marshalSize += lineBaseSize + s.Origin.marshalSize()
+	marshalSize += lineBaseSize + s.SessionName.marshalSize()
+
+	if s.SessionInformation != nil {
+		marshalSize += lineBaseSize + s.SessionInformation.marshalSize()
+	}
+
+	if s.URI != nil {
+		marshalSize += lineBaseSize + len(s.URI.String())
+	}
+
+	if s.EmailAddress != nil {
+		marshalSize += lineBaseSize + s.EmailAddress.marshalSize()
+	}
+
+	if s.PhoneNumber != nil {
+		marshalSize += lineBaseSize + s.PhoneNumber.marshalSize()
+	}
+
+	if s.ConnectionInformation != nil {
+		marshalSize += lineBaseSize + s.ConnectionInformation.marshalSize()
+	}
+
+	for _, b := range s.Bandwidth {
+		marshalSize += lineBaseSize + b.marshalSize()
+	}
+
+	for _, td := range s.TimeDescriptions {
+		marshalSize += lineBaseSize + td.Timing.marshalSize()
+		for _, r := range td.RepeatTimes {
+			marshalSize += lineBaseSize + r.marshalSize()
+		}
+	}
+
+	if len(s.TimeZones) > 0 {
+		marshalSize += lineBaseSize
+
+		for i, z := range s.TimeZones {
+			if i > 0 {
+				marshalSize++
+			}
+			marshalSize += z.marshalSize()
+		}
+	}
+
+	if s.EncryptionKey != nil {
+		marshalSize += lineBaseSize + s.EncryptionKey.marshalSize()
+	}
+
+	for _, a := range s.Attributes {
+		marshalSize += lineBaseSize + a.marshalSize()
+	}
+
+	for _, md := range s.MediaDescriptions {
+		marshalSize += lineBaseSize + md.MediaName.marshalSize()
+		if md.MediaTitle != nil {
+			marshalSize += lineBaseSize + md.MediaTitle.marshalSize()
+		}
+		if md.ConnectionInformation != nil {
+			marshalSize += lineBaseSize + md.ConnectionInformation.marshalSize()
+		}
+
+		for _, b := range md.Bandwidth {
+			marshalSize += lineBaseSize + b.marshalSize()
+		}
+
+		if md.EncryptionKey != nil {
+			marshalSize += lineBaseSize + md.EncryptionKey.marshalSize()
+		}
+
+		for _, a := range md.Attributes {
+			marshalSize += lineBaseSize + a.marshalSize()
+		}
+	}
+
+	return marshalSize
 }
 
 // marshaller contains state during marshaling.
 type marshaller []byte
 
-func (m *marshaller) addKeyValue(key, value string) {
-	if value == "" {
-		return
-	}
+func (m *marshaller) addKeyValue(key string, value func([]byte) []byte) {
 	*m = append(*m, key...)
-	*m = append(*m, value...)
+	*m = value(*m)
 	*m = append(*m, "\r\n"...)
 }
 
-func (m *marshaller) bytes() []byte {
-	return *m
+func lenUint(i uint64) (count int) {
+	if i == 0 {
+		return 1
+	}
+
+	for i != 0 {
+		i /= 10
+		count++
+	}
+	return
+}
+
+func lenInt(i int64) (count int) {
+	if i < 0 {
+		return lenUint(uint64(-i)) + 1
+	}
+	return lenUint(uint64(i))
+}
+
+func stringFromMarshal(marshalFunc func([]byte) []byte, sizeFunc func() int) string {
+	return string(marshalFunc(make([]byte, 0, sizeFunc())))
 }
diff --git a/vendor/github.com/pion/sdp/v3/media_description.go b/vendor/github.com/pion/sdp/v3/media_description.go
index c0885070..d5d76e46 100644
--- a/vendor/github.com/pion/sdp/v3/media_description.go
+++ b/vendor/github.com/pion/sdp/v3/media_description.go
@@ -1,8 +1,10 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package sdp
 
 import (
 	"strconv"
-	"strings"
 )
 
 // MediaDescription represents a media type.
@@ -62,6 +64,24 @@ func (p *RangedPort) String() string {
 	return output
 }
 
+func (p RangedPort) marshalInto(b []byte) []byte {
+	b = strconv.AppendInt(b, int64(p.Value), 10)
+	if p.Range != nil {
+		b = append(b, '/')
+		b = strconv.AppendInt(b, int64(*p.Range), 10)
+	}
+	return b
+}
+
+func (p RangedPort) marshalSize() (size int) {
+	size = lenInt(int64(p.Value))
+	if p.Range != nil {
+		size += 1 + lenInt(int64(*p.Range))
+	}
+
+	return
+}
+
 // MediaName describes the "m=" field storage structure.
 type MediaName struct {
 	Media   string
@@ -71,10 +91,38 @@ type MediaName struct {
 }
 
 func (m MediaName) String() string {
-	return strings.Join([]string{
-		m.Media,
-		m.Port.String(),
-		strings.Join(m.Protos, "/"),
-		strings.Join(m.Formats, " "),
-	}, " ")
+	return stringFromMarshal(m.marshalInto, m.marshalSize)
+}
+
+func (m MediaName) marshalInto(b []byte) []byte {
+	appendList := func(list []string, sep byte) {
+		for i, p := range list {
+			if i != 0 && i != len(list) {
+				b = append(b, sep)
+			}
+			b = append(b, p...)
+		}
+	}
+
+	b = append(append(b, m.Media...), ' ')
+	b = append(m.Port.marshalInto(b), ' ')
+	appendList(m.Protos, '/')
+	b = append(b, ' ')
+	appendList(m.Formats, ' ')
+	return b
+}
+
+func (m MediaName) marshalSize() (size int) {
+	listSize := func(list []string) {
+		for _, p := range list {
+			size += 1 + len(p)
+		}
+	}
+
+	size = len(m.Media)
+	size += 1 + m.Port.marshalSize()
+	listSize(m.Protos)
+	listSize(m.Formats)
+
+	return size
 }
diff --git a/vendor/github.com/pion/sdp/v3/renovate.json b/vendor/github.com/pion/sdp/v3/renovate.json
index f1614058..f1bb98c6 100644
--- a/vendor/github.com/pion/sdp/v3/renovate.json
+++ b/vendor/github.com/pion/sdp/v3/renovate.json
@@ -1,27 +1,6 @@
 {
+  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
   "extends": [
-    "config:base",
-    ":disableDependencyDashboard"
-  ],
-  "postUpdateOptions": [
-    "gomodTidy"
-  ],
-  "commitBody": "Generated by renovateBot",
-  "packageRules": [
-    {
-      "matchUpdateTypes": ["minor", "patch", "pin", "digest"],
-      "automerge": true
-    },
-    {
-      "packagePatterns": ["^golang.org/x/"],
-      "schedule": ["on the first day of the month"]
-    }
-  ],
-  "ignorePaths": [
-    ".github/workflows/generate-authors.yml",
-    ".github/workflows/lint.yaml",
-    ".github/workflows/renovate-go-mod-fix.yaml",
-    ".github/workflows/test.yaml",
-    ".github/workflows/tidy-check.yaml"
+    "github>pion/renovate-config"
   ]
 }
diff --git a/vendor/github.com/pion/sdp/v3/sdp.go b/vendor/github.com/pion/sdp/v3/sdp.go
index c92ac1a7..a13e838f 100644
--- a/vendor/github.com/pion/sdp/v3/sdp.go
+++ b/vendor/github.com/pion/sdp/v3/sdp.go
@@ -1,2 +1,5 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 // Package sdp implements Session Description Protocol (SDP)
 package sdp
diff --git a/vendor/github.com/pion/sdp/v3/session_description.go b/vendor/github.com/pion/sdp/v3/session_description.go
index c4aaf5f9..a9e25da0 100644
--- a/vendor/github.com/pion/sdp/v3/session_description.go
+++ b/vendor/github.com/pion/sdp/v3/session_description.go
@@ -1,7 +1,9 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package sdp
 
 import (
-	"fmt"
 	"net/url"
 	"strconv"
 )
@@ -82,7 +84,15 @@ func (s *SessionDescription) Attribute(key string) (string, bool) {
 type Version int
 
 func (v Version) String() string {
-	return strconv.Itoa(int(v))
+	return stringFromMarshal(v.marshalInto, v.marshalSize)
+}
+
+func (v Version) marshalInto(b []byte) []byte {
+	return strconv.AppendInt(b, int64(v), 10)
+}
+
+func (v Version) marshalSize() (size int) {
+	return lenInt(int64(v))
 }
 
 // Origin defines the structure for the "o=" field which provides the
@@ -97,15 +107,26 @@ type Origin struct {
 }
 
 func (o Origin) String() string {
-	return fmt.Sprintf(
-		"%v %d %d %v %v %v",
-		o.Username,
-		o.SessionID,
-		o.SessionVersion,
-		o.NetworkType,
-		o.AddressType,
-		o.UnicastAddress,
-	)
+	return stringFromMarshal(o.marshalInto, o.marshalSize)
+}
+
+func (o Origin) marshalInto(b []byte) []byte {
+	b = append(append(b, o.Username...), ' ')
+	b = append(strconv.AppendUint(b, o.SessionID, 10), ' ')
+	b = append(strconv.AppendUint(b, o.SessionVersion, 10), ' ')
+	b = append(append(b, o.NetworkType...), ' ')
+	b = append(append(b, o.AddressType...), ' ')
+	return append(b, o.UnicastAddress...)
+}
+
+func (o Origin) marshalSize() (size int) {
+	return len(o.Username) +
+		lenUint(o.SessionID) +
+		lenUint(o.SessionVersion) +
+		len(o.NetworkType) +
+		len(o.AddressType) +
+		len(o.UnicastAddress) +
+		5
 }
 
 // SessionName describes a structured representations for the "s=" field
@@ -113,7 +134,15 @@ func (o Origin) String() string {
 type SessionName string
 
 func (s SessionName) String() string {
-	return string(s)
+	return stringFromMarshal(s.marshalInto, s.marshalSize)
+}
+
+func (s SessionName) marshalInto(b []byte) []byte {
+	return append(b, s...)
+}
+
+func (s SessionName) marshalSize() (size int) {
+	return len(s)
 }
 
 // EmailAddress describes a structured representations for the "e=" line
@@ -122,7 +151,15 @@ func (s SessionName) String() string {
 type EmailAddress string
 
 func (e EmailAddress) String() string {
-	return string(e)
+	return stringFromMarshal(e.marshalInto, e.marshalSize)
+}
+
+func (e EmailAddress) marshalInto(b []byte) []byte {
+	return append(b, e...)
+}
+
+func (e EmailAddress) marshalSize() (size int) {
+	return len(e)
 }
 
 // PhoneNumber describes a structured representations for the "p=" line
@@ -131,7 +168,15 @@ func (e EmailAddress) String() string {
 type PhoneNumber string
 
 func (p PhoneNumber) String() string {
-	return string(p)
+	return stringFromMarshal(p.marshalInto, p.marshalSize)
+}
+
+func (p PhoneNumber) marshalInto(b []byte) []byte {
+	return append(b, p...)
+}
+
+func (p PhoneNumber) marshalSize() (size int) {
+	return len(p)
 }
 
 // TimeZone defines the structured object for "z=" line which describes
@@ -142,5 +187,15 @@ type TimeZone struct {
 }
 
 func (z TimeZone) String() string {
-	return strconv.FormatUint(z.AdjustmentTime, 10) + " " + strconv.FormatInt(z.Offset, 10)
+	return stringFromMarshal(z.marshalInto, z.marshalSize)
+}
+
+func (z TimeZone) marshalInto(b []byte) []byte {
+	b = strconv.AppendUint(b, z.AdjustmentTime, 10)
+	b = append(b, ' ')
+	return strconv.AppendInt(b, z.Offset, 10)
+}
+
+func (z TimeZone) marshalSize() (size int) {
+	return lenUint(z.AdjustmentTime) + 1 + lenInt(z.Offset)
 }
diff --git a/vendor/github.com/pion/sdp/v3/time_description.go b/vendor/github.com/pion/sdp/v3/time_description.go
index 8b24e130..0a5baa4e 100644
--- a/vendor/github.com/pion/sdp/v3/time_description.go
+++ b/vendor/github.com/pion/sdp/v3/time_description.go
@@ -1,8 +1,10 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package sdp
 
 import (
 	"strconv"
-	"strings"
 )
 
 // TimeDescription describes "t=", "r=" fields of the session description
@@ -26,9 +28,16 @@ type Timing struct {
 }
 
 func (t Timing) String() string {
-	output := strconv.FormatUint(t.StartTime, 10)
-	output += " " + strconv.FormatUint(t.StopTime, 10)
-	return output
+	return stringFromMarshal(t.marshalInto, t.marshalSize)
+}
+
+func (t Timing) marshalInto(b []byte) []byte {
+	b = append(strconv.AppendUint(b, t.StartTime, 10), ' ')
+	return strconv.AppendUint(b, t.StopTime, 10)
+}
+
+func (t Timing) marshalSize() (size int) {
+	return lenUint(t.StartTime) + 1 + lenUint(t.StopTime)
 }
 
 // RepeatTime describes the "r=" fields of the session description which
@@ -40,12 +49,27 @@ type RepeatTime struct {
 }
 
 func (r RepeatTime) String() string {
-	fields := make([]string, 0)
-	fields = append(fields, strconv.FormatInt(r.Interval, 10))
-	fields = append(fields, strconv.FormatInt(r.Duration, 10))
+	return stringFromMarshal(r.marshalInto, r.marshalSize)
+}
+
+func (r RepeatTime) marshalInto(b []byte) []byte {
+	b = strconv.AppendInt(b, r.Interval, 10)
+	b = append(b, ' ')
+	b = strconv.AppendInt(b, r.Duration, 10)
 	for _, value := range r.Offsets {
-		fields = append(fields, strconv.FormatInt(value, 10))
+		b = append(b, ' ')
+		b = strconv.AppendInt(b, value, 10)
+	}
+
+	return b
+}
+
+func (r RepeatTime) marshalSize() (size int) {
+	size = lenInt(r.Interval)
+	size += 1 + lenInt(r.Duration)
+	for _, o := range r.Offsets {
+		size += 1 + lenInt(o)
 	}
 
-	return strings.Join(fields, " ")
+	return
 }
diff --git a/vendor/github.com/pion/sdp/v3/unmarshal.go b/vendor/github.com/pion/sdp/v3/unmarshal.go
index 59fcbe74..3720d0de 100644
--- a/vendor/github.com/pion/sdp/v3/unmarshal.go
+++ b/vendor/github.com/pion/sdp/v3/unmarshal.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package sdp
 
 import (
@@ -6,6 +9,7 @@ import (
 	"net/url"
 	"strconv"
 	"strings"
+	"sync"
 )
 
 var (
@@ -13,57 +17,72 @@ var (
 	errSDPInvalidNumericValue = errors.New("sdp: invalid numeric value")
 	errSDPInvalidValue        = errors.New("sdp: invalid value")
 	errSDPInvalidPortValue    = errors.New("sdp: invalid port value")
+	errSDPCacheInvalid        = errors.New("sdp: invalid cache")
+
+	//nolint: gochecknoglobals
+	unmarshalCachePool = sync.Pool{
+		New: func() interface{} {
+			return &unmarshalCache{}
+		},
+	}
 )
 
-// Unmarshal is the primary function that deserializes the session description
+// UnmarshalString is the primary function that deserializes the session description
 // message and stores it inside of a structured SessionDescription object.
 //
 // The States Transition Table describes the computation flow between functions
 // (namely s1, s2, s3, ...) for a parsing procedure that complies with the
 // specifications laid out by the rfc4566#section-5 as well as by JavaScript
 // Session Establishment Protocol draft. Links:
-// 		https://tools.ietf.org/html/rfc4566#section-5
-// 		https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-24
+//
+//	https://tools.ietf.org/html/rfc4566#section-5
+//	https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-24
 //
 // https://tools.ietf.org/html/rfc4566#section-5
 // Session description
-//    v=  (protocol version)
-//    o=  (originator and session identifier)
-//    s=  (session name)
-//    i=* (session information)
-//    u=* (URI of description)
-//    e=* (email address)
-//    p=* (phone number)
-//    c=* (connection information -- not required if included in
-//         all media)
-//    b=* (zero or more bandwidth information lines)
-//    One or more time descriptions ("t=" and "r=" lines; see below)
-//    z=* (time zone adjustments)
-//    k=* (encryption key)
-//    a=* (zero or more session attribute lines)
-//    Zero or more media descriptions
+//
+//	v=  (protocol version)
+//	o=  (originator and session identifier)
+//	s=  (session name)
+//	i=* (session information)
+//	u=* (URI of description)
+//	e=* (email address)
+//	p=* (phone number)
+//	c=* (connection information -- not required if included in
+//	     all media)
+//	b=* (zero or more bandwidth information lines)
+//	One or more time descriptions ("t=" and "r=" lines; see below)
+//	z=* (time zone adjustments)
+//	k=* (encryption key)
+//	a=* (zero or more session attribute lines)
+//	Zero or more media descriptions
 //
 // Time description
-//    t=  (time the session is active)
-//    r=* (zero or more repeat times)
+//
+//	t=  (time the session is active)
+//	r=* (zero or more repeat times)
 //
 // Media description, if present
-//    m=  (media name and transport address)
-//    i=* (media title)
-//    c=* (connection information -- optional if included at
-//         session level)
-//    b=* (zero or more bandwidth information lines)
-//    k=* (encryption key)
-//    a=* (zero or more media attribute lines)
+//
+//	m=  (media name and transport address)
+//	i=* (media title)
+//	c=* (connection information -- optional if included at
+//	     session level)
+//	b=* (zero or more bandwidth information lines)
+//	k=* (encryption key)
+//	a=* (zero or more media attribute lines)
 //
 // In order to generate the following state table and draw subsequent
 // deterministic finite-state automota ("DFA") the following regex was used to
 // derive the DFA:
-//    vosi?u?e?p?c?b*(tr*)+z?k?a*(mi?c?b*k?a*)*
+//
+//	vosi?u?e?p?c?b*(tr*)+z?k?a*(mi?c?b*k?a*)*
+//
 // possible place and state to exit:
-//                    **   * * *  ** * * * *
-//                    99   1 1 1  11 1 1 1 1
-//                         3 1 1  26 5 5 4 4
+//
+//	**   * * *  ** * * * *
+//	99   1 1 1  11 1 1 1 1
+//	     3 1 1  26 5 5 4 4
 //
 // Please pay close attention to the `k`, and `a` parsing states. In the table
 // below in order to distinguish between the states belonging to the media
@@ -89,10 +108,18 @@ var (
 // |   s15  |    |    14 |    |     | 15 |     |   |    | 12 |   |   |     |   |   |    |   |    |
 // |   s16  |    |    14 |    |     |    |  15 |   |    | 12 |   |   |     |   |   |    |   |    |
 // +--------+----+-------+----+-----+----+-----+---+----+----+---+---+-----+---+---+----+---+----+
-func (s *SessionDescription) Unmarshal(value []byte) error {
+func (s *SessionDescription) UnmarshalString(value string) error {
+	var ok bool
 	l := new(lexer)
+	if l.cache, ok = unmarshalCachePool.Get().(*unmarshalCache); !ok {
+		return errSDPCacheInvalid
+	}
+	defer unmarshalCachePool.Put(l.cache)
+
+	l.cache.reset()
 	l.desc = s
 	l.value = value
+
 	for state := s1; state != nil; {
 		var err error
 		state, err = state(l)
@@ -100,12 +127,21 @@ func (s *SessionDescription) Unmarshal(value []byte) error {
 			return err
 		}
 	}
+
+	s.Attributes = l.cache.cloneSessionAttributes()
+	populateMediaAttributes(l.cache, l.desc)
 	return nil
 }
 
+// Unmarshal converts the value into a []byte and then calls UnmarshalString.
+// Callers should use the more performant UnmarshalString
+func (s *SessionDescription) Unmarshal(value []byte) error {
+	return s.UnmarshalString(string(value))
+}
+
 func s1(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
-		if key == "v=" {
+	return l.handleType(func(key byte) stateFn {
+		if key == 'v' {
 			return unmarshalProtocolVersion
 		}
 		return nil
@@ -113,8 +149,8 @@ func s1(l *lexer) (stateFn, error) {
 }
 
 func s2(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
-		if key == "o=" {
+	return l.handleType(func(key byte) stateFn {
+		if key == 'o' {
 			return unmarshalOrigin
 		}
 		return nil
@@ -122,8 +158,8 @@ func s2(l *lexer) (stateFn, error) {
 }
 
 func s3(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
-		if key == "s=" {
+	return l.handleType(func(key byte) stateFn {
+		if key == 's' {
 			return unmarshalSessionName
 		}
 		return nil
@@ -131,21 +167,21 @@ func s3(l *lexer) (stateFn, error) {
 }
 
 func s4(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
+	return l.handleType(func(key byte) stateFn {
 		switch key {
-		case "i=":
+		case 'i':
 			return unmarshalSessionInformation
-		case "u=":
+		case 'u':
 			return unmarshalURI
-		case "e=":
+		case 'e':
 			return unmarshalEmail
-		case "p=":
+		case 'p':
 			return unmarshalPhone
-		case "c=":
+		case 'c':
 			return unmarshalSessionConnectionInformation
-		case "b=":
+		case 'b':
 			return unmarshalSessionBandwidth
-		case "t=":
+		case 't':
 			return unmarshalTiming
 		}
 		return nil
@@ -153,11 +189,11 @@ func s4(l *lexer) (stateFn, error) {
 }
 
 func s5(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
+	return l.handleType(func(key byte) stateFn {
 		switch key {
-		case "b=":
+		case 'b':
 			return unmarshalSessionBandwidth
-		case "t=":
+		case 't':
 			return unmarshalTiming
 		}
 		return nil
@@ -165,15 +201,15 @@ func s5(l *lexer) (stateFn, error) {
 }
 
 func s6(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
+	return l.handleType(func(key byte) stateFn {
 		switch key {
-		case "p=":
+		case 'p':
 			return unmarshalPhone
-		case "c=":
+		case 'c':
 			return unmarshalSessionConnectionInformation
-		case "b=":
+		case 'b':
 			return unmarshalSessionBandwidth
-		case "t=":
+		case 't':
 			return unmarshalTiming
 		}
 		return nil
@@ -181,19 +217,19 @@ func s6(l *lexer) (stateFn, error) {
 }
 
 func s7(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
+	return l.handleType(func(key byte) stateFn {
 		switch key {
-		case "u=":
+		case 'u':
 			return unmarshalURI
-		case "e=":
+		case 'e':
 			return unmarshalEmail
-		case "p=":
+		case 'p':
 			return unmarshalPhone
-		case "c=":
+		case 'c':
 			return unmarshalSessionConnectionInformation
-		case "b=":
+		case 'b':
 			return unmarshalSessionBandwidth
-		case "t=":
+		case 't':
 			return unmarshalTiming
 		}
 		return nil
@@ -201,13 +237,13 @@ func s7(l *lexer) (stateFn, error) {
 }
 
 func s8(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
+	return l.handleType(func(key byte) stateFn {
 		switch key {
-		case "c=":
+		case 'c':
 			return unmarshalSessionConnectionInformation
-		case "b=":
+		case 'b':
 			return unmarshalSessionBandwidth
-		case "t=":
+		case 't':
 			return unmarshalTiming
 		}
 		return nil
@@ -215,19 +251,19 @@ func s8(l *lexer) (stateFn, error) {
 }
 
 func s9(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
+	return l.handleType(func(key byte) stateFn {
 		switch key {
-		case "z=":
+		case 'z':
 			return unmarshalTimeZones
-		case "k=":
+		case 'k':
 			return unmarshalSessionEncryptionKey
-		case "a=":
+		case 'a':
 			return unmarshalSessionAttribute
-		case "r=":
+		case 'r':
 			return unmarshalRepeatTimes
-		case "t=":
+		case 't':
 			return unmarshalTiming
-		case "m=":
+		case 'm':
 			return unmarshalMediaDescription
 		}
 		return nil
@@ -235,17 +271,17 @@ func s9(l *lexer) (stateFn, error) {
 }
 
 func s10(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
+	return l.handleType(func(key byte) stateFn {
 		switch key {
-		case "e=":
+		case 'e':
 			return unmarshalEmail
-		case "p=":
+		case 'p':
 			return unmarshalPhone
-		case "c=":
+		case 'c':
 			return unmarshalSessionConnectionInformation
-		case "b=":
+		case 'b':
 			return unmarshalSessionBandwidth
-		case "t=":
+		case 't':
 			return unmarshalTiming
 		}
 		return nil
@@ -253,11 +289,11 @@ func s10(l *lexer) (stateFn, error) {
 }
 
 func s11(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
+	return l.handleType(func(key byte) stateFn {
 		switch key {
-		case "a=":
+		case 'a':
 			return unmarshalSessionAttribute
-		case "m=":
+		case 'm':
 			return unmarshalMediaDescription
 		}
 		return nil
@@ -265,19 +301,19 @@ func s11(l *lexer) (stateFn, error) {
 }
 
 func s12(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
+	return l.handleType(func(key byte) stateFn {
 		switch key {
-		case "a=":
+		case 'a':
 			return unmarshalMediaAttribute
-		case "k=":
+		case 'k':
 			return unmarshalMediaEncryptionKey
-		case "b=":
+		case 'b':
 			return unmarshalMediaBandwidth
-		case "c=":
+		case 'c':
 			return unmarshalMediaConnectionInformation
-		case "i=":
+		case 'i':
 			return unmarshalMediaTitle
-		case "m=":
+		case 'm':
 			return unmarshalMediaDescription
 		}
 		return nil
@@ -285,13 +321,13 @@ func s12(l *lexer) (stateFn, error) {
 }
 
 func s13(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
+	return l.handleType(func(key byte) stateFn {
 		switch key {
-		case "a=":
+		case 'a':
 			return unmarshalSessionAttribute
-		case "k=":
+		case 'k':
 			return unmarshalSessionEncryptionKey
-		case "m=":
+		case 'm':
 			return unmarshalMediaDescription
 		}
 		return nil
@@ -299,23 +335,23 @@ func s13(l *lexer) (stateFn, error) {
 }
 
 func s14(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
+	return l.handleType(func(key byte) stateFn {
 		switch key {
-		case "a=":
+		case 'a':
 			return unmarshalMediaAttribute
-		case "k=":
+		case 'k':
 			// Non-spec ordering
 			return unmarshalMediaEncryptionKey
-		case "b=":
+		case 'b':
 			// Non-spec ordering
 			return unmarshalMediaBandwidth
-		case "c=":
+		case 'c':
 			// Non-spec ordering
 			return unmarshalMediaConnectionInformation
-		case "i=":
+		case 'i':
 			// Non-spec ordering
 			return unmarshalMediaTitle
-		case "m=":
+		case 'm':
 			return unmarshalMediaDescription
 		}
 		return nil
@@ -323,20 +359,20 @@ func s14(l *lexer) (stateFn, error) {
 }
 
 func s15(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
+	return l.handleType(func(key byte) stateFn {
 		switch key {
-		case "a=":
+		case 'a':
 			return unmarshalMediaAttribute
-		case "k=":
+		case 'k':
 			return unmarshalMediaEncryptionKey
-		case "b=":
+		case 'b':
 			return unmarshalMediaBandwidth
-		case "c=":
+		case 'c':
 			return unmarshalMediaConnectionInformation
-		case "i=":
+		case 'i':
 			// Non-spec ordering
 			return unmarshalMediaTitle
-		case "m=":
+		case 'm':
 			return unmarshalMediaDescription
 		}
 		return nil
@@ -344,20 +380,20 @@ func s15(l *lexer) (stateFn, error) {
 }
 
 func s16(l *lexer) (stateFn, error) {
-	return l.handleType(func(key string) stateFn {
+	return l.handleType(func(key byte) stateFn {
 		switch key {
-		case "a=":
+		case 'a':
 			return unmarshalMediaAttribute
-		case "k=":
+		case 'k':
 			return unmarshalMediaEncryptionKey
-		case "c=":
+		case 'c':
 			return unmarshalMediaConnectionInformation
-		case "b=":
+		case 'b':
 			return unmarshalMediaBandwidth
-		case "i=":
+		case 'i':
 			// Non-spec ordering
 			return unmarshalMediaTitle
-		case "m=":
+		case 'm':
 			return unmarshalMediaDescription
 		}
 		return nil
@@ -714,18 +750,19 @@ func unmarshalSessionAttribute(l *lexer) (stateFn, error) {
 	}
 
 	i := strings.IndexRune(value, ':')
-	var a Attribute
+	a := l.cache.getSessionAttribute()
 	if i > 0 {
-		a = NewAttribute(value[:i], value[i+1:])
+		a.Key = value[:i]
+		a.Value = value[i+1:]
 	} else {
-		a = NewPropertyAttribute(value)
+		a.Key = value
 	}
 
-	l.desc.Attributes = append(l.desc.Attributes, a)
 	return s11, nil
 }
 
 func unmarshalMediaDescription(l *lexer) (stateFn, error) {
+	populateMediaAttributes(l.cache, l.desc)
 	var newMediaDesc MediaDescription
 
 	// <media>
@@ -771,7 +808,7 @@ func unmarshalMediaDescription(l *lexer) (stateFn, error) {
 	// https://tools.ietf.org/html/rfc4566#section-5.14
 	// https://tools.ietf.org/html/rfc4975#section-8.1
 	for _, proto := range strings.Split(field, "/") {
-		if !anyOf(proto, "UDP", "RTP", "AVP", "SAVP", "SAVPF", "TLS", "DTLS", "SCTP", "AVPF", "TCP", "MSRP") {
+		if !anyOf(proto, "UDP", "RTP", "AVP", "SAVP", "SAVPF", "TLS", "DTLS", "SCTP", "AVPF", "TCP", "MSRP", "BFCP", "UDT", "IX") {
 			return nil, fmt.Errorf("%w `%v`", errSDPInvalidNumericValue, field)
 		}
 		newMediaDesc.MediaName.Protos = append(newMediaDesc.MediaName.Protos, proto)
@@ -853,19 +890,21 @@ func unmarshalMediaAttribute(l *lexer) (stateFn, error) {
 	}
 
 	i := strings.IndexRune(value, ':')
-	var a Attribute
+	a := l.cache.getMediaAttribute()
 	if i > 0 {
-		a = NewAttribute(value[:i], value[i+1:])
+		a.Key = value[:i]
+		a.Value = value[i+1:]
 	} else {
-		a = NewPropertyAttribute(value)
+		a.Key = value
 	}
 
-	latestMediaDesc := l.desc.MediaDescriptions[len(l.desc.MediaDescriptions)-1]
-	latestMediaDesc.Attributes = append(latestMediaDesc.Attributes, a)
 	return s14, nil
 }
 
 func parseTimeUnits(value string) (num int64, err error) {
+	if len(value) == 0 {
+		return 0, fmt.Errorf("%w `%v`", errSDPInvalidValue, value)
+	}
 	k := timeShorthand(value[len(value)-1])
 	if k > 0 {
 		num, err = strconv.ParseInt(value[:len(value)-1], 10, 64)
@@ -908,3 +947,10 @@ func parsePort(value string) (int, error) {
 
 	return port, nil
 }
+
+func populateMediaAttributes(c *unmarshalCache, s *SessionDescription) {
+	if len(s.MediaDescriptions) != 0 {
+		lastMediaDesc := s.MediaDescriptions[len(s.MediaDescriptions)-1]
+		lastMediaDesc.Attributes = c.cloneMediaAttributes()
+	}
+}
diff --git a/vendor/github.com/pion/sdp/v3/unmarshal_cache.go b/vendor/github.com/pion/sdp/v3/unmarshal_cache.go
new file mode 100644
index 00000000..728b3051
--- /dev/null
+++ b/vendor/github.com/pion/sdp/v3/unmarshal_cache.go
@@ -0,0 +1,44 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
+package sdp
+
+type unmarshalCache struct {
+	sessionAttributes []Attribute
+	mediaAttributes   []Attribute
+}
+
+func (c *unmarshalCache) reset() {
+	c.sessionAttributes = c.sessionAttributes[:0]
+	c.mediaAttributes = c.mediaAttributes[:0]
+}
+
+func (c *unmarshalCache) getSessionAttribute() *Attribute {
+	c.sessionAttributes = append(c.sessionAttributes, Attribute{})
+	return &c.sessionAttributes[len(c.sessionAttributes)-1]
+}
+
+func (c *unmarshalCache) cloneSessionAttributes() []Attribute {
+	if len(c.sessionAttributes) == 0 {
+		return nil
+	}
+	s := make([]Attribute, len(c.sessionAttributes))
+	copy(s, c.sessionAttributes)
+	c.sessionAttributes = c.sessionAttributes[:0]
+	return s
+}
+
+func (c *unmarshalCache) getMediaAttribute() *Attribute {
+	c.mediaAttributes = append(c.mediaAttributes, Attribute{})
+	return &c.mediaAttributes[len(c.mediaAttributes)-1]
+}
+
+func (c *unmarshalCache) cloneMediaAttributes() []Attribute {
+	if len(c.mediaAttributes) == 0 {
+		return nil
+	}
+	s := make([]Attribute, len(c.mediaAttributes))
+	copy(s, c.mediaAttributes)
+	c.mediaAttributes = c.mediaAttributes[:0]
+	return s
+}
diff --git a/vendor/github.com/pion/sdp/v3/util.go b/vendor/github.com/pion/sdp/v3/util.go
index 84cba7f7..0f14f15c 100644
--- a/vendor/github.com/pion/sdp/v3/util.go
+++ b/vendor/github.com/pion/sdp/v3/util.go
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
 package sdp
 
 import (
@@ -83,6 +86,16 @@ func (c Codec) String() string {
 	return fmt.Sprintf("%d %s/%d/%s (%s) [%s]", c.PayloadType, c.Name, c.ClockRate, c.EncodingParameters, c.Fmtp, strings.Join(c.RTCPFeedback, ", "))
 }
 
+func (c *Codec) appendRTCPFeedback(rtcpFeedback string) {
+	for _, existingRTCPFeedback := range c.RTCPFeedback {
+		if existingRTCPFeedback == rtcpFeedback {
+			return
+		}
+	}
+
+	c.RTCPFeedback = append(c.RTCPFeedback, rtcpFeedback)
+}
+
 func parseRtpmap(rtpmap string) (Codec, error) {
 	var codec Codec
 	parsingFailed := errExtractCodecRtpmap
@@ -150,30 +163,33 @@ func parseFmtp(fmtp string) (Codec, error) {
 	return codec, nil
 }
 
-func parseRtcpFb(rtcpFb string) (Codec, error) {
-	var codec Codec
-	parsingFailed := errExtractCodecRtcpFb
+func parseRtcpFb(rtcpFb string) (codec Codec, isWildcard bool, err error) {
+	var ptInt uint64
+	err = errExtractCodecRtcpFb
 
 	// a=ftcp-fb:<payload type> <RTCP feedback type> [<RTCP feedback parameter>]
 	split := strings.SplitN(rtcpFb, " ", 2)
 	if len(split) != 2 {
-		return codec, parsingFailed
+		return
 	}
 
 	ptSplit := strings.Split(split[0], ":")
 	if len(ptSplit) != 2 {
-		return codec, parsingFailed
+		return
 	}
 
-	ptInt, err := strconv.ParseUint(ptSplit[1], 10, 8)
-	if err != nil {
-		return codec, parsingFailed
+	isWildcard = ptSplit[1] == "*"
+	if !isWildcard {
+		ptInt, err = strconv.ParseUint(ptSplit[1], 10, 8)
+		if err != nil {
+			return
+		}
+
+		codec.PayloadType = uint8(ptInt)
 	}
 
-	codec.PayloadType = uint8(ptInt)
 	codec.RTCPFeedback = append(codec.RTCPFeedback, split[1])
-
-	return codec, nil
+	return codec, isWildcard, nil
 }
 
 func mergeCodecs(codec Codec, codecs map[uint8]Codec) {
@@ -200,8 +216,21 @@ func mergeCodecs(codec Codec, codecs map[uint8]Codec) {
 }
 
 func (s *SessionDescription) buildCodecMap() map[uint8]Codec {
-	codecs := make(map[uint8]Codec)
+	codecs := map[uint8]Codec{
+		// static codecs that do not require a rtpmap
+		0: {
+			PayloadType: 0,
+			Name:        "PCMU",
+			ClockRate:   8000,
+		},
+		8: {
+			PayloadType: 8,
+			Name:        "PCMA",
+			ClockRate:   8000,
+		},
+	}
 
+	wildcardRTCPFeedback := []string{}
 	for _, m := range s.MediaDescriptions {
 		for _, a := range m.Attributes {
 			attr := a.String()
@@ -217,14 +246,26 @@ func (s *SessionDescription) buildCodecMap() map[uint8]Codec {
 					mergeCodecs(codec, codecs)
 				}
 			case strings.HasPrefix(attr, "rtcp-fb:"):
-				codec, err := parseRtcpFb(attr)
-				if err == nil {
+				codec, isWildcard, err := parseRtcpFb(attr)
+				switch {
+				case err != nil:
+				case isWildcard:
+					wildcardRTCPFeedback = append(wildcardRTCPFeedback, codec.RTCPFeedback...)
+				default:
 					mergeCodecs(codec, codecs)
 				}
 			}
 		}
 	}
 
+	for i, codec := range codecs {
+		for _, newRTCPFeedback := range wildcardRTCPFeedback {
+			codec.appendRTCPFeedback(newRTCPFeedback)
+		}
+
+		codecs[i] = codec
+	}
+
 	return codecs
 }
 
@@ -296,15 +337,16 @@ func (s *SessionDescription) GetPayloadTypeForCodec(wanted Codec) (uint8, error)
 type stateFn func(*lexer) (stateFn, error)
 
 type lexer struct {
-	desc *SessionDescription
+	desc  *SessionDescription
+	cache *unmarshalCache
 	baseLexer
 }
 
-type keyToState func(key string) stateFn
+type keyToState func(key byte) stateFn
 
 func (l *lexer) handleType(fn keyToState) (stateFn, error) {
 	key, err := l.readType()
-	if errors.Is(err, io.EOF) && key == "" {
+	if errors.Is(err, io.EOF) && key == 0 {
 		return nil, nil //nolint:nilnil
 	} else if err != nil {
 		return nil, err
diff --git a/vendor/github.com/pion/transport/v2/deadline/deadline.go b/vendor/github.com/pion/transport/v2/deadline/deadline.go
index abd39f06..f49b908d 100644
--- a/vendor/github.com/pion/transport/v2/deadline/deadline.go
+++ b/vendor/github.com/pion/transport/v2/deadline/deadline.go
@@ -11,25 +11,46 @@ import (
 	"time"
 )
 
+type deadlineState uint8
+
+const (
+	deadlineStopped deadlineState = iota
+	deadlineStarted
+	deadlineExceeded
+)
+
+var _ context.Context = (*Deadline)(nil)
+
 // Deadline signals updatable deadline timer.
 // Also, it implements context.Context.
 type Deadline struct {
-	exceeded chan struct{}
-	stop     chan struct{}
-	stopped  chan bool
-	deadline time.Time
 	mu       sync.RWMutex
+	timer    timer
+	done     chan struct{}
+	deadline time.Time
+	state    deadlineState
+	pending  uint8
 }
 
 // New creates new deadline timer.
 func New() *Deadline {
-	d := &Deadline{
-		exceeded: make(chan struct{}),
-		stop:     make(chan struct{}),
-		stopped:  make(chan bool, 1),
+	return &Deadline{
+		done: make(chan struct{}),
 	}
-	d.stopped <- true
-	return d
+}
+
+func (d *Deadline) timeout() {
+	d.mu.Lock()
+	if d.pending--; d.pending != 0 || d.state != deadlineStarted {
+		d.mu.Unlock()
+		return
+	}
+
+	d.state = deadlineExceeded
+	done := d.done
+	d.mu.Unlock()
+
+	close(done)
 }
 
 // Set new deadline. Zero value means no deadline.
@@ -37,55 +58,43 @@ func (d *Deadline) Set(t time.Time) {
 	d.mu.Lock()
 	defer d.mu.Unlock()
 
-	d.deadline = t
+	if d.state == deadlineStarted && d.timer.Stop() {
+		d.pending--
+	}
 
-	close(d.stop)
+	d.deadline = t
+	d.pending++
 
-	select {
-	case <-d.exceeded:
-		d.exceeded = make(chan struct{})
-	default:
-		stopped := <-d.stopped
-		if !stopped {
-			d.exceeded = make(chan struct{})
-		}
+	if d.state == deadlineExceeded {
+		d.done = make(chan struct{})
 	}
-	d.stop = make(chan struct{})
-	d.stopped = make(chan bool, 1)
 
 	if t.IsZero() {
-		d.stopped <- true
+		d.pending--
+		d.state = deadlineStopped
 		return
 	}
 
 	if dur := time.Until(t); dur > 0 {
-		exceeded := d.exceeded
-		stopped := d.stopped
-		go func() {
-			timer := time.NewTimer(dur)
-			select {
-			case <-timer.C:
-				close(exceeded)
-				stopped <- false
-			case <-d.stop:
-				if !timer.Stop() {
-					<-timer.C
-				}
-				stopped <- true
-			}
-		}()
+		d.state = deadlineStarted
+		if d.timer == nil {
+			d.timer = afterFunc(dur, d.timeout)
+		} else {
+			d.timer.Reset(dur)
+		}
 		return
 	}
 
-	close(d.exceeded)
-	d.stopped <- false
+	d.pending--
+	d.state = deadlineExceeded
+	close(d.done)
 }
 
 // Done receives deadline signal.
 func (d *Deadline) Done() <-chan struct{} {
 	d.mu.RLock()
 	defer d.mu.RUnlock()
-	return d.exceeded
+	return d.done
 }
 
 // Err returns context.DeadlineExceeded if the deadline is exceeded.
@@ -93,12 +102,10 @@ func (d *Deadline) Done() <-chan struct{} {
 func (d *Deadline) Err() error {
 	d.mu.RLock()
 	defer d.mu.RUnlock()
-	select {
-	case <-d.exceeded:
+	if d.state == deadlineExceeded {
 		return context.DeadlineExceeded
-	default:
-		return nil
 	}
+	return nil
 }
 
 // Deadline returns current deadline.
diff --git a/vendor/github.com/pion/transport/v2/deadline/timer.go b/vendor/github.com/pion/transport/v2/deadline/timer.go
new file mode 100644
index 00000000..5a397247
--- /dev/null
+++ b/vendor/github.com/pion/transport/v2/deadline/timer.go
@@ -0,0 +1,13 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
+package deadline
+
+import (
+	"time"
+)
+
+type timer interface {
+	Stop() bool
+	Reset(time.Duration) bool
+}
diff --git a/vendor/github.com/pion/transport/v2/deadline/timer_generic.go b/vendor/github.com/pion/transport/v2/deadline/timer_generic.go
new file mode 100644
index 00000000..0c8f87ca
--- /dev/null
+++ b/vendor/github.com/pion/transport/v2/deadline/timer_generic.go
@@ -0,0 +1,15 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
+//go:build !js
+// +build !js
+
+package deadline
+
+import (
+	"time"
+)
+
+func afterFunc(d time.Duration, f func()) timer {
+	return time.AfterFunc(d, f)
+}
diff --git a/vendor/github.com/pion/transport/v2/deadline/timer_js.go b/vendor/github.com/pion/transport/v2/deadline/timer_js.go
new file mode 100644
index 00000000..b77e31e0
--- /dev/null
+++ b/vendor/github.com/pion/transport/v2/deadline/timer_js.go
@@ -0,0 +1,67 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
+//go:build js
+// +build js
+
+package deadline
+
+import (
+	"sync"
+	"time"
+)
+
+// jsTimer is a timer utility for wasm with a working Reset function.
+type jsTimer struct {
+	f       func()
+	mu      sync.Mutex
+	timer   *time.Timer
+	version uint64
+	started bool
+}
+
+func afterFunc(d time.Duration, f func()) timer {
+	t := &jsTimer{f: f}
+	t.Reset(d)
+	return t
+}
+
+func (t *jsTimer) Stop() bool {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+
+	t.version++
+	t.timer.Stop()
+
+	started := t.started
+	t.started = false
+	return started
+}
+
+func (t *jsTimer) Reset(d time.Duration) bool {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+
+	if t.timer != nil {
+		t.timer.Stop()
+	}
+
+	t.version++
+	version := t.version
+	t.timer = time.AfterFunc(d, func() {
+		t.mu.Lock()
+		if version != t.version {
+			t.mu.Unlock()
+			return
+		}
+
+		t.started = false
+		t.mu.Unlock()
+
+		t.f()
+	})
+
+	started := t.started
+	t.started = true
+	return started
+}
diff --git a/vendor/github.com/pion/transport/v2/packetio/buffer.go b/vendor/github.com/pion/transport/v2/packetio/buffer.go
index 2d46d796..b487457b 100644
--- a/vendor/github.com/pion/transport/v2/packetio/buffer.go
+++ b/vendor/github.com/pion/transport/v2/packetio/buffer.go
@@ -38,8 +38,9 @@ type Buffer struct {
 	data       []byte
 	head, tail int
 
-	notify chan struct{} // non-nil when we have blocked readers
-	closed bool
+	notify  chan struct{}
+	waiting bool
+	closed  bool
 
 	count                 int
 	limitCount, limitSize int
@@ -56,6 +57,7 @@ const (
 // NewBuffer creates a new Buffer.
 func NewBuffer() *Buffer {
 	return &Buffer{
+		notify:       make(chan struct{}, 1),
 		readDeadline: deadline.New(),
 	}
 }
@@ -149,14 +151,6 @@ func (b *Buffer) Write(packet []byte) (int, error) {
 		}
 	}
 
-	var notify chan struct{}
-	if b.notify != nil {
-		// Prepare to notify readers, but only
-		// actually do it after we release the lock.
-		notify = b.notify
-		b.notify = nil
-	}
-
 	// store the length of the packet
 	b.data[b.tail] = uint8(len(packet) >> 8)
 	b.tail++
@@ -178,10 +172,17 @@ func (b *Buffer) Write(packet []byte) (int, error) {
 		b.tail = m
 	}
 	b.count++
+
+	waiting := b.waiting
+	b.waiting = false
+
 	b.mutex.Unlock()
 
-	if notify != nil {
-		close(notify)
+	if waiting {
+		select {
+		case b.notify <- struct{}{}:
+		default:
+		}
 	}
 
 	return len(packet), nil
@@ -244,7 +245,7 @@ func (b *Buffer) Read(packet []byte) (n int, err error) { //nolint:gocognit
 			}
 
 			b.count--
-
+			b.waiting = false
 			b.mutex.Unlock()
 
 			if copied < count {
@@ -258,16 +259,13 @@ func (b *Buffer) Read(packet []byte) (n int, err error) { //nolint:gocognit
 			return 0, io.EOF
 		}
 
-		if b.notify == nil {
-			b.notify = make(chan struct{})
-		}
-		notify := b.notify
+		b.waiting = true
 		b.mutex.Unlock()
 
 		select {
 		case <-b.readDeadline.Done():
 			return 0, &netError{ErrTimeout, true, true}
-		case <-notify:
+		case <-b.notify:
 		}
 	}
 }
@@ -282,14 +280,17 @@ func (b *Buffer) Close() (err error) {
 		return nil
 	}
 
-	notify := b.notify
-	b.notify = nil
+	waiting := b.waiting
+	b.waiting = false
 	b.closed = true
 
 	b.mutex.Unlock()
 
-	if notify != nil {
-		close(notify)
+	if waiting {
+		select {
+		case b.notify <- struct{}{}:
+		default:
+		}
 	}
 
 	return nil
diff --git a/vendor/github.com/pion/transport/v2/udp/conn.go b/vendor/github.com/pion/transport/v2/udp/conn.go
index e2378f88..c2f257ea 100644
--- a/vendor/github.com/pion/transport/v2/udp/conn.go
+++ b/vendor/github.com/pion/transport/v2/udp/conn.go
@@ -12,6 +12,7 @@ import (
 	"sync/atomic"
 	"time"
 
+	"github.com/pion/logging"
 	"github.com/pion/transport/v2/deadline"
 	"github.com/pion/transport/v2/packetio"
 	"golang.org/x/net/ipv4"
@@ -51,6 +52,8 @@ type listener struct {
 
 	readDoneCh chan struct{}
 	errRead    atomic.Value // error
+
+	logger logging.LeveledLogger
 }
 
 // Accept waits for and returns the next connection to the listener.
@@ -151,6 +154,8 @@ type ListenConfig struct {
 	WriteBufferSize int
 
 	Batch BatchIOConfig
+
+	LoggerFactory logging.LoggerFactory
 }
 
 // Listen creates a new listener based on the ListenConfig.
@@ -175,6 +180,13 @@ func (lc *ListenConfig) Listen(network string, laddr *net.UDPAddr) (net.Listener
 		_ = conn.SetWriteBuffer(lc.WriteBufferSize)
 	}
 
+	loggerFactory := lc.LoggerFactory
+	if loggerFactory == nil {
+		loggerFactory = logging.NewDefaultLoggerFactory()
+	}
+
+	logger := loggerFactory.NewLogger("transport")
+
 	l := &listener{
 		pConn:        conn,
 		acceptCh:     make(chan *Conn, lc.Backlog),
@@ -183,6 +195,7 @@ func (lc *ListenConfig) Listen(network string, laddr *net.UDPAddr) (net.Listener
 		acceptFilter: lc.AcceptFilter,
 		connWG:       &sync.WaitGroup{},
 		readDoneCh:   make(chan struct{}),
+		logger:       logger,
 	}
 
 	if lc.Batch.Enable {
@@ -251,6 +264,7 @@ func (l *listener) read() {
 		n, raddr, err := l.pConn.ReadFrom(buf)
 		if err != nil {
 			l.errRead.Store(err)
+			l.logger.Tracef("error reading from connection err=%v", err)
 			return
 		}
 		l.dispatchMsg(raddr, buf[:n])
@@ -263,7 +277,10 @@ func (l *listener) dispatchMsg(addr net.Addr, buf []byte) {
 		return
 	}
 	if ok {
-		_, _ = conn.buffer.Write(buf)
+		_, err := conn.buffer.Write(buf)
+		if err != nil {
+			l.logger.Tracef("error dispatching message addr=%v err=%v", addr, err)
+		}
 	}
 }
 
diff --git a/vendor/github.com/pion/turn/v2/client.go b/vendor/github.com/pion/turn/v2/client.go
index be2a2431..350715c6 100644
--- a/vendor/github.com/pion/turn/v2/client.go
+++ b/vendor/github.com/pion/turn/v2/client.go
@@ -425,7 +425,7 @@ func (c *Client) PerformTransaction(msg *stun.Message, to net.Addr, ignoreResult
 
 	c.trMap.Insert(trKey, tr)
 
-	c.log.Tracef("Start %s transaction %s to %s", msg.Type, trKey, tr.To.String())
+	c.log.Tracef("Start %s transaction %s to %s", msg.Type, trKey, tr.To)
 	_, err := c.conn.WriteTo(tr.Raw, to)
 	if err != nil {
 		return client.TransactionResult{}, err
@@ -524,7 +524,7 @@ func (c *Client) handleSTUNMessage(data []byte, from net.Addr) error {
 				return err
 			}
 
-			c.log.Tracef("Data indication received from %s", from.String())
+			c.log.Tracef("Data indication received from %s", from)
 
 			relayedConn := c.relayedUDPConn()
 			if relayedConn == nil {
@@ -548,7 +548,7 @@ func (c *Client) handleSTUNMessage(data []byte, from net.Addr) error {
 				return err
 			}
 
-			c.log.Debugf("Connection attempt from %s", addr.String())
+			c.log.Debugf("Connection attempt from %s", addr)
 
 			allocation := c.getTCPAllocation()
 			if allocation == nil {
@@ -575,7 +575,7 @@ func (c *Client) handleSTUNMessage(data []byte, from net.Addr) error {
 	if !ok {
 		c.mutexTrMap.Unlock()
 		// Silently discard
-		c.log.Debugf("No transaction for %s", msg.String())
+		c.log.Debugf("No transaction for %s", msg)
 		return nil
 	}
 
@@ -589,7 +589,7 @@ func (c *Client) handleSTUNMessage(data []byte, from net.Addr) error {
 		From:    from,
 		Retries: tr.Retries(),
 	}) {
-		c.log.Debugf("No listener for %s", msg.String())
+		c.log.Debugf("No listener for %s", msg)
 	}
 
 	return nil
diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/allocation.go b/vendor/github.com/pion/turn/v2/internal/allocation/allocation.go
index 7bda593b..9bfd9105 100644
--- a/vendor/github.com/pion/turn/v2/internal/allocation/allocation.go
+++ b/vendor/github.com/pion/turn/v2/internal/allocation/allocation.go
@@ -244,9 +244,9 @@ func (a *Allocation) packetHandler(m *Manager) {
 		}
 
 		a.log.Debugf("Relay socket %s received %d bytes from %s",
-			a.RelaySocket.LocalAddr().String(),
+			a.RelaySocket.LocalAddr(),
 			n,
-			srcAddr.String())
+			srcAddr)
 
 		if channel := a.GetChannelByAddr(srcAddr); channel != nil {
 			channelData := &proto.ChannelData{
@@ -274,13 +274,13 @@ func (a *Allocation) packetHandler(m *Manager) {
 				return
 			}
 			a.log.Debugf("Relaying message from %s to client at %s",
-				srcAddr.String(),
-				a.fiveTuple.SrcAddr.String())
+				srcAddr,
+				a.fiveTuple.SrcAddr)
 			if _, err = a.TurnSocket.WriteTo(msg.Raw, a.fiveTuple.SrcAddr); err != nil {
 				a.log.Errorf("Failed to send DataIndication from allocation %v %v", srcAddr, err)
 			}
 		} else {
-			a.log.Infof("No Permission or Channel exists for %v on allocation %v", srcAddr, a.RelayAddr.String())
+			a.log.Infof("No Permission or Channel exists for %v on allocation %v", srcAddr, a.RelayAddr)
 		}
 	}
 }
diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/allocation_manager.go b/vendor/github.com/pion/turn/v2/internal/allocation/allocation_manager.go
index d56694de..2b765921 100644
--- a/vendor/github.com/pion/turn/v2/internal/allocation/allocation_manager.go
+++ b/vendor/github.com/pion/turn/v2/internal/allocation/allocation_manager.go
@@ -30,7 +30,7 @@ type Manager struct {
 	lock sync.RWMutex
 	log  logging.LeveledLogger
 
-	allocations  map[string]*Allocation
+	allocations  map[FiveTupleFingerprint]*Allocation
 	reservations []*reservation
 
 	allocatePacketConn func(network string, requestedPort int) (net.PacketConn, net.Addr, error)
@@ -51,7 +51,7 @@ func NewManager(config ManagerConfig) (*Manager, error) {
 
 	return &Manager{
 		log:                config.LeveledLogger,
-		allocations:        make(map[string]*Allocation, 64),
+		allocations:        make(map[FiveTupleFingerprint]*Allocation, 64),
 		allocatePacketConn: config.AllocatePacketConn,
 		allocateConn:       config.AllocateConn,
 		permissionHandler:  config.PermissionHandler,
@@ -113,7 +113,7 @@ func (m *Manager) CreateAllocation(fiveTuple *FiveTuple, turnSocket net.PacketCo
 	a.RelaySocket = conn
 	a.RelayAddr = relayAddr
 
-	m.log.Debugf("Listening on relay address: %s", a.RelayAddr.String())
+	m.log.Debugf("Listening on relay address: %s", a.RelayAddr)
 
 	a.lifetimeTimer = time.AfterFunc(lifetime, func() {
 		m.DeleteAllocation(a.fiveTuple)
diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/five_tuple.go b/vendor/github.com/pion/turn/v2/internal/allocation/five_tuple.go
index 99264623..6d812caf 100644
--- a/vendor/github.com/pion/turn/v2/internal/allocation/five_tuple.go
+++ b/vendor/github.com/pion/turn/v2/internal/allocation/five_tuple.go
@@ -4,7 +4,6 @@
 package allocation
 
 import (
-	"fmt"
 	"net"
 )
 
@@ -33,7 +32,32 @@ func (f *FiveTuple) Equal(b *FiveTuple) bool {
 	return f.Fingerprint() == b.Fingerprint()
 }
 
+// FiveTupleFingerprint is a comparable representation of a FiveTuple
+type FiveTupleFingerprint struct {
+	srcIP, dstIP     [16]byte
+	srcPort, dstPort uint16
+	protocol         Protocol
+}
+
 // Fingerprint is the identity of a FiveTuple
-func (f *FiveTuple) Fingerprint() string {
-	return fmt.Sprintf("%d_%s_%s", f.Protocol, f.SrcAddr.String(), f.DstAddr.String())
+func (f *FiveTuple) Fingerprint() (fp FiveTupleFingerprint) {
+	srcIP, srcPort := netAddrIPAndPort(f.SrcAddr)
+	copy(fp.srcIP[:], srcIP)
+	fp.srcPort = srcPort
+	dstIP, dstPort := netAddrIPAndPort(f.DstAddr)
+	copy(fp.dstIP[:], dstIP)
+	fp.dstPort = dstPort
+	fp.protocol = f.Protocol
+	return
+}
+
+func netAddrIPAndPort(addr net.Addr) (net.IP, uint16) {
+	switch a := addr.(type) {
+	case *net.UDPAddr:
+		return a.IP.To16(), uint16(a.Port)
+	case *net.TCPAddr:
+		return a.IP.To16(), uint16(a.Port)
+	default:
+		return nil, 0
+	}
 }
diff --git a/vendor/github.com/pion/turn/v2/internal/client/udp_conn.go b/vendor/github.com/pion/turn/v2/internal/client/udp_conn.go
index 9e206d6c..f73bf5b1 100644
--- a/vendor/github.com/pion/turn/v2/internal/client/udp_conn.go
+++ b/vendor/github.com/pion/turn/v2/internal/client/udp_conn.go
@@ -435,7 +435,7 @@ func (c *UDPConn) bind(b *binding) error {
 		return fmt.Errorf("unexpected response type %s", res.Type) //nolint:goerr113
 	}
 
-	c.log.Debugf("Channel binding successful: %s %d", b.addr.String(), b.number)
+	c.log.Debugf("Channel binding successful: %s %d", b.addr, b.number)
 
 	// Success.
 	return nil
diff --git a/vendor/github.com/pion/turn/v2/internal/server/errors.go b/vendor/github.com/pion/turn/v2/internal/server/errors.go
index 3a8911c4..ea6da834 100644
--- a/vendor/github.com/pion/turn/v2/internal/server/errors.go
+++ b/vendor/github.com/pion/turn/v2/internal/server/errors.go
@@ -7,8 +7,8 @@ import "errors"
 
 var (
 	errFailedToGenerateNonce                  = errors.New("failed to generate nonce")
+	errInvalidNonce                           = errors.New("invalid nonce")
 	errFailedToSendError                      = errors.New("failed to send error message")
-	errDuplicatedNonce                        = errors.New("duplicated Nonce generated, discarding request")
 	errNoSuchUser                             = errors.New("no such user exists")
 	errUnexpectedClass                        = errors.New("unexpected class")
 	errUnexpectedMethod                       = errors.New("unexpected method")
diff --git a/vendor/github.com/pion/turn/v2/internal/server/nonce.go b/vendor/github.com/pion/turn/v2/internal/server/nonce.go
new file mode 100644
index 00000000..b3f3131e
--- /dev/null
+++ b/vendor/github.com/pion/turn/v2/internal/server/nonce.go
@@ -0,0 +1,71 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
+package server
+
+import (
+	"crypto/hmac"
+	"crypto/rand"
+	"crypto/sha256"
+	"encoding/binary"
+	"encoding/hex"
+	"fmt"
+	"time"
+)
+
+const (
+	nonceLifetime  = time.Hour // See: https://tools.ietf.org/html/rfc5766#section-4
+	nonceLength    = 40
+	nonceKeyLength = 64
+)
+
+// NewNonceHash creates a NonceHash
+func NewNonceHash() (*NonceHash, error) {
+	key := make([]byte, nonceKeyLength)
+	if _, err := rand.Read(key); err != nil {
+		return nil, err
+	}
+
+	return &NonceHash{key}, nil
+}
+
+// NonceHash is used to create and verify nonces
+type NonceHash struct {
+	key []byte
+}
+
+// Generate a nonce
+func (n *NonceHash) Generate() (string, error) {
+	nonce := make([]byte, 8, nonceLength)
+	binary.BigEndian.PutUint64(nonce, uint64(time.Now().UnixMilli()))
+
+	hash := hmac.New(sha256.New, n.key)
+	if _, err := hash.Write(nonce[:8]); err != nil {
+		return "", fmt.Errorf("%w: %v", errFailedToGenerateNonce, err) //nolint:errorlint
+	}
+	nonce = hash.Sum(nonce)
+
+	return hex.EncodeToString(nonce), nil
+}
+
+// Validate checks that nonce is signed and is not expired
+func (n *NonceHash) Validate(nonce string) error {
+	b, err := hex.DecodeString(nonce)
+	if err != nil || len(b) != nonceLength {
+		return fmt.Errorf("%w: %v", errInvalidNonce, err) //nolint:errorlint
+	}
+
+	if ts := time.UnixMilli(int64(binary.BigEndian.Uint64(b))); time.Since(ts) > nonceLifetime {
+		return errInvalidNonce
+	}
+
+	hash := hmac.New(sha256.New, n.key)
+	if _, err = hash.Write(b[:8]); err != nil {
+		return fmt.Errorf("%w: %v", errInvalidNonce, err) //nolint:errorlint
+	}
+	if !hmac.Equal(b[8:], hash.Sum(nil)) {
+		return errInvalidNonce
+	}
+
+	return nil
+}
diff --git a/vendor/github.com/pion/turn/v2/internal/server/server.go b/vendor/github.com/pion/turn/v2/internal/server/server.go
index 0963e3e4..097cb9f0 100644
--- a/vendor/github.com/pion/turn/v2/internal/server/server.go
+++ b/vendor/github.com/pion/turn/v2/internal/server/server.go
@@ -7,7 +7,6 @@ package server
 import (
 	"fmt"
 	"net"
-	"sync"
 	"time"
 
 	"github.com/pion/logging"
@@ -25,7 +24,7 @@ type Request struct {
 
 	// Server State
 	AllocationManager *allocation.Manager
-	Nonces            *sync.Map
+	NonceHash         *NonceHash
 
 	// User Configuration
 	AuthHandler        func(username string, realm string, srcAddr net.Addr) (key []byte, ok bool)
@@ -36,7 +35,7 @@ type Request struct {
 
 // HandleRequest processes the give Request
 func HandleRequest(r Request) error {
-	r.Log.Debugf("Received %d bytes of udp from %s on %s", len(r.Buff), r.SrcAddr.String(), r.Conn.LocalAddr().String())
+	r.Log.Debugf("Received %d bytes of udp from %s on %s", len(r.Buff), r.SrcAddr, r.Conn.LocalAddr())
 
 	if proto.IsChannelData(r.Buff) {
 		return handleDataPacket(r)
diff --git a/vendor/github.com/pion/turn/v2/internal/server/stun.go b/vendor/github.com/pion/turn/v2/internal/server/stun.go
index ebd4b084..b8596d12 100644
--- a/vendor/github.com/pion/turn/v2/internal/server/stun.go
+++ b/vendor/github.com/pion/turn/v2/internal/server/stun.go
@@ -9,7 +9,7 @@ import (
 )
 
 func handleBindingRequest(r Request, m *stun.Message) error {
-	r.Log.Debugf("Received BindingRequest from %s", r.SrcAddr.String())
+	r.Log.Debugf("Received BindingRequest from %s", r.SrcAddr)
 
 	ip, port, err := ipnet.AddrIPPort(r.SrcAddr)
 	if err != nil {
diff --git a/vendor/github.com/pion/turn/v2/internal/server/turn.go b/vendor/github.com/pion/turn/v2/internal/server/turn.go
index 91d98e30..cd84834c 100644
--- a/vendor/github.com/pion/turn/v2/internal/server/turn.go
+++ b/vendor/github.com/pion/turn/v2/internal/server/turn.go
@@ -15,7 +15,7 @@ import (
 
 // See: https://tools.ietf.org/html/rfc5766#section-6.2
 func handleAllocateRequest(r Request, m *stun.Message) error {
-	r.Log.Debugf("Received AllocateRequest from %s", r.SrcAddr.String())
+	r.Log.Debugf("Received AllocateRequest from %s", r.SrcAddr)
 
 	// 1. The server MUST require that the request be authenticated.  This
 	//    authentication MUST be done using the long-term credential
@@ -177,7 +177,7 @@ func handleAllocateRequest(r Request, m *stun.Message) error {
 }
 
 func handleRefreshRequest(r Request, m *stun.Message) error {
-	r.Log.Debugf("Received RefreshRequest from %s", r.SrcAddr.String())
+	r.Log.Debugf("Received RefreshRequest from %s", r.SrcAddr)
 
 	messageIntegrity, hasAuth, err := authenticateRequest(r, m, stun.MethodRefresh)
 	if !hasAuth {
@@ -211,7 +211,7 @@ func handleRefreshRequest(r Request, m *stun.Message) error {
 }
 
 func handleCreatePermissionRequest(r Request, m *stun.Message) error {
-	r.Log.Debugf("Received CreatePermission from %s", r.SrcAddr.String())
+	r.Log.Debugf("Received CreatePermission from %s", r.SrcAddr)
 
 	a := r.AllocationManager.GetAllocation(&allocation.FiveTuple{
 		SrcAddr:  r.SrcAddr,
@@ -236,13 +236,12 @@ func handleCreatePermissionRequest(r Request, m *stun.Message) error {
 		}
 
 		if err := r.AllocationManager.GrantPermission(r.SrcAddr, peerAddress.IP); err != nil {
-			r.Log.Infof("permission denied for client %s to peer %s", r.SrcAddr.String(),
-				peerAddress.IP.String())
+			r.Log.Infof("permission denied for client %s to peer %s", r.SrcAddr, peerAddress.IP)
 			return err
 		}
 
 		r.Log.Debugf("Adding permission for %s", fmt.Sprintf("%s:%d",
-			peerAddress.IP.String(), peerAddress.Port))
+			peerAddress.IP, peerAddress.Port))
 
 		a.AddPermission(allocation.NewPermission(
 			&net.UDPAddr{
@@ -266,7 +265,7 @@ func handleCreatePermissionRequest(r Request, m *stun.Message) error {
 }
 
 func handleSendIndication(r Request, m *stun.Message) error {
-	r.Log.Debugf("Received SendIndication from %s", r.SrcAddr.String())
+	r.Log.Debugf("Received SendIndication from %s", r.SrcAddr)
 	a := r.AllocationManager.GetAllocation(&allocation.FiveTuple{
 		SrcAddr:  r.SrcAddr,
 		DstAddr:  r.Conn.LocalAddr(),
@@ -299,7 +298,7 @@ func handleSendIndication(r Request, m *stun.Message) error {
 }
 
 func handleChannelBindRequest(r Request, m *stun.Message) error {
-	r.Log.Debugf("Received ChannelBindRequest from %s", r.SrcAddr.String())
+	r.Log.Debugf("Received ChannelBindRequest from %s", r.SrcAddr)
 
 	a := r.AllocationManager.GetAllocation(&allocation.FiveTuple{
 		SrcAddr:  r.SrcAddr,
@@ -328,8 +327,7 @@ func handleChannelBindRequest(r Request, m *stun.Message) error {
 	}
 
 	if err = r.AllocationManager.GrantPermission(r.SrcAddr, peerAddr.IP); err != nil {
-		r.Log.Infof("permission denied for client %s to peer %s", r.SrcAddr.String(),
-			peerAddr.IP.String())
+		r.Log.Infof("permission denied for client %s to peer %s", r.SrcAddr, peerAddr.IP)
 
 		unauthorizedRequestMsg := buildMsg(m.TransactionID,
 			stun.NewType(stun.MethodChannelBind, stun.ClassErrorResponse),
@@ -337,9 +335,7 @@ func handleChannelBindRequest(r Request, m *stun.Message) error {
 		return buildAndSendErr(r.Conn, r.SrcAddr, err, unauthorizedRequestMsg...)
 	}
 
-	r.Log.Debugf("Binding channel %d to %s",
-		channel,
-		fmt.Sprintf("%s:%d", peerAddr.IP.String(), peerAddr.Port))
+	r.Log.Debugf("Binding channel %d to %s", channel, peerAddr)
 	err = a.AddChannelBind(allocation.NewChannelBind(
 		channel,
 		&net.UDPAddr{IP: peerAddr.IP, Port: peerAddr.Port},
@@ -353,7 +349,7 @@ func handleChannelBindRequest(r Request, m *stun.Message) error {
 }
 
 func handleChannelData(r Request, c *proto.ChannelData) error {
-	r.Log.Debugf("Received ChannelData from %s", r.SrcAddr.String())
+	r.Log.Debugf("Received ChannelData from %s", r.SrcAddr)
 
 	a := r.AllocationManager.GetAllocation(&allocation.FiveTuple{
 		SrcAddr:  r.SrcAddr,
diff --git a/vendor/github.com/pion/turn/v2/internal/server/util.go b/vendor/github.com/pion/turn/v2/internal/server/util.go
index 86e119fb..caa46e30 100644
--- a/vendor/github.com/pion/turn/v2/internal/server/util.go
+++ b/vendor/github.com/pion/turn/v2/internal/server/util.go
@@ -4,13 +4,10 @@
 package server
 
 import (
-	"crypto/md5" //nolint:gosec,gci
 	"errors"
 	"fmt"
-	"io"
 	"math/rand"
 	"net"
-	"strconv"
 	"time"
 
 	"github.com/pion/stun"
@@ -19,7 +16,6 @@ import (
 
 const (
 	maximumAllocationLifetime = time.Hour // See: https://tools.ietf.org/html/rfc5766#section-6.2 defines 3600 seconds recommendation
-	nonceLifetime             = time.Hour // See: https://tools.ietf.org/html/rfc5766#section-4
 )
 
 func randSeq(n int) string {
@@ -31,18 +27,6 @@ func randSeq(n int) string {
 	return string(b)
 }
 
-func buildNonce() (string, error) {
-	/* #nosec */
-	h := md5.New()
-	if _, err := io.WriteString(h, strconv.FormatInt(time.Now().Unix(), 10)); err != nil {
-		return "", fmt.Errorf("%w: %v", errFailedToGenerateNonce, err) //nolint:errorlint
-	}
-	if _, err := io.WriteString(h, strconv.FormatInt(rand.Int63(), 10)); err != nil { //nolint:gosec
-		return "", fmt.Errorf("%w: %v", errFailedToGenerateNonce, err) //nolint:errorlint
-	}
-	return fmt.Sprintf("%x", h.Sum(nil)), nil
-}
-
 func buildAndSend(conn net.PacketConn, dst net.Addr, attrs ...stun.Setter) error {
 	msg, err := stun.Build(attrs...)
 	if err != nil {
@@ -70,16 +54,11 @@ func buildMsg(transactionID [stun.TransactionIDSize]byte, msgType stun.MessageTy
 
 func authenticateRequest(r Request, m *stun.Message, callingMethod stun.Method) (stun.MessageIntegrity, bool, error) {
 	respondWithNonce := func(responseCode stun.ErrorCode) (stun.MessageIntegrity, bool, error) {
-		nonce, err := buildNonce()
+		nonce, err := r.NonceHash.Generate()
 		if err != nil {
 			return nil, false, err
 		}
 
-		// Nonce has already been taken
-		if _, keyCollision := r.Nonces.LoadOrStore(nonce, time.Now()); keyCollision {
-			return nil, false, errDuplicatedNonce
-		}
-
 		return nil, false, buildAndSend(r.Conn, r.SrcAddr, buildMsg(m.TransactionID,
 			stun.NewType(callingMethod, stun.ClassErrorResponse),
 			&stun.ErrorCodeAttribute{Code: responseCode},
@@ -101,15 +80,8 @@ func authenticateRequest(r Request, m *stun.Message, callingMethod stun.Method)
 		return nil, false, buildAndSendErr(r.Conn, r.SrcAddr, err, badRequestMsg...)
 	}
 
-	// Assert Nonce exists and is not expired
-	nonceCreationTime, nonceFound := r.Nonces.Load(string(*nonceAttr))
-	if !nonceFound {
-		r.Nonces.Delete(nonceAttr)
-		return respondWithNonce(stun.CodeStaleNonce)
-	}
-
-	if timeValue, ok := nonceCreationTime.(time.Time); !ok || time.Since(timeValue) >= nonceLifetime {
-		r.Nonces.Delete(nonceAttr)
+	// Assert Nonce is signed and is not expired
+	if err := r.NonceHash.Validate(nonceAttr.String()); err != nil {
 		return respondWithNonce(stun.CodeStaleNonce)
 	}
 
diff --git a/vendor/github.com/pion/turn/v2/server.go b/vendor/github.com/pion/turn/v2/server.go
index 5180d20d..ea8e04de 100644
--- a/vendor/github.com/pion/turn/v2/server.go
+++ b/vendor/github.com/pion/turn/v2/server.go
@@ -8,7 +8,6 @@ import (
 	"errors"
 	"fmt"
 	"net"
-	"sync"
 	"time"
 
 	"github.com/pion/logging"
@@ -27,7 +26,7 @@ type Server struct {
 	authHandler        AuthHandler
 	realm              string
 	channelBindTimeout time.Duration
-	nonces             *sync.Map
+	nonceHash          *server.NonceHash
 
 	packetConnConfigs  []PacketConnConfig
 	listenerConfigs    []ListenerConfig
@@ -53,6 +52,11 @@ func NewServer(config ServerConfig) (*Server, error) {
 		mtu = config.InboundMTU
 	}
 
+	nonceHash, err := server.NewNonceHash()
+	if err != nil {
+		return nil, err
+	}
+
 	s := &Server{
 		log:                loggerFactory.NewLogger("turn"),
 		authHandler:        config.AuthHandler,
@@ -60,7 +64,7 @@ func NewServer(config ServerConfig) (*Server, error) {
 		channelBindTimeout: config.ChannelBindTimeout,
 		packetConnConfigs:  config.PacketConnConfigs,
 		listenerConfigs:    config.ListenerConfigs,
-		nonces:             &sync.Map{},
+		nonceHash:          nonceHash,
 		inboundMTU:         mtu,
 	}
 
@@ -198,7 +202,7 @@ func (s *Server) readLoop(p net.PacketConn, allocationManager *allocation.Manage
 			Realm:              s.realm,
 			AllocationManager:  allocationManager,
 			ChannelBindTimeout: s.channelBindTimeout,
-			Nonces:             s.nonces,
+			NonceHash:          s.nonceHash,
 		}); err != nil {
 			s.log.Errorf("Failed to handle datagram: %v", err)
 		}
diff --git a/vendor/github.com/pion/webrtc/v3/constants.go b/vendor/github.com/pion/webrtc/v3/constants.go
index 79c2fa38..c8ebb7bf 100644
--- a/vendor/github.com/pion/webrtc/v3/constants.go
+++ b/vendor/github.com/pion/webrtc/v3/constants.go
@@ -38,6 +38,13 @@ const (
 	generatedCertificateOrigin = "WebRTC"
 
 	sdesRepairRTPStreamIDURI = "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id"
+
+	// AttributeRtxPayloadType is the interceptor attribute added when Read() returns an RTX packet containing the RTX stream payload type
+	AttributeRtxPayloadType = "rtx_payload_type"
+	// AttributeRtxSsrc is the interceptor attribute added when Read() returns an RTX packet containing the RTX stream SSRC
+	AttributeRtxSsrc = "rtx_ssrc"
+	// AttributeRtxSequenceNumber is the interceptor attribute added when Read() returns an RTX packet containing the RTX stream sequence number
+	AttributeRtxSequenceNumber = "rtx_sequence_number"
 )
 
 func defaultSrtpProtectionProfiles() []dtls.SRTPProtectionProfile {
diff --git a/vendor/github.com/pion/webrtc/v3/datachannel.go b/vendor/github.com/pion/webrtc/v3/datachannel.go
index f7c9511b..01e38b77 100644
--- a/vendor/github.com/pion/webrtc/v3/datachannel.go
+++ b/vendor/github.com/pion/webrtc/v3/datachannel.go
@@ -40,6 +40,7 @@ type DataChannel struct {
 	readyState                 atomic.Value // DataChannelState
 	bufferedAmountLowThreshold uint64
 	detachCalled               bool
+	readLoopActive             chan struct{}
 
 	// The binaryType represents attribute MUST, on getting, return the value to
 	// which it was last set. On setting, if the new value is either the string
@@ -327,6 +328,7 @@ func (d *DataChannel) handleOpen(dc *datachannel.DataChannel, isRemote, isAlread
 	defer d.mu.Unlock()
 
 	if !d.api.settingEngine.detach.DataChannels {
+		d.readLoopActive = make(chan struct{})
 		go d.readLoop()
 	}
 }
@@ -356,6 +358,7 @@ var rlBufPool = sync.Pool{New: func() interface{} {
 }}
 
 func (d *DataChannel) readLoop() {
+	defer close(d.readLoopActive)
 	for {
 		buffer := rlBufPool.Get().([]byte) //nolint:forcetypeassert
 		n, isString, err := d.dataChannel.ReadDataChannel(buffer)
@@ -438,6 +441,22 @@ func (d *DataChannel) Detach() (datachannel.ReadWriteCloser, error) {
 // Close Closes the DataChannel. It may be called regardless of whether
 // the DataChannel object was created by this peer or the remote peer.
 func (d *DataChannel) Close() error {
+	return d.close(false)
+}
+
+// Normally, close only stops writes from happening, so waitForReadsDone=true
+// will wait for reads to be finished based on underlying SCTP association
+// closure or a SCTP reset stream from the other side. This is safe to call
+// with waitForReadsDone=true after tearing down a PeerConnection but not
+// necessarily before. For example, if you used a vnet and dropped all packets
+// right before closing the DataChannel, you'd need never see a reset stream.
+func (d *DataChannel) close(waitForReadsDone bool) error {
+	if waitForReadsDone && d.readLoopActive != nil {
+		defer func() {
+			<-d.readLoopActive
+		}()
+	}
+
 	d.mu.Lock()
 	haveSctpTransport := d.dataChannel != nil
 	d.mu.Unlock()
diff --git a/vendor/github.com/pion/webrtc/v3/dtlstransport.go b/vendor/github.com/pion/webrtc/v3/dtlstransport.go
index d468eca7..0267ca59 100644
--- a/vendor/github.com/pion/webrtc/v3/dtlstransport.go
+++ b/vendor/github.com/pion/webrtc/v3/dtlstransport.go
@@ -505,7 +505,7 @@ func (t *DTLSTransport) streamsForSSRC(ssrc SSRC, streamInfo interceptor.StreamI
 		return nil, nil, nil, nil, err
 	}
 
-	rtcpInterceptor := t.api.interceptor.BindRTCPReader(interceptor.RTPReaderFunc(func(in []byte, a interceptor.Attributes) (n int, attributes interceptor.Attributes, err error) {
+	rtcpInterceptor := t.api.interceptor.BindRTCPReader(interceptor.RTCPReaderFunc(func(in []byte, a interceptor.Attributes) (n int, attributes interceptor.Attributes, err error) {
 		n, err = rtcpReadStream.Read(in)
 		return n, a, err
 	}))
diff --git a/vendor/github.com/pion/webrtc/v3/icegatherer.go b/vendor/github.com/pion/webrtc/v3/icegatherer.go
index 4265c5da..d01ecc13 100644
--- a/vendor/github.com/pion/webrtc/v3/icegatherer.go
+++ b/vendor/github.com/pion/webrtc/v3/icegatherer.go
@@ -122,6 +122,7 @@ func (g *ICEGatherer) createAgent() error {
 		UDPMux:                 g.api.settingEngine.iceUDPMux,
 		ProxyDialer:            g.api.settingEngine.iceProxyDialer,
 		DisableActiveTCP:       g.api.settingEngine.iceDisableActiveTCP,
+		BindingRequestHandler:  g.api.settingEngine.iceBindingRequestHandler,
 	}
 
 	requestedNetworkTypes := g.api.settingEngine.candidates.ICENetworkTypes
diff --git a/vendor/github.com/pion/webrtc/v3/interceptor.go b/vendor/github.com/pion/webrtc/v3/interceptor.go
index 85232f35..7a5b4a72 100644
--- a/vendor/github.com/pion/webrtc/v3/interceptor.go
+++ b/vendor/github.com/pion/webrtc/v3/interceptor.go
@@ -109,6 +109,19 @@ func ConfigureTWCCSender(mediaEngine *MediaEngine, interceptorRegistry *intercep
 	return nil
 }
 
+// ConfigureSimulcastExtensionHeaders enables the RTP Extension Headers needed for Simulcast
+func ConfigureSimulcastExtensionHeaders(mediaEngine *MediaEngine) error {
+	if err := mediaEngine.RegisterHeaderExtension(RTPHeaderExtensionCapability{URI: sdp.SDESMidURI}, RTPCodecTypeVideo); err != nil {
+		return err
+	}
+
+	if err := mediaEngine.RegisterHeaderExtension(RTPHeaderExtensionCapability{URI: sdp.SDESRTPStreamIDURI}, RTPCodecTypeVideo); err != nil {
+		return err
+	}
+
+	return mediaEngine.RegisterHeaderExtension(RTPHeaderExtensionCapability{URI: sdesRepairRTPStreamIDURI}, RTPCodecTypeVideo)
+}
+
 type interceptorToTrackLocalWriter struct{ interceptor atomic.Value } // interceptor.RTPWriter }
 
 func (i *interceptorToTrackLocalWriter) WriteRTP(header *rtp.Header, payload []byte) (int, error) {
diff --git a/vendor/github.com/pion/webrtc/v3/internal/fmtp/av1.go b/vendor/github.com/pion/webrtc/v3/internal/fmtp/av1.go
new file mode 100644
index 00000000..29eccd11
--- /dev/null
+++ b/vendor/github.com/pion/webrtc/v3/internal/fmtp/av1.go
@@ -0,0 +1,41 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
+package fmtp
+
+type av1FMTP struct {
+	parameters map[string]string
+}
+
+func (h *av1FMTP) MimeType() string {
+	return "video/av1"
+}
+
+func (h *av1FMTP) Match(b FMTP) bool {
+	c, ok := b.(*av1FMTP)
+	if !ok {
+		return false
+	}
+
+	// RTP Payload Format For AV1 (v1.0)
+	// https://aomediacodec.github.io/av1-rtp-spec/
+	// If the profile parameter is not present, it MUST be inferred to be 0 (“Main” profile).
+	hProfile, ok := h.parameters["profile"]
+	if !ok {
+		hProfile = "0"
+	}
+	cProfile, ok := c.parameters["profile"]
+	if !ok {
+		cProfile = "0"
+	}
+	if hProfile != cProfile {
+		return false
+	}
+
+	return true
+}
+
+func (h *av1FMTP) Parameter(key string) (string, bool) {
+	v, ok := h.parameters[key]
+	return v, ok
+}
diff --git a/vendor/github.com/pion/webrtc/v3/internal/fmtp/fmtp.go b/vendor/github.com/pion/webrtc/v3/internal/fmtp/fmtp.go
index 5461c019..f515a648 100644
--- a/vendor/github.com/pion/webrtc/v3/internal/fmtp/fmtp.go
+++ b/vendor/github.com/pion/webrtc/v3/internal/fmtp/fmtp.go
@@ -8,6 +8,22 @@ import (
 	"strings"
 )
 
+func parseParameters(line string) map[string]string {
+	parameters := make(map[string]string)
+
+	for _, p := range strings.Split(line, ";") {
+		pp := strings.SplitN(strings.TrimSpace(p), "=", 2)
+		key := strings.ToLower(pp[0])
+		var value string
+		if len(pp) > 1 {
+			value = pp[1]
+		}
+		parameters[key] = value
+	}
+
+	return parameters
+}
+
 // FMTP interface for implementing custom
 // FMTP parsers based on MimeType
 type FMTP interface {
@@ -23,29 +39,30 @@ type FMTP interface {
 }
 
 // Parse parses an fmtp string based on the MimeType
-func Parse(mimetype, line string) FMTP {
+func Parse(mimeType, line string) FMTP {
 	var f FMTP
 
-	parameters := make(map[string]string)
-
-	for _, p := range strings.Split(line, ";") {
-		pp := strings.SplitN(strings.TrimSpace(p), "=", 2)
-		key := strings.ToLower(pp[0])
-		var value string
-		if len(pp) > 1 {
-			value = pp[1]
-		}
-		parameters[key] = value
-	}
+	parameters := parseParameters(line)
 
 	switch {
-	case strings.EqualFold(mimetype, "video/h264"):
+	case strings.EqualFold(mimeType, "video/h264"):
 		f = &h264FMTP{
 			parameters: parameters,
 		}
+
+	case strings.EqualFold(mimeType, "video/vp9"):
+		f = &vp9FMTP{
+			parameters: parameters,
+		}
+
+	case strings.EqualFold(mimeType, "video/av1"):
+		f = &av1FMTP{
+			parameters: parameters,
+		}
+
 	default:
 		f = &genericFMTP{
-			mimeType:   mimetype,
+			mimeType:   mimeType,
 			parameters: parameters,
 		}
 	}
diff --git a/vendor/github.com/pion/webrtc/v3/internal/fmtp/vp9.go b/vendor/github.com/pion/webrtc/v3/internal/fmtp/vp9.go
new file mode 100644
index 00000000..7fc618bc
--- /dev/null
+++ b/vendor/github.com/pion/webrtc/v3/internal/fmtp/vp9.go
@@ -0,0 +1,41 @@
+// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
+// SPDX-License-Identifier: MIT
+
+package fmtp
+
+type vp9FMTP struct {
+	parameters map[string]string
+}
+
+func (h *vp9FMTP) MimeType() string {
+	return "video/vp9"
+}
+
+func (h *vp9FMTP) Match(b FMTP) bool {
+	c, ok := b.(*vp9FMTP)
+	if !ok {
+		return false
+	}
+
+	// RTP Payload Format for VP9 Video - draft-ietf-payload-vp9-16
+	// https://datatracker.ietf.org/doc/html/draft-ietf-payload-vp9-16
+	// If no profile-id is present, Profile 0 MUST be inferred
+	hProfileID, ok := h.parameters["profile-id"]
+	if !ok {
+		hProfileID = "0"
+	}
+	cProfileID, ok := c.parameters["profile-id"]
+	if !ok {
+		cProfileID = "0"
+	}
+	if hProfileID != cProfileID {
+		return false
+	}
+
+	return true
+}
+
+func (h *vp9FMTP) Parameter(key string) (string, bool) {
+	v, ok := h.parameters[key]
+	return v, ok
+}
diff --git a/vendor/github.com/pion/webrtc/v3/mediaengine.go b/vendor/github.com/pion/webrtc/v3/mediaengine.go
index 6fd1bef2..7abb8c3a 100644
--- a/vendor/github.com/pion/webrtc/v3/mediaengine.go
+++ b/vendor/github.com/pion/webrtc/v3/mediaengine.go
@@ -415,9 +415,11 @@ func (m *MediaEngine) matchRemoteCodec(remoteCodec RTPCodecParameters, typ RTPCo
 		}
 
 		aptMatch := codecMatchNone
+		var aptCodec RTPCodecParameters
 		for _, codec := range exactMatches {
 			if codec.PayloadType == PayloadType(payloadType) {
 				aptMatch = codecMatchExact
+				aptCodec = codec
 				break
 			}
 		}
@@ -426,6 +428,7 @@ func (m *MediaEngine) matchRemoteCodec(remoteCodec RTPCodecParameters, typ RTPCo
 			for _, codec := range partialMatches {
 				if codec.PayloadType == PayloadType(payloadType) {
 					aptMatch = codecMatchPartial
+					aptCodec = codec
 					break
 				}
 			}
@@ -435,8 +438,14 @@ func (m *MediaEngine) matchRemoteCodec(remoteCodec RTPCodecParameters, typ RTPCo
 			return codecMatchNone, nil // not an error, we just ignore this codec we don't support
 		}
 
+		// replace the apt value with the original codec's payload type
+		toMatchCodec := remoteCodec
+		if aptMatched, mt := codecParametersFuzzySearch(aptCodec, codecs); mt == aptMatch {
+			toMatchCodec.SDPFmtpLine = strings.Replace(toMatchCodec.SDPFmtpLine, fmt.Sprintf("apt=%d", payloadType), fmt.Sprintf("apt=%d", aptMatched.PayloadType), 1)
+		}
+
 		// if apt's media codec is partial match, then apt codec must be partial match too
-		_, matchType := codecParametersFuzzySearch(remoteCodec, codecs)
+		_, matchType := codecParametersFuzzySearch(toMatchCodec, codecs)
 		if matchType == codecMatchExact && aptMatch == codecMatchPartial {
 			matchType = codecMatchPartial
 		}
diff --git a/vendor/github.com/pion/webrtc/v3/operations.go b/vendor/github.com/pion/webrtc/v3/operations.go
index d9dca4a8..bc366ac3 100644
--- a/vendor/github.com/pion/webrtc/v3/operations.go
+++ b/vendor/github.com/pion/webrtc/v3/operations.go
@@ -16,11 +16,19 @@ type operations struct {
 	mu   sync.Mutex
 	busy bool
 	ops  *list.List
+
+	updateNegotiationNeededFlagOnEmptyChain *atomicBool
+	onNegotiationNeeded                     func()
 }
 
-func newOperations() *operations {
+func newOperations(
+	updateNegotiationNeededFlagOnEmptyChain *atomicBool,
+	onNegotiationNeeded func(),
+) *operations {
 	return &operations{
-		ops: list.New(),
+		ops:                                     list.New(),
+		updateNegotiationNeededFlagOnEmptyChain: updateNegotiationNeededFlagOnEmptyChain,
+		onNegotiationNeeded:                     onNegotiationNeeded,
 	}
 }
 
@@ -93,4 +101,9 @@ func (o *operations) start() {
 		fn()
 		fn = o.pop()
 	}
+	if !o.updateNegotiationNeededFlagOnEmptyChain.get() {
+		return
+	}
+	o.updateNegotiationNeededFlagOnEmptyChain.set(false)
+	o.onNegotiationNeeded()
 }
diff --git a/vendor/github.com/pion/webrtc/v3/peerconnection.go b/vendor/github.com/pion/webrtc/v3/peerconnection.go
index c6af1200..6a018a93 100644
--- a/vendor/github.com/pion/webrtc/v3/peerconnection.go
+++ b/vendor/github.com/pion/webrtc/v3/peerconnection.go
@@ -55,9 +55,10 @@ type PeerConnection struct {
 
 	idpLoginURL *string
 
-	isClosed               *atomicBool
-	isNegotiationNeeded    *atomicBool
-	negotiationNeededState negotiationNeededState
+	isClosed                                *atomicBool
+	isClosedDone                            chan struct{}
+	isNegotiationNeeded                     *atomicBool
+	updateNegotiationNeededFlagOnEmptyChain *atomicBool
 
 	lastOffer  string
 	lastAnswer string
@@ -115,6 +116,7 @@ func (api *API) NewPeerConnection(configuration Configuration) (*PeerConnection,
 	// https://w3c.github.io/webrtc-pc/#constructor (Step #2)
 	// Some variables defined explicitly despite their implicit zero values to
 	// allow better readability to understand what is happening.
+
 	pc := &PeerConnection{
 		statsID: fmt.Sprintf("PeerConnection-%d", time.Now().UnixNano()),
 		configuration: Configuration{
@@ -125,18 +127,20 @@ func (api *API) NewPeerConnection(configuration Configuration) (*PeerConnection,
 			Certificates:         []Certificate{},
 			ICECandidatePoolSize: 0,
 		},
-		ops:                    newOperations(),
-		isClosed:               &atomicBool{},
-		isNegotiationNeeded:    &atomicBool{},
-		negotiationNeededState: negotiationNeededStateEmpty,
-		lastOffer:              "",
-		lastAnswer:             "",
-		greaterMid:             -1,
-		signalingState:         SignalingStateStable,
+		isClosed:                                &atomicBool{},
+		isClosedDone:                            make(chan struct{}),
+		isNegotiationNeeded:                     &atomicBool{},
+		updateNegotiationNeededFlagOnEmptyChain: &atomicBool{},
+		lastOffer:                               "",
+		lastAnswer:                              "",
+		greaterMid:                              -1,
+		signalingState:                          SignalingStateStable,
 
 		api: api,
 		log: api.settingEngine.LoggerFactory.NewLogger("pc"),
 	}
+	pc.ops = newOperations(pc.updateNegotiationNeededFlagOnEmptyChain, pc.onNegotiationNeeded)
+
 	pc.iceConnectionState.Store(ICEConnectionStateNew)
 	pc.connectionState.Store(PeerConnectionStateNew)
 
@@ -293,66 +297,54 @@ func (pc *PeerConnection) OnNegotiationNeeded(f func()) {
 
 // onNegotiationNeeded enqueues negotiationNeededOp if necessary
 // caller of this method should hold `pc.mu` lock
+// https://www.w3.org/TR/webrtc/#dfn-update-the-negotiation-needed-flag
 func (pc *PeerConnection) onNegotiationNeeded() {
-	// https://w3c.github.io/webrtc-pc/#updating-the-negotiation-needed-flag
-	// non-canon step 1
-	if pc.negotiationNeededState == negotiationNeededStateRun {
-		pc.negotiationNeededState = negotiationNeededStateQueue
-		return
-	} else if pc.negotiationNeededState == negotiationNeededStateQueue {
+	// 4.7.3.1 If the length of connection.[[Operations]] is not 0, then set
+	// connection.[[UpdateNegotiationNeededFlagOnEmptyChain]] to true, and abort these steps.
+	if !pc.ops.IsEmpty() {
+		pc.updateNegotiationNeededFlagOnEmptyChain.set(true)
 		return
 	}
-	pc.negotiationNeededState = negotiationNeededStateRun
 	pc.ops.Enqueue(pc.negotiationNeededOp)
 }
 
+// https://www.w3.org/TR/webrtc/#dfn-update-the-negotiation-needed-flag
 func (pc *PeerConnection) negotiationNeededOp() {
-	// Don't run NegotiatedNeeded checks if OnNegotiationNeeded is not set
-	if handler, ok := pc.onNegotiationNeededHandler.Load().(func()); !ok || handler == nil {
-		return
-	}
-
-	// https://www.w3.org/TR/webrtc/#updating-the-negotiation-needed-flag
-	// Step 2.1
+	// 4.7.3.2.1 If connection.[[IsClosed]] is true, abort these steps.
 	if pc.isClosed.get() {
 		return
 	}
-	// non-canon step 2.2
+
+	// 4.7.3.2.2 If the length of connection.[[Operations]] is not 0,
+	// then set connection.[[UpdateNegotiationNeededFlagOnEmptyChain]] to
+	// true, and abort these steps.
 	if !pc.ops.IsEmpty() {
-		pc.ops.Enqueue(pc.negotiationNeededOp)
+		pc.updateNegotiationNeededFlagOnEmptyChain.set(true)
 		return
 	}
 
-	// non-canon, run again if there was a request
-	defer func() {
-		pc.mu.Lock()
-		defer pc.mu.Unlock()
-		if pc.negotiationNeededState == negotiationNeededStateQueue {
-			defer pc.onNegotiationNeeded()
-		}
-		pc.negotiationNeededState = negotiationNeededStateEmpty
-	}()
-
-	// Step 2.3
+	// 4.7.3.2.3 If connection's signaling state is not "stable", abort these steps.
 	if pc.SignalingState() != SignalingStateStable {
 		return
 	}
 
-	// Step 2.4
+	// 4.7.3.2.4 If the result of checking if negotiation is needed is false,
+	// clear the negotiation-needed flag by setting connection.[[NegotiationNeeded]]
+	// to false, and abort these steps.
 	if !pc.checkNegotiationNeeded() {
 		pc.isNegotiationNeeded.set(false)
 		return
 	}
 
-	// Step 2.5
+	// 4.7.3.2.5 If connection.[[NegotiationNeeded]] is already true, abort these steps.
 	if pc.isNegotiationNeeded.get() {
 		return
 	}
 
-	// Step 2.6
+	// 4.7.3.2.6 Set connection.[[NegotiationNeeded]] to true.
 	pc.isNegotiationNeeded.set(true)
 
-	// Step 2.7
+	// 4.7.3.2.7 Fire an event named negotiationneeded at connection.
 	if handler, ok := pc.onNegotiationNeededHandler.Load().(func()); ok && handler != nil {
 		handler()
 	}
@@ -994,7 +986,7 @@ func (pc *PeerConnection) SetLocalDescription(desc SessionDescription) error {
 	}
 
 	desc.parsed = &sdp.SessionDescription{}
-	if err := desc.parsed.Unmarshal([]byte(desc.SDP)); err != nil {
+	if err := desc.parsed.UnmarshalString(desc.SDP); err != nil {
 		return err
 	}
 	if err := pc.setDescription(&desc, stateChangeOpSetLocal); err != nil {
@@ -1576,12 +1568,11 @@ func (pc *PeerConnection) handleIncomingSSRC(rtpStream io.Reader, ssrc SSRC) err
 		return err
 	}
 
-	var mid, rid, rsid string
-	payloadType, err := handleUnknownRTPPacket(b[:i], uint8(midExtensionID), uint8(streamIDExtensionID), uint8(repairStreamIDExtensionID), &mid, &rid, &rsid)
-	if err != nil {
-		return err
+	if i < 4 {
+		return errRTPTooShort
 	}
 
+	payloadType := PayloadType(b[1] & 0x7f)
 	params, err := pc.api.mediaEngine.getRTPParametersByPayloadType(payloadType)
 	if err != nil {
 		return err
@@ -1593,14 +1584,21 @@ func (pc *PeerConnection) handleIncomingSSRC(rtpStream io.Reader, ssrc SSRC) err
 		return err
 	}
 
+	var mid, rid, rsid string
+	var paddingOnly bool
 	for readCount := 0; readCount <= simulcastProbeCount; readCount++ {
 		if mid == "" || (rid == "" && rsid == "") {
+			// skip padding only packets for probing
+			if paddingOnly {
+				readCount--
+			}
+
 			i, _, err := interceptor.Read(b, nil)
 			if err != nil {
 				return err
 			}
 
-			if _, err = handleUnknownRTPPacket(b[:i], uint8(midExtensionID), uint8(streamIDExtensionID), uint8(repairStreamIDExtensionID), &mid, &rid, &rsid); err != nil {
+			if _, paddingOnly, err = handleUnknownRTPPacket(b[:i], uint8(midExtensionID), uint8(streamIDExtensionID), uint8(repairStreamIDExtensionID), &mid, &rid, &rsid); err != nil {
 				return err
 			}
 
@@ -2038,14 +2036,31 @@ func (pc *PeerConnection) writeRTCP(pkts []rtcp.Packet, _ interceptor.Attributes
 	return pc.dtlsTransport.WriteRTCP(pkts)
 }
 
-// Close ends the PeerConnection
+// Close ends the PeerConnection.
+// It will make a best effort to wait for all underlying goroutines it spawned to finish,
+// except for cases that would cause deadlocks with itself.
 func (pc *PeerConnection) Close() error {
 	// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #1)
 	// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #2)
 	if pc.isClosed.swap(true) {
+		// someone else got here first but may still be closing (e.g. via DTLS close_notify)
+		<-pc.isClosedDone
 		return nil
 	}
+	defer close(pc.isClosedDone)
+
+	// Try closing everything and collect the errors
+	// Shutdown strategy:
+	// 1. Close all data channels.
+	// 2. All Conn close by closing their underlying Conn.
+	// 3. A Mux stops this chain. It won't close the underlying
+	//    Conn if one of the endpoints is closed down. To
+	//    continue the chain the Mux has to be closed.
+	pc.sctpTransport.lock.Lock()
+	closeErrs := make([]error, 0, 4+len(pc.sctpTransport.dataChannels))
+	pc.sctpTransport.lock.Unlock()
 
+	// canon steps
 	// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #3)
 	pc.signalingState.Set(SignalingStateClosed)
 
@@ -2055,7 +2070,6 @@ func (pc *PeerConnection) Close() error {
 	// 2. A Mux stops this chain. It won't close the underlying
 	//    Conn if one of the endpoints is closed down. To
 	//    continue the chain the Mux has to be closed.
-	closeErrs := make([]error, 4)
 
 	closeErrs = append(closeErrs, pc.api.interceptor.Close())
 
@@ -2082,7 +2096,6 @@ func (pc *PeerConnection) Close() error {
 
 	// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #7)
 	closeErrs = append(closeErrs, pc.dtlsTransport.Stop())
-
 	// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #8, #9, #10)
 	if pc.iceTransport != nil {
 		closeErrs = append(closeErrs, pc.iceTransport.Stop())
@@ -2091,6 +2104,13 @@ func (pc *PeerConnection) Close() error {
 	// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #11)
 	pc.updateConnectionState(pc.ICEConnectionState(), pc.dtlsTransport.State())
 
+	// non-canon steps
+	pc.sctpTransport.lock.Lock()
+	for _, d := range pc.sctpTransport.dataChannels {
+		closeErrs = append(closeErrs, d.close(true))
+	}
+	pc.sctpTransport.lock.Unlock()
+
 	return util.FlattenErrs(closeErrs)
 }
 
@@ -2292,6 +2312,7 @@ func (pc *PeerConnection) generateUnmatchedSDP(transceivers []*RTPTransceiver, u
 	if err != nil {
 		return nil, err
 	}
+	d.Attributes = append(d.Attributes, sdp.Attribute{Key: sdp.AttrKeyMsidSemantic, Value: "WMS*"})
 
 	iceParams, err := pc.iceGatherer.GetLocalParameters()
 	if err != nil {
@@ -2364,6 +2385,7 @@ func (pc *PeerConnection) generateMatchedSDP(transceivers []*RTPTransceiver, use
 	if err != nil {
 		return nil, err
 	}
+	d.Attributes = append(d.Attributes, sdp.Attribute{Key: sdp.AttrKeyMsidSemantic, Value: "WMS*"})
 
 	iceParams, err := pc.iceGatherer.GetLocalParameters()
 	if err != nil {
diff --git a/vendor/github.com/pion/webrtc/v3/peerconnectionstate.go b/vendor/github.com/pion/webrtc/v3/peerconnectionstate.go
index 1f145688..b626a31e 100644
--- a/vendor/github.com/pion/webrtc/v3/peerconnectionstate.go
+++ b/vendor/github.com/pion/webrtc/v3/peerconnectionstate.go
@@ -84,14 +84,3 @@ func (t PeerConnectionState) String() string {
 		return ErrUnknownType.Error()
 	}
 }
-
-type negotiationNeededState int
-
-const (
-	// NegotiationNeededStateEmpty not running and queue is empty
-	negotiationNeededStateEmpty = iota
-	// NegotiationNeededStateEmpty running and queue is empty
-	negotiationNeededStateRun
-	// NegotiationNeededStateEmpty running and queue
-	negotiationNeededStateQueue
-)
diff --git a/vendor/github.com/pion/webrtc/v3/rtpreceiver.go b/vendor/github.com/pion/webrtc/v3/rtpreceiver.go
index c04a715f..ec7c79bc 100644
--- a/vendor/github.com/pion/webrtc/v3/rtpreceiver.go
+++ b/vendor/github.com/pion/webrtc/v3/rtpreceiver.go
@@ -7,6 +7,7 @@
 package webrtc
 
 import (
+	"encoding/binary"
 	"fmt"
 	"io"
 	"sync"
@@ -31,13 +32,28 @@ type trackStreams struct {
 	rtcpReadStream  *srtp.ReadStreamSRTCP
 	rtcpInterceptor interceptor.RTCPReader
 
-	repairReadStream  *srtp.ReadStreamSRTP
-	repairInterceptor interceptor.RTPReader
+	repairReadStream    *srtp.ReadStreamSRTP
+	repairInterceptor   interceptor.RTPReader
+	repairStreamChannel chan rtxPacketWithAttributes
 
 	repairRtcpReadStream  *srtp.ReadStreamSRTCP
 	repairRtcpInterceptor interceptor.RTCPReader
 }
 
+type rtxPacketWithAttributes struct {
+	pkt        []byte
+	attributes interceptor.Attributes
+	pool       *sync.Pool
+}
+
+func (p *rtxPacketWithAttributes) release() {
+	if p.pkt != nil {
+		b := p.pkt[:cap(p.pkt)]
+		p.pool.Put(b) // nolint:staticcheck
+		p.pkt = nil
+	}
+}
+
 // RTPReceiver allows an application to inspect the receipt of a TrackRemote
 type RTPReceiver struct {
 	kind      RTPCodecType
@@ -52,6 +68,8 @@ type RTPReceiver struct {
 
 	// A reference to the associated api object
 	api *API
+
+	rtxPool sync.Pool
 }
 
 // NewRTPReceiver constructs a new RTPReceiver
@@ -67,6 +85,9 @@ func (api *API) NewRTPReceiver(kind RTPCodecType, transport *DTLSTransport) (*RT
 		closed:    make(chan interface{}),
 		received:  make(chan interface{}),
 		tracks:    []trackStreams{},
+		rtxPool: sync.Pool{New: func() interface{} {
+			return make([]byte, api.settingEngine.getReceiveMTU())
+		}},
 	}
 
 	return r, nil
@@ -145,6 +166,7 @@ func (r *RTPReceiver) configureReceive(parameters RTPReceiveParameters) {
 			track: newTrackRemote(
 				r.kind,
 				parameters.Encodings[i].SSRC,
+				parameters.Encodings[i].RTX.SSRC,
 				parameters.Encodings[i].RID,
 				r,
 			),
@@ -379,8 +401,6 @@ func (r *RTPReceiver) receiveForRid(rid string, params RTPParameters, streamInfo
 }
 
 // receiveForRtx starts a routine that processes the repair stream
-// These packets aren't exposed to the user yet, but we need to process them for
-// TWCC
 func (r *RTPReceiver) receiveForRtx(ssrc SSRC, rsid string, streamInfo *interceptor.StreamInfo, rtpReadStream *srtp.ReadStreamSRTP, rtpInterceptor interceptor.RTPReader, rtcpReadStream *srtp.ReadStreamSRTCP, rtcpInterceptor interceptor.RTCPReader) error {
 	var track *trackStreams
 	if ssrc != 0 && len(r.tracks) == 1 {
@@ -389,6 +409,10 @@ func (r *RTPReceiver) receiveForRtx(ssrc SSRC, rsid string, streamInfo *intercep
 		for i := range r.tracks {
 			if r.tracks[i].track.RID() == rsid {
 				track = &r.tracks[i]
+				if track.track.RtxSSRC() == 0 {
+					track.track.setRtxSSRC(SSRC(streamInfo.SSRC))
+				}
+				break
 			}
 		}
 	}
@@ -402,12 +426,56 @@ func (r *RTPReceiver) receiveForRtx(ssrc SSRC, rsid string, streamInfo *intercep
 	track.repairInterceptor = rtpInterceptor
 	track.repairRtcpReadStream = rtcpReadStream
 	track.repairRtcpInterceptor = rtcpInterceptor
+	track.repairStreamChannel = make(chan rtxPacketWithAttributes)
 
 	go func() {
-		b := make([]byte, r.api.settingEngine.getReceiveMTU())
 		for {
-			if _, _, readErr := track.repairInterceptor.Read(b, nil); readErr != nil {
+			b := r.rtxPool.Get().([]byte) // nolint:forcetypeassert
+			i, attributes, err := track.repairInterceptor.Read(b, nil)
+			if err != nil {
+				r.rtxPool.Put(b) // nolint:staticcheck
+				return
+			}
+
+			// RTX packets have a different payload format. Move the OSN in the payload to the RTP header and rewrite the
+			// payload type and SSRC, so that we can return RTX packets to the caller 'transparently' i.e. in the same format
+			// as non-RTX RTP packets
+			hasExtension := b[0]&0b10000 > 0
+			hasPadding := b[0]&0b100000 > 0
+			csrcCount := b[0] & 0b1111
+			headerLength := uint16(12 + (4 * csrcCount))
+			paddingLength := 0
+			if hasExtension {
+				headerLength += 4 * (1 + binary.BigEndian.Uint16(b[headerLength+2:headerLength+4]))
+			}
+			if hasPadding {
+				paddingLength = int(b[i-1])
+			}
+
+			if i-int(headerLength)-paddingLength < 2 {
+				// BWE probe packet, ignore
+				r.rtxPool.Put(b) // nolint:staticcheck
+				continue
+			}
+
+			if attributes == nil {
+				attributes = make(interceptor.Attributes)
+			}
+			attributes.Set(AttributeRtxPayloadType, b[1]&0x7F)
+			attributes.Set(AttributeRtxSequenceNumber, binary.BigEndian.Uint16(b[2:4]))
+			attributes.Set(AttributeRtxSsrc, binary.BigEndian.Uint32(b[8:12]))
+
+			b[1] = (b[1] & 0x80) | uint8(track.track.PayloadType())
+			b[2] = b[headerLength]
+			b[3] = b[headerLength+1]
+			binary.BigEndian.PutUint32(b[8:12], uint32(track.track.SSRC()))
+			copy(b[headerLength:i-2], b[headerLength+2:i])
+
+			select {
+			case <-r.closed:
+				r.rtxPool.Put(b) // nolint:staticcheck
 				return
+			case track.repairStreamChannel <- rtxPacketWithAttributes{pkt: b[:i-2], attributes: attributes, pool: &r.rtxPool}:
 			}
 		}
 	}()
@@ -446,3 +514,25 @@ func (r *RTPReceiver) setRTPReadDeadline(deadline time.Time, reader *TrackRemote
 	}
 	return fmt.Errorf("%w: %d", errRTPReceiverWithSSRCTrackStreamNotFound, reader.SSRC())
 }
+
+// readRTX returns an RTX packet if one is available on the RTX track, otherwise returns nil
+func (r *RTPReceiver) readRTX(reader *TrackRemote) *rtxPacketWithAttributes {
+	if !reader.HasRTX() {
+		return nil
+	}
+
+	select {
+	case <-r.received:
+	default:
+		return nil
+	}
+
+	if t := r.streamsForTrack(reader); t != nil {
+		select {
+		case rtxPacketReceived := <-t.repairStreamChannel:
+			return &rtxPacketReceived
+		default:
+		}
+	}
+	return nil
+}
diff --git a/vendor/github.com/pion/webrtc/v3/rtpsender.go b/vendor/github.com/pion/webrtc/v3/rtpsender.go
index 5b1b5d58..0c0e867e 100644
--- a/vendor/github.com/pion/webrtc/v3/rtpsender.go
+++ b/vendor/github.com/pion/webrtc/v3/rtpsender.go
@@ -204,7 +204,7 @@ func (r *RTPSender) addEncoding(track TrackLocal) {
 	}
 	trackEncoding.srtpStream.rtpSender = r
 	trackEncoding.rtcpInterceptor = r.api.interceptor.BindRTCPReader(
-		interceptor.RTPReaderFunc(func(in []byte, a interceptor.Attributes) (n int, attributes interceptor.Attributes, err error) {
+		interceptor.RTCPReaderFunc(func(in []byte, a interceptor.Attributes) (n int, attributes interceptor.Attributes, err error) {
 			n, err = trackEncoding.srtpStream.Read(in)
 			return n, a, err
 		}),
diff --git a/vendor/github.com/pion/webrtc/v3/rtptransceiver.go b/vendor/github.com/pion/webrtc/v3/rtptransceiver.go
index 02ddf792..f601a410 100644
--- a/vendor/github.com/pion/webrtc/v3/rtptransceiver.go
+++ b/vendor/github.com/pion/webrtc/v3/rtptransceiver.go
@@ -266,12 +266,16 @@ func satisfyTypeAndDirection(remoteKind RTPCodecType, remoteDirection RTPTransce
 
 // handleUnknownRTPPacket consumes a single RTP Packet and returns information that is helpful
 // for demuxing and handling an unknown SSRC (usually for Simulcast)
-func handleUnknownRTPPacket(buf []byte, midExtensionID, streamIDExtensionID, repairStreamIDExtensionID uint8, mid, rid, rsid *string) (payloadType PayloadType, err error) {
+func handleUnknownRTPPacket(buf []byte, midExtensionID, streamIDExtensionID, repairStreamIDExtensionID uint8, mid, rid, rsid *string) (payloadType PayloadType, paddingOnly bool, err error) {
 	rp := &rtp.Packet{}
 	if err = rp.Unmarshal(buf); err != nil {
 		return
 	}
 
+	if rp.Padding && len(rp.Payload) == 0 {
+		paddingOnly = true
+	}
+
 	if !rp.Header.Extension {
 		return
 	}
diff --git a/vendor/github.com/pion/webrtc/v3/sctptransport.go b/vendor/github.com/pion/webrtc/v3/sctptransport.go
index f2f33e4b..a468cbc9 100644
--- a/vendor/github.com/pion/webrtc/v3/sctptransport.go
+++ b/vendor/github.com/pion/webrtc/v3/sctptransport.go
@@ -109,6 +109,7 @@ func (r *SCTPTransport) Start(SCTPCapabilities) error {
 	sctpAssociation, err := sctp.Client(sctp.Config{
 		NetConn:              dtlsTransport.conn,
 		MaxReceiveBufferSize: r.api.settingEngine.sctp.maxReceiveBufferSize,
+		EnableZeroChecksum:   r.api.settingEngine.sctp.enableZeroChecksum,
 		LoggerFactory:        r.api.settingEngine.LoggerFactory,
 	})
 	if err != nil {
diff --git a/vendor/github.com/pion/webrtc/v3/sdp.go b/vendor/github.com/pion/webrtc/v3/sdp.go
index 1a9b2956..560fc788 100644
--- a/vendor/github.com/pion/webrtc/v3/sdp.go
+++ b/vendor/github.com/pion/webrtc/v3/sdp.go
@@ -128,6 +128,12 @@ func trackDetailsFromSDP(log logging.LeveledLogger, s *sdp.SessionDescription) (
 						}
 						rtxRepairFlows[rtxRepairFlow] = baseSsrc
 						tracksInMediaSection = filterTrackWithSSRC(tracksInMediaSection, SSRC(rtxRepairFlow)) // Remove if rtx was added as track before
+						for i := range tracksInMediaSection {
+							if tracksInMediaSection[i].ssrcs[0] == SSRC(baseSsrc) {
+								repairSsrc := SSRC(rtxRepairFlow)
+								tracksInMediaSection[i].repairSsrc = &repairSsrc
+							}
+						}
 					}
 				}
 
diff --git a/vendor/github.com/pion/webrtc/v3/sessiondescription.go b/vendor/github.com/pion/webrtc/v3/sessiondescription.go
index 12cdf0dd..91e22a91 100644
--- a/vendor/github.com/pion/webrtc/v3/sessiondescription.go
+++ b/vendor/github.com/pion/webrtc/v3/sessiondescription.go
@@ -19,6 +19,6 @@ type SessionDescription struct {
 // Unmarshal is a helper to deserialize the sdp
 func (sd *SessionDescription) Unmarshal() (*sdp.SessionDescription, error) {
 	sd.parsed = &sdp.SessionDescription{}
-	err := sd.parsed.Unmarshal([]byte(sd.SDP))
+	err := sd.parsed.UnmarshalString(sd.SDP)
 	return sd.parsed, err
 }
diff --git a/vendor/github.com/pion/webrtc/v3/settingengine.go b/vendor/github.com/pion/webrtc/v3/settingengine.go
index 921c94b2..38dbe5b0 100644
--- a/vendor/github.com/pion/webrtc/v3/settingengine.go
+++ b/vendor/github.com/pion/webrtc/v3/settingengine.go
@@ -17,6 +17,7 @@ import (
 	dtlsElliptic "github.com/pion/dtls/v2/pkg/crypto/elliptic"
 	"github.com/pion/ice/v2"
 	"github.com/pion/logging"
+	"github.com/pion/stun"
 	"github.com/pion/transport/v2"
 	"github.com/pion/transport/v2/packetio"
 	"github.com/pion/transport/v2/vnet"
@@ -75,6 +76,7 @@ type SettingEngine struct {
 	}
 	sctp struct {
 		maxReceiveBufferSize uint32
+		enableZeroChecksum   bool
 	}
 	sdpMediaLevelFingerprints                 bool
 	answeringDTLSRole                         DTLSRole
@@ -88,6 +90,7 @@ type SettingEngine struct {
 	iceUDPMux                                 ice.UDPMux
 	iceProxyDialer                            proxy.Dialer
 	iceDisableActiveTCP                       bool
+	iceBindingRequestHandler                  func(m *stun.Message, local, remote ice.Candidate, pair *ice.CandidatePair) bool
 	disableMediaEngineCopy                    bool
 	srtpProtectionProfiles                    []dtls.SRTPProtectionProfile
 	receiveMTU                                uint
@@ -434,3 +437,19 @@ func (e *SettingEngine) SetDTLSKeyLogWriter(writer io.Writer) {
 func (e *SettingEngine) SetSCTPMaxReceiveBufferSize(maxReceiveBufferSize uint32) {
 	e.sctp.maxReceiveBufferSize = maxReceiveBufferSize
 }
+
+// SetSCTPZeroChecksum enables the zero checksum feature in SCTP.
+// This removes the need to checksum every incoming/outgoing packet and will reduce
+// latency and CPU usage. This feature is not backwards compatible so is disabled by default
+func (e *SettingEngine) EnableSCTPZeroChecksum(isEnabled bool) {
+	e.sctp.enableZeroChecksum = isEnabled
+}
+
+// SetICEBindingRequestHandler sets a callback that is fired on a STUN BindingRequest
+// This allows users to do things like
+// - Log incoming Binding Requests for debugging
+// - Implement draft-thatcher-ice-renomination
+// - Implement custom CandidatePair switching logic
+func (e *SettingEngine) SetICEBindingRequestHandler(bindingRequestHandler func(m *stun.Message, local, remote ice.Candidate, pair *ice.CandidatePair) bool) {
+	e.iceBindingRequestHandler = bindingRequestHandler
+}
diff --git a/vendor/github.com/pion/webrtc/v3/track_local_static.go b/vendor/github.com/pion/webrtc/v3/track_local_static.go
index 17ce0587..1c06feba 100644
--- a/vendor/github.com/pion/webrtc/v3/track_local_static.go
+++ b/vendor/github.com/pion/webrtc/v3/track_local_static.go
@@ -304,3 +304,28 @@ func (s *TrackLocalStaticSample) WriteSample(sample media.Sample) error {
 
 	return util.FlattenErrs(writeErrs)
 }
+
+// GeneratePadding writes padding-only samples to the TrackLocalStaticSample
+// If one PeerConnection fails the packets will still be sent to
+// all PeerConnections. The error message will contain the ID of the failed
+// PeerConnections so you can remove them
+func (s *TrackLocalStaticSample) GeneratePadding(samples uint32) error {
+	s.rtpTrack.mu.RLock()
+	p := s.packetizer
+	s.rtpTrack.mu.RUnlock()
+
+	if p == nil {
+		return nil
+	}
+
+	packets := p.GeneratePadding(samples)
+
+	writeErrs := []error{}
+	for _, p := range packets {
+		if err := s.rtpTrack.WriteRTP(p); err != nil {
+			writeErrs = append(writeErrs, err)
+		}
+	}
+
+	return util.FlattenErrs(writeErrs)
+}
diff --git a/vendor/github.com/pion/webrtc/v3/track_remote.go b/vendor/github.com/pion/webrtc/v3/track_remote.go
index 150b91bc..7e448dd9 100644
--- a/vendor/github.com/pion/webrtc/v3/track_remote.go
+++ b/vendor/github.com/pion/webrtc/v3/track_remote.go
@@ -24,6 +24,7 @@ type TrackRemote struct {
 	payloadType PayloadType
 	kind        RTPCodecType
 	ssrc        SSRC
+	rtxSsrc     SSRC
 	codec       RTPCodecParameters
 	params      RTPParameters
 	rid         string
@@ -33,10 +34,11 @@ type TrackRemote struct {
 	peekedAttributes interceptor.Attributes
 }
 
-func newTrackRemote(kind RTPCodecType, ssrc SSRC, rid string, receiver *RTPReceiver) *TrackRemote {
+func newTrackRemote(kind RTPCodecType, ssrc, rtxSsrc SSRC, rid string, receiver *RTPReceiver) *TrackRemote {
 	return &TrackRemote{
 		kind:     kind,
 		ssrc:     ssrc,
+		rtxSsrc:  rtxSsrc,
 		rid:      rid,
 		receiver: receiver,
 	}
@@ -125,13 +127,23 @@ func (t *TrackRemote) Read(b []byte) (n int, attributes interceptor.Attributes,
 		}
 	}
 
-	n, attributes, err = r.readRTP(b, t)
-	if err != nil {
-		return
+	// If there's a separate RTX track and an RTX packet is available, return that
+	if rtxPacketReceived := r.readRTX(t); rtxPacketReceived != nil {
+		n = copy(b, rtxPacketReceived.pkt)
+		attributes = rtxPacketReceived.attributes
+		rtxPacketReceived.release()
+		err = nil
+	} else {
+		// If there's no separate RTX track (or there's a separate RTX track but no RTX packet waiting), wait for and return
+		// a packet from the main track
+		n, attributes, err = r.readRTP(b, t)
+		if err != nil {
+			return
+		}
+		err = t.checkAndUpdateTrack(b)
 	}
 
-	err = t.checkAndUpdateTrack(b)
-	return
+	return n, attributes, err
 }
 
 // checkAndUpdateTrack checks payloadType for every incoming packet
@@ -141,7 +153,8 @@ func (t *TrackRemote) checkAndUpdateTrack(b []byte) error {
 		return errRTPTooShort
 	}
 
-	if payloadType := PayloadType(b[1] & rtpPayloadTypeBitmask); payloadType != t.PayloadType() {
+	payloadType := PayloadType(b[1] & rtpPayloadTypeBitmask)
+	if payloadType != t.PayloadType() || len(t.params.Codecs) == 0 {
 		t.mu.Lock()
 		defer t.mu.Unlock()
 
@@ -197,3 +210,23 @@ func (t *TrackRemote) peek(b []byte) (n int, a interceptor.Attributes, err error
 func (t *TrackRemote) SetReadDeadline(deadline time.Time) error {
 	return t.receiver.setRTPReadDeadline(deadline, t)
 }
+
+// RtxSSRC returns the RTX SSRC for a track, or 0 if track does not have a separate RTX stream
+func (t *TrackRemote) RtxSSRC() SSRC {
+	t.mu.RLock()
+	defer t.mu.RUnlock()
+	return t.rtxSsrc
+}
+
+// HasRTX returns true if the track has a separate RTX stream
+func (t *TrackRemote) HasRTX() bool {
+	t.mu.RLock()
+	defer t.mu.RUnlock()
+	return t.rtxSsrc != 0
+}
+
+func (t *TrackRemote) setRtxSSRC(ssrc SSRC) {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	t.rtxSsrc = ssrc
+}
diff --git a/vendor/github.com/refraction-networking/utls/README.md b/vendor/github.com/refraction-networking/utls/README.md
index 9e37340f..0309ef90 100644
--- a/vendor/github.com/refraction-networking/utls/README.md
+++ b/vendor/github.com/refraction-networking/utls/README.md
@@ -1,16 +1,20 @@
 # ![uTLS](logo_small.png) uTLS
-[![Build Status](https://github.com/refraction-networking/utls/actions/workflows/go.yml/badge.svg?branch=master)](https://github.com/refraction-networking/utls/actions)
+[![Build Status](https://github.com/refraction-networking/utls/actions/workflows/go.yml/badge.svg?branch=master)](https://github.com/refraction-networking/utls/actions/workflows/go.yml) 
 [![godoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/github.com/refraction-networking/utls#UConn)
 ---
 uTLS is a fork of "crypto/tls", which provides ClientHello fingerprinting resistance, low-level access to handshake, fake session tickets and some other features. Handshake is still performed by "crypto/tls", this library merely changes ClientHello part of it and provides low-level access.  
-Golang 1.19+ is required.  
 
-If you have any questions, bug reports or contributions, you are welcome to publish those on GitHub. If you want to do so in private, you can contact one of developers personally via sergey.frolov@colorado.edu.
+**Minimum Go Version**: Go 1.21 
+
+If you have any questions, bug reports or contributions, you are welcome to publish those on GitHub. If you want to do so in private, ~~you can contact one of developers personally via sergey.frolov@colorado.edu~~.
+
+You can contact one of developers personally via gaukas.wang@colorado.edu.
 
 Documentation below may not keep up with all the changes and new features at all times,
 so you are encouraged to use [godoc](https://godoc.org/github.com/refraction-networking/utls#UConn).
 
-*Note: Information provided below in this README.md could be obsolete.*
+*Note: Information provided below in this README.md could be obsolete. We welcome 
+any contributions to refresh the documentations in addition to code contributions.*
 
 # Features
 ## Low-level access to handshake
@@ -82,11 +86,11 @@ This is not a problem, if you fully control the server and turn unsupported thin
 #### Parrots FAQ
 > Does it really look like, say, Google Chrome with all the [GREASE](https://tools.ietf.org/html/draft-davidben-tls-grease-01) and stuff?
 
-It LGTM, but please open up Wireshark and check. If you see something — [say something](issues).
+It LGTM, but please open up Wireshark and check. If you see something — [say something](https://github.com/refraction-networking/utls/issues).
 
 > Aren't there side channels? Everybody knows that the ~~bird is a word~~[parrot is dead](https://people.cs.umass.edu/~amir/papers/parrot.pdf)
 
-There sure are. If you found one that approaches practicality at line speed — [please tell us](issues).
+There sure are. If you found one that approaches practicality at line speed — [please tell us](https://github.com/refraction-networking/utls/issues).
 
 However, there is a difference between this sort of parroting and techniques like SkypeMorth.
 Namely, TLS is highly standardized protocol, therefore simply not that many subtle things in TLS protocol
diff --git a/vendor/github.com/refraction-networking/utls/SECURITY.md b/vendor/github.com/refraction-networking/utls/SECURITY.md
new file mode 100644
index 00000000..14a54815
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/SECURITY.md
@@ -0,0 +1,11 @@
+# Security Policy
+
+## Supported Versions
+
+We will only maintain one branch which is the master branch. Unless otherwise requested, no security patches will be applied to older Major/Minor versions. 
+
+## Reporting a Vulnerability
+
+For a vulnerability of low to no severity, which causing no threats to security, you may report it openly to us by [opening an issue](https://github.com/refraction-networking/utls/issues/new)
+
+If the vulnerability you are reporting inflicts some security impact, please [do so privately](https://github.com/refraction-networking/utls/security/advisories/new).
diff --git a/vendor/github.com/refraction-networking/utls/alert.go b/vendor/github.com/refraction-networking/utls/alert.go
index 4790b737..aba46055 100644
--- a/vendor/github.com/refraction-networking/utls/alert.go
+++ b/vendor/github.com/refraction-networking/utls/alert.go
@@ -6,6 +6,16 @@ package tls
 
 import "strconv"
 
+// An AlertError is a TLS alert.
+//
+// When using a QUIC transport, QUICConn methods will return an error
+// which wraps AlertError rather than sending a TLS alert.
+type AlertError uint8
+
+func (e AlertError) Error() string {
+	return alert(e).String()
+}
+
 type alert uint8
 
 const (
@@ -48,6 +58,7 @@ const (
 	alertUnknownPSKIdentity           alert = 115
 	alertCertificateRequired          alert = 116
 	alertNoApplicationProtocol        alert = 120
+	alertECHRequired                  alert = 121
 )
 
 var alertText = map[alert]string{
@@ -84,6 +95,7 @@ var alertText = map[alert]string{
 	alertUnknownPSKIdentity:           "unknown PSK identity",
 	alertCertificateRequired:          "certificate required",
 	alertNoApplicationProtocol:        "no application protocol",
+	alertECHRequired:                  "ECH required",
 }
 
 func (e alert) String() string {
diff --git a/vendor/github.com/refraction-networking/utls/auth.go b/vendor/github.com/refraction-networking/utls/auth.go
index 7c5675c6..77266306 100644
--- a/vendor/github.com/refraction-networking/utls/auth.go
+++ b/vendor/github.com/refraction-networking/utls/auth.go
@@ -15,6 +15,9 @@ import (
 	"fmt"
 	"hash"
 	"io"
+
+	circlPki "github.com/cloudflare/circl/pki"
+	circlSign "github.com/cloudflare/circl/sign"
 )
 
 // verifyHandshakeSignature verifies a signature against pre-hashed
@@ -55,7 +58,20 @@ func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc c
 			return err
 		}
 	default:
-		return errors.New("internal error: unknown signature type")
+		// [UTLS SECTION BEGINS]
+		// Ported from cloudflare/go
+		scheme := circlSchemeBySigType(sigType)
+		if scheme == nil {
+			return errors.New("internal error: unknown signature type")
+		}
+		pubKey, ok := pubkey.(circlSign.PublicKey)
+		if !ok {
+			return fmt.Errorf("expected a %s public key, got %T", scheme.Name(), pubkey)
+		}
+		if !scheme.Verify(pubKey, signed, sig, nil) {
+			return fmt.Errorf("%s verification failure", scheme.Name())
+		}
+		// [UTLS SECTION ENDS]
 	}
 	return nil
 }
@@ -106,7 +122,18 @@ func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType
 	case Ed25519:
 		sigType = signatureEd25519
 	default:
-		return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
+		// [UTLS SECTION BEGINS]
+		// Ported from cloudflare/go
+		scheme := circlPki.SchemeByTLSID(uint(signatureAlgorithm))
+		if scheme == nil {
+			return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
+		}
+		sigType = sigTypeByCirclScheme(scheme)
+		if sigType == 0 {
+			return 0, 0, fmt.Errorf("circl scheme %s not supported",
+				scheme.Name())
+		}
+		// [UTLS SECTION ENDS]
 	}
 	switch signatureAlgorithm {
 	case PKCS1WithSHA1, ECDSAWithSHA1:
@@ -120,7 +147,14 @@ func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType
 	case Ed25519:
 		hash = directSigning
 	default:
-		return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
+		// [UTLS SECTION BEGINS]
+		// Ported from cloudflare/go
+		scheme := circlPki.SchemeByTLSID(uint(signatureAlgorithm))
+		if scheme == nil {
+			return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
+		}
+		hash = directSigning
+		// [UTLS SECTION ENDS]
 	}
 	return sigType, hash, nil
 }
@@ -140,6 +174,11 @@ func legacyTypeAndHashFromPublicKey(pub crypto.PublicKey) (sigType uint8, hash c
 		// 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")
+	// [UTLS SECTION BEGINS]
+	// Ported from cloudflare/go
+	case circlSign.PublicKey:
+		return 0, 0, fmt.Errorf("tls: circl public keys are not supported before TLS 1.2")
+	// [UTLS SECTION ENDS]
 	default:
 		return 0, 0, fmt.Errorf("tls: unsupported public key: %T", pub)
 	}
@@ -210,6 +249,16 @@ func signatureSchemesForCertificate(version uint16, cert *Certificate) []Signatu
 		}
 	case ed25519.PublicKey:
 		sigAlgs = []SignatureScheme{Ed25519}
+	// [UTLS SECTION BEGINS]
+	// Ported from cloudflare/go
+	case circlSign.PublicKey:
+		scheme := pub.Scheme()
+		tlsScheme, ok := scheme.(circlPki.TLSScheme)
+		if !ok {
+			return nil
+		}
+		sigAlgs = []SignatureScheme{SignatureScheme(tlsScheme.TLSIdentifier())}
+	// [UTLS SECTION ENDS]
 	default:
 		return nil
 	}
diff --git a/vendor/github.com/refraction-networking/utls/cache.go b/vendor/github.com/refraction-networking/utls/cache.go
new file mode 100644
index 00000000..a7677611
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/cache.go
@@ -0,0 +1,95 @@
+// 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 tls
+
+import (
+	"crypto/x509"
+	"runtime"
+	"sync"
+	"sync/atomic"
+)
+
+type cacheEntry struct {
+	refs atomic.Int64
+	cert *x509.Certificate
+}
+
+// certCache implements an intern table for reference counted x509.Certificates,
+// implemented in a similar fashion to BoringSSL's CRYPTO_BUFFER_POOL. This
+// allows for a single x509.Certificate to be kept in memory and referenced from
+// multiple Conns. Returned references should not be mutated by callers. Certificates
+// are still safe to use after they are removed from the cache.
+//
+// Certificates are returned wrapped in an activeCert struct that should be held by
+// the caller. When references to the activeCert are freed, the number of references
+// to the certificate in the cache is decremented. Once the number of references
+// reaches zero, the entry is evicted from the cache.
+//
+// The main difference between this implementation and CRYPTO_BUFFER_POOL is that
+// CRYPTO_BUFFER_POOL is a more  generic structure which supports blobs of data,
+// rather than specific structures. Since we only care about x509.Certificates,
+// certCache is implemented as a specific cache, rather than a generic one.
+//
+// See https://boringssl.googlesource.com/boringssl/+/master/include/openssl/pool.h
+// and https://boringssl.googlesource.com/boringssl/+/master/crypto/pool/pool.c
+// for the BoringSSL reference.
+type certCache struct {
+	sync.Map
+}
+
+var globalCertCache = new(certCache)
+
+// activeCert is a handle to a certificate held in the cache. Once there are
+// no alive activeCerts for a given certificate, the certificate is removed
+// from the cache by a finalizer.
+type activeCert struct {
+	cert *x509.Certificate
+}
+
+// active increments the number of references to the entry, wraps the
+// certificate in the entry in an activeCert, and sets the finalizer.
+//
+// Note that there is a race between active and the finalizer set on the
+// returned activeCert, triggered if active is called after the ref count is
+// decremented such that refs may be > 0 when evict is called. We consider this
+// safe, since the caller holding an activeCert for an entry that is no longer
+// in the cache is fine, with the only side effect being the memory overhead of
+// there being more than one distinct reference to a certificate alive at once.
+func (cc *certCache) active(e *cacheEntry) *activeCert {
+	e.refs.Add(1)
+	a := &activeCert{e.cert}
+	runtime.SetFinalizer(a, func(_ *activeCert) {
+		if e.refs.Add(-1) == 0 {
+			cc.evict(e)
+		}
+	})
+	return a
+}
+
+// evict removes a cacheEntry from the cache.
+func (cc *certCache) evict(e *cacheEntry) {
+	cc.Delete(string(e.cert.Raw))
+}
+
+// newCert returns a x509.Certificate parsed from der. If there is already a copy
+// of the certificate in the cache, a reference to the existing certificate will
+// be returned. Otherwise, a fresh certificate will be added to the cache, and
+// the reference returned. The returned reference should not be mutated.
+func (cc *certCache) newCert(der []byte) (*activeCert, error) {
+	if entry, ok := cc.Load(string(der)); ok {
+		return cc.active(entry.(*cacheEntry)), nil
+	}
+
+	cert, err := x509.ParseCertificate(der)
+	if err != nil {
+		return nil, err
+	}
+
+	entry := &cacheEntry{cert: cert}
+	if entry, loaded := cc.LoadOrStore(string(der), entry); loaded {
+		return cc.active(entry.(*cacheEntry)), nil
+	}
+	return cc.active(entry), nil
+}
diff --git a/vendor/github.com/refraction-networking/utls/cfkem.go b/vendor/github.com/refraction-networking/utls/cfkem.go
new file mode 100644
index 00000000..8d440e4c
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/cfkem.go
@@ -0,0 +1,101 @@
+// Copyright 2022 Cloudflare, Inc. All rights reserved. Use of this source code
+// is governed by a BSD-style license that can be found in the LICENSE file.
+//
+// Glue to add Circl's (post-quantum) hybrid KEMs.
+//
+// To enable set CurvePreferences with the desired scheme as the first element:
+//
+//   import (
+//      "crypto/tls"
+//
+//          [...]
+//
+//   config.CurvePreferences = []tls.CurveID{
+//      tls.X25519Kyber768Draft00,
+//      tls.X25519,
+//      tls.P256,
+//   }
+
+package tls
+
+import (
+	"fmt"
+	"io"
+
+	"crypto/ecdh"
+
+	"github.com/cloudflare/circl/kem"
+	"github.com/cloudflare/circl/kem/hybrid"
+)
+
+// Either *ecdh.PrivateKey or *kemPrivateKey
+type clientKeySharePrivate interface{}
+
+type kemPrivateKey struct {
+	secretKey kem.PrivateKey
+	curveID   CurveID
+}
+
+var (
+	X25519Kyber512Draft00    = CurveID(0xfe30)
+	X25519Kyber768Draft00    = CurveID(0x6399)
+	X25519Kyber768Draft00Old = CurveID(0xfe31)
+	P256Kyber768Draft00      = CurveID(0xfe32)
+	invalidCurveID           = CurveID(0)
+)
+
+// Extract CurveID from clientKeySharePrivate
+func clientKeySharePrivateCurveID(ks clientKeySharePrivate) CurveID {
+	switch v := ks.(type) {
+	case *kemPrivateKey:
+		return v.curveID
+	case *ecdh.PrivateKey:
+		ret, ok := curveIDForCurve(v.Curve())
+		if !ok {
+			panic("cfkem: internal error: unknown curve")
+		}
+		return ret
+	default:
+		panic("cfkem: internal error: unknown clientKeySharePrivate")
+	}
+}
+
+// Returns scheme by CurveID if supported by Circl
+func curveIdToCirclScheme(id CurveID) kem.Scheme {
+	switch id {
+	case X25519Kyber512Draft00:
+		return hybrid.Kyber512X25519()
+	case X25519Kyber768Draft00, X25519Kyber768Draft00Old:
+		return hybrid.Kyber768X25519()
+	case P256Kyber768Draft00:
+		return hybrid.P256Kyber768Draft00()
+	}
+	return nil
+}
+
+// Generate a new shared secret and encapsulates it for the packed
+// public key in ppk using randomness from rnd.
+func encapsulateForKem(scheme kem.Scheme, rnd io.Reader, ppk []byte) (
+	ct, ss []byte, alert alert, err error) {
+	pk, err := scheme.UnmarshalBinaryPublicKey(ppk)
+	if err != nil {
+		return nil, nil, alertIllegalParameter, fmt.Errorf("unpack pk: %w", err)
+	}
+	seed := make([]byte, scheme.EncapsulationSeedSize())
+	if _, err := io.ReadFull(rnd, seed); err != nil {
+		return nil, nil, alertInternalError, fmt.Errorf("random: %w", err)
+	}
+	ct, ss, err = scheme.EncapsulateDeterministically(pk, seed)
+	return ct, ss, alertIllegalParameter, err
+}
+
+// Generate a new keypair using randomness from rnd.
+func generateKemKeyPair(scheme kem.Scheme, curveID CurveID, rnd io.Reader) (
+	kem.PublicKey, *kemPrivateKey, error) {
+	seed := make([]byte, scheme.SeedSize())
+	if _, err := io.ReadFull(rnd, seed); err != nil {
+		return nil, nil, err
+	}
+	pk, sk := scheme.DeriveKeyPair(seed)
+	return pk, &kemPrivateKey{sk, curveID}, nil
+}
diff --git a/vendor/github.com/refraction-networking/utls/cipher_suites.go b/vendor/github.com/refraction-networking/utls/cipher_suites.go
index 5b6e9fd9..4204ff83 100644
--- a/vendor/github.com/refraction-networking/utls/cipher_suites.go
+++ b/vendor/github.com/refraction-networking/utls/cipher_suites.go
@@ -19,6 +19,7 @@ import (
 	"hash"
 	"runtime"
 
+	"github.com/refraction-networking/utls/internal/boring"
 	"golang.org/x/sys/cpu"
 
 	"golang.org/x/crypto/chacha20poly1305"
@@ -47,18 +48,13 @@ var (
 
 // CipherSuites returns a list of cipher suites currently implemented by this
 // package, excluding those with security issues, which are returned by
-// InsecureCipherSuites.
+// [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},
@@ -80,14 +76,18 @@ func CipherSuites() []*CipherSuite {
 // 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.
+// 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_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, true},
+		{TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, true},
 		{TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
+		{TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, true},
+		{TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384", 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},
@@ -324,23 +324,48 @@ var cipherSuitesPreferenceOrderNoAES = []uint16{
 	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{
+// disabledCipherSuites are not used unless explicitly listed in Config.CipherSuites.
+var disabledCipherSuites = map[uint16]bool{
 	// 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,
+	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: true,
+	TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:   true,
+	TLS_RSA_WITH_AES_128_CBC_SHA256:         true,
 
 	// RC4
-	TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
-	TLS_RSA_WITH_RC4_128_SHA,
+	TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: true,
+	TLS_ECDHE_RSA_WITH_RC4_128_SHA:   true,
+	TLS_RSA_WITH_RC4_128_SHA:         true,
+}
+
+// rsaKexCiphers contains the ciphers which use RSA based key exchange,
+// which we also disable by default unless a GODEBUG is set.
+var rsaKexCiphers = map[uint16]bool{
+	TLS_RSA_WITH_RC4_128_SHA:        true,
+	TLS_RSA_WITH_3DES_EDE_CBC_SHA:   true,
+	TLS_RSA_WITH_AES_128_CBC_SHA:    true,
+	TLS_RSA_WITH_AES_256_CBC_SHA:    true,
+	TLS_RSA_WITH_AES_128_CBC_SHA256: true,
+	TLS_RSA_WITH_AES_128_GCM_SHA256: true,
+	TLS_RSA_WITH_AES_256_GCM_SHA384: true,
+}
+
+var defaultCipherSuites []uint16
+var defaultCipherSuitesWithRSAKex []uint16
+
+func init() {
+	defaultCipherSuites = make([]uint16, 0, len(cipherSuitesPreferenceOrder))
+	defaultCipherSuitesWithRSAKex = make([]uint16, 0, len(cipherSuitesPreferenceOrder))
+	for _, c := range cipherSuitesPreferenceOrder {
+		if disabledCipherSuites[c] {
+			continue
+		}
+		if !rsaKexCiphers[c] {
+			defaultCipherSuites = append(defaultCipherSuites, c)
+		}
+		defaultCipherSuitesWithRSAKex = append(defaultCipherSuitesWithRSAKex, c)
+	}
 }
 
-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.
@@ -379,14 +404,6 @@ var aesgcmCiphers = map[uint16]bool{
 	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 {
@@ -475,7 +492,7 @@ func (f *prefixNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([
 	return f.aead.Open(out, f.nonce[:], ciphertext, additionalData)
 }
 
-// xoredNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce
+// xorNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce
 // before each call.
 type xorNonceAEAD struct {
 	nonceMask [aeadNonceLength]byte
@@ -542,7 +559,13 @@ func aeadAESGCMTLS13(key, nonceMask []byte) aead {
 	if err != nil {
 		panic(err)
 	}
-	aead, err := cipher.NewGCM(aes)
+	var aead cipher.AEAD
+	if boring.Enabled {
+		aead, err = boring.NewGCMTLS13(aes)
+	} else {
+		boring.Unreachable()
+		aead, err = cipher.NewGCM(aes)
+	}
 	if err != nil {
 		panic(err)
 	}
diff --git a/vendor/github.com/refraction-networking/utls/common.go b/vendor/github.com/refraction-networking/utls/common.go
index ec3b8493..c6da2c7a 100644
--- a/vendor/github.com/refraction-networking/utls/common.go
+++ b/vendor/github.com/refraction-networking/utls/common.go
@@ -36,6 +36,26 @@ const (
 	VersionSSL30 = 0x0300
 )
 
+// VersionName returns the name for the provided TLS version number
+// (e.g. "TLS 1.3"), or a fallback representation of the value if the
+// version is not implemented by this package.
+func VersionName(version uint16) string {
+	switch version {
+	case VersionSSL30:
+		return "SSLv3"
+	case VersionTLS10:
+		return "TLS 1.0"
+	case VersionTLS11:
+		return "TLS 1.1"
+	case VersionTLS12:
+		return "TLS 1.2"
+	case VersionTLS13:
+		return "TLS 1.3"
+	default:
+		return fmt.Sprintf("0x%04X", version)
+	}
+}
+
 const (
 	maxPlaintext       = 16384        // maximum plaintext payload length
 	maxCiphertext      = 16384 + 2048 // maximum ciphertext payload length
@@ -91,6 +111,7 @@ const (
 	extensionALPN                    uint16 = 16
 	extensionStatusRequestV2         uint16 = 17
 	extensionSCT                     uint16 = 18
+	extensionExtendedMasterSecret    uint16 = 23
 	extensionDelegatedCredentials    uint16 = 34
 	extensionSessionTicket           uint16 = 35
 	extensionPreSharedKey            uint16 = 41
@@ -101,6 +122,7 @@ const (
 	extensionCertificateAuthorities  uint16 = 47
 	extensionSignatureAlgorithmsCert uint16 = 50
 	extensionKeyShare                uint16 = 51
+	extensionQUICTransportParameters uint16 = 57
 	extensionRenegotiationInfo       uint16 = 0xff01
 )
 
@@ -167,6 +189,7 @@ const (
 	signatureRSAPSS
 	signatureECDSA
 	signatureEd25519
+	signatureEdDilithium3
 )
 
 // directSigning is a standard Hash value that signals that no pre-hashing
@@ -253,6 +276,8 @@ type ConnectionState struct {
 	// 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 and its contents should not be modified.
 	PeerCertificates []*x509.Certificate
 
 	// VerifiedChains is a list of one or more chains where the first element is
@@ -262,6 +287,8 @@ type ConnectionState struct {
 	// 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 and its contents should not be modified.
 	VerifiedChains [][]*x509.Certificate
 
 	// SignedCertificateTimestamps is a list of SCTs provided by the peer
@@ -273,22 +300,29 @@ type ConnectionState struct {
 	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.
+	// Section 3). This value will be nil for TLS 1.3 connections and for
+	// resumed connections that don't support Extended Master Secret (RFC 7627).
 	TLSUnique []byte
 
 	// ekm is a closure exposed via ExportKeyingMaterial.
 	ekm func(label string, context []byte, length int) ([]byte, error)
+
+	// ECHRetryConfigs contains the ECH retry configurations sent by the server in
+	// EncryptedExtensions message. It is only populated if the server sent the
+	// ech extension in EncryptedExtensions message.
+	ECHRetryConfigs []ECHConfig // [uTLS]
 }
 
 // ExportKeyingMaterial returns length bytes of exported key material in a new
 // slice as defined in RFC 5705. If context is nil, it is not used as part of
 // the seed. If the connection was set to allow renegotiation via
-// Config.Renegotiation, this function will return an error.
+// Config.Renegotiation, or if the connections supports neither TLS 1.3 nor
+// Extended Master Secret, this function will return an error.
+//
+// Exporting key material without Extended Master Secret or TLS 1.3 was disabled
+// in Go 1.22 due to security issues (see the Security Considerations sections
+// of RFC 5705 and RFC 7627), but can be re-enabled with the GODEBUG setting
+// tlsunsafeekm=1.
 func (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
 	return cs.ekm(label, context, length)
 }
@@ -332,25 +366,6 @@ func requiresClientCert(c ClientAuthType) bool {
 	}
 }
 
-// ClientSessionState contains the state needed by clients to resume TLS
-// sessions.
-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
@@ -561,6 +576,8 @@ type Config struct {
 	// 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.
+	//
+	// Once a Certificate is returned it should not be modified.
 	GetCertificate func(*ClientHelloInfo) (*Certificate, error)
 
 	// GetClientCertificate, if not nil, is called when a server requests a
@@ -576,6 +593,8 @@ type Config struct {
 	//
 	// GetClientCertificate may be called multiple times for the same
 	// connection if renegotiation occurs or if TLS 1.3 is in use.
+	//
+	// Once a Certificate is returned it should not be modified.
 	GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error)
 
 	// GetConfigForClient, if not nil, is called after a ClientHello is
@@ -600,10 +619,18 @@ type Config struct {
 	// 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.
+	// considering this callback. If normal verification is disabled (on the
+	// client when InsecureSkipVerify is set, or on a server when ClientAuth is
+	// RequestClientCert or RequireAnyClientCert), then this callback will be
+	// considered but the verifiedChains argument will always be nil. When
+	// ClientAuth is NoClientCert, this callback is not called on the server.
+	// rawCerts may be empty on the server if ClientAuth is RequestClientCert or
+	// VerifyClientCertIfGiven.
+	//
+	// This callback is not invoked on resumed connections, as certificates are
+	// not re-verified on resumption.
+	//
+	// verifiedChains and its contents should not be modified.
 	VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
 
 	// VerifyConnection, if not nil, is called after normal certificate
@@ -612,8 +639,9 @@ type Config struct {
 	// 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.
+	// considering this callback. This callback will run for all connections,
+	// including resumptions, regardless of InsecureSkipVerify or ClientAuth
+	// settings.
 	VerifyConnection func(ConnectionState) error
 
 	// RootCAs defines the set of root certificate authorities
@@ -657,12 +685,20 @@ type Config struct {
 	InsecureSkipVerify bool
 
 	// InsecureSkipTimeVerify controls whether a client verifies the server's
-	// certificate chain against time. If InsecureSkipTimeVerify is true, 
-	// crypto/tls accepts the certificate even when it is expired. 
+	// certificate chain against time. If InsecureSkipTimeVerify is true,
+	// crypto/tls accepts the certificate even when it is expired.
 	//
 	// This field is ignored when InsecureSkipVerify is true.
 	InsecureSkipTimeVerify bool // [uTLS]
 
+	// OmitEmptyPsk determines whether utls will automatically conceal
+	// the psk extension when it is empty. When the psk extension is empty, the
+	// browser omits it from the client hello. Utls can mimic this behavior,
+	// but it deviates from the provided client hello specification, rendering
+	// it unsuitable as the default behavior. Users have the option to enable
+	// this behavior at their own discretion.
+	OmitEmptyPsk bool // [uTLS]
+
 	// InsecureServerNameToVerify is used to verify the hostname on the returned
 	// certificates. It is intended to use with spoofed ServerName.
 	// If InsecureServerNameToVerify is "*", crypto/tls will do normal
@@ -671,11 +707,26 @@ type Config struct {
 	// This field is ignored when InsecureSkipVerify is true.
 	InsecureServerNameToVerify string // [uTLS]
 
+	// PreferSkipResumptionOnNilExtension controls the behavior when session resumption is enabled but the corresponding session extensions are nil.
+	//
+	// To successfully use session resumption, ensure that the following requirements are met:
+	//  - SessionTicketsDisabled is set to false
+	//  - ClientSessionCache is non-nil
+	//  - For TLS 1.2, SessionTicketExtension is non-nil
+	//  - For TLS 1.3, PreSharedKeyExtension is non-nil
+	//
+	// There may be cases where users enable session resumption (SessionTicketsDisabled: false && ClientSessionCache: non-nil), but they do not provide SessionTicketExtension or PreSharedKeyExtension in the ClientHelloSpec. This could be intentional or accidental.
+	//
+	// By default, utls throws an exception in such scenarios. Set this to true to skip the resumption and suppress the exception.
+	PreferSkipResumptionOnNilExtension bool // [uTLS]
+
 	// 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.
+	// suites might change over time. In Go 1.22 RSA key exchange based cipher
+	// suites were removed from the default list, but can be re-added with the
+	// GODEBUG setting tlsrsakex=1.
 	CipherSuites []uint16
 
 	// PreferServerCipherSuites is a legacy field and has no effect.
@@ -707,16 +758,42 @@ type Config struct {
 	// session resumption. It is only used by clients.
 	ClientSessionCache ClientSessionCache
 
+	// UnwrapSession is called on the server to turn a ticket/identity
+	// previously produced by [WrapSession] into a usable session.
+	//
+	// UnwrapSession will usually either decrypt a session state in the ticket
+	// (for example with [Config.EncryptTicket]), or use the ticket as a handle
+	// to recover a previously stored state. It must use [ParseSessionState] to
+	// deserialize the session state.
+	//
+	// If UnwrapSession returns an error, the connection is terminated. If it
+	// returns (nil, nil), the session is ignored. crypto/tls may still choose
+	// not to resume the returned session.
+	UnwrapSession func(identity []byte, cs ConnectionState) (*SessionState, error)
+
+	// WrapSession is called on the server to produce a session ticket/identity.
+	//
+	// WrapSession must serialize the session state with [SessionState.Bytes].
+	// It may then encrypt the serialized state (for example with
+	// [Config.DecryptTicket]) and use it as the ticket, or store the state and
+	// return a handle for it.
+	//
+	// If WrapSession returns an error, the connection is terminated.
+	//
+	// Warning: the return value will be exposed on the wire and to clients in
+	// plaintext. The application is in charge of encrypting and authenticating
+	// it (and rotating keys) or returning high-entropy identifiers. Failing to
+	// do so correctly can compromise current, previous, and future connections
+	// depending on the protocol version.
+	WrapSession func(ConnectionState, *SessionState) ([]byte, error)
+
 	// MinVersion contains the minimum TLS version that is acceptable.
 	//
-	// By default, TLS 1.2 is currently used as the minimum when acting as a
-	// client, and TLS 1.0 when acting as a server. TLS 1.0 is the minimum
-	// supported by this package, both as a client and as a server.
+	// By default, TLS 1.2 is currently used as the minimum. TLS 1.0 is the
+	// minimum supported by this package.
 	//
-	// The client-side default can temporarily be reverted to TLS 1.0 by
-	// including the value "x509sha1=1" in the GODEBUG environment variable.
-	// Note that this option will be removed in Go 1.19 (but it will still be
-	// possible to set this field to VersionTLS10 explicitly).
+	// The server-side default can be reverted to TLS 1.0 by including the value
+	// "tls10server=1" in the GODEBUG environment variable.
 	MinVersion uint16
 
 	// MaxVersion contains the maximum TLS version that is acceptable.
@@ -731,6 +808,11 @@ type Config struct {
 	// its key share in TLS 1.3. This may change in the future.
 	CurvePreferences []CurveID
 
+	// PQSignatureSchemesEnabled controls whether additional post-quantum
+	// signature schemes are supported for peer certificates. For available
+	// signature schemes, see tls_cf.go.
+	PQSignatureSchemesEnabled bool // [UTLS] ported from cloudflare/go
+
 	// 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
@@ -751,7 +833,7 @@ type Config struct {
 
 	// mutex protects sessionTicketKeys and autoSessionTicketKeys.
 	mutex sync.RWMutex
-	// sessionTicketKeys contains zero or more ticket keys. If set, it means the
+	// sessionTicketKeys contains zero or more ticket keys. If set, it means
 	// 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
@@ -760,13 +842,20 @@ type Config struct {
 	// autoSessionTicketKeys is like sessionTicketKeys but is owned by the
 	// auto-rotation logic. See Config.ticketKeys.
 	autoSessionTicketKeys []ticketKey
+
+	// ECHConfigs contains the ECH configurations to be used by the ECH
+	// extension if any.
+	// It could either be distributed by the server in EncryptedExtensions
+	// message or out-of-band.
+	//
+	// If ECHConfigs is nil and an ECH extension is present, GREASEd ECH
+	// extension will be sent.
+	//
+	// If GREASE ECH extension is present, this field will be ignored.
+	ECHConfigs []ECHConfig // [uTLS]
 }
 
 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
@@ -778,9 +867,6 @@ const (
 
 // 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.
@@ -792,18 +878,21 @@ type ticketKey struct {
 // 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])
+	// The first 16 bytes of the hash used to be exposed on the wire as a ticket
+	// prefix. They MUST NOT be used as a secret. In the future, it would make
+	// sense to use a proper KDF here, like HKDF with a fixed salt.
+	const legacyTicketKeyNameLen = 16
+	copy(key.aesKey[:], hashed[legacyTicketKeyNameLen:])
+	copy(key.hmacKey[:], hashed[legacyTicketKeyNameLen+len(key.aesKey):])
 	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.
+// ticket, and the lifetime we set for all 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
+// 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 {
@@ -830,19 +919,26 @@ func (c *Config) Clone() *Config {
 		InsecureSkipVerify:          c.InsecureSkipVerify,
 		InsecureSkipTimeVerify:      c.InsecureSkipTimeVerify,
 		InsecureServerNameToVerify:  c.InsecureServerNameToVerify,
+		OmitEmptyPsk:                c.OmitEmptyPsk,
 		CipherSuites:                c.CipherSuites,
 		PreferServerCipherSuites:    c.PreferServerCipherSuites,
 		SessionTicketsDisabled:      c.SessionTicketsDisabled,
 		SessionTicketKey:            c.SessionTicketKey,
 		ClientSessionCache:          c.ClientSessionCache,
+		UnwrapSession:               c.UnwrapSession,
+		WrapSession:                 c.WrapSession,
 		MinVersion:                  c.MinVersion,
 		MaxVersion:                  c.MaxVersion,
 		CurvePreferences:            c.CurvePreferences,
+		PQSignatureSchemesEnabled:   c.PQSignatureSchemesEnabled, // [UTLS]
 		DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
 		Renegotiation:               c.Renegotiation,
 		KeyLogWriter:                c.KeyLogWriter,
 		sessionTicketKeys:           c.sessionTicketKeys,
 		autoSessionTicketKeys:       c.autoSessionTicketKeys,
+
+		PreferSkipResumptionOnNilExtension: c.PreferSkipResumptionOnNilExtension, // [UTLS]
+		ECHConfigs:                         c.ECHConfigs,                         // [uTLS]
 	}
 }
 
@@ -988,6 +1084,8 @@ func (c *Config) time() time.Time {
 	return t()
 }
 
+// var tlsrsakex = godebug.New("tlsrsakex") // [UTLS] unsupported
+
 func (c *Config) cipherSuites() []uint16 {
 	if needFIPS() {
 		return fipsCipherSuites(c)
@@ -995,6 +1093,13 @@ func (c *Config) cipherSuites() []uint16 {
 	if c.CipherSuites != nil {
 		return c.CipherSuites
 	}
+
+	// [uTLS SECTION BEGIN]
+	// Disable unsupported godebug package
+	// if tlsrsakex.Value() == "1" {
+	// 	return defaultCipherSuitesWithRSAKex
+	// }
+	// [uTLS SECTION END]
 	return defaultCipherSuites
 }
 
@@ -1010,15 +1115,24 @@ var supportedVersions = []uint16{
 const roleClient = true
 const roleServer = false
 
+// var tls10server = godebug.New("tls10server") // [UTLS] unsupported
+
 func (c *Config) supportedVersions(isClient bool) []uint16 {
 	versions := make([]uint16, 0, len(supportedVersions))
 	for _, v := range supportedVersions {
 		if needFIPS() && (v < fipsMinVersion(c) || v > fipsMaxVersion(c)) {
 			continue
 		}
-		if (c == nil || c.MinVersion == 0) &&
-			isClient && v < VersionTLS12 {
-			continue
+		if (c == nil || c.MinVersion == 0) && v < VersionTLS12 {
+			// [uTLS SECTION BEGIN]
+			// Disable unsupported godebug package
+			// if isClient || tls10server.Value() != "1" {
+			// 	continue
+			// }
+			if isClient {
+				continue
+			}
+			// [uTLS SECTION END]
 		}
 		if c != nil && c.MinVersion != 0 && v < c.MinVersion {
 			continue
@@ -1139,9 +1253,9 @@ func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, err
 // 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
+// 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
@@ -1367,7 +1481,7 @@ func (c *Config) writeKeyLog(label string, clientRandom, secret []byte) error {
 		return nil
 	}
 
-	logLine := []byte(fmt.Sprintf("%s %x %x\n", label, clientRandom, secret))
+	logLine := fmt.Appendf(nil, "%s %x %x\n", label, clientRandom, secret)
 
 	writerMutex.Lock()
 	_, err := c.KeyLogWriter.Write(logLine)
@@ -1432,7 +1546,7 @@ type lruSessionCacheEntry struct {
 	state      *ClientSessionState
 }
 
-// NewLRUClientSessionCache returns a ClientSessionCache with the given
+// 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 {
@@ -1481,7 +1595,7 @@ func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) {
 	c.m[sessionKey] = elem
 }
 
-// Get returns the ClientSessionState value associated with a given key. It
+// 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()
@@ -1512,3 +1626,18 @@ func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlg
 	}
 	return false
 }
+
+// CertificateVerificationError is returned when certificate verification fails during the handshake.
+type CertificateVerificationError struct {
+	// UnverifiedCertificates and its contents should not be modified.
+	UnverifiedCertificates []*x509.Certificate
+	Err                    error
+}
+
+func (e *CertificateVerificationError) Error() string {
+	return fmt.Sprintf("tls: failed to verify certificate: %s", e.Err)
+}
+
+func (e *CertificateVerificationError) Unwrap() error {
+	return e.Err
+}
diff --git a/vendor/github.com/refraction-networking/utls/conn.go b/vendor/github.com/refraction-networking/utls/conn.go
index 7f6f1f89..36222bdd 100644
--- a/vendor/github.com/refraction-networking/utls/conn.go
+++ b/vendor/github.com/refraction-networking/utls/conn.go
@@ -29,12 +29,12 @@ type Conn struct {
 	conn        net.Conn
 	isClient    bool
 	handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake
+	quic        *quicState                  // nil for non-QUIC connections
 
-	// handshakeStatus is 1 if the connection is currently transferring
+	// isHandshakeComplete is true 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
+	// isHandshakeComplete is true implies handshakeErr == nil.
+	isHandshakeComplete atomic.Bool
 	// constant after handshake; protected by handshakeMutex
 	handshakeMutex sync.Mutex
 	handshakeErr   error   // error resulting from handshake
@@ -45,11 +45,15 @@ type Conn struct {
 	// connection so far. If renegotiation is disabled then this is either
 	// zero or one.
 	handshakes       int
+	extMasterSecret  bool
 	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
+	// activeCertHandles contains the cache handles to certificates in
+	// peerCertificates that are used to track active references.
+	activeCertHandles []*activeCert
 	// verifiedChains contains the certificate chains that we built, as
 	// opposed to the ones presented by the server.
 	verifiedChains [][]*x509.Certificate
@@ -62,7 +66,7 @@ type Conn struct {
 	// ekm is a closure for exporting keying material.
 	ekm func(label string, context []byte, length int) ([]byte, error)
 	// resumptionSecret is the resumption_master_secret for handling
-	// NewSessionTicket messages. nil if config.SessionTicketsDisabled.
+	// or sending NewSessionTicket messages.
 	resumptionSecret []byte
 
 	// ticketKeys is the set of active session ticket keys for this
@@ -92,9 +96,7 @@ type Conn struct {
 	// clientProtocol is the negotiated ALPN protocol.
 	clientProtocol string
 
-	// [UTLS SECTION START]
-	utls utlsConnExtraFields // used for extensive things such as ALPS
-	// [UTLS SECTION END]
+	utls utlsConnExtraFields // [UTLS] used for extensive things such as ALPS, PSK, etc
 
 	// input/output
 	in, out   halfConn
@@ -114,10 +116,9 @@ type Conn struct {
 	// 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
+	// activeCall indicates whether Close has been call in the low bit.
+	// the rest of the bits are the number of goroutines in Conn.Write.
+	activeCall atomic.Int32
 
 	tmp [16]byte
 }
@@ -137,21 +138,21 @@ func (c *Conn) RemoteAddr() net.Addr {
 }
 
 // SetDeadline sets the read and write deadlines associated with the connection.
-// A zero value for t means Read and Write will not time out.
+// A zero value for t means [Conn.Read] and [Conn.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.
+// A zero value for t means [Conn.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.
+// A zero value for t means [Conn.Write] will not time out.
+// After a [Conn.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)
 }
@@ -179,7 +180,8 @@ type halfConn struct {
 	nextCipher any       // next encryption state
 	nextMac    hash.Hash // next MAC algorithm
 
-	trafficSecret []byte // current TLS 1.3 traffic secret
+	level         QUICEncryptionLevel // current QUIC encryption level
+	trafficSecret []byte              // current TLS 1.3 traffic secret
 }
 
 type permanentError struct {
@@ -224,8 +226,9 @@ func (hc *halfConn) changeCipherSpec() error {
 	return nil
 }
 
-func (hc *halfConn) setTrafficSecret(suite *cipherSuiteTLS13, secret []byte) {
+func (hc *halfConn) setTrafficSecret(suite *cipherSuiteTLS13, level QUICEncryptionLevel, secret []byte) {
 	hc.trafficSecret = secret
+	hc.level = level
 	key, iv := suite.trafficKey(secret)
 	hc.cipher = suite.aead(key, iv)
 	for i := range hc.seq {
@@ -608,7 +611,7 @@ func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error {
 	if c.in.err != nil {
 		return c.in.err
 	}
-	handshakeComplete := c.handshakeComplete()
+	handshakeComplete := c.isHandshakeComplete.Load()
 
 	// This function modifies c.rawInput, which owns the c.input memory.
 	if c.input.Len() != 0 {
@@ -616,6 +619,10 @@ func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error {
 	}
 	c.input.Reset(nil)
 
+	if c.quic != nil {
+		return c.in.setErrorLocked(errors.New("tls: internal error: attempted to read record with QUIC transport"))
+	}
+
 	// Read header, payload.
 	if err := c.readFromUntil(c.conn, recordHeaderLen); err != nil {
 		// RFC 8446, Section 6.1 suggests that EOF without an alertCloseNotify
@@ -642,10 +649,16 @@ func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error {
 	}
 
 	vers := uint16(hdr[1])<<8 | uint16(hdr[2])
+	expectedVers := c.vers
+	if expectedVers == VersionTLS13 {
+		// All TLS 1.3 records are expected to have 0x0303 (1.2) after
+		// the initial hello (RFC 8446 Section 5.1).
+		expectedVers = VersionTLS12
+	}
 	n := int(hdr[3])<<8 | int(hdr[4])
-	if c.haveVers && c.vers != VersionTLS13 && vers != c.vers {
+	if c.haveVers && vers != expectedVers {
 		c.sendAlert(alertProtocolVersion)
-		msg := fmt.Sprintf("received record with version %x when expecting version %x", vers, c.vers)
+		msg := fmt.Sprintf("received record with version %x when expecting version %x", vers, expectedVers)
 		return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg))
 	}
 	if !c.haveVers {
@@ -699,6 +712,9 @@ func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error {
 		return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
 
 	case recordTypeAlert:
+		if c.quic != nil {
+			return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+		}
 		if len(data) != 2 {
 			return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
 		}
@@ -814,8 +830,12 @@ func (c *Conn) readFromUntil(r io.Reader, n int) error {
 	return err
 }
 
-// sendAlert sends a TLS alert message.
+// sendAlertLocked sends a TLS alert message.
 func (c *Conn) sendAlertLocked(err alert) error {
+	if c.quic != nil {
+		return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
+	}
+
 	switch err {
 	case alertNoRenegotiation, alertCloseNotify:
 		c.tmp[0] = alertLevelWarning
@@ -950,6 +970,19 @@ var outBufPool = sync.Pool{
 // 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) {
+	if c.quic != nil {
+		if typ != recordTypeHandshake {
+			return 0, errors.New("tls: internal error: sending non-handshake message to QUIC transport")
+		}
+		c.quicWriteCryptoData(c.out.level, data)
+		if !c.buffering {
+			if _, err := c.flush(); err != nil {
+				return 0, err
+			}
+		}
+		return len(data), nil
+	}
+
 	outBufPtr := outBufPool.Get().(*[]byte)
 	outBuf := *outBufPtr
 	defer func() {
@@ -1034,28 +1067,40 @@ func (c *Conn) writeChangeCipherRecord() error {
 	return err
 }
 
+// readHandshakeBytes reads handshake data until c.hand contains at least n bytes.
+func (c *Conn) readHandshakeBytes(n int) error {
+	if c.quic != nil {
+		return c.quicReadHandshakeBytes(n)
+	}
+	for c.hand.Len() < n {
+		if err := c.readRecord(); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
 // readHandshake reads the next handshake message from
 // the record layer. If transcript is non-nil, the message
 // is written to the passed transcriptHash.
 func (c *Conn) readHandshake(transcript transcriptHash) (any, error) {
-	for c.hand.Len() < 4 {
-		if err := c.readRecord(); err != nil {
-			return nil, err
-		}
+	if err := c.readHandshakeBytes(4); 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
-		}
+	if err := c.readHandshakeBytes(4 + n); err != nil {
+		return nil, err
 	}
 	data = c.hand.Next(4 + n)
+	return c.unmarshalHandshakeMessage(data, transcript)
+}
+
+func (c *Conn) unmarshalHandshakeMessage(data []byte, transcript transcriptHash) (handshakeMessage, error) {
 	var m handshakeMessage
 	switch data[0] {
 	case typeHelloRequest:
@@ -1139,22 +1184,22 @@ var (
 
 // 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.
+// As Write calls [Conn.Handshake], in order to prevent indefinite blocking a deadline
+// must be set for both [Conn.Read] and Write before Write is called when the handshake
+// has not yet completed. See [Conn.SetDeadline], [Conn.SetReadDeadline], and
+// [Conn.SetWriteDeadline].
 func (c *Conn) Write(b []byte) (int, error) {
 	// interlock with Close below
 	for {
-		x := atomic.LoadInt32(&c.activeCall)
+		x := c.activeCall.Load()
 		if x&1 != 0 {
 			return 0, net.ErrClosed
 		}
-		if atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) {
+		if c.activeCall.CompareAndSwap(x, x+2) {
 			break
 		}
 	}
-	defer atomic.AddInt32(&c.activeCall, -2)
+	defer c.activeCall.Add(-2)
 
 	if err := c.Handshake(); err != nil {
 		return 0, err
@@ -1167,7 +1212,7 @@ func (c *Conn) Write(b []byte) (int, error) {
 		return 0, err
 	}
 
-	if !c.handshakeComplete() {
+	if !c.isHandshakeComplete.Load() {
 		return 0, alertInternalError
 	}
 
@@ -1237,7 +1282,7 @@ func (c *Conn) handleRenegotiation() error {
 	c.handshakeMutex.Lock()
 	defer c.handshakeMutex.Unlock()
 
-	atomic.StoreUint32(&c.handshakeStatus, 0)
+	c.isHandshakeComplete.Store(false)
 	if c.handshakeErr = c.clientHandshake(context.Background()); c.handshakeErr == nil {
 		c.handshakes++
 	}
@@ -1255,7 +1300,6 @@ func (c *Conn) handlePostHandshakeMessage() error {
 	if err != nil {
 		return err
 	}
-
 	c.retryCount++
 	if c.retryCount > maxUselessRecords {
 		c.sendAlert(alertUnexpectedMessage)
@@ -1267,20 +1311,28 @@ func (c *Conn) handlePostHandshakeMessage() error {
 		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)
 	}
+	// The QUIC layer is supposed to treat an unexpected post-handshake CertificateRequest
+	// as a QUIC-level PROTOCOL_VIOLATION error (RFC 9001, Section 4.4). Returning an
+	// unexpected_message alert here doesn't provide it with enough information to distinguish
+	// this condition from other unexpected messages. This is probably fine.
+	c.sendAlert(alertUnexpectedMessage)
+	return fmt.Errorf("tls: received unexpected handshake message of type %T", msg)
 }
 
 func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
+	if c.quic != nil {
+		c.sendAlert(alertUnexpectedMessage)
+		return c.in.setErrorLocked(errors.New("tls: received unexpected key update message"))
+	}
+
 	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)
+	c.in.setTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret)
 
 	if keyUpdate.updateRequested {
 		c.out.Lock()
@@ -1299,7 +1351,7 @@ func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
 		}
 
 		newSecret := cipherSuite.nextTrafficSecret(c.out.trafficSecret)
-		c.out.setTrafficSecret(cipherSuite, newSecret)
+		c.out.setTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret)
 	}
 
 	return nil
@@ -1307,10 +1359,10 @@ func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
 
 // 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.
+// As Read calls [Conn.Handshake], in order to prevent indefinite blocking a deadline
+// must be set for both Read and [Conn.Write] before Read is called when the handshake
+// has not yet completed. See [Conn.SetDeadline], [Conn.SetReadDeadline], and
+// [Conn.SetWriteDeadline].
 func (c *Conn) Read(b []byte) (int, error) {
 	if err := c.Handshake(); err != nil {
 		return 0, err
@@ -1359,11 +1411,11 @@ func (c *Conn) Close() error {
 	// Interlock with Conn.Write above.
 	var x int32
 	for {
-		x = atomic.LoadInt32(&c.activeCall)
+		x = c.activeCall.Load()
 		if x&1 != 0 {
 			return net.ErrClosed
 		}
-		if atomic.CompareAndSwapInt32(&c.activeCall, x, x|1) {
+		if c.activeCall.CompareAndSwap(x, x|1) {
 			break
 		}
 	}
@@ -1378,7 +1430,7 @@ func (c *Conn) Close() error {
 	}
 
 	var alertErr error
-	if c.handshakeComplete() {
+	if c.isHandshakeComplete.Load() {
 		if err := c.closeNotify(); err != nil {
 			alertErr = fmt.Errorf("tls: failed to send closeNotify alert (but connection was closed anyway): %w", err)
 		}
@@ -1394,9 +1446,9 @@ var errEarlyCloseWrite = errors.New("tls: CloseWrite called before handshake com
 
 // 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.
+// underlying connection. Most callers should just use [Conn.Close].
 func (c *Conn) CloseWrite() error {
-	if !c.handshakeComplete() {
+	if !c.isHandshakeComplete.Load() {
 		return errEarlyCloseWrite
 	}
 
@@ -1422,10 +1474,15 @@ func (c *Conn) closeNotify() error {
 // 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.
+// first [Conn.Read] or [Conn.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.
+// [Conn.HandshakeContext] or the [Dialer]'s DialContext method instead.
+//
+// In order to avoid denial of service attacks, the maximum RSA key size allowed
+// in certificates sent by either the TLS server or client is limited to 8192
+// bits. This limit can be overridden by setting tlsmaxrsasize in the GODEBUG
+// environment variable (e.g. GODEBUG=tlsmaxrsasize=4096).
 func (c *Conn) Handshake() error {
 	return c.HandshakeContext(context.Background())
 }
@@ -1439,7 +1496,7 @@ func (c *Conn) Handshake() error {
 // connection.
 //
 // Most uses of this package need not call HandshakeContext explicitly: the
-// first Read or Write will call it automatically.
+// first [Conn.Read] or [Conn.Write] will call it automatically.
 func (c *Conn) HandshakeContext(ctx context.Context) error {
 	// Delegate to unexported method for named return
 	// without confusing documented signature.
@@ -1450,7 +1507,7 @@ 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() {
+	if c.isHandshakeComplete.Load() {
 		return nil
 	}
 
@@ -1460,12 +1517,15 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
 	// 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 {
+	if c.quic != nil {
+		c.quic.cancelc = handshakeCtx.Done()
+		c.quic.cancel = cancel
+	} else if ctx.Done() != nil {
+		// 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.
 		done := make(chan struct{})
 		interruptRes := make(chan error, 1)
 		defer func() {
@@ -1493,7 +1553,7 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
 	if err := c.handshakeErr; err != nil {
 		return err
 	}
-	if c.handshakeComplete() {
+	if c.isHandshakeComplete.Load() {
 		return nil
 	}
 
@@ -1509,13 +1569,37 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
 		c.flush()
 	}
 
-	if c.handshakeErr == nil && !c.handshakeComplete() {
+	if c.handshakeErr == nil && !c.isHandshakeComplete.Load() {
 		c.handshakeErr = errors.New("tls: internal error: handshake should have had a result")
 	}
-	if c.handshakeErr != nil && c.handshakeComplete() {
+	if c.handshakeErr != nil && c.isHandshakeComplete.Load() {
 		panic("tls: internal error: handshake returned an error but is marked successful")
 	}
 
+	if c.quic != nil {
+		if c.handshakeErr == nil {
+			c.quicHandshakeComplete()
+			// Provide the 1-RTT read secret now that the handshake is complete.
+			// The QUIC layer MUST NOT decrypt 1-RTT packets prior to completing
+			// the handshake (RFC 9001, Section 5.7).
+			c.quicSetReadSecret(QUICEncryptionLevelApplication, c.cipherSuite, c.in.trafficSecret)
+		} else {
+			var a alert
+			c.out.Lock()
+			if !errors.As(c.out.err, &a) {
+				a = alertInternalError
+			}
+			c.out.Unlock()
+			// Return an error which wraps both the handshake error and
+			// any alert error we may have sent, or alertInternalError
+			// if we didn't send an alert.
+			// Truncate the text of the alert to 0 characters.
+			c.handshakeErr = fmt.Errorf("%w%.0w", c.handshakeErr, AlertError(a))
+		}
+		close(c.quic.blockedc)
+		close(c.quic.signalc)
+	}
+
 	return c.handshakeErr
 }
 
@@ -1526,9 +1610,11 @@ func (c *Conn) ConnectionState() ConnectionState {
 	return c.connectionStateLocked()
 }
 
+// var tlsunsafeekm = godebug.New("tlsunsafeekm") // [uTLS] unsupportted
+
 func (c *Conn) connectionStateLocked() ConnectionState {
 	var state ConnectionState
-	state.HandshakeComplete = c.handshakeComplete()
+	state.HandshakeComplete = c.isHandshakeComplete.Load()
 	state.Version = c.vers
 	state.NegotiatedProtocol = c.clientProtocol
 	state.DidResume = c.didResume
@@ -1539,7 +1625,7 @@ func (c *Conn) connectionStateLocked() ConnectionState {
 	state.VerifiedChains = c.verifiedChains
 	state.SignedCertificateTimestamps = c.scts
 	state.OCSPResponse = c.ocspResponse
-	if !c.didResume && c.vers != VersionTLS13 {
+	if (!c.didResume || c.extMasterSecret) && c.vers != VersionTLS13 {
 		if c.clientFinishedIsFirst {
 			state.TLSUnique = c.clientFinished[:]
 		} else {
@@ -1547,7 +1633,18 @@ func (c *Conn) connectionStateLocked() ConnectionState {
 		}
 	}
 	if c.config.Renegotiation != RenegotiateNever {
-		state.ekm = noExportedKeyingMaterial
+		state.ekm = noEKMBecauseRenegotiation
+	} else if c.vers != VersionTLS13 && !c.extMasterSecret {
+		state.ekm = func(label string, context []byte, length int) ([]byte, error) {
+			// [uTLS SECTION START]
+			// Disabling unsupported godebug package
+			// if tlsunsafeekm.Value() == "1" {
+			// 	tlsunsafeekm.IncNonDefault()
+			// 	return c.ekm(label, context, length)
+			// }
+			// [uTLS SECTION END]
+			return noEKMBecauseNoEMS(label, context, length)
+		}
 	} else {
 		state.ekm = c.ekm
 	}
@@ -1575,7 +1672,7 @@ func (c *Conn) VerifyHostname(host string) error {
 	if !c.isClient {
 		return errors.New("tls: VerifyHostname called on TLS server connection")
 	}
-	if !c.handshakeComplete() {
+	if !c.isHandshakeComplete.Load() {
 		return errors.New("tls: handshake has not yet been performed")
 	}
 	if len(c.verifiedChains) == 0 {
@@ -1583,7 +1680,3 @@ func (c *Conn) VerifyHostname(host string) error {
 	}
 	return c.peerCertificates[0].VerifyHostname(host)
 }
-
-func (c *Conn) handshakeComplete() bool {
-	return atomic.LoadUint32(&c.handshakeStatus) == 1
-}
diff --git a/vendor/github.com/gaukas/godicttls/LICENSE b/vendor/github.com/refraction-networking/utls/dicttls/LICENSE
similarity index 100%
rename from vendor/github.com/gaukas/godicttls/LICENSE
rename to vendor/github.com/refraction-networking/utls/dicttls/LICENSE
diff --git a/vendor/github.com/gaukas/godicttls/README.md b/vendor/github.com/refraction-networking/utls/dicttls/README.md
similarity index 77%
rename from vendor/github.com/gaukas/godicttls/README.md
rename to vendor/github.com/refraction-networking/utls/dicttls/README.md
index 81c37729..7a26134a 100644
--- a/vendor/github.com/gaukas/godicttls/README.md
+++ b/vendor/github.com/refraction-networking/utls/dicttls/README.md
@@ -1,3 +1,9 @@
+# Dict TLS
+
+This is a vendored version of [godicttls](https://github.com/gaukas/godicttls)
+
+Below is a copy of the original README.md
+
 # godicttls
 Dictionary for TLS written in Go providing bidirectional mapping values to their names, plus enum convenience for values.
 
diff --git a/vendor/github.com/gaukas/godicttls/alerts.go b/vendor/github.com/refraction-networking/utls/dicttls/alerts.go
similarity index 99%
rename from vendor/github.com/gaukas/godicttls/alerts.go
rename to vendor/github.com/refraction-networking/utls/dicttls/alerts.go
index ef9691c6..ec1f4e7f 100644
--- a/vendor/github.com/gaukas/godicttls/alerts.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/alerts.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-6
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/authorization_data_formats.go b/vendor/github.com/refraction-networking/utls/dicttls/authorization_data_formats.go
similarity index 98%
rename from vendor/github.com/gaukas/godicttls/authorization_data_formats.go
rename to vendor/github.com/refraction-networking/utls/dicttls/authorization_data_formats.go
index d8b668f7..5a1847e4 100644
--- a/vendor/github.com/gaukas/godicttls/authorization_data_formats.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/authorization_data_formats.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#authorization-data
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/cachedinformationtype_values.go b/vendor/github.com/refraction-networking/utls/dicttls/cachedinformationtype_values.go
similarity index 96%
rename from vendor/github.com/gaukas/godicttls/cachedinformationtype_values.go
rename to vendor/github.com/refraction-networking/utls/dicttls/cachedinformationtype_values.go
index 1973d834..8e1469b1 100644
--- a/vendor/github.com/gaukas/godicttls/cachedinformationtype_values.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/cachedinformationtype_values.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#cachedinformationtype
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/certificate_compression_algorithm_ids.go b/vendor/github.com/refraction-networking/utls/dicttls/certificate_compression_algorithm_ids.go
similarity index 96%
rename from vendor/github.com/gaukas/godicttls/certificate_compression_algorithm_ids.go
rename to vendor/github.com/refraction-networking/utls/dicttls/certificate_compression_algorithm_ids.go
index a2c057f1..e5ffca3f 100644
--- a/vendor/github.com/gaukas/godicttls/certificate_compression_algorithm_ids.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/certificate_compression_algorithm_ids.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#tls-certificate-compression-algorithm-ids
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/certificate_status_types.go b/vendor/github.com/refraction-networking/utls/dicttls/certificate_status_types.go
similarity index 95%
rename from vendor/github.com/gaukas/godicttls/certificate_status_types.go
rename to vendor/github.com/refraction-networking/utls/dicttls/certificate_status_types.go
index 37747bf2..67e02852 100644
--- a/vendor/github.com/gaukas/godicttls/certificate_status_types.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/certificate_status_types.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#certificate-status
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/certificte_types.go b/vendor/github.com/refraction-networking/utls/dicttls/certificte_types.go
similarity index 96%
rename from vendor/github.com/gaukas/godicttls/certificte_types.go
rename to vendor/github.com/refraction-networking/utls/dicttls/certificte_types.go
index 46ca3ee4..93a3285a 100644
--- a/vendor/github.com/gaukas/godicttls/certificte_types.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/certificte_types.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#tls-extensiontype-values-3
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/cipher_suites.go b/vendor/github.com/refraction-networking/utls/dicttls/cipher_suites.go
similarity index 99%
rename from vendor/github.com/gaukas/godicttls/cipher_suites.go
rename to vendor/github.com/refraction-networking/utls/dicttls/cipher_suites.go
index 1b292fec..d7875210 100644
--- a/vendor/github.com/gaukas/godicttls/cipher_suites.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/cipher_suites.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/clientcertificatetype_identifiers.go b/vendor/github.com/refraction-networking/utls/dicttls/clientcertificatetype_identifiers.go
similarity index 98%
rename from vendor/github.com/gaukas/godicttls/clientcertificatetype_identifiers.go
rename to vendor/github.com/refraction-networking/utls/dicttls/clientcertificatetype_identifiers.go
index 56354c9e..c022bfdc 100644
--- a/vendor/github.com/gaukas/godicttls/clientcertificatetype_identifiers.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/clientcertificatetype_identifiers.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-2
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/comp_meth_ids.go b/vendor/github.com/refraction-networking/utls/dicttls/comp_meth_ids.go
similarity index 95%
rename from vendor/github.com/gaukas/godicttls/comp_meth_ids.go
rename to vendor/github.com/refraction-networking/utls/dicttls/comp_meth_ids.go
index c1d5908d..a3f951d3 100644
--- a/vendor/github.com/gaukas/godicttls/comp_meth_ids.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/comp_meth_ids.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/comp-meth-ids/comp-meth-ids-2.csv
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/contenttype.go b/vendor/github.com/refraction-networking/utls/dicttls/contenttype.go
similarity index 97%
rename from vendor/github.com/gaukas/godicttls/contenttype.go
rename to vendor/github.com/refraction-networking/utls/dicttls/contenttype.go
index dce2f059..b54c84dd 100644
--- a/vendor/github.com/gaukas/godicttls/contenttype.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/contenttype.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-5
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/ec_curve_types.go b/vendor/github.com/refraction-networking/utls/dicttls/ec_curve_types.go
similarity index 96%
rename from vendor/github.com/gaukas/godicttls/ec_curve_types.go
rename to vendor/github.com/refraction-networking/utls/dicttls/ec_curve_types.go
index 733a86f1..c15db247 100644
--- a/vendor/github.com/gaukas/godicttls/ec_curve_types.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/ec_curve_types.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-10
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/ec_point_formats.go b/vendor/github.com/refraction-networking/utls/dicttls/ec_point_formats.go
similarity index 96%
rename from vendor/github.com/gaukas/godicttls/ec_point_formats.go
rename to vendor/github.com/refraction-networking/utls/dicttls/ec_point_formats.go
index e57f1980..bfe44bba 100644
--- a/vendor/github.com/gaukas/godicttls/ec_point_formats.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/ec_point_formats.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-9
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/exttype_values.go b/vendor/github.com/refraction-networking/utls/dicttls/exttype_values.go
similarity index 95%
rename from vendor/github.com/gaukas/godicttls/exttype_values.go
rename to vendor/github.com/refraction-networking/utls/dicttls/exttype_values.go
index 8422c401..103e8800 100644
--- a/vendor/github.com/gaukas/godicttls/exttype_values.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/exttype_values.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#tls-extensiontype-values-1
 // last updated: March 2023
@@ -38,7 +38,7 @@ const (
 	ExtType_password_salt                          uint16 = 31
 	ExtType_ticket_pinning                         uint16 = 32
 	ExtType_tls_cert_with_extern_psk               uint16 = 33
-	ExtType_delegated_credentials                  uint16 = 34
+	ExtType_delegated_credentials                  uint16 = 34 // IANA name: delegated_credentials, IETF name: delegated_credential
 	ExtType_session_ticket                         uint16 = 35
 	ExtType_TLMSP                                  uint16 = 36
 	ExtType_TLMSP_proxying                         uint16 = 37
@@ -108,7 +108,7 @@ var DictExtTypeValueIndexed = map[uint16]string{
 	31:    "password_salt",
 	32:    "ticket_pinning",
 	33:    "tls_cert_with_extern_psk",
-	34:    "delegated_credentials",
+	34:    "delegated_credentials", // IANA name: delegated_credentials, IETF name: delegated_credential
 	35:    "session_ticket",
 	36:    "TLMSP",
 	37:    "TLMSP_proxying",
@@ -175,7 +175,8 @@ var DictExtTypeNameIndexed = map[string]uint16{
 	"password_salt":                          31,
 	"ticket_pinning":                         32,
 	"tls_cert_with_extern_psk":               33,
-	"delegated_credentials":                  34,
+	"delegated_credentials":                  34, // IANA name: delegated_credentials
+	"delegated_credential":                   34, // IETF name: delegated_credential
 	"session_ticket":                         35,
 	"TLMSP":                                  36,
 	"TLMSP_proxying":                         37,
diff --git a/vendor/github.com/gaukas/godicttls/handshaketype.go b/vendor/github.com/refraction-networking/utls/dicttls/handshaketype.go
similarity index 99%
rename from vendor/github.com/gaukas/godicttls/handshaketype.go
rename to vendor/github.com/refraction-networking/utls/dicttls/handshaketype.go
index cafba3b9..798a1c37 100644
--- a/vendor/github.com/gaukas/godicttls/handshaketype.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/handshaketype.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-7
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/hashalgorithm.go b/vendor/github.com/refraction-networking/utls/dicttls/hashalgorithm.go
similarity index 97%
rename from vendor/github.com/gaukas/godicttls/hashalgorithm.go
rename to vendor/github.com/refraction-networking/utls/dicttls/hashalgorithm.go
index 420bb0ae..24e61586 100644
--- a/vendor/github.com/gaukas/godicttls/hashalgorithm.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/hashalgorithm.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-18
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/heartbeat_message_types.go b/vendor/github.com/refraction-networking/utls/dicttls/heartbeat_message_types.go
similarity index 95%
rename from vendor/github.com/gaukas/godicttls/heartbeat_message_types.go
rename to vendor/github.com/refraction-networking/utls/dicttls/heartbeat_message_types.go
index 46db1a6e..0b076be1 100644
--- a/vendor/github.com/gaukas/godicttls/heartbeat_message_types.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/heartbeat_message_types.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/heartbeat-message-types.csv
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/heartbeat_mode.go b/vendor/github.com/refraction-networking/utls/dicttls/heartbeat_mode.go
similarity index 96%
rename from vendor/github.com/gaukas/godicttls/heartbeat_mode.go
rename to vendor/github.com/refraction-networking/utls/dicttls/heartbeat_mode.go
index 0847cb2b..747ae6e1 100644
--- a/vendor/github.com/gaukas/godicttls/heartbeat_mode.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/heartbeat_mode.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/heartbeat-modes.csv
 // last updated: March 2023
diff --git a/vendor/github.com/refraction-networking/utls/dicttls/hpke_aead_identifiers.go b/vendor/github.com/refraction-networking/utls/dicttls/hpke_aead_identifiers.go
new file mode 100644
index 00000000..c4f82314
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/dicttls/hpke_aead_identifiers.go
@@ -0,0 +1,19 @@
+package dicttls
+
+// source: https://www.iana.org/assignments/hpke/hpke.xhtml
+// last updated: December 2023
+
+const (
+	AEAD_AES_128_GCM       uint16 = 0x0001 // NIST Special Publication 800-38D
+	AEAD_AES_256_GCM       uint16 = 0x0002 // NIST Special Publication 800-38D
+	AEAD_CHACHA20_POLY1305 uint16 = 0x0003 // RFC 8439
+	AEAD_EXPORT_ONLY       uint16 = 0xFFFF // RFC 9180
+)
+
+var DictAEADIdentifierValueIndexed = map[uint16]string{
+	0x0000: "Reserved", // RFC 9180
+	0x0001: "AES-128-GCM",
+	0x0002: "AES-256-GCM",
+	0x0003: "ChaCha20Poly1305",
+	0xFFFF: "Export-only", // RFC 9180
+}
diff --git a/vendor/github.com/gaukas/godicttls/kdf_identifiers.go b/vendor/github.com/refraction-networking/utls/dicttls/hpke_kdf_identifiers.go
similarity index 52%
rename from vendor/github.com/gaukas/godicttls/kdf_identifiers.go
rename to vendor/github.com/refraction-networking/utls/dicttls/hpke_kdf_identifiers.go
index f77a0f83..7471943f 100644
--- a/vendor/github.com/gaukas/godicttls/kdf_identifiers.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/hpke_kdf_identifiers.go
@@ -1,19 +1,24 @@
-package godicttls
+package dicttls
 
-// source: https://www.iana.org/assignments/tls-parameters/tls-kdf-ids.csv
-// last updated: March 2023
+// source: https://www.iana.org/assignments/hpke/hpke.xhtml
+// last updated: December 2023
 
 const (
 	HKDF_SHA256 uint16 = 0x0001
 	HKDF_SHA384 uint16 = 0x0002
+	HKDF_SHA512 uint16 = 0x0003
 )
 
 var DictKDFIdentifierValueIndexed = map[uint16]string{
+	0x0000: "Reserved", // RFC 9180
 	0x0001: "HKDF_SHA256",
 	0x0002: "HKDF_SHA384",
+	0x0003: "HKDF_SHA512",
 }
 
 var DictKDFIdentifierNameIndexed = map[string]uint16{
+	"Reserved":    0x0000, // RFC 9180
 	"HKDF_SHA256": 0x0001,
 	"HKDF_SHA384": 0x0002,
+	"HKDF_SHA512": 0x0003,
 }
diff --git a/vendor/github.com/refraction-networking/utls/dicttls/hpke_kem_identifiers.go b/vendor/github.com/refraction-networking/utls/dicttls/hpke_kem_identifiers.go
new file mode 100644
index 00000000..213e7f8c
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/dicttls/hpke_kem_identifiers.go
@@ -0,0 +1,53 @@
+package dicttls
+
+// source: https://www.iana.org/assignments/hpke/hpke.xhtml
+// last updated: December 2023
+
+const (
+	DHKEM_P256_HKDF_SHA256      uint16 = 0x0010 // RFC 5869
+	DHKEM_P384_HKDF_SHA384      uint16 = 0x0011 // RFC 5869
+	DHKEM_P521_HKDF_SHA512      uint16 = 0x0012 // RFC 5869
+	DHKEM_CP256_HKDF_SHA256     uint16 = 0x0013 // RFC 6090
+	DHKEM_CP384_HKDF_SHA384     uint16 = 0x0014 // RFC 6090
+	DHKEM_CP521_HKDF_SHA512     uint16 = 0x0015 // RFC 6090
+	DHKEM_SECP256K1_HKDF_SHA256 uint16 = 0x0016 // draft-wahby-cfrg-hpke-kem-secp256k1-01
+
+	DHKEM_X25519_HKDF_SHA256 uint16 = 0x0020 // RFC 7748
+	DHKEM_X448_HKDF_SHA512   uint16 = 0x0021 // RFC 7748
+
+	X25519_KYBER768_DRAFT00 uint16 = 0x0030 // draft-westerbaan-cfrg-hpke-xyber768d00-02
+)
+
+var DictKEMIdentifierValueIndexed = map[uint16]string{
+	0x0000: "Reserved", // RFC 9180
+
+	0x0010: "DHKEM(P-256, HKDF-SHA256)",
+	0x0011: "DHKEM(P-384, HKDF-SHA384)",
+	0x0012: "DHKEM(P-521, HKDF-SHA512)",
+	0x0013: "DHKEM(CP-256, HKDF-SHA256)",
+	0x0014: "DHKEM(CP-384, HKDF-SHA384)",
+	0x0015: "DHKEM(CP-521, HKDF-SHA512)",
+	0x0016: "DHKEM(secp256k1, HKDF-SHA256)",
+
+	0x0020: "DHKEM(X25519, HKDF-SHA256)",
+	0x0021: "DHKEM(X448, HKDF-SHA512)",
+
+	0x0030: "X25519Kyber768Draft00",
+}
+
+var DictKEMIdentifierNameIndexed = map[string]uint16{
+	"Reserved": 0x0000, // RFC 9180
+
+	"DHKEM(P-256, HKDF-SHA256)":     0x0010,
+	"DHKEM(P-384, HKDF-SHA384)":     0x0011,
+	"DHKEM(P-521, HKDF-SHA512)":     0x0012,
+	"DHKEM(CP-256, HKDF-SHA256)":    0x0013,
+	"DHKEM(CP-384, HKDF-SHA384)":    0x0014,
+	"DHKEM(CP-521, HKDF-SHA512)":    0x0015,
+	"DHKEM(secp256k1, HKDF-SHA256)": 0x0016,
+
+	"DHKEM(X25519, HKDF-SHA256)": 0x0020,
+	"DHKEM(X448, HKDF-SHA512)":   0x0021,
+
+	"X25519Kyber768Draft00": 0x0030,
+}
diff --git a/vendor/github.com/gaukas/godicttls/psk_key_exchange_mode.go b/vendor/github.com/refraction-networking/utls/dicttls/psk_key_exchange_mode.go
similarity index 95%
rename from vendor/github.com/gaukas/godicttls/psk_key_exchange_mode.go
rename to vendor/github.com/refraction-networking/utls/dicttls/psk_key_exchange_mode.go
index 8df086ab..7f3cc388 100644
--- a/vendor/github.com/gaukas/godicttls/psk_key_exchange_mode.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/psk_key_exchange_mode.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-pskkeyexchangemode.csv
 // last updated: March 2023
diff --git a/vendor/github.com/refraction-networking/utls/dicttls/quic_frame_types.go b/vendor/github.com/refraction-networking/utls/dicttls/quic_frame_types.go
new file mode 100644
index 00000000..a7dd0ac6
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/dicttls/quic_frame_types.go
@@ -0,0 +1,112 @@
+package dicttls
+
+// source: https://www.iana.org/assignments/quic/quic.xhtml#quic-frame-types
+// last updated: July 2023
+
+const (
+	QUICFrameType_PADDING              uint8 = 0x00
+	QUICFrameType_PING                 uint8 = 0x01
+	QUICFrameType_ACK                  uint8 = 0x02
+	QUICFrameType_ACK_ecn              uint8 = 0x03
+	QUICFrameType_RESET_STREAM         uint8 = 0x04
+	QUICFrameType_STOP_SENDING         uint8 = 0x05
+	QUICFrameType_CRYPTO               uint8 = 0x06
+	QUICFrameType_NEW_TOKEN            uint8 = 0x07
+	QUICFrameType_STREAM               uint8 = 0x08
+	QUICFrameType_STREAM_fin           uint8 = 0x09
+	QUICFrameType_STREAM_len           uint8 = 0x0a
+	QUICFrameType_STREAM_len_fin       uint8 = 0x0b
+	QUICFrameType_STREAM_off           uint8 = 0x0c
+	QUICFrameType_STREAM_off_fin       uint8 = 0x0d
+	QUICFrameType_STREAM_off_len       uint8 = 0x0e
+	QUICFrameType_STREAM_off_len_fin   uint8 = 0x0f
+	QUICFrameType_MAX_DATA             uint8 = 0x10
+	QUICFrameType_MAX_STREAM_DATA      uint8 = 0x11
+	QUICFrameType_MAX_STREAMS_bidi     uint8 = 0x12
+	QUICFrameType_MAX_STREAMS_uni      uint8 = 0x13
+	QUICFrameType_DATA_BLOCKED         uint8 = 0x14
+	QUICFrameType_STREAM_DATA_BLOCKED  uint8 = 0x15
+	QUICFrameType_STREAMS_BLOCKED_bidi uint8 = 0x16
+	QUICFrameType_STREAMS_BLOCKED_uni  uint8 = 0x17
+	QUICFrameType_NEW_CONNECTION_ID    uint8 = 0x18
+	QUICFrameType_RETIRE_CONNECTION_ID uint8 = 0x19
+	QUICFrameType_PATH_CHALLENGE       uint8 = 0x1a
+	QUICFrameType_PATH_RESPONSE        uint8 = 0x1b
+	QUICFrameType_CONNECTION_CLOSE     uint8 = 0x1c
+	QUICFrameType_CONNECTION_CLOSE_app uint8 = 0x1d
+	QUICFrameType_HANDSHAKE_DONE       uint8 = 0x1e
+	QUICFrameType_DATAGRAM             uint8 = 0x30 // RFC9221
+	QUICFrameType_DATAGRAM_len         uint8 = 0x31 // RFC9221
+)
+
+var DictQUICFrameTypeValueIndexed = map[uint8]string{
+	0x00: "PADDING",
+	0x01: "PING",
+	0x02: "ACK",
+	0x03: "ACK_ecn",
+	0x04: "RESET_STREAM",
+	0x05: "STOP_SENDING",
+	0x06: "CRYPTO",
+	0x07: "NEW_TOKEN",
+	0x08: "STREAM",
+	0x09: "STREAM_fin",
+	0x0a: "STREAM_len",
+	0x0b: "STREAM_len_fin",
+	0x0c: "STREAM_off",
+	0x0d: "STREAM_off_fin",
+	0x0e: "STREAM_off_len",
+	0x0f: "STREAM_off_len_fin",
+	0x10: "MAX_DATA",
+	0x11: "MAX_STREAM_DATA",
+	0x12: "MAX_STREAMS_bidi",
+	0x13: "MAX_STREAMS_uni",
+	0x14: "DATA_BLOCKED",
+	0x15: "STREAM_DATA_BLOCKED",
+	0x16: "STREAMS_BLOCKED_bidi",
+	0x17: "STREAMS_BLOCKED_uni",
+	0x18: "NEW_CONNECTION_ID",
+	0x19: "RETIRE_CONNECTION_ID",
+	0x1a: "PATH_CHALLENGE",
+	0x1b: "PATH_RESPONSE",
+	0x1c: "CONNECTION_CLOSE",
+	0x1d: "CONNECTION_CLOSE_app",
+	0x1e: "HANDSHAKE_DONE",
+	0x30: "DATAGRAM",
+	0x31: "DATAGRAM_len",
+}
+
+var DictQUICFrameTypeNameIndexed = map[string]uint8{
+	"PADDING":              0x00,
+	"PING":                 0x01,
+	"ACK":                  0x02,
+	"ACK_ecn":              0x03,
+	"RESET_STREAM":         0x04,
+	"STOP_SENDING":         0x05,
+	"CRYPTO":               0x06,
+	"NEW_TOKEN":            0x07,
+	"STREAM":               0x08,
+	"STREAM_fin":           0x09,
+	"STREAM_len":           0x0a,
+	"STREAM_len_fin":       0x0b,
+	"STREAM_off":           0x0c,
+	"STREAM_off_fin":       0x0d,
+	"STREAM_off_len":       0x0e,
+	"STREAM_off_len_fin":   0x0f,
+	"MAX_DATA":             0x10,
+	"MAX_STREAM_DATA":      0x11,
+	"MAX_STREAMS_bidi":     0x12,
+	"MAX_STREAMS_uni":      0x13,
+	"DATA_BLOCKED":         0x14,
+	"STREAM_DATA_BLOCKED":  0x15,
+	"STREAMS_BLOCKED_bidi": 0x16,
+	"STREAMS_BLOCKED_uni":  0x17,
+	"NEW_CONNECTION_ID":    0x18,
+	"RETIRE_CONNECTION_ID": 0x19,
+	"PATH_CHALLENGE":       0x1a,
+	"PATH_RESPONSE":        0x1b,
+	"CONNECTION_CLOSE":     0x1c,
+	"CONNECTION_CLOSE_app": 0x1d,
+	"HANDSHAKE_DONE":       0x1e,
+	"DATAGRAM":             0x30,
+	"DATAGRAM_len":         0x31,
+}
diff --git a/vendor/github.com/refraction-networking/utls/dicttls/quic_transport_error_codes.go b/vendor/github.com/refraction-networking/utls/dicttls/quic_transport_error_codes.go
new file mode 100644
index 00000000..52d2c8bd
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/dicttls/quic_transport_error_codes.go
@@ -0,0 +1,70 @@
+package dicttls
+
+// source: https://www.iana.org/assignments/quic/quic.xhtml#quic-transport-error-codes
+// last updated: July 2023
+
+const (
+	QUICTransportErrorCode_NO_ERROR                  uint16 = 0x0000
+	QUICTransportErrorCode_INTERNAL_ERROR            uint16 = 0x0001
+	QUICTransportErrorCode_CONNECTION_REFUSED        uint16 = 0x0002
+	QUICTransportErrorCode_FLOW_CONTROL_ERROR        uint16 = 0x0003
+	QUICTransportErrorCode_STREAM_LIMIT_ERROR        uint16 = 0x0004
+	QUICTransportErrorCode_STREAM_STATE_ERROR        uint16 = 0x0005
+	QUICTransportErrorCode_FINAL_SIZE_ERROR          uint16 = 0x0006
+	QUICTransportErrorCode_FRAME_ENCODING_ERROR      uint16 = 0x0007
+	QUICTransportErrorCode_TRANSPORT_PARAMETER_ERROR uint16 = 0x0008
+	QUICTransportErrorCode_CONNECTION_ID_LIMIT_ERROR uint16 = 0x0009
+	QUICTransportErrorCode_PROTOCOL_VIOLATION        uint16 = 0x000A
+	QUICTransportErrorCode_INVALID_TOKEN             uint16 = 0x000B
+	QUICTransportErrorCode_APPLICATION_ERROR         uint16 = 0x000C
+	QUICTransportErrorCode_CRYPTO_BUFFER_EXCEEDED    uint16 = 0x000D
+	QUICTransportErrorCode_KEY_UPDATE_ERROR          uint16 = 0x000E
+	QUICTransportErrorCode_AEAD_LIMIT_REACHED        uint16 = 0x000F
+	QUICTransportErrorCode_NO_VIABLE_PATH            uint16 = 0x0010
+	QUICTransportErrorCode_VERSION_NEGOTIATION_ERROR uint16 = 0x0011 // RFC9368
+	QUICTransportErrorCode_CRYPTO_ERROR              uint16 = 0x0100 // 0x0100-0x01FF, use with bitwise operator
+)
+
+var DictQUICTransportErrorCodeValueIndexed = map[uint16]string{
+	0x0000: "NO_ERROR",
+	0x0001: "INTERNAL_ERROR",
+	0x0002: "CONNECTION_REFUSED",
+	0x0003: "FLOW_CONTROL_ERROR",
+	0x0004: "STREAM_LIMIT_ERROR",
+	0x0005: "STREAM_STATE_ERROR",
+	0x0006: "FINAL_SIZE_ERROR",
+	0x0007: "FRAME_ENCODING_ERROR",
+	0x0008: "TRANSPORT_PARAMETER_ERROR",
+	0x0009: "CONNECTION_ID_LIMIT_ERROR",
+	0x000A: "PROTOCOL_VIOLATION",
+	0x000B: "INVALID_TOKEN",
+	0x000C: "APPLICATION_ERROR",
+	0x000D: "CRYPTO_BUFFER_EXCEEDED",
+	0x000E: "KEY_UPDATE_ERROR",
+	0x000F: "AEAD_LIMIT_REACHED",
+	0x0010: "NO_VIABLE_PATH",
+	0x0011: "VERSION_NEGOTIATION_ERROR",
+	0x0100: "CRYPTO_ERROR",
+}
+
+var DictQUICTransportErrorCodeNameIndexed = map[string]uint16{
+	"NO_ERROR":                  0x0000,
+	"INTERNAL_ERROR":            0x0001,
+	"CONNECTION_REFUSED":        0x0002,
+	"FLOW_CONTROL_ERROR":        0x0003,
+	"STREAM_LIMIT_ERROR":        0x0004,
+	"STREAM_STATE_ERROR":        0x0005,
+	"FINAL_SIZE_ERROR":          0x0006,
+	"FRAME_ENCODING_ERROR":      0x0007,
+	"TRANSPORT_PARAMETER_ERROR": 0x0008,
+	"CONNECTION_ID_LIMIT_ERROR": 0x0009,
+	"PROTOCOL_VIOLATION":        0x000A,
+	"INVALID_TOKEN":             0x000B,
+	"APPLICATION_ERROR":         0x000C,
+	"CRYPTO_BUFFER_EXCEEDED":    0x000D,
+	"KEY_UPDATE_ERROR":          0x000E,
+	"AEAD_LIMIT_REACHED":        0x000F,
+	"NO_VIABLE_PATH":            0x0010,
+	"VERSION_NEGOTIATION_ERROR": 0x0011,
+	"CRYPTO_ERROR":              0x0100,
+}
diff --git a/vendor/github.com/refraction-networking/utls/dicttls/quic_transport_parameters.go b/vendor/github.com/refraction-networking/utls/dicttls/quic_transport_parameters.go
new file mode 100644
index 00000000..66eb881b
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/dicttls/quic_transport_parameters.go
@@ -0,0 +1,91 @@
+package dicttls
+
+// source: https://www.iana.org/assignments/quic/quic.xhtml#quic-transport
+// last updated: July 2023
+
+const (
+	QUICTransportParameter_original_destination_connection_id  uint64 = 0x00
+	QUICTransportParameter_max_idle_timeout                    uint64 = 0x01
+	QUICTransportParameter_stateless_reset_token               uint64 = 0x02
+	QUICTransportParameter_max_udp_payload_size                uint64 = 0x03
+	QUICTransportParameter_initial_max_data                    uint64 = 0x04
+	QUICTransportParameter_initial_max_stream_data_bidi_local  uint64 = 0x05
+	QUICTransportParameter_initial_max_stream_data_bidi_remote uint64 = 0x06
+	QUICTransportParameter_initial_max_stream_data_uni         uint64 = 0x07
+	QUICTransportParameter_initial_max_streams_bidi            uint64 = 0x08
+	QUICTransportParameter_initial_max_streams_uni             uint64 = 0x09
+	QUICTransportParameter_ack_delay_exponent                  uint64 = 0x0a
+	QUICTransportParameter_max_ack_delay                       uint64 = 0x0b
+	QUICTransportParameter_disable_active_migration            uint64 = 0x0c
+	QUICTransportParameter_preferred_address                   uint64 = 0x0d
+	QUICTransportParameter_active_connection_id_limit          uint64 = 0x0e
+	QUICTransportParameter_initial_source_connection_id        uint64 = 0x0f
+	QUICTransportParameter_retry_source_connection_id          uint64 = 0x10
+	QUICTransportParameter_version_information                 uint64 = 0x11   // RFC9368
+	QUICTransportParameter_max_datagram_frame_size             uint64 = 0x20   // RFC9221
+	QUICTransportParameter_discard                             uint64 = 0x173e // David_Schinazi: Receiver silently discards. https://github.com/quicwg/base-drafts/wiki/Quantum-Readiness-test
+	QUICTransportParameter_google_handshake_message            uint64 = 0x26ab // Google: Used to carry Google internal handshake message
+	QUICTransportParameter_grease_quic_bit                     uint64 = 0x2ab2 // RFC9287
+	QUICTransportParameter_initial_rtt                         uint64 = 0x3127 // Google: Initial RTT in microseconds
+	QUICTransportParameter_google_connection_options           uint64 = 0x3128 // Google: Google connection options for experimentation
+	QUICTransportParameter_user_agent                          uint64 = 0x3129 // Google: User agent string (deprecated)
+	QUICTransportParameter_google_version                      uint64 = 0x4752 // Google: Google QUIC version downgrade prevention
+)
+
+var DictQUICTransportParameterValueIndexed = map[uint64]string{
+	0x00:   "original_destination_connection_id",
+	0x01:   "max_idle_timeout",
+	0x02:   "stateless_reset_token",
+	0x03:   "max_udp_payload_size",
+	0x04:   "initial_max_data",
+	0x05:   "initial_max_stream_data_bidi_local",
+	0x06:   "initial_max_stream_data_bidi_remote",
+	0x07:   "initial_max_stream_data_uni",
+	0x08:   "initial_max_streams_bidi",
+	0x09:   "initial_max_streams_uni",
+	0x0a:   "ack_delay_exponent",
+	0x0b:   "max_ack_delay",
+	0x0c:   "disable_active_migration",
+	0x0d:   "preferred_address",
+	0x0e:   "active_connection_id_limit",
+	0x0f:   "initial_source_connection_id",
+	0x10:   "retry_source_connection_id",
+	0x11:   "version_information",
+	0x20:   "max_datagram_frame_size",
+	0x173e: "discard",
+	0x26ab: "google handshake message",
+	0x2ab2: "grease_quic_bit",
+	0x3127: "initial_rtt",
+	0x3128: "google_connection_options",
+	0x3129: "user_agent",
+	0x4752: "google_version",
+}
+
+var DictQUICTransportParameterNameIndexed = map[string]uint64{
+	"original_destination_connection_id":  0x00,
+	"max_idle_timeout":                    0x01,
+	"stateless_reset_token":               0x02,
+	"max_udp_payload_size":                0x03,
+	"initial_max_data":                    0x04,
+	"initial_max_stream_data_bidi_local":  0x05,
+	"initial_max_stream_data_bidi_remote": 0x06,
+	"initial_max_stream_data_uni":         0x07,
+	"initial_max_streams_bidi":            0x08,
+	"initial_max_streams_uni":             0x09,
+	"ack_delay_exponent":                  0x0a,
+	"max_ack_delay":                       0x0b,
+	"disable_active_migration":            0x0c,
+	"preferred_address":                   0x0d,
+	"active_connection_id_limit":          0x0e,
+	"initial_source_connection_id":        0x0f,
+	"retry_source_connection_id":          0x10,
+	"version_information":                 0x11,
+	"max_datagram_frame_size":             0x20,
+	"discard":                             0x173e,
+	"google handshake message":            0x26ab,
+	"grease_quic_bit":                     0x2ab2,
+	"initial_rtt":                         0x3127,
+	"google_connection_options":           0x3128,
+	"user_agent":                          0x3129,
+	"google_version":                      0x4752,
+}
diff --git a/vendor/github.com/gaukas/godicttls/signaturealgorithm.go b/vendor/github.com/refraction-networking/utls/dicttls/signaturealgorithm.go
similarity index 98%
rename from vendor/github.com/gaukas/godicttls/signaturealgorithm.go
rename to vendor/github.com/refraction-networking/utls/dicttls/signaturealgorithm.go
index e219dfc0..65c40c4f 100644
--- a/vendor/github.com/gaukas/godicttls/signaturealgorithm.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/signaturealgorithm.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // Note: values in this file was used in TLS 1.2's signature_algorithms extension
 // in combination with the values in hashalgorithm.go.
diff --git a/vendor/github.com/gaukas/godicttls/signaturescheme.go b/vendor/github.com/refraction-networking/utls/dicttls/signaturescheme.go
similarity index 99%
rename from vendor/github.com/gaukas/godicttls/signaturescheme.go
rename to vendor/github.com/refraction-networking/utls/dicttls/signaturescheme.go
index 969eca82..d0b9803f 100644
--- a/vendor/github.com/gaukas/godicttls/signaturescheme.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/signaturescheme.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-signaturescheme.csv
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/supplemental_data_formats.go b/vendor/github.com/refraction-networking/utls/dicttls/supplemental_data_formats.go
similarity index 96%
rename from vendor/github.com/gaukas/godicttls/supplemental_data_formats.go
rename to vendor/github.com/refraction-networking/utls/dicttls/supplemental_data_formats.go
index 2ea74f77..9dd7f176 100644
--- a/vendor/github.com/gaukas/godicttls/supplemental_data_formats.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/supplemental_data_formats.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-12
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/supported_groups.go b/vendor/github.com/refraction-networking/utls/dicttls/supported_groups.go
similarity index 99%
rename from vendor/github.com/gaukas/godicttls/supported_groups.go
rename to vendor/github.com/refraction-networking/utls/dicttls/supported_groups.go
index 1daea63c..7c5cb541 100644
--- a/vendor/github.com/gaukas/godicttls/supported_groups.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/supported_groups.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
 // last updated: March 2023
diff --git a/vendor/github.com/gaukas/godicttls/usermappingtype_values.go b/vendor/github.com/refraction-networking/utls/dicttls/usermappingtype_values.go
similarity index 95%
rename from vendor/github.com/gaukas/godicttls/usermappingtype_values.go
rename to vendor/github.com/refraction-networking/utls/dicttls/usermappingtype_values.go
index 79108427..a16d071f 100644
--- a/vendor/github.com/gaukas/godicttls/usermappingtype_values.go
+++ b/vendor/github.com/refraction-networking/utls/dicttls/usermappingtype_values.go
@@ -1,4 +1,4 @@
-package godicttls
+package dicttls
 
 // source: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-14
 // last updated: March 2023
diff --git a/vendor/github.com/refraction-networking/utls/handshake_client.go b/vendor/github.com/refraction-networking/utls/handshake_client.go
index d9021488..b142b4d6 100644
--- a/vendor/github.com/refraction-networking/utls/handshake_client.go
+++ b/vendor/github.com/refraction-networking/utls/handshake_client.go
@@ -8,6 +8,7 @@ import (
 	"bytes"
 	"context"
 	"crypto"
+	"crypto/ecdh"
 	"crypto/ecdsa"
 	"crypto/ed25519"
 	"crypto/rsa"
@@ -19,8 +20,9 @@ import (
 	"io"
 	"net"
 	"strings"
-	"sync/atomic"
 	"time"
+
+	circlSign "github.com/cloudflare/circl/sign"
 )
 
 type clientHandshakeState struct {
@@ -31,14 +33,15 @@ type clientHandshakeState struct {
 	suite        *cipherSuite
 	finishedHash finishedHash
 	masterSecret []byte
-	session      *ClientSessionState
+	session      *SessionState // the session being resumed
+	ticket       []byte        // a fresh ticket received during this handshake
 
 	uconn *UConn // [uTLS]
 }
 
 var testingOnlyForceClientHelloSignatureAlgorithms []SignatureScheme
 
-func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
+func (c *Conn) makeClientHello() (*clientHelloMsg, clientKeySharePrivate, error) { // [uTLS] using clientKeySharePrivate instead of ecdheKey
 	config := c.config
 
 	// [UTLS SECTION START]
@@ -76,7 +79,7 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
 		vers:                         clientHelloVersion,
 		compressionMethods:           []uint8{compressionNone},
 		random:                       make([]byte, 32),
-		sessionId:                    make([]byte, 32),
+		extendedMasterSecret:         true,
 		ocspStapling:                 true,
 		scts:                         true,
 		serverName:                   hostnameInSNI(config.ServerName),
@@ -119,37 +122,78 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, 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 _, err := io.ReadFull(config.rand(), hello.sessionId); err != nil {
-		return nil, nil, errors.New("tls: short read from Rand: " + err.Error())
+	//
+	// The session ID is not set for QUIC connections (see RFC 9001, Section 8.4).
+	if c.quic == 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()
+		// hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
+		hello.supportedSignatureAlgorithms = config.supportedSignatureAlgorithms() // [UTLS] ported from cloudflare/go
 	}
 	if testingOnlyForceClientHelloSignatureAlgorithms != nil {
 		hello.supportedSignatureAlgorithms = testingOnlyForceClientHelloSignatureAlgorithms
 	}
 
-	var params ecdheParameters
+	// var key *ecdh.PrivateKey
+	var secret clientKeySharePrivate // [UTLS]
 	if hello.supportedVersions[0] == VersionTLS13 {
-		if hasAESGCMHardwareSupport {
+		// Reset the list of ciphers when the client only supports TLS 1.3.
+		if len(hello.supportedVersions) == 1 {
+			hello.cipherSuites = nil
+		}
+		if needFIPS() {
+			hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13FIPS...)
+		} 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")
+		// [UTLS SECTION BEGINS]
+		// Ported from cloudflare/go with modifications to preserve crypto/tls compatibility
+		if scheme := curveIdToCirclScheme(curveID); scheme != nil {
+			pk, sk, err := generateKemKeyPair(scheme, curveID, config.rand())
+			if err != nil {
+				return nil, nil, fmt.Errorf("generateKemKeyPair %s: %w", scheme.Name(), err)
+			}
+			packedPk, err := pk.MarshalBinary()
+			if err != nil {
+				return nil, nil, fmt.Errorf("pack circl public key %s: %w", scheme.Name(), err)
+			}
+			hello.keyShares = []keyShare{{group: curveID, data: packedPk}}
+			secret = sk
+		} else {
+			if _, ok := curveForCurveID(curveID); !ok {
+				return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve")
+			}
+			key, err := generateECDHEKey(config.rand(), curveID)
+			if err != nil {
+				return nil, nil, err
+			}
+			hello.keyShares = []keyShare{{group: curveID, data: key.PublicKey().Bytes()}}
+			secret = key
 		}
-		params, err = generateECDHEParameters(config.rand(), curveID)
+		// [UTLS SECTION ENDS]
+	}
+
+	if c.quic != nil {
+		p, err := c.quicGetTransportParameters()
 		if err != nil {
 			return nil, nil, err
 		}
-		hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
+		if p == nil {
+			p = []byte{}
+		}
+		hello.quicTransportParameters = p
 	}
 
-	return hello, params, nil
+	return hello, secret, nil
 }
 
 func (c *Conn) clientHandshake(ctx context.Context) (err error) {
@@ -161,17 +205,18 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
 	// need to be reset.
 	c.didResume = false
 
-	hello, ecdheParams, err := c.makeClientHello()
+	// hello, ecdheKey, err := c.makeClientHello()
+	hello, keySharePrivate, err := c.makeClientHello() // [uTLS] using keySharePrivate instead of ecdheKey
 	if err != nil {
 		return err
 	}
 	c.serverName = hello.serverName
 
-	cacheKey, session, earlySecret, binderKey, err := c.loadSession(hello)
+	session, earlySecret, binderKey, err := c.loadSession(hello)
 	if err != nil {
 		return err
 	}
-	if cacheKey != "" && session != nil {
+	if session != nil {
 		defer func() {
 			// If we got a handshake failure when resuming a session, throw away
 			// the session ticket. See RFC 5077, Section 3.2.
@@ -180,7 +225,9 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
 			// 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 cacheKey := c.clientSessionCacheKey(); cacheKey != "" {
+					c.config.ClientSessionCache.Put(cacheKey, nil)
+				}
 			}
 		}()
 	}
@@ -189,6 +236,16 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
 		return err
 	}
 
+	if hello.earlyData {
+		suite := cipherSuiteTLS13ByID(session.cipherSuite)
+		transcript := suite.hash.New()
+		if err := transcriptMsg(hello, transcript); err != nil {
+			return err
+		}
+		earlyTrafficSecret := suite.deriveSecret(earlySecret, clientEarlyTrafficLabel, transcript)
+		c.quicSetWriteSecret(QUICEncryptionLevelEarly, suite.id, earlyTrafficSecret)
+	}
+
 	// serverHelloMsg is not included in the transcript
 	msg, err := c.readHandshake(nil)
 	if err != nil {
@@ -219,15 +276,24 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
 
 	if c.vers == VersionTLS13 {
 		hs := &clientHandshakeStateTLS13{
-			c:                    c,
-			ctx:                  ctx,
-			serverHello:          serverHello,
-			hello:                hello,
-			ecdheParams:          ecdheParams,
-			keySharesEcdheParams: make(KeySharesEcdheParameters, 2), // [uTLS]
-			session:              session,
-			earlySecret:          earlySecret,
-			binderKey:            binderKey,
+			c:           c,
+			ctx:         ctx,
+			serverHello: serverHello,
+			hello:       hello,
+			// ecdheKey:    ecdheKey, // [uTLS]
+			session:     session,
+			earlySecret: earlySecret,
+			binderKey:   binderKey,
+
+			keySharesParams: NewKeySharesParameters(), // [uTLS]
+		}
+
+		if ecdheKey, ok := keySharePrivate.(*ecdh.PrivateKey); ok {
+			hs.ecdheKey = ecdheKey
+		} else if kemKey, ok := keySharePrivate.(*kemPrivateKey); ok {
+			hs.kemKey = kemKey
+		} else {
+			return fmt.Errorf("tls: unknown key share type %T", keySharePrivate)
 		}
 
 		// In TLS 1.3, session tickets are delivered after the handshake.
@@ -246,19 +312,19 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
 		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, hs.session)
-	}
-
 	return nil
 }
 
-func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
-	session *ClientSessionState, earlySecret, binderKey []byte, err error) {
+func (c *Conn) loadSession(hello *clientHelloMsg) (
+	session *SessionState, earlySecret, binderKey []byte, err error) {
+	// [UTLS SECTION START]
+	if c.utls.sessionController != nil {
+		c.utls.sessionController.onEnterLoadSessionCheck()
+		defer c.utls.sessionController.onLoadSessionReturn()
+	}
+	// [UTLS SECTION END]
 	if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil {
-		return "", nil, nil, nil, nil
+		return nil, nil, nil, nil
 	}
 
 	hello.ticketSupported = true
@@ -273,43 +339,52 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
 	// 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, nil
+		return nil, nil, nil, nil
 	}
 
 	// Try to resume a previously negotiated TLS session, if available.
-	cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
-	session, ok := c.config.ClientSessionCache.Get(cacheKey)
-	if !ok || session == nil {
-		return cacheKey, nil, nil, nil, nil
+	cacheKey := c.clientSessionCacheKey()
+	if cacheKey == "" {
+		return nil, nil, nil, nil
+	}
+	cs, ok := c.config.ClientSessionCache.Get(cacheKey)
+	if !ok || cs == nil {
+		return nil, nil, nil, nil
 	}
+	session = cs.session
 
 	// Check that version used for the previous session is still valid.
 	versOk := false
 	for _, v := range hello.supportedVersions {
-		if v == session.vers {
+		if v == session.version {
 			versOk = true
 			break
 		}
 	}
 	if !versOk {
-		return cacheKey, nil, nil, nil, nil
+		return nil, 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.time().After(session.peerCertificates[0].NotAfter) {
+		// Expired certificate, delete the entry.
+		c.config.ClientSessionCache.Put(cacheKey, nil)
+		return nil, nil, nil, nil
+	}
 	if !c.config.InsecureSkipVerify {
 		if len(session.verifiedChains) == 0 {
 			// The original connection had InsecureSkipVerify, while this doesn't.
-			return cacheKey, nil, nil, nil, nil
+			return nil, nil, nil, nil
 		}
-		serverCert := session.serverCertificates[0]
+		serverCert := session.peerCertificates[0]
 		// [UTLS SECTION START]
 		if !c.config.InsecureSkipTimeVerify {
 			if c.config.time().After(serverCert.NotAfter) {
 				// Expired certificate, delete the entry.
 				c.config.ClientSessionCache.Put(cacheKey, nil)
-				return cacheKey, nil, nil, nil, nil
+				return nil, nil, nil, nil
 			}
 		}
 		var dnsName string
@@ -320,34 +395,34 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
 		}
 		if len(dnsName) > 0 {
 			if err := serverCert.VerifyHostname(dnsName); err != nil {
-				return cacheKey, nil, nil, nil, nil
+				return nil, nil, nil, nil
 			}
 		}
 		// [UTLS SECTION END]
 	}
 
-	if session.vers != VersionTLS13 {
+	if session.version != 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, nil
+			return nil, nil, nil, nil
 		}
 
-		hello.sessionTicket = session.sessionTicket
+		hello.sessionTicket = cs.ticket
 		return
 	}
 
 	// Check that the session ticket is not expired.
-	if c.config.time().After(session.useBy) {
+	if c.config.time().After(time.Unix(int64(session.useBy), 0)) {
 		c.config.ClientSessionCache.Put(cacheKey, nil)
-		return cacheKey, nil, nil, nil, nil
+		return nil, 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, nil
+		return nil, nil, nil, nil
 	}
 	cipherSuiteOk := false
 	for _, offeredID := range hello.cipherSuites {
@@ -358,32 +433,48 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
 		}
 	}
 	if !cipherSuiteOk {
-		return cacheKey, nil, nil, nil, nil
+		return nil, nil, nil, nil
+	}
+
+	if c.quic != nil && session.EarlyData {
+		// For 0-RTT, the cipher suite has to match exactly, and we need to be
+		// offering the same ALPN.
+		if mutualCipherSuiteTLS13(hello.cipherSuites, session.cipherSuite) != nil {
+			for _, alpn := range hello.alpnProtocols {
+				if alpn == session.alpnProtocol {
+					hello.earlyData = true
+					break
+				}
+			}
+		}
 	}
 
 	// Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1.
-	ticketAge := uint32(c.config.time().Sub(session.receivedAt) / time.Millisecond)
+	ticketAge := c.config.time().Sub(time.Unix(int64(session.createdAt), 0))
 	identity := pskIdentity{
-		label:               session.sessionTicket,
-		obfuscatedTicketAge: ticketAge + session.ageAdd,
+		label:               cs.ticket,
+		obfuscatedTicketAge: uint32(ticketAge/time.Millisecond) + 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)
+	earlySecret = cipherSuite.extract(session.secret, nil)
 	binderKey = cipherSuite.deriveSecret(earlySecret, resumptionBinderLabel, nil)
+	// [UTLS SECTION START]
+	if c.utls.sessionController != nil && !c.utls.sessionController.shouldLoadSessionWriteBinders() {
+		return
+	}
+	// [UTLS SECTION END]
 	transcript := cipherSuite.hash.New()
 	helloBytes, err := hello.marshalWithoutBinders()
 	if err != nil {
-		return "", nil, nil, nil, err
+		return nil, nil, nil, err
 	}
 	transcript.Write(helloBytes)
 	pskBinders := [][]byte{cipherSuite.finishedHash(binderKey, transcript)}
 	if err := hello.updateBinders(pskBinders); err != nil {
-		return "", nil, nil, nil, err
+		return nil, nil, nil, err
 	}
 
 	return
@@ -485,9 +576,12 @@ func (hs *clientHandshakeState) handshake() error {
 			return err
 		}
 	}
+	if err := hs.saveSessionTicket(); err != nil {
+		return err
+	}
 
 	c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random)
-	atomic.StoreUint32(&c.handshakeStatus, 1)
+	c.isHandshakeComplete.Store(true)
 
 	return nil
 }
@@ -498,6 +592,13 @@ func (hs *clientHandshakeState) pickCipherSuite() error {
 		return errors.New("tls: server chose an unconfigured cipher suite")
 	}
 
+	// [UTLS SECTION START]
+	// Disable unsupported godebug packages
+	// if hs.c.config.CipherSuites == nil && rsaKexCiphers[hs.suite.id] {
+	// 	tlsrsakex.IncNonDefault()
+	// }
+	// [UTLS SECTION END]
+
 	hs.c.cipherSuite = hs.suite.id
 	return nil
 }
@@ -623,10 +724,18 @@ func (hs *clientHandshakeState) doFullHandshake() error {
 		}
 	}
 
-	// [UTLS SECTION START]
-	/* sessionHash does not include CertificateVerify */
-	sessionHash := hs.finishedHash.Sum()
-	// [UTLS SECTION END]
+	if hs.serverHello.extendedMasterSecret {
+		c.extMasterSecret = true
+		hs.masterSecret = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret,
+			hs.finishedHash.Sum())
+	} else {
+		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())
+	}
 
 	if chainToSend != nil && len(chainToSend.Certificate) > 0 {
 		certVerify := &certificateVerifyMsg{}
@@ -659,7 +768,7 @@ func (hs *clientHandshakeState) doFullHandshake() error {
 			}
 		}
 
-		signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret)
+		signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash)
 		signOpts := crypto.SignerOpts(sigHash)
 		if sigType == signatureRSAPSS {
 			signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
@@ -675,19 +784,6 @@ func (hs *clientHandshakeState) doFullHandshake() error {
 		}
 	}
 
-	// [UTLS SECTION START]
-	if hs.hello.ems && hs.serverHello.ems {
-		hs.masterSecret = extendedMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, sessionHash)
-	} else {
-		hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
-	}
-	// [UTLS SECTION END]
-
-	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
@@ -752,7 +848,7 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
 		}
 	}
 
-	if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol); err != nil {
+	if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol, false); err != nil {
 		c.sendAlert(alertUnsupportedExtension)
 		return false, err
 	}
@@ -764,7 +860,7 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
 		return false, nil
 	}
 
-	if hs.session.vers != c.vers {
+	if hs.session.version != c.vers {
 		c.sendAlert(alertHandshakeFailure)
 		return false, errors.New("tls: server resumed a session with a different version")
 	}
@@ -774,9 +870,17 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
 		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
+	// RFC 7627, Section 5.3
+	if hs.session.extMasterSecret != hs.serverHello.extendedMasterSecret {
+		c.sendAlert(alertHandshakeFailure)
+		return false, errors.New("tls: server resumed a session with a different EMS extension")
+	}
+
+	// Restore master secret and certificates from previous state
+	hs.masterSecret = hs.session.secret
+	c.extMasterSecret = hs.session.extMasterSecret
+	c.peerCertificates = hs.session.peerCertificates
+	c.activeCertHandles = hs.c.activeCertHandles
 	c.verifiedChains = hs.session.verifiedChains
 	c.ocspResponse = hs.session.ocspResponse
 	// Let the ServerHello SCTs override the session SCTs from the original
@@ -790,8 +894,12 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
 
 // 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 {
+func checkALPN(clientProtos []string, serverProto string, quic bool) error {
 	if serverProto == "" {
+		if quic && len(clientProtos) > 0 {
+			// RFC 9001, Section 8.1
+			return errors.New("tls: server did not select an ALPN protocol")
+		}
 		return nil
 	}
 	if len(clientProtos) == 0 {
@@ -844,8 +952,13 @@ func (hs *clientHandshakeState) readSessionTicket() error {
 	if !hs.serverHello.ticketSupported {
 		return nil
 	}
-
 	c := hs.c
+
+	if !hs.hello.ticketSupported {
+		c.sendAlert(alertIllegalParameter)
+		return errors.New("tls: server sent unrequested session ticket")
+	}
+
 	msg, err := c.readHandshake(&hs.finishedHash)
 	if err != nil {
 		return err
@@ -856,18 +969,33 @@ func (hs *clientHandshakeState) readSessionTicket() error {
 		return unexpectedMessageError(sessionTicketMsg, msg)
 	}
 
-	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,
+	hs.ticket = sessionTicketMsg.ticket
+	return nil
+}
+
+func (hs *clientHandshakeState) saveSessionTicket() error {
+	if hs.ticket == nil {
+		return nil
+	}
+	c := hs.c
+
+	cacheKey := c.clientSessionCacheKey()
+	if cacheKey == "" {
+		return nil
+	}
+
+	session, err := c.sessionState()
+	if err != nil {
+		return err
 	}
+	session.secret = hs.masterSecret
 
+	cs := &ClientSessionState{ticket: hs.ticket, session: session}
+	// [UTLS BEGIN]
+	if c.config.ClientSessionCache != nil { // skip saving session if cache is nil
+		c.config.ClientSessionCache.Put(cacheKey, cs)
+	}
+	// [UTLS END]
 	return nil
 }
 
@@ -887,17 +1015,47 @@ func (hs *clientHandshakeState) sendFinished(out []byte) error {
 	return nil
 }
 
+// defaultMaxRSAKeySize is the maximum RSA key size in bits that we are willing
+// to verify the signatures of during a TLS handshake.
+const defaultMaxRSAKeySize = 8192
+
+// var tlsmaxrsasize = godebug.New("tlsmaxrsasize") // [uTLS] unused
+
+func checkKeySize(n int) (max int, ok bool) {
+	// [uTLS SECTION START]
+	// Disable the unsupported godebug package
+	// if v := tlsmaxrsasize.Value(); v != "" {
+	// 	if max, err := strconv.Atoi(v); err == nil {
+	// 		if (n <= max) != (n <= defaultMaxRSAKeySize) {
+	// 			tlsmaxrsasize.IncNonDefault()
+	// 		}
+	// 		return max, n <= max
+	// 	}
+	// }
+	// [uTLS SECTION END]
+	return defaultMaxRSAKeySize, n <= defaultMaxRSAKeySize
+}
+
 // 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 {
+	activeHandles := make([]*activeCert, len(certificates))
 	certs := make([]*x509.Certificate, len(certificates))
 	for i, asn1Data := range certificates {
-		cert, err := x509.ParseCertificate(asn1Data)
+		cert, err := globalCertCache.newCert(asn1Data)
 		if err != nil {
 			c.sendAlert(alertBadCertificate)
 			return errors.New("tls: failed to parse certificate from server: " + err.Error())
 		}
-		certs[i] = cert
+		if cert.cert.PublicKeyAlgorithm == x509.RSA {
+			n := cert.cert.PublicKey.(*rsa.PublicKey).N.BitLen()
+			if max, ok := checkKeySize(n); !ok {
+				c.sendAlert(alertBadCertificate)
+				return fmt.Errorf("tls: server sent certificate containing RSA key larger than %d bits", max)
+			}
+		}
+		activeHandles[i] = cert
+		certs[i] = cert.cert
 	}
 
 	if !c.config.InsecureSkipVerify {
@@ -926,18 +1084,19 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
 		c.verifiedChains, err = certs[0].Verify(opts)
 		if err != nil {
 			c.sendAlert(alertBadCertificate)
-			return err
+			return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
 		}
 	}
 
 	switch certs[0].PublicKey.(type) {
-	case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
+	case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey, circlSign.PublicKey: // [UTLS] ported from cloudflare/go
 		break
 	default:
 		c.sendAlert(alertUnsupportedCertificate)
 		return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
 	}
 
+	c.activeCertHandles = activeHandles
 	c.peerCertificates = certs
 
 	if c.config.VerifyPeerCertificate != nil {
@@ -1041,11 +1200,14 @@ func (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate,
 
 // 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 config.ServerName
+func (c *Conn) clientSessionCacheKey() string {
+	if len(c.config.ServerName) > 0 {
+		return c.config.ServerName
+	}
+	if c.conn != nil {
+		return c.conn.RemoteAddr().String()
 	}
-	return serverAddr.String()
+	return ""
 }
 
 // hostnameInSNI converts name into an appropriate hostname for SNI.
diff --git a/vendor/github.com/refraction-networking/utls/handshake_client_tls13.go b/vendor/github.com/refraction-networking/utls/handshake_client_tls13.go
index 2385c15d..e4f955e0 100644
--- a/vendor/github.com/refraction-networking/utls/handshake_client_tls13.go
+++ b/vendor/github.com/refraction-networking/utls/handshake_client_tls13.go
@@ -8,43 +8,86 @@ import (
 	"bytes"
 	"context"
 	"crypto"
+	"crypto/ecdh"
 	"crypto/hmac"
 	"crypto/rsa"
 	"errors"
 	"fmt"
 	"hash"
-	"sync/atomic"
 	"time"
+
+	"github.com/cloudflare/circl/kem"
 )
 
 // [uTLS SECTION START]
-type KeySharesEcdheParameters map[CurveID]ecdheParameters
+// KeySharesParameters serves as a in-memory storage for generated keypairs by UTLS when generating
+// ClientHello. It is used to store both ecdhe and kem keypairs.
+type KeySharesParameters struct {
+	ecdhePrivKeymap map[CurveID]*ecdh.PrivateKey
+	ecdhePubKeymap  map[CurveID]*ecdh.PublicKey
+
+	// based on cloudflare/go
+	kemPrivKeymap map[CurveID]kem.PrivateKey
+	kemPubKeymap  map[CurveID]kem.PublicKey
+}
+
+func NewKeySharesParameters() *KeySharesParameters {
+	return &KeySharesParameters{
+		ecdhePrivKeymap: make(map[CurveID]*ecdh.PrivateKey),
+		ecdhePubKeymap:  make(map[CurveID]*ecdh.PublicKey),
+
+		kemPrivKeymap: make(map[CurveID]kem.PrivateKey),
+		kemPubKeymap:  make(map[CurveID]kem.PublicKey),
+	}
+}
+
+func (ksp *KeySharesParameters) AddEcdheKeypair(curveID CurveID, ecdheKey *ecdh.PrivateKey, ecdhePubKey *ecdh.PublicKey) {
+	ksp.ecdhePrivKeymap[curveID] = ecdheKey
+	ksp.ecdhePubKeymap[curveID] = ecdhePubKey
+}
 
-func (keymap KeySharesEcdheParameters) AddEcdheParams(curveID CurveID, params ecdheParameters) {
-	keymap[curveID] = params
+func (ksp *KeySharesParameters) GetEcdheKey(curveID CurveID) (ecdheKey *ecdh.PrivateKey, ok bool) {
+	ecdheKey, ok = ksp.ecdhePrivKeymap[curveID]
+	return
 }
-func (keymap KeySharesEcdheParameters) GetEcdheParams(curveID CurveID) (params ecdheParameters, ok bool) {
-	params, ok = keymap[curveID]
+
+func (ksp *KeySharesParameters) GetEcdhePubkey(curveID CurveID) (params *ecdh.PublicKey, ok bool) {
+	params, ok = ksp.ecdhePubKeymap[curveID]
 	return
 }
-func (keymap KeySharesEcdheParameters) GetPublicEcdheParams(curveID CurveID) (params EcdheParameters, ok bool) {
-	params, ok = keymap[curveID]
+
+func (ksp *KeySharesParameters) AddKemKeypair(curveID CurveID, kemKey kem.PrivateKey, kemPubKey kem.PublicKey) {
+	if curveIdToCirclScheme(curveID) != nil { // only store for circl schemes
+		ksp.kemPrivKeymap[curveID] = kemKey
+		ksp.kemPubKeymap[curveID] = kemPubKey
+	}
+}
+
+func (ksp *KeySharesParameters) GetKemKey(curveID CurveID) (kemKey kem.PrivateKey, ok bool) {
+	kemKey, ok = ksp.kemPrivKeymap[curveID]
+	return
+}
+
+func (ksp *KeySharesParameters) GetKemPubkey(curveID CurveID) (params kem.PublicKey, ok bool) {
+	params, ok = ksp.kemPubKeymap[curveID]
 	return
 }
 
 // [uTLS SECTION END]
 
 type clientHandshakeStateTLS13 struct {
-	c                    *Conn
-	ctx                  context.Context
-	serverHello          *serverHelloMsg
-	hello                *clientHelloMsg
-	ecdheParams          ecdheParameters
-	keySharesEcdheParams KeySharesEcdheParameters // [uTLS]
-
-	session     *ClientSessionState
-	earlySecret []byte
-	binderKey   []byte
+	c               *Conn
+	ctx             context.Context
+	serverHello     *serverHelloMsg
+	hello           *clientHelloMsg
+	ecdheKey        *ecdh.PrivateKey
+	kemKey          *kemPrivateKey       // [uTLS] ported from cloudflare/go
+	keySharesParams *KeySharesParameters // [uTLS] support both ecdhe and kem
+
+	session       *SessionState
+	earlySecret   []byte
+	binderKey     []byte
+	selectedGroup CurveID // [uTLS] ported from cloudflare/go
 
 	certReq       *certificateRequestMsgTLS13
 	usingPSK      bool
@@ -57,7 +100,7 @@ type clientHandshakeStateTLS13 struct {
 	uconn *UConn // [uTLS]
 }
 
-// handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheParams, and,
+// handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheKey, and,
 // optionally, hs.session, hs.earlySecret and hs.binderKey to be set.
 func (hs *clientHandshakeStateTLS13) handshake() error {
 	c := hs.c
@@ -74,15 +117,23 @@ func (hs *clientHandshakeStateTLS13) handshake() error {
 	}
 
 	// [uTLS SECTION START]
-
 	// set echdheParams to what we received from server
-	if ecdheParams, ok := hs.keySharesEcdheParams.GetEcdheParams(hs.serverHello.serverShare.group); ok {
-		hs.ecdheParams = ecdheParams
+	if ecdheKey, ok := hs.keySharesParams.GetEcdheKey(hs.serverHello.serverShare.group); ok {
+		hs.ecdheKey = ecdheKey
+		hs.kemKey = nil // unset kemKey if any
+	}
+	// set kemParams to what we received from server
+	if kemKey, ok := hs.keySharesParams.GetKemKey(hs.serverHello.serverShare.group); ok {
+		hs.kemKey = &kemPrivateKey{
+			secretKey: kemKey,
+			curveID:   hs.serverHello.serverShare.group,
+		}
+		hs.ecdheKey = nil // unset ecdheKey if any
 	}
 	// [uTLS SECTION END]
 
 	// Consistency check on the presence of a keyShare and its parameters.
-	if hs.ecdheParams == nil || len(hs.hello.keyShares) < 1 { // [uTLS]
+	if (hs.ecdheKey == nil && hs.kemKey == nil) || len(hs.hello.keyShares) < 1 { // [uTLS]
 		// keyshares "< 1" instead of "!= 1", as uTLS may send multiple
 		return c.sendAlert(alertInternalError)
 	}
@@ -144,7 +195,7 @@ func (hs *clientHandshakeStateTLS13) handshake() error {
 		return err
 	}
 
-	atomic.StoreUint32(&c.handshakeStatus, 1)
+	c.isHandshakeComplete.Store(true)
 
 	return nil
 }
@@ -171,6 +222,7 @@ func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error {
 
 	if hs.serverHello.ocspStapling ||
 		hs.serverHello.ticketSupported ||
+		hs.serverHello.extendedMasterSecret ||
 		hs.serverHello.secureRenegotiationSupported ||
 		len(hs.serverHello.secureRenegotiation) != 0 ||
 		len(hs.serverHello.alpnProtocol) != 0 ||
@@ -207,6 +259,9 @@ func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error {
 // 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.c.quic != nil {
+		return nil
+	}
 	if hs.sentDummyCCS {
 		return nil
 	}
@@ -243,18 +298,6 @@ func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
 		hs.hello.cookie = hs.serverHello.cookie
 	}
 
-	// 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")
@@ -275,21 +318,55 @@ func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
 			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 {
+
+		// [UTLS SECTION BEGINS]
+		// ported from cloudflare/go, slightly modified to maintain compatibility with crypto/tls upstream
+		if hs.ecdheKey != nil {
+			if sentID, _ := curveIDForCurve(hs.ecdheKey.Curve()); sentID == curveID {
+				c.sendAlert(alertIllegalParameter)
+				return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share")
+			}
+		} else if hs.kemKey != nil {
+			if clientKeySharePrivateCurveID(hs.kemKey) == curveID {
+				c.sendAlert(alertIllegalParameter)
+				return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share")
+			}
+		} else {
 			c.sendAlert(alertInternalError)
-			return errors.New("tls: CurvePreferences includes unsupported curve")
+			return errors.New("tls: ecdheKey and kemKey are both nil")
 		}
-		params, err := generateECDHEParameters(c.config.rand(), curveID)
-		if err != nil {
-			c.sendAlert(alertInternalError)
-			return err
+
+		if scheme := curveIdToCirclScheme(curveID); scheme != nil {
+			pk, sk, err := generateKemKeyPair(scheme, curveID, c.config.rand())
+			if err != nil {
+				c.sendAlert(alertInternalError)
+				return fmt.Errorf("HRR generateKemKeyPair %s: %w",
+					scheme.Name(), err)
+			}
+			packedPk, err := pk.MarshalBinary()
+			if err != nil {
+				c.sendAlert(alertInternalError)
+				return fmt.Errorf("HRR pack circl public key %s: %w",
+					scheme.Name(), err)
+			}
+			hs.kemKey = sk
+			hs.ecdheKey = nil // unset ecdheKey if any
+			hs.hello.keyShares = []keyShare{{group: curveID, data: packedPk}}
+		} else {
+			if _, ok := curveForCurveID(curveID); !ok {
+				c.sendAlert(alertInternalError)
+				return errors.New("tls: CurvePreferences includes unsupported curve")
+			}
+			key, err := generateECDHEKey(c.config.rand(), curveID)
+			if err != nil {
+				c.sendAlert(alertInternalError)
+				return err
+			}
+			hs.ecdheKey = key
+			hs.kemKey = nil // unset kemKey if any
+			hs.hello.keyShares = []keyShare{{group: curveID, data: key.PublicKey().Bytes()}}
 		}
-		hs.ecdheParams = params
-		hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
+		// [UTLS SECTION ENDS]
 	}
 
 	hs.hello.raw = nil
@@ -300,13 +377,13 @@ func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
 		}
 		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
+			ticketAge := c.config.time().Sub(time.Unix(int64(hs.session.createdAt), 0))
+			hs.hello.pskIdentities[0].obfuscatedTicketAge = uint32(ticketAge/time.Millisecond) + hs.session.ageAdd
 
 			transcript := hs.suite.hash.New()
 			transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
 			transcript.Write(chHash)
-			if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
+			if err := transcriptMsg(hs.serverHello, transcript); err != nil {
 				return err
 			}
 			helloBytes, err := hs.hello.marshalWithoutBinders()
@@ -386,6 +463,10 @@ func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
 		}
 	}
 	// [uTLS SECTION ENDS]
+	if hs.hello.earlyData {
+		hs.hello.earlyData = false
+		c.quicRejectedEarlyData()
+	}
 
 	if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != nil {
 		return err
@@ -433,10 +514,22 @@ func (hs *clientHandshakeStateTLS13) processServerHello() error {
 		c.sendAlert(alertIllegalParameter)
 		return errors.New("tls: server did not send a key share")
 	}
-	if hs.serverHello.serverShare.group != hs.ecdheParams.CurveID() {
+
+	// [UTLS SECTION BEGINS]
+	var supportedGroupCompatible bool
+	if hs.ecdheKey != nil { // if we did send ECDHE KeyShare
+		if sentID, _ := curveIDForCurve(hs.ecdheKey.Curve()); hs.serverHello.serverShare.group == sentID { // and server selected ECDHE KeyShare
+			supportedGroupCompatible = true
+		}
+	}
+	if hs.kemKey != nil && clientKeySharePrivateCurveID(hs.kemKey) == hs.serverHello.serverShare.group { // we did send KEM KeyShare and server selected KEM KeyShare
+		supportedGroupCompatible = true
+	}
+	if !supportedGroupCompatible { // none matched
 		c.sendAlert(alertIllegalParameter)
 		return errors.New("tls: server selected unsupported group")
 	}
+	// [UTLS SECTION ENDS]
 
 	if !hs.serverHello.selectedIdentityPresent {
 		return nil
@@ -461,7 +554,8 @@ func (hs *clientHandshakeStateTLS13) processServerHello() error {
 
 	hs.usingPSK = true
 	c.didResume = true
-	c.peerCertificates = hs.session.serverCertificates
+	c.peerCertificates = hs.session.peerCertificates
+	c.activeCertHandles = hs.session.activeCertHandles
 	c.verifiedChains = hs.session.verifiedChains
 	c.ocspResponse = hs.session.ocspResponse
 	c.scts = hs.session.scts
@@ -471,11 +565,38 @@ func (hs *clientHandshakeStateTLS13) processServerHello() error {
 func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
 	c := hs.c
 
-	sharedKey := hs.ecdheParams.SharedKey(hs.serverHello.serverShare.data)
+	// [UTLS SECTION BEGINS]
+	// ported from cloudflare/go, slightly modified to maintain compatibility with crypto/tls upstream
+	var sharedKey []byte
+	var err error
+
+	if hs.ecdheKey != nil {
+		if ecdheCurveID, _ := curveIDForCurve(hs.ecdheKey.Curve()); ecdheCurveID == hs.serverHello.serverShare.group {
+			peerKey, err := hs.ecdheKey.Curve().NewPublicKey(hs.serverHello.serverShare.data)
+			if err != nil {
+				c.sendAlert(alertIllegalParameter)
+				return errors.New("tls: invalid server key share")
+			}
+			sharedKey, err = hs.ecdheKey.ECDH(peerKey)
+			if err != nil {
+				c.sendAlert(alertIllegalParameter)
+				return errors.New("tls: invalid server key share")
+			}
+		}
+	}
+	if sharedKey == nil && hs.kemKey != nil && clientKeySharePrivateCurveID(hs.kemKey) == hs.serverHello.serverShare.group {
+		sk := hs.kemKey.secretKey
+		sharedKey, err = sk.Scheme().Decapsulate(sk, hs.serverHello.serverShare.data)
+		if err != nil {
+			c.sendAlert(alertIllegalParameter)
+			return fmt.Errorf("%s decaps: %w", sk.Scheme().Name(), err)
+		}
+	}
 	if sharedKey == nil {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: invalid server key share")
+		c.sendAlert(alertInternalError)
+		return errors.New("tls: ecdheKey and circlKey are both nil")
 	}
+	// [UTLS SECTION ENDS]
 
 	earlySecret := hs.earlySecret
 	if !hs.usingPSK {
@@ -487,12 +608,20 @@ func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
 
 	clientSecret := hs.suite.deriveSecret(handshakeSecret,
 		clientHandshakeTrafficLabel, hs.transcript)
-	c.out.setTrafficSecret(hs.suite, clientSecret)
+	c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret)
 	serverSecret := hs.suite.deriveSecret(handshakeSecret,
 		serverHandshakeTrafficLabel, hs.transcript)
-	c.in.setTrafficSecret(hs.suite, serverSecret)
+	c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret)
+
+	if c.quic != nil {
+		if c.hand.Len() != 0 {
+			c.sendAlert(alertUnexpectedMessage)
+		}
+		c.quicSetWriteSecret(QUICEncryptionLevelHandshake, hs.suite.id, clientSecret)
+		c.quicSetReadSecret(QUICEncryptionLevelHandshake, hs.suite.id, serverSecret)
+	}
 
-	err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret)
+	err = c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret)
 	if err != nil {
 		c.sendAlert(alertInternalError)
 		return err
@@ -523,8 +652,12 @@ func (hs *clientHandshakeStateTLS13) readServerParameters() error {
 		return unexpectedMessageError(encryptedExtensions, msg)
 	}
 
-	if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol); err != nil {
-		c.sendAlert(alertUnsupportedExtension)
+	if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol, c.quic != nil); err != nil {
+		// RFC 8446 specifies that no_application_protocol is sent by servers, but
+		// does not specify how clients handle the selection of an incompatible protocol.
+		// RFC 9001 Section 8.1 specifies that QUIC clients send no_application_protocol
+		// in this case. Always sending no_application_protocol seems reasonable.
+		c.sendAlert(alertNoApplicationProtocol)
 		return err
 	}
 	c.clientProtocol = encryptedExtensions.alpnProtocol
@@ -538,6 +671,39 @@ func (hs *clientHandshakeStateTLS13) readServerParameters() error {
 		}
 	}
 	// [UTLS SECTION ENDS]
+
+	if c.quic != nil {
+		if encryptedExtensions.quicTransportParameters == nil {
+			// RFC 9001 Section 8.2.
+			c.sendAlert(alertMissingExtension)
+			return errors.New("tls: server did not send a quic_transport_parameters extension")
+		}
+		c.quicSetTransportParameters(encryptedExtensions.quicTransportParameters)
+	} else {
+		if encryptedExtensions.quicTransportParameters != nil {
+			c.sendAlert(alertUnsupportedExtension)
+			return errors.New("tls: server sent an unexpected quic_transport_parameters extension")
+		}
+	}
+
+	if !hs.hello.earlyData && encryptedExtensions.earlyData {
+		c.sendAlert(alertUnsupportedExtension)
+		return errors.New("tls: server sent an unexpected early_data extension")
+	}
+	if hs.hello.earlyData && !encryptedExtensions.earlyData {
+		c.quicRejectedEarlyData()
+	}
+	if encryptedExtensions.earlyData {
+		if hs.session.cipherSuite != c.cipherSuite {
+			c.sendAlert(alertHandshakeFailure)
+			return errors.New("tls: server accepted 0-RTT with the wrong cipher suite")
+		}
+		if hs.session.alpnProtocol != c.clientProtocol {
+			c.sendAlert(alertHandshakeFailure)
+			return errors.New("tls: server accepted 0-RTT with the wrong ALPN")
+		}
+	}
+
 	return nil
 }
 
@@ -632,7 +798,7 @@ func (hs *clientHandshakeStateTLS13) readServerCertificate() error {
 	}
 
 	// See RFC 8446, Section 4.4.3.
-	if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) {
+	if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, c.config.supportedSignatureAlgorithms()) { // [UTLS] ported from cloudflare/go
 		c.sendAlert(alertIllegalParameter)
 		return errors.New("tls: certificate used with invalid signature algorithm")
 	}
@@ -691,7 +857,7 @@ func (hs *clientHandshakeStateTLS13) readServerFinished() error {
 		clientApplicationTrafficLabel, hs.transcript)
 	serverSecret := hs.suite.deriveSecret(hs.masterSecret,
 		serverApplicationTrafficLabel, hs.transcript)
-	c.in.setTrafficSecret(hs.suite, serverSecret)
+	c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret)
 
 	err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret)
 	if err != nil {
@@ -787,13 +953,20 @@ func (hs *clientHandshakeStateTLS13) sendClientFinished() error {
 		return err
 	}
 
-	c.out.setTrafficSecret(hs.suite, hs.trafficSecret)
+	c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret)
 
 	if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil {
 		c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
 			resumptionLabel, hs.transcript)
 	}
 
+	if c.quic != nil {
+		if c.hand.Len() != 0 {
+			c.sendAlert(alertUnexpectedMessage)
+		}
+		c.quicSetWriteSecret(QUICEncryptionLevelApplication, hs.suite.id, hs.trafficSecret)
+	}
+
 	return nil
 }
 
@@ -817,32 +990,34 @@ func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error {
 		return errors.New("tls: received a session ticket with invalid lifetime")
 	}
 
+	// RFC 9001, Section 4.6.1
+	if c.quic != nil && msg.maxEarlyData != 0 && msg.maxEarlyData != 0xffffffff {
+		c.sendAlert(alertIllegalParameter)
+		return errors.New("tls: invalid early data for QUIC connection")
+	}
+
 	cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
 	if cipherSuite == nil || c.resumptionSecret == nil {
 		return c.sendAlert(alertInternalError)
 	}
 
-	// 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:              msg.nonce,
-		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, session)
+	psk := cipherSuite.expandLabel(c.resumptionSecret, "resumption",
+		msg.nonce, cipherSuite.hash.Size())
+
+	session, err := c.sessionState()
+	if err != nil {
+		c.sendAlert(alertInternalError)
+		return err
+	}
+	session.secret = psk
+	session.useBy = uint64(c.config.time().Add(lifetime).Unix())
+	session.ageAdd = msg.ageAdd
+	session.EarlyData = c.quic != nil && msg.maxEarlyData == 0xffffffff // RFC 9001, Section 4.6.1
+	cs := &ClientSessionState{ticket: msg.label, session: session}
+
+	if cacheKey := c.clientSessionCacheKey(); cacheKey != "" {
+		c.config.ClientSessionCache.Put(cacheKey, cs)
+	}
 
 	return nil
 }
diff --git a/vendor/github.com/refraction-networking/utls/handshake_messages.go b/vendor/github.com/refraction-networking/utls/handshake_messages.go
index 296512ea..9520246f 100644
--- a/vendor/github.com/refraction-networking/utls/handshake_messages.go
+++ b/vendor/github.com/refraction-networking/utls/handshake_messages.go
@@ -84,16 +84,18 @@ type clientHelloMsg struct {
 	supportedSignatureAlgorithmsCert []SignatureScheme
 	secureRenegotiationSupported     bool
 	secureRenegotiation              []byte
+	extendedMasterSecret             bool
 	alpnProtocols                    []string
 	scts                             bool
-	ems                              bool // [uTLS] actually implemented due to its prevalence
-	supportedVersions                []uint16
-	cookie                           []byte
-	keyShares                        []keyShare
-	earlyData                        bool
-	pskModes                         []uint8
-	pskIdentities                    []pskIdentity
-	pskBinders                       [][]byte
+	// ems                              bool // [uTLS] actually implemented due to its prevalence // removed since crypto/tls implements it
+	supportedVersions       []uint16
+	cookie                  []byte
+	keyShares               []keyShare
+	earlyData               bool
+	pskModes                []uint8
+	pskIdentities           []pskIdentity
+	pskBinders              [][]byte
+	quicTransportParameters []byte
 
 	// [uTLS]
 	nextProtoNeg bool
@@ -184,6 +186,11 @@ func (m *clientHelloMsg) marshal() ([]byte, error) {
 			})
 		})
 	}
+	if m.extendedMasterSecret {
+		// RFC 7627
+		exts.AddUint16(extensionExtendedMasterSecret)
+		exts.AddUint16(0) // empty extension_data
+	}
 	if len(m.alpnProtocols) > 0 {
 		// RFC 7301, Section 3.1
 		exts.AddUint16(extensionALPN)
@@ -250,6 +257,13 @@ func (m *clientHelloMsg) marshal() ([]byte, error) {
 			})
 		})
 	}
+	if m.quicTransportParameters != nil { // marshal zero-length parameters when present
+		// RFC 9001, Section 8.2
+		exts.AddUint16(extensionQUICTransportParameters)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddBytes(m.quicTransportParameters)
+		})
+	}
 	if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension
 		// RFC 8446, Section 4.2.11
 		exts.AddUint16(extensionPreSharedKey)
@@ -305,7 +319,7 @@ func (m *clientHelloMsg) marshal() ([]byte, error) {
 }
 
 // marshalWithoutBinders returns the ClientHello through the
-// FakePreSharedKeyExtension.identities field, according to RFC 8446, Section
+// 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, error) {
 	bindersLen := 2 // uint16 length prefix
@@ -506,6 +520,9 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
 				return false
 			}
 			m.secureRenegotiationSupported = true
+		case extensionExtendedMasterSecret:
+			// RFC 7627
+			m.extendedMasterSecret = true
 		case extensionALPN:
 			// RFC 7301, Section 3.1
 			var protoList cryptobyte.String
@@ -564,6 +581,11 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
 			if !readUint8LengthPrefixed(&extData, &m.pskModes) {
 				return false
 			}
+		case extensionQUICTransportParameters:
+			m.quicTransportParameters = make([]byte, len(extData))
+			if !extData.CopyBytes(m.quicTransportParameters) {
+				return false
+			}
 		case extensionPreSharedKey:
 			// RFC 8446, Section 4.2.11
 			if !extensions.Empty() {
@@ -618,8 +640,8 @@ type serverHelloMsg struct {
 	ticketSupported              bool
 	secureRenegotiationSupported bool
 	secureRenegotiation          []byte
+	extendedMasterSecret         bool
 	alpnProtocol                 string
-	ems                          bool
 	scts                         [][]byte
 	supportedVersion             uint16
 	serverShare                  keyShare
@@ -658,6 +680,10 @@ func (m *serverHelloMsg) marshal() ([]byte, error) {
 			})
 		})
 	}
+	if m.extendedMasterSecret {
+		exts.AddUint16(extensionExtendedMasterSecret)
+		exts.AddUint16(0) // empty extension_data
+	}
 	if len(m.alpnProtocol) > 0 {
 		exts.AddUint16(extensionALPN)
 		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
@@ -793,17 +819,20 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
 			m.ocspStapling = true
 		case extensionSessionTicket:
 			m.ticketSupported = true
-		case utlsExtensionExtendedMasterSecret:
-			// No sanity check for this extension: pretending not to know it.
-			// if length > 0 {
-			// 	return false
-			// }
-			m.ems = true
+		// [UTLS] crypto/tls finally supports EMS! Now we don't do anything special here.
+		// case utlsExtensionExtendedMasterSecret:
+		// 	// No sanity check for this extension: pretending not to know it.
+		// 	// if length > 0 {
+		// 	// 	return false
+		// 	// }
+		// 	m.ems = true
 		case extensionRenegotiationInfo:
 			if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) {
 				return false
 			}
 			m.secureRenegotiationSupported = true
+		case extensionExtendedMasterSecret:
+			m.extendedMasterSecret = true
 		case extensionALPN:
 			var protoList cryptobyte.String
 			if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
@@ -875,8 +904,10 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
 }
 
 type encryptedExtensionsMsg struct {
-	raw          []byte
-	alpnProtocol string
+	raw                     []byte
+	alpnProtocol            string
+	quicTransportParameters []byte
+	earlyData               bool
 
 	utls utlsEncryptedExtensionsMsgExtraFields // [uTLS]
 }
@@ -900,6 +931,18 @@ func (m *encryptedExtensionsMsg) marshal() ([]byte, error) {
 					})
 				})
 			}
+			if m.quicTransportParameters != nil { // marshal zero-length parameters when present
+				// draft-ietf-quic-tls-32, Section 8.2
+				b.AddUint16(extensionQUICTransportParameters)
+				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+					b.AddBytes(m.quicTransportParameters)
+				})
+			}
+			if m.earlyData {
+				// RFC 8446, Section 4.2.10
+				b.AddUint16(extensionEarlyData)
+				b.AddUint16(0) // empty extension_data
+			}
 		})
 	})
 
@@ -938,6 +981,14 @@ func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
 				return false
 			}
 			m.alpnProtocol = string(proto)
+		case extensionQUICTransportParameters:
+			m.quicTransportParameters = make([]byte, len(extData))
+			if !extData.CopyBytes(m.quicTransportParameters) {
+				return false
+			}
+		case extensionEarlyData:
+			// RFC 8446, Section 4.2.10
+			m.earlyData = true
 		default:
 			// [UTLS SECTION START]
 			if !m.utlsUnmarshal(extension, extData) {
diff --git a/vendor/github.com/refraction-networking/utls/handshake_server.go b/vendor/github.com/refraction-networking/utls/handshake_server.go
index 8cb9acf5..ca10a3a2 100644
--- a/vendor/github.com/refraction-networking/utls/handshake_server.go
+++ b/vendor/github.com/refraction-networking/utls/handshake_server.go
@@ -16,8 +16,9 @@ import (
 	"fmt"
 	"hash"
 	"io"
-	"sync/atomic"
 	"time"
+
+	circlSign "github.com/cloudflare/circl/sign"
 )
 
 // serverHandshakeState contains details of a server handshake in progress.
@@ -32,7 +33,7 @@ type serverHandshakeState struct {
 	ecSignOk     bool
 	rsaDecryptOk bool
 	rsaSignOk    bool
-	sessionState *sessionState
+	sessionState *SessionState
 	finishedHash finishedHash
 	masterSecret []byte
 	cert         *Certificate
@@ -71,7 +72,10 @@ func (hs *serverHandshakeState) handshake() error {
 
 	// For an overview of TLS handshaking, see RFC 5246, Section 7.3.
 	c.buffering = true
-	if hs.checkForResumption() {
+	if err := hs.checkForResumption(); err != nil {
+		return err
+	}
+	if hs.sessionState != nil {
 		// The client has included a session ticket and so we do an abbreviated handshake.
 		c.didResume = true
 		if err := hs.doResumeHandshake(); err != nil {
@@ -122,7 +126,7 @@ func (hs *serverHandshakeState) handshake() error {
 	}
 
 	c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random)
-	atomic.StoreUint32(&c.handshakeStatus, 1)
+	c.isHandshakeComplete.Store(true)
 
 	return nil
 }
@@ -167,6 +171,13 @@ func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) {
 	c.in.version = c.vers
 	c.out.version = c.vers
 
+	// [UTLS SECTION BEGIN]
+	// Disable unsupported godebug package
+	// if c.config.MinVersion == 0 && c.vers < VersionTLS12 {
+	// 	tls10server.IncNonDefault()
+	// }
+	// [UTLS SECTION END]
+
 	return clientHello, nil
 }
 
@@ -213,13 +224,14 @@ func (hs *serverHandshakeState) processClientHello() error {
 		return errors.New("tls: initial handshake had non-empty renegotiation extension")
 	}
 
+	hs.hello.extendedMasterSecret = hs.clientHello.extendedMasterSecret
 	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)
+	selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols, false)
 	if err != nil {
 		c.sendAlert(alertNoApplicationProtocol)
 		return err
@@ -280,8 +292,12 @@ func (hs *serverHandshakeState) processClientHello() error {
 // 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) {
+func negotiateALPN(serverProtos, clientProtos []string, quic bool) (string, error) {
 	if len(serverProtos) == 0 || len(clientProtos) == 0 {
+		if quic && len(serverProtos) != 0 {
+			// RFC 9001, Section 8.1
+			return "", fmt.Errorf("tls: client did not request an application protocol")
+		}
 		return "", nil
 	}
 	var http11fallback bool
@@ -360,6 +376,13 @@ func (hs *serverHandshakeState) pickCipherSuite() error {
 	}
 	c.cipherSuite = hs.suite.id
 
+	// [UTLS SECTION BEGIN]
+	// Disable unsupported godebug package
+	// if c.config.CipherSuites == nil && rsaKexCiphers[hs.suite.id] {
+	// 	tlsrsakex.IncNonDefault()
+	// }
+	// [UTLS SECTION END]
+
 	for _, id := range hs.clientHello.cipherSuites {
 		if id == TLS_FALLBACK_SCSV {
 			// The client is doing a fallback connection. See RFC 7507.
@@ -396,62 +419,102 @@ func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool {
 }
 
 // checkForResumption reports whether we should perform resumption on this connection.
-func (hs *serverHandshakeState) checkForResumption() bool {
+func (hs *serverHandshakeState) checkForResumption() error {
 	c := hs.c
 
 	if c.config.SessionTicketsDisabled {
-		return false
+		return nil
 	}
 
-	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
+	var sessionState *SessionState
+	if c.config.UnwrapSession != nil {
+		ss, err := c.config.UnwrapSession(hs.clientHello.sessionTicket, c.connectionStateLocked())
+		if err != nil {
+			return err
+		}
+		if ss == nil {
+			return nil
+		}
+		sessionState = ss
+	} else {
+		plaintext := c.config.decryptTicket(hs.clientHello.sessionTicket, c.ticketKeys)
+		if plaintext == nil {
+			return nil
+		}
+		ss, err := ParseSessionState(plaintext)
+		if err != nil {
+			return nil
+		}
+		sessionState = ss
 	}
 
-	createdAt := time.Unix(int64(hs.sessionState.createdAt), 0)
+	// TLS 1.2 tickets don't natively have a lifetime, but we want to avoid
+	// re-wrapping the same master secret in different tickets over and over for
+	// too long, weakening forward secrecy.
+	createdAt := time.Unix(int64(sessionState.createdAt), 0)
 	if c.config.time().Sub(createdAt) > maxSessionTicketLifetime {
-		return false
+		return nil
 	}
 
 	// Never resume a session for a different TLS version.
-	if c.vers != hs.sessionState.vers {
-		return false
+	if c.vers != sessionState.version {
+		return nil
 	}
 
 	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 {
+		if id == sessionState.cipherSuite {
 			cipherSuiteOk = true
 			break
 		}
 	}
 	if !cipherSuiteOk {
-		return false
+		return nil
 	}
 
 	// Check that we also support the ciphersuite from the session.
-	hs.suite = selectCipherSuite([]uint16{hs.sessionState.cipherSuite},
+	suite := selectCipherSuite([]uint16{sessionState.cipherSuite},
 		c.config.cipherSuites(), hs.cipherSuiteOk)
-	if hs.suite == nil {
-		return false
+	if suite == nil {
+		return nil
 	}
 
-	sessionHasClientCerts := len(hs.sessionState.certificates) != 0
+	sessionHasClientCerts := len(sessionState.peerCertificates) != 0
 	needClientCerts := requiresClientCert(c.config.ClientAuth)
 	if needClientCerts && !sessionHasClientCerts {
-		return false
+		return nil
 	}
 	if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
-		return false
+		return nil
+	}
+	if sessionHasClientCerts && c.config.time().After(sessionState.peerCertificates[0].NotAfter) {
+		return nil
+	}
+	if sessionHasClientCerts && c.config.ClientAuth >= VerifyClientCertIfGiven &&
+		len(sessionState.verifiedChains) == 0 {
+		return nil
 	}
 
-	return true
+	// RFC 7627, Section 5.3
+	if !sessionState.extMasterSecret && hs.clientHello.extendedMasterSecret {
+		return nil
+	}
+	if sessionState.extMasterSecret && !hs.clientHello.extendedMasterSecret {
+		// Aborting is somewhat harsh, but it's a MUST and it would indicate a
+		// weird downgrade in client capabilities.
+		return errors.New("tls: session supported extended_master_secret but client does not")
+	}
+
+	c.peerCertificates = sessionState.peerCertificates
+	c.ocspResponse = sessionState.ocspResponse
+	c.scts = sessionState.scts
+	c.verifiedChains = sessionState.verifiedChains
+	c.extMasterSecret = sessionState.extMasterSecret
+	hs.sessionState = sessionState
+	hs.suite = suite
+	c.didResume = true
+	return nil
 }
 
 func (hs *serverHandshakeState) doResumeHandshake() error {
@@ -462,7 +525,10 @@ func (hs *serverHandshakeState) doResumeHandshake() error {
 	// 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
+	// We always send a new session ticket, even if it wraps the same master
+	// secret and it's potentially encrypted with the same key, to help the
+	// client avoid cross-connection tracking from a network observer.
+	hs.hello.ticketSupported = true
 	hs.finishedHash = newFinishedHash(c.vers, hs.suite)
 	hs.finishedHash.discardHandshakeBuffer()
 	if err := transcriptMsg(hs.clientHello, &hs.finishedHash); err != nil {
@@ -472,12 +538,6 @@ func (hs *serverHandshakeState) doResumeHandshake() error {
 		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)
@@ -485,7 +545,7 @@ func (hs *serverHandshakeState) doResumeHandshake() error {
 		}
 	}
 
-	hs.masterSecret = hs.sessionState.masterSecret
+	hs.masterSecret = hs.sessionState.secret
 
 	return nil
 }
@@ -549,7 +609,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
 		}
 		if c.vers >= VersionTLS12 {
 			certReq.hasSignatureAlgorithm = true
-			certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
+			certReq.supportedSignatureAlgorithms = c.config.supportedSignatureAlgorithms() // [UTLS] ported from cloudflare/go
 		}
 
 		// An empty list of certificateAuthorities signals to
@@ -623,7 +683,14 @@ func (hs *serverHandshakeState) doFullHandshake() error {
 		c.sendAlert(alertHandshakeFailure)
 		return err
 	}
-	hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random)
+	if hs.hello.extendedMasterSecret {
+		c.extMasterSecret = true
+		hs.masterSecret = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret,
+			hs.finishedHash.Sum())
+	} else {
+		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
@@ -668,7 +735,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
 			}
 		}
 
-		signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret)
+		signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash)
 		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())
@@ -755,31 +822,30 @@ func (hs *serverHandshakeState) sendSessionTicket() error {
 	c := hs.c
 	m := new(newSessionTicketMsg)
 
-	createdAt := uint64(c.config.time().Unix())
+	state, err := c.sessionState()
+	if err != nil {
+		return err
+	}
+	state.secret = hs.masterSecret
 	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,
-	}
-	stateBytes, err := state.marshal()
-	if err != nil {
-		return err
+		state.createdAt = hs.sessionState.createdAt
 	}
-	m.ticket, err = c.encryptTicket(stateBytes)
-	if err != nil {
-		return err
+	if c.config.WrapSession != nil {
+		m.ticket, err = c.config.WrapSession(c.connectionStateLocked(), state)
+		if err != nil {
+			return err
+		}
+	} else {
+		stateBytes, err := state.Bytes()
+		if err != nil {
+			return err
+		}
+		m.ticket, err = c.config.encryptTicket(stateBytes, c.ticketKeys)
+		if err != nil {
+			return err
+		}
 	}
 
 	if _, err := hs.c.writeHandshakeRecord(m, &hs.finishedHash); err != nil {
@@ -808,8 +874,7 @@ func (hs *serverHandshakeState) sendFinished(out []byte) error {
 }
 
 // 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.
+// Certificates message and verifies them.
 func (c *Conn) processCertsFromClient(certificate Certificate) error {
 	certificates := certificate.Certificate
 	certs := make([]*x509.Certificate, len(certificates))
@@ -819,10 +884,21 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error {
 			c.sendAlert(alertBadCertificate)
 			return errors.New("tls: failed to parse client certificate: " + err.Error())
 		}
+		if certs[i].PublicKeyAlgorithm == x509.RSA {
+			n := certs[i].PublicKey.(*rsa.PublicKey).N.BitLen()
+			if max, ok := checkKeySize(n); !ok {
+				c.sendAlert(alertBadCertificate)
+				return fmt.Errorf("tls: client sent certificate containing RSA key larger than %d bits", max)
+			}
+		}
 	}
 
 	if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) {
-		c.sendAlert(alertBadCertificate)
+		if c.vers == VersionTLS13 {
+			c.sendAlert(alertCertificateRequired)
+		} else {
+			c.sendAlert(alertBadCertificate)
+		}
 		return errors.New("tls: client didn't provide a certificate")
 	}
 
@@ -840,8 +916,15 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error {
 
 		chains, err := certs[0].Verify(opts)
 		if err != nil {
-			c.sendAlert(alertBadCertificate)
-			return errors.New("tls: failed to verify client certificate: " + err.Error())
+			var errCertificateInvalid x509.CertificateInvalidError
+			if errors.As(err, &x509.UnknownAuthorityError{}) {
+				c.sendAlert(alertUnknownCA)
+			} else if errors.As(err, &errCertificateInvalid) && errCertificateInvalid.Reason == x509.Expired {
+				c.sendAlert(alertCertificateExpired)
+			} else {
+				c.sendAlert(alertBadCertificate)
+			}
+			return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
 		}
 
 		c.verifiedChains = chains
@@ -853,7 +936,7 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error {
 
 	if len(certs) > 0 {
 		switch certs[0].PublicKey.(type) {
-		case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey:
+		case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey, circlSign.PublicKey: // [UTLS] ported from cloudflare/go
 		default:
 			c.sendAlert(alertUnsupportedCertificate)
 			return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey)
diff --git a/vendor/github.com/refraction-networking/utls/handshake_server_tls13.go b/vendor/github.com/refraction-networking/utls/handshake_server_tls13.go
index 0043e16b..f0e4b70a 100644
--- a/vendor/github.com/refraction-networking/utls/handshake_server_tls13.go
+++ b/vendor/github.com/refraction-networking/utls/handshake_server_tls13.go
@@ -12,9 +12,9 @@ import (
 	"crypto/rsa"
 	"encoding/binary"
 	"errors"
+	"fmt"
 	"hash"
 	"io"
-	"sync/atomic"
 	"time"
 )
 
@@ -30,9 +30,11 @@ type serverHandshakeStateTLS13 struct {
 	hello           *serverHelloMsg
 	sentDummyCCS    bool
 	usingPSK        bool
+	earlyData       bool
 	suite           *cipherSuiteTLS13
 	cert            *Certificate
 	sigAlg          SignatureScheme
+	selectedGroup   CurveID
 	earlySecret     []byte
 	sharedKey       []byte
 	handshakeSecret []byte
@@ -82,7 +84,7 @@ func (hs *serverHandshakeStateTLS13) handshake() error {
 		return err
 	}
 
-	atomic.StoreUint32(&c.handshakeStatus, 1)
+	c.isHandshakeComplete.Store(true)
 
 	return nil
 }
@@ -140,7 +142,12 @@ func (hs *serverHandshakeStateTLS13) processClientHello() error {
 		return errors.New("tls: initial handshake had non-empty renegotiation extension")
 	}
 
-	if hs.clientHello.earlyData {
+	if hs.clientHello.earlyData && c.quic != nil {
+		if len(hs.clientHello.pskIdentities) == 0 {
+			c.sendAlert(alertIllegalParameter)
+			return errors.New("tls: early_data without pre_shared_key")
+		}
+	} else if hs.clientHello.earlyData {
 		// See RFC 8446, Section 4.2.10 for the complicated behavior required
 		// here. The scenario is that a different server at our address offered
 		// to accept early data in the past, which we can't handle. For now, all
@@ -158,6 +165,9 @@ func (hs *serverHandshakeStateTLS13) processClientHello() error {
 	if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
 		preferenceList = defaultCipherSuitesTLS13NoAES
 	}
+	if needFIPS() {
+		preferenceList = defaultCipherSuitesTLS13FIPS
+	}
 	for _, suiteID := range preferenceList {
 		hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID)
 		if hs.suite != nil {
@@ -206,21 +216,65 @@ GroupSelection:
 		clientKeyShare = &hs.clientHello.keyShares[0]
 	}
 
-	if _, ok := curveForCurveID(selectedGroup); selectedGroup != X25519 && !ok {
+	// [uTLS SECTION BEGIN]
+	// ported from cloudflare/go
+	if _, ok := curveForCurveID(selectedGroup); selectedGroup != X25519 && curveIdToCirclScheme(selectedGroup) == nil && !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
+	if kem := curveIdToCirclScheme(selectedGroup); kem != nil {
+		ct, ss, alert, err := encapsulateForKem(kem, c.config.rand(), clientKeyShare.data)
+		if err != nil {
+			c.sendAlert(alert)
+			return fmt.Errorf("%s encap: %w", kem.Name(), err)
+		}
+		hs.hello.serverShare = keyShare{group: selectedGroup, data: ct}
+		hs.sharedKey = ss
+	} else {
+		key, err := generateECDHEKey(c.config.rand(), selectedGroup)
+		if err != nil {
+			c.sendAlert(alertInternalError)
+			return err
+		}
+		hs.hello.serverShare = keyShare{group: selectedGroup, data: key.PublicKey().Bytes()}
+		peerKey, err := key.Curve().NewPublicKey(clientKeyShare.data)
+		if err == nil {
+			hs.sharedKey, _ = key.ECDH(peerKey)
+		}
 	}
-	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")
 	}
+	// [uTLS SECTION END]
+
+	selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols, c.quic != nil)
+	if err != nil {
+		c.sendAlert(alertNoApplicationProtocol)
+		return err
+	}
+	c.clientProtocol = selectedProto
+
+	if c.quic != nil {
+		// RFC 9001 Section 4.2: Clients MUST NOT offer TLS versions older than 1.3.
+		for _, v := range hs.clientHello.supportedVersions {
+			if v < VersionTLS13 {
+				c.sendAlert(alertProtocolVersion)
+				return errors.New("tls: client offered TLS version older than TLS 1.3")
+			}
+		}
+		// RFC 9001 Section 8.2.
+		if hs.clientHello.quicTransportParameters == nil {
+			c.sendAlert(alertMissingExtension)
+			return errors.New("tls: client did not send a quic_transport_parameters extension")
+		}
+		c.quicSetTransportParameters(hs.clientHello.quicTransportParameters)
+	} else {
+		if hs.clientHello.quicTransportParameters != nil {
+			c.sendAlert(alertUnsupportedExtension)
+			return errors.New("tls: client sent an unexpected quic_transport_parameters extension")
+		}
+	}
 
 	c.serverName = hs.clientHello.serverName
 	return nil
@@ -257,12 +311,29 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
 			break
 		}
 
-		plaintext, _ := c.decryptTicket(identity.label)
-		if plaintext == nil {
-			continue
+		var sessionState *SessionState
+		if c.config.UnwrapSession != nil {
+			var err error
+			sessionState, err = c.config.UnwrapSession(identity.label, c.connectionStateLocked())
+			if err != nil {
+				return err
+			}
+			if sessionState == nil {
+				continue
+			}
+		} else {
+			plaintext := c.config.decryptTicket(identity.label, c.ticketKeys)
+			if plaintext == nil {
+				continue
+			}
+			var err error
+			sessionState, err = ParseSessionState(plaintext)
+			if err != nil {
+				continue
+			}
 		}
-		sessionState := new(sessionStateTLS13)
-		if ok := sessionState.unmarshal(plaintext); !ok {
+
+		if sessionState.version != VersionTLS13 {
 			continue
 		}
 
@@ -271,10 +342,6 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
 			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
@@ -283,7 +350,7 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
 		// 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
+		sessionHasClientCerts := len(sessionState.peerCertificates) != 0
 		needClientCerts := requiresClientCert(c.config.ClientAuth)
 		if needClientCerts && !sessionHasClientCerts {
 			continue
@@ -291,10 +358,15 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
 		if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
 			continue
 		}
+		if sessionHasClientCerts && c.config.time().After(sessionState.peerCertificates[0].NotAfter) {
+			continue
+		}
+		if sessionHasClientCerts && c.config.ClientAuth >= VerifyClientCertIfGiven &&
+			len(sessionState.verifiedChains) == 0 {
+			continue
+		}
 
-		psk := hs.suite.expandLabel(sessionState.resumptionSecret, "resumption",
-			nil, hs.suite.hash.Size())
-		hs.earlySecret = hs.suite.extract(psk, nil)
+		hs.earlySecret = hs.suite.extract(sessionState.secret, 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)
@@ -314,11 +386,25 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
 			return errors.New("tls: invalid PSK binder")
 		}
 
-		c.didResume = true
-		if err := c.processCertsFromClient(sessionState.certificate); err != nil {
-			return err
+		if c.quic != nil && hs.clientHello.earlyData && i == 0 &&
+			sessionState.EarlyData && sessionState.cipherSuite == hs.suite.id &&
+			sessionState.alpnProtocol == c.clientProtocol {
+			hs.earlyData = true
+
+			transcript := hs.suite.hash.New()
+			if err := transcriptMsg(hs.clientHello, transcript); err != nil {
+				return err
+			}
+			earlyTrafficSecret := hs.suite.deriveSecret(hs.earlySecret, clientEarlyTrafficLabel, transcript)
+			c.quicSetReadSecret(QUICEncryptionLevelEarly, hs.suite.id, earlyTrafficSecret)
 		}
 
+		c.didResume = true
+		c.peerCertificates = sessionState.peerCertificates
+		c.ocspResponse = sessionState.ocspResponse
+		c.scts = sessionState.scts
+		c.verifiedChains = sessionState.verifiedChains
+
 		hs.hello.selectedIdentityPresent = true
 		hs.hello.selectedIdentity = uint16(i)
 		hs.usingPSK = true
@@ -393,6 +479,9 @@ func (hs *serverHandshakeStateTLS13) pickCertificate() error {
 // 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.c.quic != nil {
+		return nil
+	}
 	if hs.sentDummyCCS {
 		return nil
 	}
@@ -544,10 +633,18 @@ func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
 
 	clientSecret := hs.suite.deriveSecret(hs.handshakeSecret,
 		clientHandshakeTrafficLabel, hs.transcript)
-	c.in.setTrafficSecret(hs.suite, clientSecret)
+	c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret)
 	serverSecret := hs.suite.deriveSecret(hs.handshakeSecret,
 		serverHandshakeTrafficLabel, hs.transcript)
-	c.out.setTrafficSecret(hs.suite, serverSecret)
+	c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret)
+
+	if c.quic != nil {
+		if c.hand.Len() != 0 {
+			c.sendAlert(alertUnexpectedMessage)
+		}
+		c.quicSetWriteSecret(QUICEncryptionLevelHandshake, hs.suite.id, serverSecret)
+		c.quicSetReadSecret(QUICEncryptionLevelHandshake, hs.suite.id, clientSecret)
+	}
 
 	err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret)
 	if err != nil {
@@ -561,14 +658,16 @@ func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
 	}
 
 	encryptedExtensions := new(encryptedExtensionsMsg)
+	encryptedExtensions.alpnProtocol = c.clientProtocol
 
-	selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
-	if err != nil {
-		c.sendAlert(alertNoApplicationProtocol)
-		return err
+	if c.quic != nil {
+		p, err := c.quicGetTransportParameters()
+		if err != nil {
+			return err
+		}
+		encryptedExtensions.quicTransportParameters = p
+		encryptedExtensions.earlyData = hs.earlyData
 	}
-	encryptedExtensions.alpnProtocol = selectedProto
-	c.clientProtocol = selectedProto
 
 	if _, err := hs.c.writeHandshakeRecord(encryptedExtensions, hs.transcript); err != nil {
 		return err
@@ -594,7 +693,7 @@ func (hs *serverHandshakeStateTLS13) sendServerCertificate() error {
 		certReq := new(certificateRequestMsgTLS13)
 		certReq.ocspStapling = true
 		certReq.scts = true
-		certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
+		certReq.supportedSignatureAlgorithms = c.config.supportedSignatureAlgorithms() // [UTLS] ported from cloudflare/go
 		if c.config.ClientCAs != nil {
 			certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
 		}
@@ -668,7 +767,15 @@ func (hs *serverHandshakeStateTLS13) sendServerFinished() error {
 		clientApplicationTrafficLabel, hs.transcript)
 	serverSecret := hs.suite.deriveSecret(hs.masterSecret,
 		serverApplicationTrafficLabel, hs.transcript)
-	c.out.setTrafficSecret(hs.suite, serverSecret)
+	c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret)
+
+	if c.quic != nil {
+		if c.hand.Len() != 0 {
+			// TODO: Handle this in setTrafficSecret?
+			c.sendAlert(alertUnexpectedMessage)
+		}
+		c.quicSetWriteSecret(QUICEncryptionLevelApplication, hs.suite.id, serverSecret)
+	}
 
 	err := c.config.writeKeyLog(keyLogLabelClientTraffic, hs.clientHello.random, hs.trafficSecret)
 	if err != nil {
@@ -700,6 +807,11 @@ func (hs *serverHandshakeStateTLS13) shouldSendSessionTickets() bool {
 		return false
 	}
 
+	// QUIC tickets are sent by QUICConn.SendSessionTicket, not automatically.
+	if hs.c.quic != nil {
+		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 {
@@ -720,37 +832,48 @@ func (hs *serverHandshakeStateTLS13) sendSessionTickets() error {
 		return err
 	}
 
+	c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
+		resumptionLabel, hs.transcript)
+
 	if !hs.shouldSendSessionTickets() {
 		return nil
 	}
+	return c.sendSessionTicket(false)
+}
 
-	resumptionSecret := hs.suite.deriveSecret(hs.masterSecret,
-		resumptionLabel, hs.transcript)
+func (c *Conn) sendSessionTicket(earlyData bool) error {
+	suite := cipherSuiteTLS13ByID(c.cipherSuite)
+	if suite == nil {
+		return errors.New("tls: internal error: unknown cipher suite")
+	}
+	// ticket_nonce, which must be unique per connection, is always left at
+	// zero because we only ever send one ticket per connection.
+	psk := suite.expandLabel(c.resumptionSecret, "resumption",
+		nil, suite.hash.Size())
 
 	m := new(newSessionTicketMsgTLS13)
 
-	var certsFromClient [][]byte
-	for _, cert := range c.peerCertificates {
-		certsFromClient = append(certsFromClient, cert.Raw)
-	}
-	state := sessionStateTLS13{
-		cipherSuite:      hs.suite.id,
-		createdAt:        uint64(c.config.time().Unix()),
-		resumptionSecret: resumptionSecret,
-		certificate: Certificate{
-			Certificate:                 certsFromClient,
-			OCSPStaple:                  c.ocspResponse,
-			SignedCertificateTimestamps: c.scts,
-		},
-	}
-	stateBytes, err := state.marshal()
+	state, err := c.sessionState()
 	if err != nil {
-		c.sendAlert(alertInternalError)
 		return err
 	}
-	m.label, err = c.encryptTicket(stateBytes)
-	if err != nil {
-		return err
+	state.secret = psk
+	state.EarlyData = earlyData
+	if c.config.WrapSession != nil {
+		m.label, err = c.config.WrapSession(c.connectionStateLocked(), state)
+		if err != nil {
+			return err
+		}
+	} else {
+		stateBytes, err := state.Bytes()
+		if err != nil {
+			c.sendAlert(alertInternalError)
+			return err
+		}
+		m.label, err = c.config.encryptTicket(stateBytes, c.ticketKeys)
+		if err != nil {
+			return err
+		}
 	}
 	m.lifetime = uint32(maxSessionTicketLifetime / time.Second)
 
@@ -758,14 +881,16 @@ func (hs *serverHandshakeStateTLS13) sendSessionTickets() error {
 	// 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 = hs.c.config.rand().Read(ageAdd)
+	_, err = c.config.rand().Read(ageAdd)
 	if err != nil {
 		return 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 earlyData {
+		// RFC 9001, Section 4.6.1
+		m.maxEarlyData = 0xffffffff
+	}
 
 	if _, err := c.writeHandshakeRecord(m, nil); err != nil {
 		return err
@@ -830,7 +955,7 @@ func (hs *serverHandshakeStateTLS13) readClientCertificate() error {
 		}
 
 		// See RFC 8446, Section 4.4.3.
-		if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) {
+		if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, c.config.supportedSignatureAlgorithms()) { // [UTLS] ported from cloudflare/go
 			c.sendAlert(alertIllegalParameter)
 			return errors.New("tls: client certificate used with invalid signature algorithm")
 		}
@@ -883,7 +1008,7 @@ func (hs *serverHandshakeStateTLS13) readClientFinished() error {
 		return errors.New("tls: invalid client finished hash")
 	}
 
-	c.in.setTrafficSecret(hs.suite, hs.trafficSecret)
+	c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret)
 
 	return nil
 }
diff --git a/vendor/github.com/refraction-networking/utls/internal/boring/notboring.go b/vendor/github.com/refraction-networking/utls/internal/boring/notboring.go
new file mode 100644
index 00000000..913afd5d
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/internal/boring/notboring.go
@@ -0,0 +1,20 @@
+package boring
+
+import (
+	"crypto/cipher"
+	"errors"
+)
+
+const Enabled bool = false
+
+func NewGCMTLS(_ cipher.Block) (cipher.AEAD, error) {
+	return nil, errors.New("boring not implemented")
+}
+
+func NewGCMTLS13(_ cipher.Block) (cipher.AEAD, error) {
+	return nil, errors.New("boring not implemented")
+}
+
+func Unreachable() {
+	// do nothing
+}
diff --git a/vendor/github.com/refraction-networking/utls/internal/quicvarint/protocol/protocol.go b/vendor/github.com/refraction-networking/utls/internal/quicvarint/protocol/protocol.go
new file mode 100644
index 00000000..3cbc3423
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/internal/quicvarint/protocol/protocol.go
@@ -0,0 +1,157 @@
+// Copyright 2024 The quic-go Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file of
+// the quic-go repository.
+
+package protocol
+
+import (
+	"fmt"
+	"time"
+)
+
+// The PacketType is the Long Header Type
+type PacketType uint8
+
+const (
+	// PacketTypeInitial is the packet type of an Initial packet
+	PacketTypeInitial PacketType = 1 + iota
+	// PacketTypeRetry is the packet type of a Retry packet
+	PacketTypeRetry
+	// PacketTypeHandshake is the packet type of a Handshake packet
+	PacketTypeHandshake
+	// PacketType0RTT is the packet type of a 0-RTT packet
+	PacketType0RTT
+)
+
+func (t PacketType) String() string {
+	switch t {
+	case PacketTypeInitial:
+		return "Initial"
+	case PacketTypeRetry:
+		return "Retry"
+	case PacketTypeHandshake:
+		return "Handshake"
+	case PacketType0RTT:
+		return "0-RTT Protected"
+	default:
+		return fmt.Sprintf("unknown packet type: %d", t)
+	}
+}
+
+type ECN uint8
+
+const (
+	ECNUnsupported ECN = iota
+	ECNNon             // 00
+	ECT1               // 01
+	ECT0               // 10
+	ECNCE              // 11
+)
+
+func ParseECNHeaderBits(bits byte) ECN {
+	switch bits {
+	case 0:
+		return ECNNon
+	case 0b00000010:
+		return ECT0
+	case 0b00000001:
+		return ECT1
+	case 0b00000011:
+		return ECNCE
+	default:
+		panic("invalid ECN bits")
+	}
+}
+
+func (e ECN) ToHeaderBits() byte {
+	//nolint:exhaustive // There are only 4 values.
+	switch e {
+	case ECNNon:
+		return 0
+	case ECT0:
+		return 0b00000010
+	case ECT1:
+		return 0b00000001
+	case ECNCE:
+		return 0b00000011
+	default:
+		panic("ECN unsupported")
+	}
+}
+
+func (e ECN) String() string {
+	switch e {
+	case ECNUnsupported:
+		return "ECN unsupported"
+	case ECNNon:
+		return "Not-ECT"
+	case ECT1:
+		return "ECT(1)"
+	case ECT0:
+		return "ECT(0)"
+	case ECNCE:
+		return "CE"
+	default:
+		return fmt.Sprintf("invalid ECN value: %d", e)
+	}
+}
+
+// A ByteCount in QUIC
+type ByteCount int64
+
+// MaxByteCount is the maximum value of a ByteCount
+const MaxByteCount = ByteCount(1<<62 - 1)
+
+// InvalidByteCount is an invalid byte count
+const InvalidByteCount ByteCount = -1
+
+// A StatelessResetToken is a stateless reset token.
+type StatelessResetToken [16]byte
+
+// MaxPacketBufferSize maximum packet size of any QUIC packet, based on
+// ethernet's max size, minus the IP and UDP headers. IPv6 has a 40 byte header,
+// UDP adds an additional 8 bytes.  This is a total overhead of 48 bytes.
+// Ethernet's max packet size is 1500 bytes,  1500 - 48 = 1452.
+const MaxPacketBufferSize = 1452
+
+// MaxLargePacketBufferSize is used when using GSO
+const MaxLargePacketBufferSize = 20 * 1024
+
+// MinInitialPacketSize is the minimum size an Initial packet is required to have.
+const MinInitialPacketSize = 1200
+
+// MinUnknownVersionPacketSize is the minimum size a packet with an unknown version
+// needs to have in order to trigger a Version Negotiation packet.
+const MinUnknownVersionPacketSize = MinInitialPacketSize
+
+// MinStatelessResetSize is the minimum size of a stateless reset packet that we send
+const MinStatelessResetSize = 1 /* first byte */ + 20 /* max. conn ID length */ + 4 /* max. packet number length */ + 1 /* min. payload length */ + 16 /* token */
+
+// MinConnectionIDLenInitial is the minimum length of the destination connection ID on an Initial packet.
+const MinConnectionIDLenInitial = 8
+
+// DefaultAckDelayExponent is the default ack delay exponent
+const DefaultAckDelayExponent = 3
+
+// DefaultActiveConnectionIDLimit is the default active connection ID limit
+const DefaultActiveConnectionIDLimit = 2
+
+// MaxAckDelayExponent is the maximum ack delay exponent
+const MaxAckDelayExponent = 20
+
+// DefaultMaxAckDelay is the default max_ack_delay
+const DefaultMaxAckDelay = 25 * time.Millisecond
+
+// MaxMaxAckDelay is the maximum max_ack_delay
+const MaxMaxAckDelay = (1<<14 - 1) * time.Millisecond
+
+// MaxConnIDLen is the maximum length of the connection ID
+const MaxConnIDLen = 20
+
+// InvalidPacketLimitAES is the maximum number of packets that we can fail to decrypt when using
+// AEAD_AES_128_GCM or AEAD_AES_265_GCM.
+const InvalidPacketLimitAES = 1 << 52
+
+// InvalidPacketLimitChaCha is the maximum number of packets that we can fail to decrypt when using AEAD_CHACHA20_POLY1305.
+const InvalidPacketLimitChaCha = 1 << 36
diff --git a/vendor/github.com/refraction-networking/utls/internal/quicvarint/varint.go b/vendor/github.com/refraction-networking/utls/internal/quicvarint/varint.go
new file mode 100644
index 00000000..e4a1063d
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/internal/quicvarint/varint.go
@@ -0,0 +1,146 @@
+// Copyright 2024 The quic-go Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file of
+// the quic-go repository.
+
+package quicvarint
+
+import (
+	"fmt"
+	"io"
+
+	"github.com/refraction-networking/utls/internal/quicvarint/protocol"
+)
+
+// taken from the QUIC draft
+const (
+	// Min is the minimum value allowed for a QUIC varint.
+	Min = 0
+
+	// Max is the maximum allowed value for a QUIC varint (2^62-1).
+	Max = maxVarInt8
+
+	maxVarInt1 = 63
+	maxVarInt2 = 16383
+	maxVarInt4 = 1073741823
+	maxVarInt8 = 4611686018427387903
+)
+
+// Read reads a number in the QUIC varint format from r.
+func Read(r io.ByteReader) (uint64, error) {
+	firstByte, err := r.ReadByte()
+	if err != nil {
+		return 0, err
+	}
+	// the first two bits of the first byte encode the length
+	len := 1 << ((firstByte & 0xc0) >> 6)
+	b1 := firstByte & (0xff - 0xc0)
+	if len == 1 {
+		return uint64(b1), nil
+	}
+	b2, err := r.ReadByte()
+	if err != nil {
+		return 0, err
+	}
+	if len == 2 {
+		return uint64(b2) + uint64(b1)<<8, nil
+	}
+	b3, err := r.ReadByte()
+	if err != nil {
+		return 0, err
+	}
+	b4, err := r.ReadByte()
+	if err != nil {
+		return 0, err
+	}
+	if len == 4 {
+		return uint64(b4) + uint64(b3)<<8 + uint64(b2)<<16 + uint64(b1)<<24, nil
+	}
+	b5, err := r.ReadByte()
+	if err != nil {
+		return 0, err
+	}
+	b6, err := r.ReadByte()
+	if err != nil {
+		return 0, err
+	}
+	b7, err := r.ReadByte()
+	if err != nil {
+		return 0, err
+	}
+	b8, err := r.ReadByte()
+	if err != nil {
+		return 0, err
+	}
+	return uint64(b8) + uint64(b7)<<8 + uint64(b6)<<16 + uint64(b5)<<24 + uint64(b4)<<32 + uint64(b3)<<40 + uint64(b2)<<48 + uint64(b1)<<56, nil
+}
+
+// Append appends i in the QUIC varint format.
+func Append(b []byte, i uint64) []byte {
+	if i <= maxVarInt1 {
+		return append(b, uint8(i))
+	}
+	if i <= maxVarInt2 {
+		return append(b, []byte{uint8(i>>8) | 0x40, uint8(i)}...)
+	}
+	if i <= maxVarInt4 {
+		return append(b, []byte{uint8(i>>24) | 0x80, uint8(i >> 16), uint8(i >> 8), uint8(i)}...)
+	}
+	if i <= maxVarInt8 {
+		return append(b, []byte{
+			uint8(i>>56) | 0xc0, uint8(i >> 48), uint8(i >> 40), uint8(i >> 32),
+			uint8(i >> 24), uint8(i >> 16), uint8(i >> 8), uint8(i),
+		}...)
+	}
+	panic(fmt.Sprintf("%#x doesn't fit into 62 bits", i))
+}
+
+// AppendWithLen append i in the QUIC varint format with the desired length.
+func AppendWithLen(b []byte, i uint64, length protocol.ByteCount) []byte {
+	if length != 1 && length != 2 && length != 4 && length != 8 {
+		panic("invalid varint length")
+	}
+	l := Len(i)
+	if l == length {
+		return Append(b, i)
+	}
+	if l > length {
+		panic(fmt.Sprintf("cannot encode %d in %d bytes", i, length))
+	}
+	if length == 2 {
+		b = append(b, 0b01000000)
+	} else if length == 4 {
+		b = append(b, 0b10000000)
+	} else if length == 8 {
+		b = append(b, 0b11000000)
+	}
+	for j := protocol.ByteCount(1); j < length-l; j++ {
+		b = append(b, 0)
+	}
+	for j := protocol.ByteCount(0); j < l; j++ {
+		b = append(b, uint8(i>>(8*(l-1-j))))
+	}
+	return b
+}
+
+// Len determines the number of bytes that will be needed to write the number i.
+func Len(i uint64) protocol.ByteCount {
+	if i <= maxVarInt1 {
+		return 1
+	}
+	if i <= maxVarInt2 {
+		return 2
+	}
+	if i <= maxVarInt4 {
+		return 4
+	}
+	if i <= maxVarInt8 {
+		return 8
+	}
+	// Don't use a fmt.Sprintf here to format the error message.
+	// The function would then exceed the inlining budget.
+	panic(struct {
+		message string
+		num     uint64
+	}{"value doesn't fit into 62 bits: ", i})
+}
diff --git a/vendor/github.com/refraction-networking/utls/key_agreement.go b/vendor/github.com/refraction-networking/utls/key_agreement.go
index c28a64f3..ab103880 100644
--- a/vendor/github.com/refraction-networking/utls/key_agreement.go
+++ b/vendor/github.com/refraction-networking/utls/key_agreement.go
@@ -6,6 +6,7 @@ package tls
 
 import (
 	"crypto"
+	"crypto/ecdh"
 	"crypto/md5"
 	"crypto/rsa"
 	"crypto/sha1"
@@ -129,7 +130,7 @@ func md5SHA1Hash(slices [][]byte) []byte {
 // 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 {
+	if sigType == signatureEd25519 || circlSchemeBySigType(sigType) != nil { // [UTLS] ported from cloudflare/go
 		var signed []byte
 		for _, slice := range slices {
 			signed = append(signed, slice...)
@@ -157,7 +158,7 @@ func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint1
 type ecdheKeyAgreement struct {
 	version uint16
 	isRSA   bool
-	params  ecdheParameters
+	key     *ecdh.PrivateKey
 
 	// ckx and preMasterSecret are generated in processServerKeyExchange
 	// and returned in generateClientKeyExchange.
@@ -168,7 +169,7 @@ type ecdheKeyAgreement struct {
 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) {
+		if config.supportsCurve(c) && curveIdToCirclScheme(c) == nil { // [uTLS] ported from cloudflare/go
 			curveID = c
 			break
 		}
@@ -177,18 +178,18 @@ func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Cer
 	if curveID == 0 {
 		return nil, errors.New("tls: no supported elliptic curves offered")
 	}
-	if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
+	if _, ok := curveForCurveID(curveID); !ok {
 		return nil, errors.New("tls: CurvePreferences includes unsupported curve")
 	}
 
-	params, err := generateECDHEParameters(config.rand(), curveID)
+	key, err := generateECDHEKey(config.rand(), curveID)
 	if err != nil {
 		return nil, err
 	}
-	ka.params = params
+	ka.key = key
 
 	// See RFC 4492, Section 5.4.
-	ecdhePublic := params.PublicKey()
+	ecdhePublic := key.PublicKey().Bytes()
 	serverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic))
 	serverECDHEParams[0] = 3 // named curve
 	serverECDHEParams[1] = byte(curveID >> 8)
@@ -259,8 +260,12 @@ func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Cert
 		return nil, errClientKeyExchange
 	}
 
-	preMasterSecret := ka.params.SharedKey(ckx.ciphertext[1:])
-	if preMasterSecret == nil {
+	peerKey, err := ka.key.Curve().NewPublicKey(ckx.ciphertext[1:])
+	if err != nil {
+		return nil, errClientKeyExchange
+	}
+	preMasterSecret, err := ka.key.ECDH(peerKey)
+	if err != nil {
 		return nil, errClientKeyExchange
 	}
 
@@ -288,22 +293,26 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell
 		return errServerKeyExchange
 	}
 
-	if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
+	if _, ok := curveForCurveID(curveID); !ok {
 		return errors.New("tls: server selected unsupported curve")
 	}
 
-	params, err := generateECDHEParameters(config.rand(), curveID)
+	key, err := generateECDHEKey(config.rand(), curveID)
 	if err != nil {
 		return err
 	}
-	ka.params = params
+	ka.key = key
 
-	ka.preMasterSecret = params.SharedKey(publicKey)
-	if ka.preMasterSecret == nil {
+	peerKey, err := key.Curve().NewPublicKey(publicKey)
+	if err != nil {
+		return errServerKeyExchange
+	}
+	ka.preMasterSecret, err = key.ECDH(peerKey)
+	if err != nil {
 		return errServerKeyExchange
 	}
 
-	ourPublicKey := params.PublicKey()
+	ourPublicKey := key.PublicKey().Bytes()
 	ka.ckx = new(clientKeyExchangeMsg)
 	ka.ckx.ciphertext = make([]byte, 1+len(ourPublicKey))
 	ka.ckx.ciphertext[0] = byte(len(ourPublicKey))
diff --git a/vendor/github.com/refraction-networking/utls/key_schedule.go b/vendor/github.com/refraction-networking/utls/key_schedule.go
index 185137ba..d7f082c9 100644
--- a/vendor/github.com/refraction-networking/utls/key_schedule.go
+++ b/vendor/github.com/refraction-networking/utls/key_schedule.go
@@ -5,16 +5,14 @@
 package tls
 
 import (
-	"crypto/elliptic"
+	"crypto/ecdh"
 	"crypto/hmac"
 	"errors"
 	"fmt"
 	"hash"
 	"io"
-	"math/big"
 
 	"golang.org/x/crypto/cryptobyte"
-	"golang.org/x/crypto/curve25519"
 	"golang.org/x/crypto/hkdf"
 )
 
@@ -23,6 +21,7 @@ import (
 
 const (
 	resumptionBinderLabel         = "res binder"
+	clientEarlyTrafficLabel       = "c e traffic"
 	clientHandshakeTrafficLabel   = "c hs traffic"
 	serverHandshakeTrafficLabel   = "s hs traffic"
 	clientApplicationTrafficLabel = "c ap traffic"
@@ -118,99 +117,43 @@ func (c *cipherSuiteTLS13) exportKeyingMaterial(masterSecret []byte, transcript
 	}
 }
 
-// ecdheParameters implements Diffie-Hellman with either NIST curves or X25519,
+// generateECDHEKey returns a PrivateKey that implements Diffie-Hellman
 // 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
-	}
-
+func generateECDHEKey(rand io.Reader, curveID CurveID) (*ecdh.PrivateKey, error) {
 	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
+	return curve.GenerateKey(rand)
 }
 
-func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
+func curveForCurveID(id CurveID) (ecdh.Curve, bool) {
 	switch id {
+	case X25519:
+		return ecdh.X25519(), true
 	case CurveP256:
-		return elliptic.P256(), true
+		return ecdh.P256(), true
 	case CurveP384:
-		return elliptic.P384(), true
+		return ecdh.P384(), true
 	case CurveP521:
-		return elliptic.P521(), true
+		return ecdh.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
+func curveIDForCurve(curve ecdh.Curve) (CurveID, bool) {
+	switch curve {
+	case ecdh.X25519():
+		return X25519, true
+	case ecdh.P256():
+		return CurveP256, true
+	case ecdh.P384():
+		return CurveP384, true
+	case ecdh.P521():
+		return CurveP521, true
+	default:
+		return 0, false
 	}
-	return sharedKey
 }
diff --git a/vendor/github.com/refraction-networking/utls/notboring.go b/vendor/github.com/refraction-networking/utls/notboring.go
index 43840696..82dd5977 100644
--- a/vendor/github.com/refraction-networking/utls/notboring.go
+++ b/vendor/github.com/refraction-networking/utls/notboring.go
@@ -3,11 +3,6 @@
 // license that can be found in the LICENSE file.
 package tls
 
-import (
-	"crypto/cipher"
-	"errors"
-)
-
 func needFIPS() bool { return false }
 
 func supportedSignatureAlgorithms() []SignatureScheme {
@@ -21,19 +16,4 @@ func fipsCipherSuites(c *Config) []uint16      { panic("fipsCipherSuites") }
 
 var fipsSupportedSignatureAlgorithms []SignatureScheme
 
-// [uTLS]
-// Boring struct is only to be used to record static env variables
-// in boring package. We do not implement BoringSSL compatibliity here.
-type Boring struct {
-	Enabled bool
-}
-
-func (*Boring) NewGCMTLS(_ cipher.Block) (cipher.AEAD, error) {
-	return nil, errors.New("boring not implemented")
-}
-
-func (*Boring) Unreachable() {
-	// do nothing
-}
-
-var boring Boring
+var defaultCipherSuitesTLS13FIPS []uint16
diff --git a/vendor/github.com/refraction-networking/utls/prf.go b/vendor/github.com/refraction-networking/utls/prf.go
index 13bfa009..c525facd 100644
--- a/vendor/github.com/refraction-networking/utls/prf.go
+++ b/vendor/github.com/refraction-networking/utls/prf.go
@@ -80,6 +80,7 @@ const (
 )
 
 var masterSecretLabel = []byte("master secret")
+var extendedMasterSecretLabel = []byte("extended master secret")
 var keyExpansionLabel = []byte("key expansion")
 var clientFinishedLabel = []byte("client finished")
 var serverFinishedLabel = []byte("server finished")
@@ -115,6 +116,14 @@ func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecr
 	return masterSecret
 }
 
+// extMasterFromPreMasterSecret generates the extended master secret from the
+// pre-master secret. See RFC 7627.
+func extMasterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, transcript []byte) []byte {
+	masterSecret := make([]byte, masterSecretLength)
+	prfForVersion(version, suite)(masterSecret, preMasterSecret, extendedMasterSecretLabel, transcript)
+	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.
@@ -215,12 +224,12 @@ func (h finishedHash) serverSum(masterSecret []byte) []byte {
 
 // 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 {
+func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash) []byte {
+	if (h.version >= VersionTLS12 || sigType == signatureEd25519 || circlSchemeBySigType(sigType) != nil) && h.buffer == nil { // [UTLS] ported from cloudflare/go
 		panic("tls: handshake hash for a client certificate requested after discarding the handshake buffer")
 	}
 
-	if sigType == signatureEd25519 {
+	if sigType == signatureEd25519 || circlSchemeBySigType(sigType) != nil { // [UTLS] ported from cloudflare/go
 		return h.buffer
 	}
 
@@ -243,13 +252,20 @@ func (h *finishedHash) discardHandshakeBuffer() {
 	h.buffer = nil
 }
 
-// noExportedKeyingMaterial is used as a value of
+// noEKMBecauseRenegotiation 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) {
+func noEKMBecauseRenegotiation(label string, context []byte, length int) ([]byte, error) {
 	return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled")
 }
 
+// noEKMBecauseNoEMS is used as a value of ConnectionState.ekm when Extended
+// Master Secret is not negotiated and thus we wish to fail all key-material
+// export requests.
+func noEKMBecauseNoEMS(label string, context []byte, length int) ([]byte, error) {
+	return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when neither TLS 1.3 nor Extended Master Secret are negotiated; override with GODEBUG=tlsunsafeekm=1")
+}
+
 // 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) {
diff --git a/vendor/github.com/refraction-networking/utls/quic.go b/vendor/github.com/refraction-networking/utls/quic.go
new file mode 100644
index 00000000..3518169b
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/quic.go
@@ -0,0 +1,421 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"context"
+	"errors"
+	"fmt"
+)
+
+// QUICEncryptionLevel represents a QUIC encryption level used to transmit
+// handshake messages.
+type QUICEncryptionLevel int
+
+const (
+	QUICEncryptionLevelInitial = QUICEncryptionLevel(iota)
+	QUICEncryptionLevelEarly
+	QUICEncryptionLevelHandshake
+	QUICEncryptionLevelApplication
+)
+
+func (l QUICEncryptionLevel) String() string {
+	switch l {
+	case QUICEncryptionLevelInitial:
+		return "Initial"
+	case QUICEncryptionLevelEarly:
+		return "Early"
+	case QUICEncryptionLevelHandshake:
+		return "Handshake"
+	case QUICEncryptionLevelApplication:
+		return "Application"
+	default:
+		return fmt.Sprintf("QUICEncryptionLevel(%v)", int(l))
+	}
+}
+
+// A QUICConn represents a connection which uses a QUIC implementation as the underlying
+// transport as described in RFC 9001.
+//
+// Methods of QUICConn are not safe for concurrent use.
+type QUICConn struct {
+	conn *Conn
+
+	sessionTicketSent bool
+}
+
+// A QUICConfig configures a [QUICConn].
+type QUICConfig struct {
+	TLSConfig *Config
+}
+
+// A QUICEventKind is a type of operation on a QUIC connection.
+type QUICEventKind int
+
+const (
+	// QUICNoEvent indicates that there are no events available.
+	QUICNoEvent QUICEventKind = iota
+
+	// QUICSetReadSecret and QUICSetWriteSecret provide the read and write
+	// secrets for a given encryption level.
+	// QUICEvent.Level, QUICEvent.Data, and QUICEvent.Suite are set.
+	//
+	// Secrets for the Initial encryption level are derived from the initial
+	// destination connection ID, and are not provided by the QUICConn.
+	QUICSetReadSecret
+	QUICSetWriteSecret
+
+	// QUICWriteData provides data to send to the peer in CRYPTO frames.
+	// QUICEvent.Data is set.
+	QUICWriteData
+
+	// QUICTransportParameters provides the peer's QUIC transport parameters.
+	// QUICEvent.Data is set.
+	QUICTransportParameters
+
+	// QUICTransportParametersRequired indicates that the caller must provide
+	// QUIC transport parameters to send to the peer. The caller should set
+	// the transport parameters with QUICConn.SetTransportParameters and call
+	// QUICConn.NextEvent again.
+	//
+	// If transport parameters are set before calling QUICConn.Start, the
+	// connection will never generate a QUICTransportParametersRequired event.
+	QUICTransportParametersRequired
+
+	// QUICRejectedEarlyData indicates that the server rejected 0-RTT data even
+	// if we offered it. It's returned before QUICEncryptionLevelApplication
+	// keys are returned.
+	QUICRejectedEarlyData
+
+	// QUICHandshakeDone indicates that the TLS handshake has completed.
+	QUICHandshakeDone
+)
+
+// A QUICEvent is an event occurring on a QUIC connection.
+//
+// The type of event is specified by the Kind field.
+// The contents of the other fields are kind-specific.
+type QUICEvent struct {
+	Kind QUICEventKind
+
+	// Set for QUICSetReadSecret, QUICSetWriteSecret, and QUICWriteData.
+	Level QUICEncryptionLevel
+
+	// Set for QUICTransportParameters, QUICSetReadSecret, QUICSetWriteSecret, and QUICWriteData.
+	// The contents are owned by crypto/tls, and are valid until the next NextEvent call.
+	Data []byte
+
+	// Set for QUICSetReadSecret and QUICSetWriteSecret.
+	Suite uint16
+}
+
+type quicState struct {
+	events    []QUICEvent
+	nextEvent int
+
+	// eventArr is a statically allocated event array, large enough to handle
+	// the usual maximum number of events resulting from a single call: transport
+	// parameters, Initial data, Early read secret, Handshake write and read
+	// secrets, Handshake data, Application write secret, Application data.
+	eventArr [8]QUICEvent
+
+	started  bool
+	signalc  chan struct{}   // handshake data is available to be read
+	blockedc chan struct{}   // handshake is waiting for data, closed when done
+	cancelc  <-chan struct{} // handshake has been canceled
+	cancel   context.CancelFunc
+
+	// readbuf is shared between HandleData and the handshake goroutine.
+	// HandshakeCryptoData passes ownership to the handshake goroutine by
+	// reading from signalc, and reclaims ownership by reading from blockedc.
+	readbuf []byte
+
+	transportParams []byte // to send to the peer
+}
+
+// QUICClient returns a new TLS client side connection using QUICTransport as the
+// underlying transport. The config cannot be nil.
+//
+// The config's MinVersion must be at least TLS 1.3.
+func QUICClient(config *QUICConfig) *QUICConn {
+	return newQUICConn(Client(nil, config.TLSConfig))
+}
+
+// QUICServer returns a new TLS server side connection using QUICTransport as the
+// underlying transport. The config cannot be nil.
+//
+// The config's MinVersion must be at least TLS 1.3.
+func QUICServer(config *QUICConfig) *QUICConn {
+	return newQUICConn(Server(nil, config.TLSConfig))
+}
+
+func newQUICConn(conn *Conn) *QUICConn {
+	conn.quic = &quicState{
+		signalc:  make(chan struct{}),
+		blockedc: make(chan struct{}),
+	}
+	conn.quic.events = conn.quic.eventArr[:0]
+	return &QUICConn{
+		conn: conn,
+	}
+}
+
+// Start starts the client or server handshake protocol.
+// It may produce connection events, which may be read with [QUICConn.NextEvent].
+//
+// Start must be called at most once.
+func (q *QUICConn) Start(ctx context.Context) error {
+	if q.conn.quic.started {
+		return quicError(errors.New("tls: Start called more than once"))
+	}
+	q.conn.quic.started = true
+	if q.conn.config.MinVersion < VersionTLS13 {
+		return quicError(errors.New("tls: Config MinVersion must be at least TLS 1.13"))
+	}
+	go q.conn.HandshakeContext(ctx)
+	if _, ok := <-q.conn.quic.blockedc; !ok {
+		return q.conn.handshakeErr
+	}
+	return nil
+}
+
+// NextEvent returns the next event occurring on the connection.
+// It returns an event with a Kind of [QUICNoEvent] when no events are available.
+func (q *QUICConn) NextEvent() QUICEvent {
+	qs := q.conn.quic
+	if last := qs.nextEvent - 1; last >= 0 && len(qs.events[last].Data) > 0 {
+		// Write over some of the previous event's data,
+		// to catch callers erroniously retaining it.
+		qs.events[last].Data[0] = 0
+	}
+	if qs.nextEvent >= len(qs.events) {
+		qs.events = qs.events[:0]
+		qs.nextEvent = 0
+		return QUICEvent{Kind: QUICNoEvent}
+	}
+	e := qs.events[qs.nextEvent]
+	qs.events[qs.nextEvent] = QUICEvent{} // zero out references to data
+	qs.nextEvent++
+	return e
+}
+
+// Close closes the connection and stops any in-progress handshake.
+func (q *QUICConn) Close() error {
+	if q.conn.quic.cancel == nil {
+		return nil // never started
+	}
+	q.conn.quic.cancel()
+	for range q.conn.quic.blockedc {
+		// Wait for the handshake goroutine to return.
+	}
+	return q.conn.handshakeErr
+}
+
+// HandleData handles handshake bytes received from the peer.
+// It may produce connection events, which may be read with [QUICConn.NextEvent].
+func (q *QUICConn) HandleData(level QUICEncryptionLevel, data []byte) error {
+	c := q.conn
+	if c.in.level != level {
+		return quicError(c.in.setErrorLocked(errors.New("tls: handshake data received at wrong level")))
+	}
+	c.quic.readbuf = data
+	<-c.quic.signalc
+	_, ok := <-c.quic.blockedc
+	if ok {
+		// The handshake goroutine is waiting for more data.
+		return nil
+	}
+	// The handshake goroutine has exited.
+	c.handshakeMutex.Lock()
+	defer c.handshakeMutex.Unlock()
+	c.hand.Write(c.quic.readbuf)
+	c.quic.readbuf = nil
+	for q.conn.hand.Len() >= 4 && q.conn.handshakeErr == nil {
+		b := q.conn.hand.Bytes()
+		n := int(b[1])<<16 | int(b[2])<<8 | int(b[3])
+		if n > maxHandshake {
+			q.conn.handshakeErr = fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake)
+			break
+		}
+		if len(b) < 4+n {
+			return nil
+		}
+		if err := q.conn.handlePostHandshakeMessage(); err != nil {
+			q.conn.handshakeErr = err
+		}
+	}
+	if q.conn.handshakeErr != nil {
+		return quicError(q.conn.handshakeErr)
+	}
+	return nil
+}
+
+type QUICSessionTicketOptions struct {
+	// EarlyData specifies whether the ticket may be used for 0-RTT.
+	EarlyData bool
+}
+
+// SendSessionTicket sends a session ticket to the client.
+// It produces connection events, which may be read with [QUICConn.NextEvent].
+// Currently, it can only be called once.
+func (q *QUICConn) SendSessionTicket(opts QUICSessionTicketOptions) error {
+	c := q.conn
+	if !c.isHandshakeComplete.Load() {
+		return quicError(errors.New("tls: SendSessionTicket called before handshake completed"))
+	}
+	if c.isClient {
+		return quicError(errors.New("tls: SendSessionTicket called on the client"))
+	}
+	if q.sessionTicketSent {
+		return quicError(errors.New("tls: SendSessionTicket called multiple times"))
+	}
+	q.sessionTicketSent = true
+	return quicError(c.sendSessionTicket(opts.EarlyData))
+}
+
+// ConnectionState returns basic TLS details about the connection.
+func (q *QUICConn) ConnectionState() ConnectionState {
+	return q.conn.ConnectionState()
+}
+
+// SetTransportParameters sets the transport parameters to send to the peer.
+//
+// Server connections may delay setting the transport parameters until after
+// receiving the client's transport parameters. See [QUICTransportParametersRequired].
+func (q *QUICConn) SetTransportParameters(params []byte) {
+	if params == nil {
+		params = []byte{}
+	}
+	q.conn.quic.transportParams = params
+	if q.conn.quic.started {
+		<-q.conn.quic.signalc
+		<-q.conn.quic.blockedc
+	}
+}
+
+// quicError ensures err is an AlertError.
+// If err is not already, quicError wraps it with alertInternalError.
+func quicError(err error) error {
+	if err == nil {
+		return nil
+	}
+	var ae AlertError
+	if errors.As(err, &ae) {
+		return err
+	}
+	var a alert
+	if !errors.As(err, &a) {
+		a = alertInternalError
+	}
+	// Return an error wrapping the original error and an AlertError.
+	// Truncate the text of the alert to 0 characters.
+	return fmt.Errorf("%w%.0w", err, AlertError(a))
+}
+
+func (c *Conn) quicReadHandshakeBytes(n int) error {
+	for c.hand.Len() < n {
+		if err := c.quicWaitForSignal(); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (c *Conn) quicSetReadSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
+	c.quic.events = append(c.quic.events, QUICEvent{
+		Kind:  QUICSetReadSecret,
+		Level: level,
+		Suite: suite,
+		Data:  secret,
+	})
+}
+
+func (c *Conn) quicSetWriteSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
+	c.quic.events = append(c.quic.events, QUICEvent{
+		Kind:  QUICSetWriteSecret,
+		Level: level,
+		Suite: suite,
+		Data:  secret,
+	})
+}
+
+func (c *Conn) quicWriteCryptoData(level QUICEncryptionLevel, data []byte) {
+	var last *QUICEvent
+	if len(c.quic.events) > 0 {
+		last = &c.quic.events[len(c.quic.events)-1]
+	}
+	if last == nil || last.Kind != QUICWriteData || last.Level != level {
+		c.quic.events = append(c.quic.events, QUICEvent{
+			Kind:  QUICWriteData,
+			Level: level,
+		})
+		last = &c.quic.events[len(c.quic.events)-1]
+	}
+	last.Data = append(last.Data, data...)
+}
+
+func (c *Conn) quicSetTransportParameters(params []byte) {
+	c.quic.events = append(c.quic.events, QUICEvent{
+		Kind: QUICTransportParameters,
+		Data: params,
+	})
+}
+
+func (c *Conn) quicGetTransportParameters() ([]byte, error) {
+	if c.quic.transportParams == nil {
+		c.quic.events = append(c.quic.events, QUICEvent{
+			Kind: QUICTransportParametersRequired,
+		})
+	}
+	for c.quic.transportParams == nil {
+		if err := c.quicWaitForSignal(); err != nil {
+			return nil, err
+		}
+	}
+	return c.quic.transportParams, nil
+}
+
+func (c *Conn) quicHandshakeComplete() {
+	c.quic.events = append(c.quic.events, QUICEvent{
+		Kind: QUICHandshakeDone,
+	})
+}
+
+func (c *Conn) quicRejectedEarlyData() {
+	c.quic.events = append(c.quic.events, QUICEvent{
+		Kind: QUICRejectedEarlyData,
+	})
+}
+
+// quicWaitForSignal notifies the QUICConn that handshake progress is blocked,
+// and waits for a signal that the handshake should proceed.
+//
+// The handshake may become blocked waiting for handshake bytes
+// or for the user to provide transport parameters.
+func (c *Conn) quicWaitForSignal() error {
+	// Drop the handshake mutex while blocked to allow the user
+	// to call ConnectionState before the handshake completes.
+	c.handshakeMutex.Unlock()
+	defer c.handshakeMutex.Lock()
+	// Send on blockedc to notify the QUICConn that the handshake is blocked.
+	// Exported methods of QUICConn wait for the handshake to become blocked
+	// before returning to the user.
+	select {
+	case c.quic.blockedc <- struct{}{}:
+	case <-c.quic.cancelc:
+		return c.sendAlertLocked(alertCloseNotify)
+	}
+	// The QUICConn reads from signalc to notify us that the handshake may
+	// be able to proceed. (The QUICConn reads, because we close signalc to
+	// indicate that the handshake has completed.)
+	select {
+	case c.quic.signalc <- struct{}{}:
+		c.hand.Write(c.quic.readbuf)
+		c.quic.readbuf = nil
+	case <-c.quic.cancelc:
+		return c.sendAlertLocked(alertCloseNotify)
+	}
+	return nil
+}
diff --git a/vendor/github.com/refraction-networking/utls/ticket.go b/vendor/github.com/refraction-networking/utls/ticket.go
index c861e92c..182411e7 100644
--- a/vendor/github.com/refraction-networking/utls/ticket.go
+++ b/vendor/github.com/refraction-networking/utls/ticket.go
@@ -5,198 +5,433 @@
 package tls
 
 import (
-	"bytes"
 	"crypto/aes"
 	"crypto/cipher"
 	"crypto/hmac"
 	"crypto/sha256"
 	"crypto/subtle"
+	"crypto/x509"
 	"errors"
 	"io"
 
 	"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
+// A SessionState is a resumable session.
+type SessionState struct {
+	// Encoded as a SessionState (in the language of RFC 8446, Section 3).
+	//
+	//   enum { server(1), client(2) } SessionStateType;
+	//
+	//   opaque Certificate<1..2^24-1>;
+	//
+	//   Certificate CertificateChain<0..2^24-1>;
+	//
+	//   opaque Extra<0..2^24-1>;
+	//
+	//   struct {
+	//       uint16 version;
+	//       SessionStateType type;
+	//       uint16 cipher_suite;
+	//       uint64 created_at;
+	//       opaque secret<1..2^8-1>;
+	//       Extra extra<0..2^24-1>;
+	//       uint8 ext_master_secret = { 0, 1 };
+	//       uint8 early_data = { 0, 1 };
+	//       CertificateEntry certificate_list<0..2^24-1>;
+	//       CertificateChain verified_chains<0..2^24-1>; /* excluding leaf */
+	//       select (SessionState.early_data) {
+	//           case 0: Empty;
+	//           case 1: opaque alpn<1..2^8-1>;
+	//       };
+	//       select (SessionState.type) {
+	//           case server: Empty;
+	//           case client: struct {
+	//               select (SessionState.version) {
+	//                   case VersionTLS10..VersionTLS12: Empty;
+	//                   case VersionTLS13: struct {
+	//                       uint64 use_by;
+	//                       uint32 age_add;
+	//                   };
+	//               };
+	//           };
+	//       };
+	//   } SessionState;
+	//
+
+	// Extra is ignored by crypto/tls, but is encoded by [SessionState.Bytes]
+	// and parsed by [ParseSessionState].
+	//
+	// This allows [Config.UnwrapSession]/[Config.WrapSession] and
+	// [ClientSessionCache] implementations to store and retrieve additional
+	// data alongside this session.
+	//
+	// To allow different layers in a protocol stack to share this field,
+	// applications must only append to it, not replace it, and must use entries
+	// that can be recognized even if out of order (for example, by starting
+	// with an id and version prefix).
+	Extra [][]byte
+
+	// EarlyData indicates whether the ticket can be used for 0-RTT in a QUIC
+	// connection. The application may set this to false if it is true to
+	// decline to offer 0-RTT even if supported.
+	EarlyData bool
+
+	version     uint16
+	isClient    bool
+	cipherSuite uint16
+	// createdAt is the generation time of the secret on the sever (which for
+	// TLS 1.0–1.2 might be earlier than the current session) and the time at
+	// which the ticket was received on the client.
+	createdAt         uint64 // seconds since UNIX epoch
+	secret            []byte // master secret for TLS 1.2, or the PSK for TLS 1.3
+	extMasterSecret   bool
+	peerCertificates  []*x509.Certificate
+	activeCertHandles []*activeCert
+	ocspResponse      []byte
+	scts              [][]byte
+	verifiedChains    [][]*x509.Certificate
+	alpnProtocol      string // only set if EarlyData is true
+
+	// Client-side TLS 1.3-only fields.
+	useBy  uint64 // seconds since UNIX epoch
+	ageAdd uint32
 }
 
-func (m *sessionState) marshal() ([]byte, error) {
+// Bytes encodes the session, including any private fields, so that it can be
+// parsed by [ParseSessionState]. The encoding contains secret values critical
+// to the security of future and possibly past sessions.
+//
+// The specific encoding should be considered opaque and may change incompatibly
+// between Go versions.
+func (s *SessionState) Bytes() ([]byte, error) {
 	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.AddUint16(s.version)
+	if s.isClient {
+		b.AddUint8(2) // client
+	} else {
+		b.AddUint8(1) // server
+	}
+	b.AddUint16(s.cipherSuite)
+	addUint64(&b, s.createdAt)
+	b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+		b.AddBytes(s.secret)
+	})
+	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+		for _, extra := range s.Extra {
+			b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+				b.AddBytes(extra)
+			})
+		}
+	})
+	if s.extMasterSecret {
+		b.AddUint8(1)
+	} else {
+		b.AddUint8(0)
+	}
+	if s.EarlyData {
+		b.AddUint8(1)
+	} else {
+		b.AddUint8(0)
+	}
+	marshalCertificate(&b, Certificate{
+		Certificate:                 certificatesToBytesSlice(s.peerCertificates),
+		OCSPStaple:                  s.ocspResponse,
+		SignedCertificateTimestamps: s.scts,
 	})
 	b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-		for _, cert := range m.certificates {
+		for _, chain := range s.verifiedChains {
 			b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-				b.AddBytes(cert)
+				// We elide the first certificate because it's always the leaf.
+				if len(chain) == 0 {
+					b.SetError(errors.New("tls: internal error: empty verified chain"))
+					return
+				}
+				for _, cert := range chain[1:] {
+					b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+						b.AddBytes(cert.Raw)
+					})
+				}
 			})
 		}
 	})
+	if s.EarlyData {
+		b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+			b.AddBytes([]byte(s.alpnProtocol))
+		})
+	}
+	if s.isClient {
+		if s.version >= VersionTLS13 {
+			addUint64(&b, s.useBy)
+			b.AddUint32(s.ageAdd)
+		}
+	}
 	return b.Bytes()
 }
 
-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)
+func certificatesToBytesSlice(certs []*x509.Certificate) [][]byte {
+	s := make([][]byte, 0, len(certs))
+	for _, c := range certs {
+		s = append(s, c.Raw)
 	}
-	return s.Empty()
+	return s
 }
 
-// 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.
-type sessionStateTLS13 struct {
-	// uint8 version  = 0x0304;
-	// uint8 revision = 0;
-	cipherSuite      uint16
-	createdAt        uint64
-	resumptionSecret []byte      // opaque resumption_master_secret<1..2^8-1>;
-	certificate      Certificate // CertificateEntry certificate_list<0..2^24-1>;
+// ParseSessionState parses a [SessionState] encoded by [SessionState.Bytes].
+func ParseSessionState(data []byte) (*SessionState, error) {
+	ss := &SessionState{}
+	s := cryptobyte.String(data)
+	var typ, extMasterSecret, earlyData uint8
+	var cert Certificate
+	var extra cryptobyte.String
+	if !s.ReadUint16(&ss.version) ||
+		!s.ReadUint8(&typ) ||
+		(typ != 1 && typ != 2) ||
+		!s.ReadUint16(&ss.cipherSuite) ||
+		!readUint64(&s, &ss.createdAt) ||
+		!readUint8LengthPrefixed(&s, &ss.secret) ||
+		!s.ReadUint24LengthPrefixed(&extra) ||
+		!s.ReadUint8(&extMasterSecret) ||
+		!s.ReadUint8(&earlyData) ||
+		len(ss.secret) == 0 ||
+		!unmarshalCertificate(&s, &cert) {
+		return nil, errors.New("tls: invalid session encoding")
+	}
+	for !extra.Empty() {
+		var e []byte
+		if !readUint24LengthPrefixed(&extra, &e) {
+			return nil, errors.New("tls: invalid session encoding")
+		}
+		ss.Extra = append(ss.Extra, e)
+	}
+	switch extMasterSecret {
+	case 0:
+		ss.extMasterSecret = false
+	case 1:
+		ss.extMasterSecret = true
+	default:
+		return nil, errors.New("tls: invalid session encoding")
+	}
+	switch earlyData {
+	case 0:
+		ss.EarlyData = false
+	case 1:
+		ss.EarlyData = true
+	default:
+		return nil, errors.New("tls: invalid session encoding")
+	}
+	for _, cert := range cert.Certificate {
+		c, err := globalCertCache.newCert(cert)
+		if err != nil {
+			return nil, err
+		}
+		ss.activeCertHandles = append(ss.activeCertHandles, c)
+		ss.peerCertificates = append(ss.peerCertificates, c.cert)
+	}
+	ss.ocspResponse = cert.OCSPStaple
+	ss.scts = cert.SignedCertificateTimestamps
+	var chainList cryptobyte.String
+	if !s.ReadUint24LengthPrefixed(&chainList) {
+		return nil, errors.New("tls: invalid session encoding")
+	}
+	for !chainList.Empty() {
+		var certList cryptobyte.String
+		if !chainList.ReadUint24LengthPrefixed(&certList) {
+			return nil, errors.New("tls: invalid session encoding")
+		}
+		var chain []*x509.Certificate
+		if len(ss.peerCertificates) == 0 {
+			return nil, errors.New("tls: invalid session encoding")
+		}
+		chain = append(chain, ss.peerCertificates[0])
+		for !certList.Empty() {
+			var cert []byte
+			if !readUint24LengthPrefixed(&certList, &cert) {
+				return nil, errors.New("tls: invalid session encoding")
+			}
+			c, err := globalCertCache.newCert(cert)
+			if err != nil {
+				return nil, err
+			}
+			ss.activeCertHandles = append(ss.activeCertHandles, c)
+			chain = append(chain, c.cert)
+		}
+		ss.verifiedChains = append(ss.verifiedChains, chain)
+	}
+	if ss.EarlyData {
+		var alpn []byte
+		if !readUint8LengthPrefixed(&s, &alpn) {
+			return nil, errors.New("tls: invalid session encoding")
+		}
+		ss.alpnProtocol = string(alpn)
+	}
+	if isClient := typ == 2; !isClient {
+		if !s.Empty() {
+			return nil, errors.New("tls: invalid session encoding")
+		}
+		return ss, nil
+	}
+	ss.isClient = true
+	if len(ss.peerCertificates) == 0 {
+		return nil, errors.New("tls: no server certificates in client session")
+	}
+	if ss.version < VersionTLS13 {
+		if !s.Empty() {
+			return nil, errors.New("tls: invalid session encoding")
+		}
+		return ss, nil
+	}
+	if !s.ReadUint64(&ss.useBy) || !s.ReadUint32(&ss.ageAdd) || !s.Empty() {
+		return nil, errors.New("tls: invalid session encoding")
+	}
+	return ss, nil
 }
 
-func (m *sessionStateTLS13) marshal() ([]byte, error) {
-	var b cryptobyte.Builder
-	b.AddUint16(VersionTLS13)
-	b.AddUint8(0) // revision
-	b.AddUint16(m.cipherSuite)
-	addUint64(&b, m.createdAt)
-	b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-		b.AddBytes(m.resumptionSecret)
-	})
-	marshalCertificate(&b, m.certificate)
-	return b.Bytes()
+// sessionState returns a partially filled-out [SessionState] with information
+// from the current connection.
+func (c *Conn) sessionState() (*SessionState, error) {
+	return &SessionState{
+		version:           c.vers,
+		cipherSuite:       c.cipherSuite,
+		createdAt:         uint64(c.config.time().Unix()),
+		alpnProtocol:      c.clientProtocol,
+		peerCertificates:  c.peerCertificates,
+		activeCertHandles: c.activeCertHandles,
+		ocspResponse:      c.ocspResponse,
+		scts:              c.scts,
+		isClient:          c.isClient,
+		extMasterSecret:   c.extMasterSecret,
+		verifiedChains:    c.verifiedChains,
+	}, nil
 }
 
-func (m *sessionStateTLS13) unmarshal(data []byte) bool {
-	*m = sessionStateTLS13{}
-	s := cryptobyte.String(data)
-	var version uint16
-	var revision uint8
-	return s.ReadUint16(&version) &&
-		version == VersionTLS13 &&
-		s.ReadUint8(&revision) &&
-		revision == 0 &&
-		s.ReadUint16(&m.cipherSuite) &&
-		readUint64(&s, &m.createdAt) &&
-		readUint8LengthPrefixed(&s, &m.resumptionSecret) &&
-		len(m.resumptionSecret) != 0 &&
-		unmarshalCertificate(&s, &m.certificate) &&
-		s.Empty()
+// EncryptTicket encrypts a ticket with the [Config]'s configured (or default)
+// session ticket keys. It can be used as a [Config.WrapSession] implementation.
+func (c *Config) EncryptTicket(cs ConnectionState, ss *SessionState) ([]byte, error) {
+	ticketKeys := c.ticketKeys(nil)
+	stateBytes, err := ss.Bytes()
+	if err != nil {
+		return nil, err
+	}
+	return c.encryptTicket(stateBytes, ticketKeys)
 }
 
-func (c *Conn) encryptTicket(state []byte) ([]byte, error) {
-	if len(c.ticketKeys) == 0 {
+func (c *Config) encryptTicket(state []byte, ticketKeys []ticketKey) ([]byte, error) {
+	if len(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]
+	encrypted := make([]byte, aes.BlockSize+len(state)+sha256.Size)
+	iv := encrypted[:aes.BlockSize]
+	ciphertext := encrypted[aes.BlockSize : len(encrypted)-sha256.Size]
+	authenticated := encrypted[:len(encrypted)-sha256.Size]
 	macBytes := encrypted[len(encrypted)-sha256.Size:]
 
-	if _, err := io.ReadFull(c.config.rand(), iv); err != nil {
+	if _, err := io.ReadFull(c.rand(), iv); err != nil {
 		return nil, err
 	}
-	key := c.ticketKeys[0]
-	copy(keyName, key.keyName[:])
+	key := ticketKeys[0]
 	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)
+	cipher.NewCTR(block, iv).XORKeyStream(ciphertext, state)
 
 	mac := hmac.New(sha256.New, key.hmacKey[:])
-	mac.Write(encrypted[:len(encrypted)-sha256.Size])
+	mac.Write(authenticated)
 	mac.Sum(macBytes[:0])
 
 	return encrypted, nil
 }
 
-// [uTLS] added exported DecryptTicketWith func below
-func (c *Conn) decryptTicket(encrypted []byte) (plaintext []byte, usedOldKey bool) {
-	if len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size {
-		return nil, false
+// DecryptTicket decrypts a ticket encrypted by [Config.EncryptTicket]. It can
+// be used as a [Config.UnwrapSession] implementation.
+//
+// If the ticket can't be decrypted or parsed, DecryptTicket returns (nil, nil).
+func (c *Config) DecryptTicket(identity []byte, cs ConnectionState) (*SessionState, error) {
+	ticketKeys := c.ticketKeys(nil)
+	stateBytes := c.decryptTicket(identity, ticketKeys)
+	if stateBytes == nil {
+		return nil, nil
+	}
+	s, err := ParseSessionState(stateBytes)
+	if err != nil {
+		return nil, nil // drop unparsable tickets on the floor
 	}
+	return s, nil
+}
 
-	keyName := encrypted[:ticketKeyNameLen]
-	iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
+func (c *Config) decryptTicket(encrypted []byte, ticketKeys []ticketKey) []byte {
+	if len(encrypted) < aes.BlockSize+sha256.Size {
+		return nil
+	}
+
+	iv := encrypted[:aes.BlockSize]
+	ciphertext := encrypted[aes.BlockSize : len(encrypted)-sha256.Size]
+	authenticated := encrypted[:len(encrypted)-sha256.Size]
 	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
+	for _, key := range ticketKeys {
+		mac := hmac.New(sha256.New, key.hmacKey[:])
+		mac.Write(authenticated)
+		expected := mac.Sum(nil)
+
+		if subtle.ConstantTimeCompare(macBytes, expected) != 1 {
+			continue
 		}
-	}
-	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)
+		block, err := aes.NewCipher(key.aesKey[:])
+		if err != nil {
+			return nil
+		}
+		plaintext := make([]byte, len(ciphertext))
+		cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)
 
-	if subtle.ConstantTimeCompare(macBytes, expected) != 1 {
-		return nil, false
+		return plaintext
 	}
 
-	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 nil
+}
 
-	return plaintext, keyIndex > 0
+// ClientSessionState contains the state needed by a client to
+// resume a previous TLS session.
+type ClientSessionState struct {
+	ticket  []byte
+	session *SessionState
 }
 
-// DecryptTicketWith decrypts an encrypted session ticket
-// using a TicketKeys (ie []TicketKey) struct
+// ResumptionState returns the session ticket sent by the server (also known as
+// the session's identity) and the state necessary to resume this session.
 //
-// usedOldKey will be true if the key used for decryption is
-// not the first in the []TicketKey slice
-//
-// [uTLS] changed to be made public and take a TicketKeys and use a fake conn receiver
-func DecryptTicketWith(encrypted []byte, tks TicketKeys) (plaintext []byte, usedOldKey bool) {
-	// create fake conn
-	c := &Conn{
-		ticketKeys: tks.ToPrivate(),
-	}
+// It can be called by [ClientSessionCache.Put] to serialize (with
+// [SessionState.Bytes]) and store the session.
+func (cs *ClientSessionState) ResumptionState() (ticket []byte, state *SessionState, err error) {
+	return cs.ticket, cs.session, nil
+}
 
-	return c.decryptTicket(encrypted)
+// NewResumptionState returns a state value that can be returned by
+// [ClientSessionCache.Get] to resume a previous session.
+//
+// state needs to be returned by [ParseSessionState], and the ticket and session
+// state must have been returned by [ClientSessionState.ResumptionState].
+func NewResumptionState(ticket []byte, state *SessionState) (*ClientSessionState, error) {
+	return &ClientSessionState{
+		ticket: ticket, session: state,
+	}, nil
 }
+
+// // DecryptTicketWith decrypts an encrypted session ticket
+// // using a TicketKeys (ie []TicketKey) struct
+// //
+// // usedOldKey will be true if the key used for decryption is
+// // not the first in the []TicketKey slice
+// //
+// // [uTLS] changed to be made public and take a TicketKeys and use a fake conn receiver
+// func DecryptTicketWith(encrypted []byte, tks TicketKeys) (plaintext []byte, usedOldKey bool) {
+// 	// create fake conn
+// 	c := &Conn{
+// 		ticketKeys: tks.ToPrivate(),
+// 	}
+
+// 	return c.decryptTicket(encrypted)
+// }
diff --git a/vendor/github.com/refraction-networking/utls/tls.go b/vendor/github.com/refraction-networking/utls/tls.go
index b529c705..4168eeed 100644
--- a/vendor/github.com/refraction-networking/utls/tls.go
+++ b/vendor/github.com/refraction-networking/utls/tls.go
@@ -25,6 +25,8 @@ import (
 	"net"
 	"os"
 	"strings"
+
+	circlSign "github.com/cloudflare/circl/sign"
 )
 
 // Server returns a new TLS server side connection
@@ -71,7 +73,7 @@ func (l *listener) Accept() (net.Conn, error) {
 }
 
 // NewListener creates a Listener which accepts connections from an inner
-// Listener and wraps each connection with Server.
+// 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) net.Listener {
@@ -109,10 +111,10 @@ func (timeoutError) Temporary() bool { return true }
 // handshake as a whole.
 //
 // DialWithDialer interprets a nil configuration as equivalent to the zero
-// configuration; see the documentation of Config for the defaults.
+// 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.
+// use [Dialer.DialContext] with NetDialer set to the desired dialer.
 func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
 	return dial(context.Background(), dialer, network, addr, config)
 }
@@ -189,10 +191,10 @@ type Dialer struct {
 // 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.
+// The returned [Conn], if any, will always be of type *[Conn].
 //
 // Dial uses context.Background internally; to specify the context,
-// use DialContext.
+// use [Dialer.DialContext].
 func (d *Dialer) Dial(network, addr string) (net.Conn, error) {
 	return d.DialContext(context.Background(), network, addr)
 }
@@ -212,7 +214,7 @@ func (d *Dialer) netDialer() *net.Dialer {
 // connected, any expiration of the context will not affect the
 // connection.
 //
-// The returned Conn, if any, will always be of type *Conn.
+// 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)
 	if err != nil {
@@ -326,6 +328,20 @@ func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
 		if !bytes.Equal(priv.Public().(ed25519.PublicKey), pub) {
 			return fail(errors.New("tls: private key does not match public key"))
 		}
+	// [UTLS SECTION BEGINS]
+	// Ported from cloudflare/go
+	case circlSign.PublicKey:
+		priv, ok := cert.PrivateKey.(circlSign.PrivateKey)
+		if !ok {
+			return fail(errors.New("tls: private key type does not match public key type"))
+		}
+		pkBytes, err := priv.Public().(circlSign.PublicKey).MarshalBinary()
+		pkBytes2, err2 := pub.MarshalBinary()
+
+		if err != nil || err2 != nil || !bytes.Equal(pkBytes, pkBytes2) {
+			return fail(errors.New("tls: private key does not match public key"))
+		}
+	// [UTLS SECTION ENDS]
 	default:
 		return fail(errors.New("tls: unknown public key algorithm"))
 	}
@@ -342,7 +358,7 @@ func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
 	}
 	if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
 		switch key := key.(type) {
-		case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey:
+		case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey, circlSign.PrivateKey: // [uTLS] ported from cloudflare/go
 			return key, nil
 		default:
 			return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping")
diff --git a/vendor/github.com/refraction-networking/utls/tls_cf.go b/vendor/github.com/refraction-networking/utls/tls_cf.go
new file mode 100644
index 00000000..8160be09
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/tls_cf.go
@@ -0,0 +1,66 @@
+// Copyright 2021 Cloudflare, Inc. All rights reserved. Use of this source code
+// is governed by a BSD-style license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	circlPki "github.com/cloudflare/circl/pki"
+	circlSign "github.com/cloudflare/circl/sign"
+	"github.com/cloudflare/circl/sign/eddilithium3"
+)
+
+// To add a signature scheme from Circl
+//
+//   1. make sure it implements TLSScheme and CertificateScheme,
+//   2. follow the instructions in crypto/x509/x509_cf.go
+//   3. add a signature<NameOfAlg> to the iota in common.go
+//   4. add row in the circlSchemes lists below
+
+var circlSchemes = [...]struct {
+	sigType uint8
+	scheme  circlSign.Scheme
+}{
+	{signatureEdDilithium3, eddilithium3.Scheme()},
+}
+
+func circlSchemeBySigType(sigType uint8) circlSign.Scheme {
+	for _, cs := range circlSchemes {
+		if cs.sigType == sigType {
+			return cs.scheme
+		}
+	}
+	return nil
+}
+
+func sigTypeByCirclScheme(scheme circlSign.Scheme) uint8 {
+	for _, cs := range circlSchemes {
+		if cs.scheme == scheme {
+			return cs.sigType
+		}
+	}
+	return 0
+}
+
+var supportedSignatureAlgorithmsWithCircl []SignatureScheme
+
+// supportedSignatureAlgorithms returns enabled signature schemes. PQ signature
+// schemes are only included when tls.Config#PQSignatureSchemesEnabled is set
+// and FIPS-only mode is not enabled.
+func (c *Config) supportedSignatureAlgorithms() []SignatureScheme {
+	// If FIPS-only mode is requested, do not add other algos.
+	if needFIPS() {
+		return supportedSignatureAlgorithms()
+	}
+	if c != nil && c.PQSignatureSchemesEnabled {
+		return supportedSignatureAlgorithmsWithCircl
+	}
+	return defaultSupportedSignatureAlgorithms
+}
+
+func init() {
+	supportedSignatureAlgorithmsWithCircl = append([]SignatureScheme{}, defaultSupportedSignatureAlgorithms...)
+	for _, cs := range circlSchemes {
+		supportedSignatureAlgorithmsWithCircl = append(supportedSignatureAlgorithmsWithCircl,
+			SignatureScheme(cs.scheme.(circlPki.TLSScheme).TLSIdentifier()))
+	}
+}
diff --git a/vendor/github.com/refraction-networking/utls/u_alias.go b/vendor/github.com/refraction-networking/utls/u_alias.go
new file mode 100644
index 00000000..af579c2e
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/u_alias.go
@@ -0,0 +1,12 @@
+package tls
+
+// This file contains all the alias functions, symbols, names, etc. that
+// was once used in the old version of the library.  This is to ensure
+// backwards compatibility with the old version of the library.
+
+// TLS Extensions
+
+// UtlsExtendedMasterSecretExtension is an alias for ExtendedMasterSecretExtension.
+//
+// Deprecated: Use ExtendedMasterSecretExtension instead.
+type UtlsExtendedMasterSecretExtension = ExtendedMasterSecretExtension
diff --git a/vendor/github.com/refraction-networking/utls/u_clienthello_json.go b/vendor/github.com/refraction-networking/utls/u_clienthello_json.go
index 2529bf78..027e082c 100644
--- a/vendor/github.com/refraction-networking/utls/u_clienthello_json.go
+++ b/vendor/github.com/refraction-networking/utls/u_clienthello_json.go
@@ -6,7 +6,7 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/gaukas/godicttls"
+	"github.com/refraction-networking/utls/dicttls"
 )
 
 var ErrUnknownExtension = errors.New("extension name is unknown to the dictionary")
@@ -45,7 +45,7 @@ func (c *CipherSuitesJSONUnmarshaler) UnmarshalJSON(jsonStr []byte) error {
 			continue
 		}
 
-		if id, ok := godicttls.DictCipherSuiteNameIndexed[name]; ok {
+		if id, ok := dicttls.DictCipherSuiteNameIndexed[name]; ok {
 			c.cipherSuites = append(c.cipherSuites, id)
 		} else {
 			return fmt.Errorf("unknown cipher suite name: %s", name)
@@ -70,7 +70,7 @@ func (c *CompressionMethodsJSONUnmarshaler) UnmarshalJSON(jsonStr []byte) error
 	}
 
 	for _, name := range compressionMethodNames {
-		if id, ok := godicttls.DictCompMethNameIndexed[name]; ok {
+		if id, ok := dicttls.DictCompMethNameIndexed[name]; ok {
 			c.compressionMethods = append(c.compressionMethods, id)
 		} else {
 			return fmt.Errorf("unknown compression method name: %s", name)
@@ -85,7 +85,9 @@ func (c *CompressionMethodsJSONUnmarshaler) CompressionMethods() []uint8 {
 }
 
 type TLSExtensionsJSONUnmarshaler struct {
-	extensions []TLSExtensionJSON
+	AllowUnknownExt bool // if set, unknown extensions will be added as GenericExtension, without recovering ext payload
+	UseRealPSK      bool // if set, PSK extension will be real PSK extension, otherwise it will be fake PSK extension
+	extensions      []TLSExtensionJSON
 }
 
 func (e *TLSExtensionsJSONUnmarshaler) UnmarshalJSON(jsonStr []byte) error {
@@ -101,20 +103,34 @@ func (e *TLSExtensionsJSONUnmarshaler) UnmarshalJSON(jsonStr []byte) error {
 			continue
 		}
 
-		if extID, ok := godicttls.DictExtTypeNameIndexed[accepter.extNameOnly.Name]; !ok {
+		if extID, ok := dicttls.DictExtTypeNameIndexed[accepter.extNameOnly.Name]; !ok {
 			return fmt.Errorf("%w: %s", ErrUnknownExtension, accepter.extNameOnly.Name)
 		} else {
 			// get extension type from ID
 			var ext TLSExtension = ExtensionFromID(extID)
 			if ext == nil {
-				// fallback to generic extension
-				ext = genericExtension(extID, accepter.extNameOnly.Name)
+				if e.AllowUnknownExt {
+					// fallback to generic extension, without recovering ext payload
+					ext = genericExtension(extID, accepter.extNameOnly.Name)
+				} else {
+					return fmt.Errorf("extension %s (%d) is not JSON compatible", accepter.extNameOnly.Name, extID)
+				}
+			}
+
+			switch extID {
+			case extensionPreSharedKey:
+				// PSK extension, need to see if we do real or fake PSK
+				if e.UseRealPSK {
+					ext = &UtlsPreSharedKeyExtension{}
+				} else {
+					ext = &FakePreSharedKeyExtension{}
+				}
 			}
 
 			if extJsonCompatible, ok := ext.(TLSExtensionJSON); ok {
 				exts = append(exts, extJsonCompatible)
 			} else {
-				return fmt.Errorf("extension %d (%s) is not JSON compatible", extID, accepter.extNameOnly.Name)
+				return fmt.Errorf("extension %s (%d) is not JSON compatible", accepter.extNameOnly.Name, extID)
 			}
 		}
 	}
diff --git a/vendor/github.com/refraction-networking/utls/u_common.go b/vendor/github.com/refraction-networking/utls/u_common.go
index 33e3a282..59a5a2e3 100644
--- a/vendor/github.com/refraction-networking/utls/u_common.go
+++ b/vendor/github.com/refraction-networking/utls/u_common.go
@@ -34,11 +34,12 @@ const (
 const (
 	extensionNextProtoNeg uint16 = 13172 // not IANA assigned. Removed by crypto/tls since Nov 2019
 
-	utlsExtensionPadding              uint16 = 21
-	utlsExtensionExtendedMasterSecret uint16 = 23    // https://tools.ietf.org/html/rfc7627
-	utlsExtensionCompressCertificate  uint16 = 27    // https://datatracker.ietf.org/doc/html/rfc8879#section-7.1
-	utlsExtensionApplicationSettings  uint16 = 17513 // not IANA assigned
-	utlsFakeExtensionCustom           uint16 = 1234  // not IANA assigned, for ALPS
+	utlsExtensionPadding             uint16 = 21
+	utlsExtensionCompressCertificate uint16 = 27     // https://datatracker.ietf.org/doc/html/rfc8879#section-7.1
+	utlsExtensionApplicationSettings uint16 = 17513  // not IANA assigned
+	utlsFakeExtensionCustom          uint16 = 1234   // not IANA assigned, for ALPS
+	utlsExtensionECH                 uint16 = 0xfe0d // draft-ietf-tls-esni-17
+	utlsExtensionECHOuterExtensions  uint16 = 0xfd00 // draft-ietf-tls-esni-17
 
 	// extensions with 'fake' prefix break connection, if server echoes them back
 	fakeExtensionEncryptThenMAC       uint16 = 22
@@ -73,6 +74,19 @@ const (
 	FAKE_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = uint16(0xc008)
 )
 
+const (
+	CurveSECP256R1 CurveID = 0x0017
+	CurveSECP384R1 CurveID = 0x0018
+	CurveSECP521R1 CurveID = 0x0019
+	CurveX25519    CurveID = 0x001d
+
+	FakeCurveFFDHE2048 CurveID = 0x0100
+	FakeCurveFFDHE3072 CurveID = 0x0101
+	FakeCurveFFDHE4096 CurveID = 0x0102
+	FakeCurveFFDHE6144 CurveID = 0x0103
+	FakeCurveFFDHE8192 CurveID = 0x0104
+)
+
 // Other things
 const (
 	fakeRecordSizeLimit uint16 = 0x001c
@@ -196,9 +210,7 @@ func (chs *ClientHelloSpec) ReadCompressionMethods(compressionMethods []byte) er
 
 // ReadTLSExtensions is a helper function to construct a list of TLS extensions from
 // a byte slice into []TLSExtension.
-//
-// If keepPSK is not set, the PSK extension will cause an error.
-func (chs *ClientHelloSpec) ReadTLSExtensions(b []byte, allowBluntMimicry bool) error {
+func (chs *ClientHelloSpec) ReadTLSExtensions(b []byte, allowBluntMimicry bool, realPSK bool) error {
 	extensions := cryptobyte.String(b)
 	for !extensions.Empty() {
 		var extension uint16
@@ -213,10 +225,19 @@ func (chs *ClientHelloSpec) ReadTLSExtensions(b []byte, allowBluntMimicry bool)
 		ext := ExtensionFromID(extension)
 		extWriter, ok := ext.(TLSExtensionWriter)
 		if ext != nil && ok { // known extension and implements TLSExtensionWriter properly
-			if extension == extensionSupportedVersions {
+			switch extension {
+			case extensionPreSharedKey:
+				// PSK extension, need to see if we do real or fake PSK
+				if realPSK {
+					extWriter = &UtlsPreSharedKeyExtension{}
+				} else {
+					extWriter = &FakePreSharedKeyExtension{}
+				}
+			case extensionSupportedVersions:
 				chs.TLSVersMin = 0
 				chs.TLSVersMax = 0
 			}
+
 			if _, err := extWriter.Write(extData); err != nil {
 				return err
 			}
@@ -235,13 +256,15 @@ func (chs *ClientHelloSpec) ReadTLSExtensions(b []byte, allowBluntMimicry bool)
 
 func (chs *ClientHelloSpec) AlwaysAddPadding() {
 	alreadyHasPadding := false
-	for _, ext := range chs.Extensions {
+	for idx, ext := range chs.Extensions {
 		if _, ok := ext.(*UtlsPaddingExtension); ok {
 			alreadyHasPadding = true
 			break
 		}
-		if _, ok := ext.(*FakePreSharedKeyExtension); ok {
-			alreadyHasPadding = true // PSK must be last, so we don't need to add padding
+		if _, ok := ext.(PreSharedKeyExtension); ok {
+			alreadyHasPadding = true // PSK must be last, so we can't append padding after it
+			// instead we will insert padding before PSK
+			chs.Extensions = append(chs.Extensions[:idx], append([]TLSExtension{&UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle}}, chs.Extensions[idx:]...)...)
 			break
 		}
 	}
@@ -412,7 +435,7 @@ func (chs *ClientHelloSpec) ImportTLSClientHello(data map[string][]byte) error {
 			case utlsExtensionApplicationSettings:
 				// TODO: tlsfingerprint.io should record/provide application settings data
 				extWriter.(*ApplicationSettingsExtension).SupportedProtocols = []string{"h2"}
-			case fakeExtensionPreSharedKey:
+			case extensionPreSharedKey:
 				log.Printf("[Warning] PSK extension added without data")
 			default:
 				if !isGREASEUint16(extType) {
@@ -440,14 +463,20 @@ func (chs *ClientHelloSpec) ImportTLSClientHelloFromJSON(jsonB []byte) error {
 }
 
 // FromRaw converts a ClientHello message in the form of raw bytes into a ClientHelloSpec.
-func (chs *ClientHelloSpec) FromRaw(raw []byte, allowBluntMimicry ...bool) error {
+//
+// ctrlFlags: []bool{bluntMimicry, realPSK}
+func (chs *ClientHelloSpec) FromRaw(raw []byte, ctrlFlags ...bool) error {
 	if chs == nil {
 		return errors.New("cannot unmarshal into nil ClientHelloSpec")
 	}
 
 	var bluntMimicry = false
-	if len(allowBluntMimicry) == 1 {
-		bluntMimicry = allowBluntMimicry[0]
+	var realPSK = false
+	if len(ctrlFlags) > 0 {
+		bluntMimicry = ctrlFlags[0]
+	}
+	if len(ctrlFlags) > 1 {
+		realPSK = ctrlFlags[1]
 	}
 
 	*chs = ClientHelloSpec{} // reset
@@ -514,10 +543,19 @@ func (chs *ClientHelloSpec) FromRaw(raw []byte, allowBluntMimicry ...bool) error
 		return errors.New("unable to read extensions data")
 	}
 
-	if err := chs.ReadTLSExtensions(extensions, bluntMimicry); err != nil {
+	if err := chs.ReadTLSExtensions(extensions, bluntMimicry, realPSK); err != nil {
 		return err
 	}
 
+	// if extension list includes padding, we update the padding-to-len according to
+	// the raw ClientHello length
+	for _, ext := range chs.Extensions {
+		if _, ok := ext.(*UtlsPaddingExtension); ok {
+			ext.(*UtlsPaddingExtension).GetPaddingLen = AlwaysPadToLen(len(raw) - 5)
+			break
+		}
+	}
+
 	return nil
 }
 
@@ -549,7 +587,7 @@ var (
 	HelloRandomizedNoALPN = ClientHelloID{helloRandomizedNoALPN, helloAutoVers, nil, nil}
 
 	// The rest will will parrot given browser.
-	HelloFirefox_Auto = HelloFirefox_105
+	HelloFirefox_Auto = HelloFirefox_120
 	HelloFirefox_55   = ClientHelloID{helloFirefox, "55", nil, nil}
 	HelloFirefox_56   = ClientHelloID{helloFirefox, "56", nil, nil}
 	HelloFirefox_63   = ClientHelloID{helloFirefox, "63", nil, nil}
@@ -557,8 +595,9 @@ var (
 	HelloFirefox_99   = ClientHelloID{helloFirefox, "99", nil, nil}
 	HelloFirefox_102  = ClientHelloID{helloFirefox, "102", nil, nil}
 	HelloFirefox_105  = ClientHelloID{helloFirefox, "105", nil, nil}
+	HelloFirefox_120  = ClientHelloID{helloFirefox, "120", nil, nil}
 
-	HelloChrome_Auto        = HelloChrome_106_Shuffle
+	HelloChrome_Auto        = HelloChrome_120
 	HelloChrome_58          = ClientHelloID{helloChrome, "58", nil, nil}
 	HelloChrome_62          = ClientHelloID{helloChrome, "62", nil, nil}
 	HelloChrome_70          = ClientHelloID{helloChrome, "70", nil, nil}
@@ -568,11 +607,24 @@ var (
 	HelloChrome_96          = ClientHelloID{helloChrome, "96", nil, nil}
 	HelloChrome_100         = ClientHelloID{helloChrome, "100", nil, nil}
 	HelloChrome_102         = ClientHelloID{helloChrome, "102", nil, nil}
-	HelloChrome_106_Shuffle = ClientHelloID{helloChrome, "106", nil, nil} // beta: shuffler enabled starting from 106
+	HelloChrome_106_Shuffle = ClientHelloID{helloChrome, "106", nil, nil} // TLS Extension shuffler enabled starting from 106
+
+	// Chrome w/ PSK: Chrome start sending this ClientHello after doing TLS 1.3 handshake with the same server.
+	// Beta: PSK extension added. However, uTLS doesn't ship with full PSK support.
+	// Use at your own discretion.
+	HelloChrome_100_PSK              = ClientHelloID{helloChrome, "100_PSK", nil, nil}
+	HelloChrome_112_PSK_Shuf         = ClientHelloID{helloChrome, "112_PSK", nil, nil}
+	HelloChrome_114_Padding_PSK_Shuf = ClientHelloID{helloChrome, "114_PSK", nil, nil}
 
-	// Chrome with PSK: Chrome start sending this ClientHello after doing TLS 1.3 handshake with the same server.
-	HelloChrome_100_PSK      = ClientHelloID{helloChrome, "100_PSK", nil, nil} // beta: PSK extension added. uTLS doesn't fully support PSK. Use at your own risk.
-	HelloChrome_112_PSK_Shuf = ClientHelloID{helloChrome, "112_PSK", nil, nil} // beta: PSK extension added. uTLS doesn't fully support PSK. Use at your own risk.
+	// Chrome w/ Post-Quantum Key Agreement
+	// Beta: PQ extension added. However, uTLS doesn't ship with full PQ support. Use at your own discretion.
+	HelloChrome_115_PQ     = ClientHelloID{helloChrome, "115_PQ", nil, nil}
+	HelloChrome_115_PQ_PSK = ClientHelloID{helloChrome, "115_PQ_PSK", nil, nil}
+
+	// Chrome ECH
+	HelloChrome_120 = ClientHelloID{helloChrome, "120", nil, nil}
+	// Chrome w/ Post-Quantum Key Agreement and Encrypted ClientHello
+	HelloChrome_120_PQ = ClientHelloID{helloChrome, "120_PQ", nil, nil}
 
 	HelloIOS_Auto = HelloIOS_14
 	HelloIOS_11_1 = ClientHelloID{helloIOS, "111", nil, nil} // legacy "111" means 11.1
@@ -688,3 +740,61 @@ func EnableWeakCiphers() {
 			suiteECDHE | suiteTLS12 | suiteSHA384, cipherAES, utlsMacSHA384, nil},
 	}...)
 }
+
+func mapSlice[T any, U any](slice []T, transform func(T) U) []U {
+	newSlice := make([]U, 0, len(slice))
+	for _, t := range slice {
+		newSlice = append(newSlice, transform(t))
+	}
+	return newSlice
+}
+
+func panicOnNil(caller string, params ...any) {
+	for i, p := range params {
+		if p == nil {
+			panic(fmt.Sprintf("tls: %s failed: the [%d] parameter is nil", caller, i))
+		}
+	}
+}
+
+func anyTrue[T any](slice []T, predicate func(i int, t *T) bool) bool {
+	for i := 0; i < len(slice); i++ {
+		if predicate(i, &slice[i]) {
+			return true
+		}
+	}
+	return false
+}
+
+func allTrue[T any](slice []T, predicate func(i int, t *T) bool) bool {
+	for i := 0; i < len(slice); i++ {
+		if !predicate(i, &slice[i]) {
+			return false
+		}
+	}
+	return true
+}
+
+func uAssert(condition bool, msg string) {
+	if !condition {
+		panic(msg)
+	}
+}
+
+func sliceEq[T comparable](sliceA []T, sliceB []T) bool {
+	if len(sliceA) != len(sliceB) {
+		return false
+	}
+	for i := 0; i < len(sliceA); i++ {
+		if sliceA[i] != sliceB[i] {
+			return false
+		}
+	}
+	return true
+}
+
+type Initializable interface {
+	// IsInitialized returns a boolean indicating whether the extension has been initialized.
+	// If false is returned, utls will initialize the extension.
+	IsInitialized() bool
+}
diff --git a/vendor/github.com/refraction-networking/utls/u_conn.go b/vendor/github.com/refraction-networking/utls/u_conn.go
index 4a3d7cec..f683c05c 100644
--- a/vendor/github.com/refraction-networking/utls/u_conn.go
+++ b/vendor/github.com/refraction-networking/utls/u_conn.go
@@ -9,36 +9,48 @@ import (
 	"bytes"
 	"context"
 	"crypto/cipher"
+	"crypto/ecdh"
 	"encoding/binary"
 	"errors"
 	"fmt"
 	"hash"
-	"io"
 	"net"
 	"strconv"
-	"sync/atomic"
 )
 
+type ClientHelloBuildStatus int
+
+const NotBuilt ClientHelloBuildStatus = 0
+const BuildByUtls ClientHelloBuildStatus = 1
+const BuildByGoTLS ClientHelloBuildStatus = 2
+
 type UConn struct {
 	*Conn
 
-	Extensions    []TLSExtension
-	ClientHelloID ClientHelloID
+	Extensions        []TLSExtension
+	ClientHelloID     ClientHelloID
+	sessionController *sessionController
 
-	ClientHelloBuilt bool
-	HandshakeState   PubClientHandshakeState
+	clientHelloBuildStatus ClientHelloBuildStatus
 
-	// sessionID may or may not depend on ticket; nil => random
-	GetSessionID func(ticket []byte) [32]byte
+	HandshakeState PubClientHandshakeState
 
 	greaseSeed [ssl_grease_last_index]uint16
 
 	omitSNIExtension bool
 
+	// skipResumptionOnNilExtension is copied from `Config.PreferSkipResumptionOnNilExtension`.
+	//
+	// By default, if ClientHelloSpec is predefined or utls-generated (as opposed to HelloCustom), this flag will be updated to true.
+	skipResumptionOnNilExtension bool
+
 	// certCompressionAlgs represents the set of advertised certificate compression
 	// algorithms, as specified in the ClientHello. This is only relevant client-side, for the
 	// server certificate. All other forms of certificate compression are unsupported.
 	certCompressionAlgs []CertCompressionAlgo
+
+	// ech extension is a shortcut to the ECH extension in the Extensions slice if there is one.
+	ech ECHExtension
 }
 
 // UClient returns a new uTLS client, with behavior depending on clientHelloID.
@@ -52,6 +64,9 @@ func UClient(conn net.Conn, config *Config, clientHelloID ClientHelloID) *UConn
 	uconn := UConn{Conn: &tlsConn, ClientHelloID: clientHelloID, HandshakeState: handshakeState}
 	uconn.HandshakeState.uconn = &uconn
 	uconn.handshakeFn = uconn.clientHandshake
+	uconn.sessionController = newSessionController(&uconn)
+	uconn.utls.sessionController = uconn.sessionController
+	uconn.skipResumptionOnNilExtension = config.PreferSkipResumptionOnNilExtension || clientHelloID.Client != helloCustom
 	return &uconn
 }
 
@@ -68,25 +83,48 @@ func UClient(conn net.Conn, config *Config, clientHelloID ClientHelloID) *UConn
 //	[each call] marshal ClientHello.
 //
 // BuildHandshakeState is automatically called before uTLS performs handshake,
-// amd should only be called explicitly to inspect/change fields of
+// and should only be called explicitly to inspect/change fields of
 // default/mimicked ClientHello.
+// With the excpetion of session ticket and psk extensions, which cannot be changed
+// after calling BuildHandshakeState, all other fields can be modified.
 func (uconn *UConn) BuildHandshakeState() error {
+	return uconn.buildHandshakeState(true)
+}
+
+// BuildHandshakeStateWithoutSession is the same as BuildHandshakeState, but does not
+// set the session. This is only useful when you want to inspect the ClientHello before
+// setting the session manually through SetSessionTicketExtension or SetPSKExtension.
+// BuildHandshakeState is automatically called before uTLS performs handshake.
+func (uconn *UConn) BuildHandshakeStateWithoutSession() error {
+	return uconn.buildHandshakeState(false)
+}
+
+func (uconn *UConn) buildHandshakeState(loadSession bool) error {
 	if uconn.ClientHelloID == HelloGolang {
-		if uconn.ClientHelloBuilt {
+		if uconn.clientHelloBuildStatus == BuildByGoTLS {
 			return nil
 		}
+		uAssert(uconn.clientHelloBuildStatus == NotBuilt, "BuildHandshakeState failed: invalid call, client hello has already been built by utls")
 
 		// use default Golang ClientHello.
-		hello, ecdheParams, err := uconn.makeClientHello()
+		hello, keySharePrivate, err := uconn.makeClientHello()
 		if err != nil {
 			return err
 		}
 
 		uconn.HandshakeState.Hello = hello.getPublicPtr()
-		uconn.HandshakeState.State13.EcdheParams = ecdheParams
+		if ecdheKey, ok := keySharePrivate.(*ecdh.PrivateKey); ok {
+			uconn.HandshakeState.State13.EcdheKey = ecdheKey
+		} else if kemKey, ok := keySharePrivate.(*kemPrivateKey); ok {
+			uconn.HandshakeState.State13.KEMKey = kemKey.ToPublic()
+		} else {
+			return fmt.Errorf("uTLS: unknown keySharePrivate type: %T", keySharePrivate)
+		}
 		uconn.HandshakeState.C = uconn.Conn
+		uconn.clientHelloBuildStatus = BuildByGoTLS
 	} else {
-		if !uconn.ClientHelloBuilt {
+		uAssert(uconn.clientHelloBuildStatus == BuildByUtls || uconn.clientHelloBuildStatus == NotBuilt, "BuildHandshakeState failed: invalid call, client hello has already been built by go-tls")
+		if uconn.clientHelloBuildStatus == NotBuilt {
 			err := uconn.applyPresetByID(uconn.ClientHelloID)
 			if err != nil {
 				return err
@@ -100,52 +138,110 @@ func (uconn *UConn) BuildHandshakeState() error {
 		if err != nil {
 			return err
 		}
+
+		if loadSession {
+			err = uconn.uLoadSession()
+			if err != nil {
+				return err
+			}
+		}
+
 		err = uconn.MarshalClientHello()
 		if err != nil {
 			return err
 		}
+
+		if loadSession {
+			uconn.uApplyPatch()
+			uconn.sessionController.finalCheck()
+		}
+
+		uconn.clientHelloBuildStatus = BuildByUtls
+	}
+	return nil
+}
+
+func (uconn *UConn) uLoadSession() error {
+	if cfg := uconn.config; cfg.SessionTicketsDisabled || cfg.ClientSessionCache == nil {
+		return nil
+	}
+	switch uconn.sessionController.shouldLoadSession() {
+	case shouldReturn:
+	case shouldSetTicket:
+		uconn.sessionController.setSessionTicketToUConn()
+	case shouldSetPsk:
+		uconn.sessionController.setPskToUConn()
+	case shouldLoad:
+		hello := uconn.HandshakeState.Hello.getPrivatePtr()
+		uconn.sessionController.utlsAboutToLoadSession()
+		session, earlySecret, binderKey, err := uconn.loadSession(hello)
+		if session == nil || err != nil {
+			return err
+		}
+		if session.version == VersionTLS12 {
+			// We use the session ticket extension for tls 1.2 session resumption
+			uconn.sessionController.initSessionTicketExt(session, hello.sessionTicket)
+			uconn.sessionController.setSessionTicketToUConn()
+		} else {
+			uconn.sessionController.initPskExt(session, earlySecret, binderKey, hello.pskIdentities)
+		}
 	}
-	uconn.ClientHelloBuilt = true
+
 	return nil
 }
 
+func (uconn *UConn) uApplyPatch() {
+	helloLen := len(uconn.HandshakeState.Hello.Raw)
+	if uconn.sessionController.shouldUpdateBinders() {
+		uconn.sessionController.updateBinders()
+		uconn.sessionController.setPskToUConn()
+	}
+	uAssert(helloLen == len(uconn.HandshakeState.Hello.Raw), "tls: uApplyPatch Failed: the patch should never change the length of the marshaled clientHello")
+}
+
+func (uconn *UConn) DidTls12Resume() bool {
+	return uconn.didResume
+}
+
 // SetSessionState sets the session ticket, which may be preshared or fake.
 // If session is nil, the body of session ticket extension will be unset,
 // but the extension itself still MAY be present for mimicking purposes.
 // Session tickets to be reused - use same cache on following connections.
+//
+// Deprecated: This method is deprecated in favor of SetSessionTicketExtension,
+// as it only handles session override of TLS 1.2
 func (uconn *UConn) SetSessionState(session *ClientSessionState) error {
-	uconn.HandshakeState.Session = session
-	var sessionTicket []uint8
+	sessionTicketExt := &SessionTicketExtension{Initialized: true}
 	if session != nil {
-		sessionTicket = session.sessionTicket
+		sessionTicketExt.Ticket = session.ticket
+		sessionTicketExt.Session = session.session
 	}
-	uconn.HandshakeState.Hello.TicketSupported = true
-	uconn.HandshakeState.Hello.SessionTicket = sessionTicket
+	return uconn.SetSessionTicketExtension(sessionTicketExt)
+}
 
-	for _, ext := range uconn.Extensions {
-		st, ok := ext.(*SessionTicketExtension)
-		if !ok {
-			continue
-		}
-		st.Session = session
-		if session != nil {
-			if len(session.SessionTicket()) > 0 {
-				if uconn.GetSessionID != nil {
-					sid := uconn.GetSessionID(session.SessionTicket())
-					uconn.HandshakeState.Hello.SessionId = sid[:]
-					return nil
-				}
-			}
-			var sessionID [32]byte
-			_, err := io.ReadFull(uconn.config.rand(), sessionID[:])
-			if err != nil {
-				return err
-			}
-			uconn.HandshakeState.Hello.SessionId = sessionID[:]
-		}
+// SetSessionTicket sets the session ticket extension.
+// If extension is nil, this will be a no-op.
+func (uconn *UConn) SetSessionTicketExtension(sessionTicketExt ISessionTicketExtension) error {
+	if uconn.config.SessionTicketsDisabled || uconn.config.ClientSessionCache == nil {
+		return fmt.Errorf("tls: SetSessionTicketExtension failed: session is disabled")
+	}
+	if sessionTicketExt == nil {
 		return nil
 	}
-	return nil
+	return uconn.sessionController.overrideSessionTicketExt(sessionTicketExt)
+}
+
+// SetPskExtension sets the psk extension for tls 1.3 resumption. This is a no-op if the psk is nil.
+func (uconn *UConn) SetPskExtension(pskExt PreSharedKeyExtension) error {
+	if uconn.config.SessionTicketsDisabled || uconn.config.ClientSessionCache == nil {
+		return fmt.Errorf("tls: SetPskExtension failed: session is disabled")
+	}
+	if pskExt == nil {
+		return nil
+	}
+
+	uconn.HandshakeState.Hello.TicketSupported = true
+	return uconn.sessionController.overridePskExt(pskExt)
 }
 
 // If you want session tickets to be reused - use same cache on following connections
@@ -182,7 +278,7 @@ func (uconn *UConn) SetSNI(sni string) {
 // It returns an error when used with HelloGolang ClientHelloID
 func (uconn *UConn) RemoveSNIExtension() error {
 	if uconn.ClientHelloID == HelloGolang {
-		return fmt.Errorf("Cannot call RemoveSNIExtension on a UConn with a HelloGolang ClientHelloID")
+		return fmt.Errorf("cannot call RemoveSNIExtension on a UConn with a HelloGolang ClientHelloID")
 	}
 	uconn.omitSNIExtension = true
 	return nil
@@ -221,7 +317,7 @@ func (c *UConn) 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() {
+	if c.isHandshakeComplete.Load() {
 		return nil
 	}
 
@@ -236,7 +332,10 @@ func (c *UConn) handshakeContext(ctx context.Context) (ret error) {
 	//
 	// 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 {
+	if c.quic != nil {
+		c.quic.cancelc = handshakeCtx.Done()
+		c.quic.cancel = cancel
+	} else if ctx.Done() != nil {
 		done := make(chan struct{})
 		interruptRes := make(chan error, 1)
 		defer func() {
@@ -264,7 +363,7 @@ func (c *UConn) handshakeContext(ctx context.Context) (ret error) {
 	if err := c.handshakeErr; err != nil {
 		return err
 	}
-	if c.handshakeComplete() {
+	if c.isHandshakeComplete.Load() {
 		return nil
 	}
 
@@ -288,9 +387,36 @@ func (c *UConn) handshakeContext(ctx context.Context) (ret error) {
 		c.flush()
 	}
 
-	if c.handshakeErr == nil && !c.handshakeComplete() {
+	if c.handshakeErr == nil && !c.isHandshakeComplete.Load() {
 		c.handshakeErr = errors.New("tls: internal error: handshake should have had a result")
 	}
+	if c.handshakeErr != nil && c.isHandshakeComplete.Load() {
+		panic("tls: internal error: handshake returned an error but is marked successful")
+	}
+
+	if c.quic != nil {
+		if c.handshakeErr == nil {
+			c.quicHandshakeComplete()
+			// Provide the 1-RTT read secret now that the handshake is complete.
+			// The QUIC layer MUST NOT decrypt 1-RTT packets prior to completing
+			// the handshake (RFC 9001, Section 5.7).
+			c.quicSetReadSecret(QUICEncryptionLevelApplication, c.cipherSuite, c.in.trafficSecret)
+		} else {
+			var a alert
+			c.out.Lock()
+			if !errors.As(c.out.err, &a) {
+				a = alertInternalError
+			}
+			c.out.Unlock()
+			// Return an error which wraps both the handshake error and
+			// any alert error we may have sent, or alertInternalError
+			// if we didn't send an alert.
+			// Truncate the text of the alert to 0 characters.
+			c.handshakeErr = fmt.Errorf("%w%.0w", c.handshakeErr, AlertError(a))
+		}
+		close(c.quic.blockedc)
+		close(c.quic.signalc)
+	}
 
 	return c.handshakeErr
 }
@@ -300,12 +426,12 @@ func (c *UConn) handshakeContext(ctx context.Context) (ret error) {
 func (c *UConn) Write(b []byte) (int, error) {
 	// interlock with Close below
 	for {
-		x := atomic.LoadInt32(&c.activeCall)
+		x := c.activeCall.Load()
 		if x&1 != 0 {
 			return 0, net.ErrClosed
 		}
-		if atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) {
-			defer atomic.AddInt32(&c.activeCall, -2)
+		if c.activeCall.CompareAndSwap(x, x+2) {
+			defer c.activeCall.Add(-2)
 			break
 		}
 	}
@@ -321,7 +447,7 @@ func (c *UConn) Write(b []byte) (int, error) {
 		return 0, err
 	}
 
-	if !c.handshakeComplete() {
+	if !c.isHandshakeComplete.Load() {
 		return 0, alertInternalError
 	}
 
@@ -360,7 +486,7 @@ func (c *UConn) clientHandshake(ctx context.Context) (err error) {
 	hello := c.HandshakeState.Hello.getPrivatePtr()
 	defer func() { c.HandshakeState.Hello = hello.getPublicPtr() }()
 
-	sessionIsAlreadySet := c.HandshakeState.Session != nil
+	sessionIsLocked := c.utls.sessionController.isSessionLocked()
 
 	// after this point exactly 1 out of 2 HandshakeState pointers is non-nil,
 	// useTLS13 variable tells which pointer
@@ -397,13 +523,28 @@ func (c *UConn) clientHandshake(ctx context.Context) (err error) {
 	if c.handshakes > 0 {
 		hello.secureRenegotiation = c.clientFinished[:]
 	}
-	// [uTLS section ends]
 
-	cacheKey, session, earlySecret, binderKey, err := c.loadSession(hello)
+	var (
+		session     *SessionState
+		earlySecret []byte
+		binderKey   []byte
+	)
+	if !sessionIsLocked {
+		// [uTLS section ends]
+
+		session, earlySecret, binderKey, err = c.loadSession(hello)
+
+		// [uTLS section start]
+	} else {
+		session = c.HandshakeState.Session
+		earlySecret = c.HandshakeState.State13.EarlySecret
+		binderKey = c.HandshakeState.State13.BinderKey
+	}
+	// [uTLS section ends]
 	if err != nil {
 		return err
 	}
-	if cacheKey != "" && session != nil {
+	if session != nil {
 		defer func() {
 			// If we got a handshake failure when resuming a session, throw away
 			// the session ticket. See RFC 5077, Section 3.2.
@@ -412,22 +553,27 @@ func (c *UConn) clientHandshake(ctx context.Context) (err error) {
 			// 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 cacheKey := c.clientSessionCacheKey(); cacheKey != "" {
+					c.config.ClientSessionCache.Put(cacheKey, nil)
+				}
 			}
 		}()
 	}
 
-	if !sessionIsAlreadySet { // uTLS: do not overwrite already set session
-		err = c.SetSessionState(session)
-		if err != nil {
-			return
-		}
-	}
-
 	if _, err := c.writeHandshakeRecord(hello, nil); err != nil {
 		return err
 	}
 
+	if hello.earlyData {
+		suite := cipherSuiteTLS13ByID(session.cipherSuite)
+		transcript := suite.hash.New()
+		if err := transcriptMsg(hello, transcript); err != nil {
+			return err
+		}
+		earlyTrafficSecret := suite.deriveSecret(earlySecret, clientEarlyTrafficLabel, transcript)
+		c.quicSetWriteSecret(QUICEncryptionLevelEarly, suite.id, earlyTrafficSecret)
+	}
+
 	msg, err := c.readHandshake(nil)
 	if err != nil {
 		return err
@@ -448,9 +594,13 @@ func (c *UConn) clientHandshake(ctx context.Context) (err error) {
 		hs13 := c.HandshakeState.toPrivate13()
 		hs13.serverHello = serverHello
 		hs13.hello = hello
-		if !sessionIsAlreadySet {
+		if hs13.keySharesParams == nil {
+			hs13.keySharesParams = NewKeySharesParameters()
+		}
+		if !sessionIsLocked {
 			hs13.earlySecret = earlySecret
 			hs13.binderKey = binderKey
+			hs13.session = session
 		}
 		hs13.ctx = ctx
 		// In TLS 1.3, session tickets are delivered after the handshake.
@@ -465,6 +615,7 @@ func (c *UConn) clientHandshake(ctx context.Context) (err error) {
 	hs12.serverHello = serverHello
 	hs12.hello = hello
 	hs12.ctx = ctx
+	hs12.session = session
 	err = hs12.handshake()
 	if handshakeState := hs12.toPublic12(); handshakeState != nil {
 		c.HandshakeState = *handshakeState
@@ -472,12 +623,6 @@ func (c *UConn) clientHandshake(ctx context.Context) (err error) {
 	if 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 != "" && hs12.session != nil && session != hs12.session {
-		c.config.ClientSessionCache.Put(cacheKey, hs12.session)
-	}
 	return nil
 }
 
@@ -492,13 +637,26 @@ func (uconn *UConn) ApplyConfig() error {
 }
 
 func (uconn *UConn) MarshalClientHello() error {
+	if len(uconn.config.ECHConfigs) > 0 && uconn.ech != nil {
+		if err := uconn.ech.Configure(uconn.config.ECHConfigs); err != nil {
+			return err
+		}
+		return uconn.ech.MarshalClientHello(uconn)
+	}
+
+	return uconn.MarshalClientHelloNoECH() // if no ECH pointer, just marshal normally
+}
+
+// MarshalClientHelloNoECH marshals ClientHello as if there was no
+// ECH extension present.
+func (uconn *UConn) MarshalClientHelloNoECH() error {
 	hello := uconn.HandshakeState.Hello
 	headerLength := 2 + 32 + 1 + len(hello.SessionId) +
 		2 + len(hello.CipherSuites)*2 +
 		1 + len(hello.CompressionMethods)
 
 	extensionsLen := 0
-	var paddingExt *UtlsPaddingExtension
+	var paddingExt *UtlsPaddingExtension // reference to padding extension, if present
 	for _, ext := range uconn.Extensions {
 		if pe, ok := ext.(*UtlsPaddingExtension); !ok {
 			// If not padding - just add length of extension to total length
@@ -508,7 +666,7 @@ func (uconn *UConn) MarshalClientHello() error {
 			if paddingExt == nil {
 				paddingExt = pe
 			} else {
-				return errors.New("Multiple padding extensions!")
+				return errors.New("multiple padding extensions")
 			}
 		}
 	}
@@ -550,7 +708,9 @@ func (uconn *UConn) MarshalClientHello() error {
 	if len(uconn.Extensions) > 0 {
 		binary.Write(bufferedWriter, binary.BigEndian, uint16(extensionsLen))
 		for _, ext := range uconn.Extensions {
-			bufferedWriter.ReadFrom(ext)
+			if _, err := bufferedWriter.ReadFrom(ext); err != nil {
+				return err
+			}
 		}
 	}
 
@@ -576,7 +736,7 @@ func (uconn *UConn) GetOutKeystream(length int) ([]byte, error) {
 		// AEAD.Seal() does not mutate internal state, other ciphers might
 		return outCipher.Seal(nil, uconn.out.seq[:], zeros, nil), nil
 	}
-	return nil, errors.New("Could not convert OutCipher to cipher.AEAD")
+	return nil, errors.New("could not convert OutCipher to cipher.AEAD")
 }
 
 // SetTLSVers sets min and max TLS version in all appropriate places.
@@ -686,7 +846,7 @@ func MakeConnWithCompleteHandshake(tcpConn net.Conn, version uint16, cipherSuite
 		}
 
 		// skip the handshake states
-		atomic.StoreUint32(&tlsConn.handshakeStatus, 1)
+		tlsConn.isHandshakeComplete.Store(true)
 		tlsConn.cipherSuite = cipherSuite
 		tlsConn.haveVers = true
 		tlsConn.vers = version
@@ -733,10 +893,148 @@ func (c *Conn) utlsHandshakeMessageType(msgType byte) (handshakeMessage, error)
 // Extending (*Conn).connectionStateLocked()
 func (c *Conn) utlsConnectionStateLocked(state *ConnectionState) {
 	state.PeerApplicationSettings = c.utls.peerApplicationSettings
+	state.ECHRetryConfigs = c.utls.echRetryConfigs
 }
 
 type utlsConnExtraFields struct {
+	// Application Settings (ALPS)
 	hasApplicationSettings   bool
 	peerApplicationSettings  []byte
 	localApplicationSettings []byte
+
+	// Encrypted Client Hello (ECH)
+	echRetryConfigs []ECHConfig
+
+	sessionController *sessionController
+}
+
+// Read reads data from the connection.
+//
+// As Read calls [Conn.Handshake], in order to prevent indefinite blocking a deadline
+// must be set for both Read and [Conn.Write] before Read is called when the handshake
+// has not yet completed. See [Conn.SetDeadline], [Conn.SetReadDeadline], and
+// [Conn.SetWriteDeadline].
+func (c *UConn) 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
+}
+
+// handleRenegotiation processes a HelloRequest handshake message.
+func (c *UConn) handleRenegotiation() error {
+	if c.vers == VersionTLS13 {
+		return errors.New("tls: internal error: unexpected renegotiation")
+	}
+
+	msg, err := c.readHandshake(nil)
+	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()
+
+	c.isHandshakeComplete.Store(false)
+
+	// [uTLS section begins]
+	if err = c.BuildHandshakeState(); err != nil {
+		return err
+	}
+	// [uTLS section ends]
+	if c.handshakeErr = c.clientHandshake(context.Background()); c.handshakeErr == nil {
+		c.handshakes++
+	}
+	return c.handshakeErr
+}
+
+// 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 *UConn) handlePostHandshakeMessage() error {
+	if c.vers != VersionTLS13 {
+		return c.handleRenegotiation()
+	}
+
+	msg, err := c.readHandshake(nil)
+	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)
+	}
+	// The QUIC layer is supposed to treat an unexpected post-handshake CertificateRequest
+	// as a QUIC-level PROTOCOL_VIOLATION error (RFC 9001, Section 4.4). Returning an
+	// unexpected_message alert here doesn't provide it with enough information to distinguish
+	// this condition from other unexpected messages. This is probably fine.
+	c.sendAlert(alertUnexpectedMessage)
+	return fmt.Errorf("tls: received unexpected handshake message of type %T", msg)
 }
diff --git a/vendor/github.com/refraction-networking/utls/u_ech.go b/vendor/github.com/refraction-networking/utls/u_ech.go
new file mode 100644
index 00000000..fad8dd02
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/u_ech.go
@@ -0,0 +1,329 @@
+package tls
+
+import (
+	"crypto/rand"
+	"errors"
+	"fmt"
+	"io"
+	"math/big"
+	"sync"
+
+	"github.com/cloudflare/circl/hpke"
+	"github.com/refraction-networking/utls/dicttls"
+	"golang.org/x/crypto/cryptobyte"
+)
+
+// Unstable API: This is a work in progress and may change in the future. Using
+// it in your application may cause your application to break when updating to
+// a new version of uTLS.
+
+const (
+	OuterClientHello byte = 0x00
+	InnerClientHello byte = 0x01
+)
+
+type EncryptedClientHelloExtension interface {
+	// TLSExtension must be implemented by all EncryptedClientHelloExtension implementations.
+	TLSExtension
+
+	// Configure configures the EncryptedClientHelloExtension with the given slice of ECHConfig.
+	Configure([]ECHConfig) error
+
+	// MarshalClientHello is called by (*UConn).MarshalClientHello() when an ECH extension
+	// is present to allow the ECH extension to take control of the generation of the
+	// entire ClientHello message.
+	MarshalClientHello(*UConn) error
+
+	mustEmbedUnimplementedECHExtension()
+}
+
+type ECHExtension = EncryptedClientHelloExtension // alias
+
+// type guard: GREASEEncryptedClientHelloExtension must implement EncryptedClientHelloExtension
+var (
+	_ EncryptedClientHelloExtension = (*GREASEEncryptedClientHelloExtension)(nil)
+
+	_ EncryptedClientHelloExtension = (*UnimplementedECHExtension)(nil)
+)
+
+type GREASEEncryptedClientHelloExtension struct {
+	CandidateCipherSuites []HPKESymmetricCipherSuite
+	cipherSuite           HPKESymmetricCipherSuite // randomly picked from CandidateCipherSuites or generated if empty
+	CandidateConfigIds    []uint8
+	configId              uint8    // randomly picked from CandidateConfigIds or generated if empty
+	EncapsulatedKey       []byte   // if empty, will generate random bytes
+	CandidatePayloadLens  []uint16 // Pre-encryption. If 0, will pick 128(+16=144)
+	payload               []byte   // payload should be calculated ONCE and stored here, HRR will reuse this
+
+	initOnce sync.Once
+
+	UnimplementedECHExtension
+}
+
+type GREASEECHExtension = GREASEEncryptedClientHelloExtension // alias
+
+// init initializes the GREASEEncryptedClientHelloExtension with random values if they are not set.
+//
+// Based on cloudflare/go's echGenerateGreaseExt()
+func (g *GREASEEncryptedClientHelloExtension) init() error {
+	var initErr error
+	g.initOnce.Do(func() {
+		// Set the config_id field to a random byte.
+		//
+		// Note: must not reuse this extension unless for HRR. It is required
+		// to generate new random bytes for config_id for each new ClientHello,
+		// but reuse the same config_id for HRR.
+		if len(g.CandidateConfigIds) == 0 {
+			var b []byte = make([]byte, 1)
+			_, err := rand.Read(b[:])
+			if err != nil {
+				initErr = fmt.Errorf("error generating random byte for config_id: %w", err)
+				return
+			}
+			g.configId = b[0]
+		} else {
+			// randomly pick one from the list
+			rndIndex, err := rand.Int(rand.Reader, big.NewInt(int64(len(g.CandidateConfigIds))))
+			if err != nil {
+				initErr = fmt.Errorf("error generating random index for config_id: %w", err)
+				return
+			}
+			g.configId = g.CandidateConfigIds[rndIndex.Int64()]
+		}
+
+		// Set the cipher_suite field to a supported HpkeSymmetricCipherSuite.
+		// The selection SHOULD vary to exercise all supported configurations,
+		// but MAY be held constant for successive connections to the same server
+		// in the same session.
+		if len(g.CandidateCipherSuites) == 0 {
+			_, kdf, aead := defaultHPKESuite.Params()
+			g.cipherSuite = HPKESymmetricCipherSuite{uint16(kdf), uint16(aead)}
+		} else {
+			// randomly pick one from the list
+			rndIndex, err := rand.Int(rand.Reader, big.NewInt(int64(len(g.CandidateCipherSuites))))
+			if err != nil {
+				initErr = fmt.Errorf("error generating random index for cipher_suite: %w", err)
+				return
+			}
+			g.cipherSuite = HPKESymmetricCipherSuite{
+				g.CandidateCipherSuites[rndIndex.Int64()].KdfId,
+				g.CandidateCipherSuites[rndIndex.Int64()].AeadId,
+			}
+			// aead = hpke.AEAD(g.cipherSuite.AeadId)
+		}
+
+		if len(g.EncapsulatedKey) == 0 {
+			// use default random key from cloudflare/go
+			kem := hpke.KEM_X25519_HKDF_SHA256
+
+			pk, err := kem.Scheme().UnmarshalBinaryPublicKey(dummyX25519PublicKey)
+			if err != nil {
+				initErr = fmt.Errorf("tls: grease ech: failed to parse dummy public key: %w", err)
+				return
+			}
+			sender, err := defaultHPKESuite.NewSender(pk, nil)
+			if err != nil {
+				initErr = fmt.Errorf("tls: grease ech: failed to create sender: %w", err)
+				return
+			}
+
+			g.EncapsulatedKey, _, err = sender.Setup(rand.Reader)
+			if err != nil {
+				initErr = fmt.Errorf("tls: grease ech: failed to setup encapsulated key: %w", err)
+				return
+			}
+		}
+
+		if len(g.payload) == 0 {
+			if len(g.CandidatePayloadLens) == 0 {
+				g.CandidatePayloadLens = []uint16{128}
+			}
+
+			// randomly pick one from the list
+			rndIndex, err := rand.Int(rand.Reader, big.NewInt(int64(len(g.CandidatePayloadLens))))
+			if err != nil {
+				initErr = fmt.Errorf("error generating random index for payload length: %w", err)
+				return
+			}
+
+			initErr = g.randomizePayload(g.CandidatePayloadLens[rndIndex.Int64()])
+		}
+	})
+
+	return initErr
+}
+
+func (g *GREASEEncryptedClientHelloExtension) randomizePayload(encodedHelloInnerLen uint16) error {
+	if len(g.payload) != 0 {
+		return errors.New("tls: grease ech: regenerating payload is forbidden")
+	}
+
+	aead := hpke.AEAD(g.cipherSuite.AeadId)
+	g.payload = make([]byte, int(aead.CipherLen(uint(encodedHelloInnerLen))))
+	_, err := rand.Read(g.payload)
+	if err != nil {
+		return fmt.Errorf("tls: generating grease ech payload: %w", err)
+	}
+	return nil
+}
+
+// writeToUConn implements TLSExtension.
+//
+// For ECH extensions, writeToUConn simply points the ech field in UConn to the extension.
+func (g *GREASEEncryptedClientHelloExtension) writeToUConn(uconn *UConn) error {
+	uconn.ech = g
+	return uconn.MarshalClientHelloNoECH()
+}
+
+// Len implements TLSExtension.
+func (g *GREASEEncryptedClientHelloExtension) Len() int {
+	g.init()
+	return 2 + 2 + 1 /* ClientHello Type */ + 4 /* CipherSuite */ + 1 /* Config ID */ + 2 + len(g.EncapsulatedKey) + 2 + len(g.payload)
+}
+
+// Read implements TLSExtension.
+func (g *GREASEEncryptedClientHelloExtension) Read(b []byte) (int, error) {
+	if len(b) < g.Len() {
+		return 0, io.ErrShortBuffer
+	}
+
+	b[0] = byte(utlsExtensionECH >> 8)
+	b[1] = byte(utlsExtensionECH & 0xFF)
+	b[2] = byte((g.Len() - 4) >> 8)
+	b[3] = byte((g.Len() - 4) & 0xFF)
+	b[4] = OuterClientHello
+	b[5] = byte(g.cipherSuite.KdfId >> 8)
+	b[6] = byte(g.cipherSuite.KdfId & 0xFF)
+	b[7] = byte(g.cipherSuite.AeadId >> 8)
+	b[8] = byte(g.cipherSuite.AeadId & 0xFF)
+	b[9] = g.configId
+	b[10] = byte(len(g.EncapsulatedKey) >> 8)
+	b[11] = byte(len(g.EncapsulatedKey) & 0xFF)
+	copy(b[12:], g.EncapsulatedKey)
+	b[12+len(g.EncapsulatedKey)] = byte(len(g.payload) >> 8)
+	b[12+len(g.EncapsulatedKey)+1] = byte(len(g.payload) & 0xFF)
+	copy(b[12+len(g.EncapsulatedKey)+2:], g.payload)
+
+	return g.Len(), io.EOF
+}
+
+// Configure implements EncryptedClientHelloExtension.
+func (*GREASEEncryptedClientHelloExtension) Configure([]ECHConfig) error {
+	return nil // no-op, it is not possible to configure a GREASE extension for now
+}
+
+// MarshalClientHello implements EncryptedClientHelloExtension.
+func (*GREASEEncryptedClientHelloExtension) MarshalClientHello(*UConn) error {
+	return errors.New("tls: grease ech: MarshalClientHello() is not implemented, use (*UConn).MarshalClientHello() instead")
+}
+
+// Write implements TLSExtensionWriter.
+func (g *GREASEEncryptedClientHelloExtension) Write(b []byte) (int, error) {
+	fullLen := len(b)
+	extData := cryptobyte.String(b)
+
+	// Check the extension type, it must be OuterClientHello otherwise we are not
+	// parsing the correct extension
+	var chType uint8 // 0: outer, 1: inner
+	var ignored cryptobyte.String
+	if !extData.ReadUint8(&chType) || chType != 0 {
+		return fullLen, errors.New("bad Client Hello type, expected 0, got " + fmt.Sprintf("%d", chType))
+	}
+
+	// Parse the cipher suite
+	if !extData.ReadUint16(&g.cipherSuite.KdfId) || !extData.ReadUint16(&g.cipherSuite.AeadId) {
+		return fullLen, errors.New("bad cipher suite")
+	}
+	if g.cipherSuite.KdfId != dicttls.HKDF_SHA256 &&
+		g.cipherSuite.KdfId != dicttls.HKDF_SHA384 &&
+		g.cipherSuite.KdfId != dicttls.HKDF_SHA512 {
+		return fullLen, errors.New("bad KDF ID: " + fmt.Sprintf("%d", g.cipherSuite.KdfId))
+	}
+	if g.cipherSuite.AeadId != dicttls.AEAD_AES_128_GCM &&
+		g.cipherSuite.AeadId != dicttls.AEAD_AES_256_GCM &&
+		g.cipherSuite.AeadId != dicttls.AEAD_CHACHA20_POLY1305 {
+		return fullLen, errors.New("bad AEAD ID: " + fmt.Sprintf("%d", g.cipherSuite.AeadId))
+	}
+	g.CandidateCipherSuites = []HPKESymmetricCipherSuite{g.cipherSuite}
+
+	// GREASE the ConfigId
+	if !extData.ReadUint8(&g.configId) {
+		return fullLen, errors.New("bad config ID")
+	}
+	// we don't write to CandidateConfigIds because we don't really want to reuse the same config_id
+
+	// GREASE the EncapsulatedKey
+	if !extData.ReadUint16LengthPrefixed(&ignored) {
+		return fullLen, errors.New("bad encapsulated key")
+	}
+	g.EncapsulatedKey = make([]byte, len(ignored))
+	n, err := rand.Read(g.EncapsulatedKey)
+	if err != nil {
+		return fullLen, fmt.Errorf("tls: generating grease ech encapsulated key: %w", err)
+	}
+	if n != len(g.EncapsulatedKey) {
+		return fullLen, fmt.Errorf("tls: generating grease ech encapsulated key: short read for %d bytes", len(ignored)-n)
+	}
+
+	// GREASE the payload
+	if !extData.ReadUint16LengthPrefixed(&ignored) {
+		return fullLen, errors.New("bad payload")
+	}
+	aead := hpke.AEAD(g.cipherSuite.AeadId)
+	g.CandidatePayloadLens = []uint16{uint16(len(ignored) - int(aead.CipherLen(0)))}
+
+	return fullLen, nil
+}
+
+// UnimplementedECHExtension is a placeholder for an ECH extension that is not implemented.
+// All implementations of EncryptedClientHelloExtension should embed this struct to ensure
+// forward compatibility.
+type UnimplementedECHExtension struct{}
+
+// writeToUConn implements TLSExtension.
+func (*UnimplementedECHExtension) writeToUConn(_ *UConn) error {
+	return errors.New("tls: unimplemented ECHExtension")
+}
+
+// Len implements TLSExtension.
+func (*UnimplementedECHExtension) Len() int {
+	return 0
+}
+
+// Read implements TLSExtension.
+func (*UnimplementedECHExtension) Read(_ []byte) (int, error) {
+	return 0, errors.New("tls: unimplemented ECHExtension")
+}
+
+// Configure implements EncryptedClientHelloExtension.
+func (*UnimplementedECHExtension) Configure([]ECHConfig) error {
+	return errors.New("tls: unimplemented ECHExtension")
+}
+
+// MarshalClientHello implements EncryptedClientHelloExtension.
+func (*UnimplementedECHExtension) MarshalClientHello(*UConn) error {
+	return errors.New("tls: unimplemented ECHExtension")
+}
+
+// mustEmbedUnimplementedECHExtension is a noop function but is required to
+// ensure forward compatibility.
+func (*UnimplementedECHExtension) mustEmbedUnimplementedECHExtension() {
+	panic("mustEmbedUnimplementedECHExtension() is not implemented")
+}
+
+// BoringGREASEECH returns a GREASE scheme BoringSSL uses by default.
+func BoringGREASEECH() *GREASEEncryptedClientHelloExtension {
+	return &GREASEEncryptedClientHelloExtension{
+		CandidateCipherSuites: []HPKESymmetricCipherSuite{
+			{
+				KdfId:  dicttls.HKDF_SHA256,
+				AeadId: dicttls.AEAD_AES_128_GCM,
+			},
+			{
+				KdfId:  dicttls.HKDF_SHA256,
+				AeadId: dicttls.AEAD_CHACHA20_POLY1305,
+			},
+		},
+		CandidatePayloadLens: []uint16{128, 160, 192, 224}, // +16: 144, 176, 208, 240
+	}
+}
diff --git a/vendor/github.com/refraction-networking/utls/u_ech_config.go b/vendor/github.com/refraction-networking/utls/u_ech_config.go
new file mode 100644
index 00000000..633c7b12
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/u_ech_config.go
@@ -0,0 +1,135 @@
+package tls
+
+import (
+	"errors"
+	"fmt"
+
+	"github.com/cloudflare/circl/hpke"
+	"golang.org/x/crypto/cryptobyte"
+)
+
+type ECHConfigContents struct {
+	KeyConfig         HPKEKeyConfig
+	MaximumNameLength uint8
+	PublicName        []byte
+	// Extensions        []TLSExtension // ignored for now
+	rawExtensions []byte
+}
+
+func UnmarshalECHConfigContents(contents []byte) (ECHConfigContents, error) {
+	var (
+		contentCryptobyte = cryptobyte.String(contents)
+		config            ECHConfigContents
+	)
+
+	// Parse KeyConfig
+	var t cryptobyte.String
+	if !contentCryptobyte.ReadUint8(&config.KeyConfig.ConfigId) ||
+		!contentCryptobyte.ReadUint16(&config.KeyConfig.KemId) ||
+		!contentCryptobyte.ReadUint16LengthPrefixed(&t) ||
+		!t.ReadBytes(&config.KeyConfig.rawPublicKey, len(t)) ||
+		!contentCryptobyte.ReadUint16LengthPrefixed(&t) ||
+		len(t)%4 != 0 {
+		return config, errors.New("error parsing KeyConfig")
+	}
+
+	// Parse all CipherSuites in KeyConfig
+	config.KeyConfig.CipherSuites = nil
+	for !t.Empty() {
+		var kdfId, aeadId uint16
+		if !t.ReadUint16(&kdfId) || !t.ReadUint16(&aeadId) {
+			// This indicates an internal bug.
+			panic("internal error while parsing contents.cipher_suites")
+		}
+		config.KeyConfig.CipherSuites = append(config.KeyConfig.CipherSuites, HPKESymmetricCipherSuite{kdfId, aeadId})
+	}
+
+	if !contentCryptobyte.ReadUint8(&config.MaximumNameLength) ||
+		!contentCryptobyte.ReadUint8LengthPrefixed(&t) ||
+		!t.ReadBytes(&config.PublicName, len(t)) ||
+		!contentCryptobyte.ReadUint16LengthPrefixed(&t) ||
+		!t.ReadBytes(&config.rawExtensions, len(t)) ||
+		!contentCryptobyte.Empty() {
+		return config, errors.New("error parsing ECHConfigContents")
+	}
+	return config, nil
+}
+
+func (echcc *ECHConfigContents) ParsePublicKey() error {
+	var err error
+	kem := hpke.KEM(echcc.KeyConfig.KemId)
+	if !kem.IsValid() {
+		return errors.New("invalid KEM")
+	}
+	echcc.KeyConfig.PublicKey, err = kem.Scheme().UnmarshalBinaryPublicKey(echcc.KeyConfig.rawPublicKey)
+	if err != nil {
+		return fmt.Errorf("error parsing public key: %s", err)
+	}
+	return nil
+}
+
+type ECHConfig struct {
+	Version  uint16
+	Length   uint16
+	Contents ECHConfigContents
+
+	raw []byte
+}
+
+// UnmarshalECHConfigs parses a sequence of ECH configurations.
+//
+// Ported from cloudflare/go
+func UnmarshalECHConfigs(raw []byte) ([]ECHConfig, error) {
+	var (
+		err         error
+		config      ECHConfig
+		t, contents cryptobyte.String
+	)
+	configs := make([]ECHConfig, 0)
+	s := cryptobyte.String(raw)
+	if !s.ReadUint16LengthPrefixed(&t) || !s.Empty() {
+		return configs, errors.New("error parsing configs")
+	}
+	raw = raw[2:]
+ConfigsLoop:
+	for !t.Empty() {
+		l := len(t)
+		if !t.ReadUint16(&config.Version) ||
+			!t.ReadUint16LengthPrefixed(&contents) {
+			return nil, errors.New("error parsing config")
+		}
+		config.Length = uint16(len(contents))
+		n := l - len(t)
+		config.raw = raw[:n]
+		raw = raw[n:]
+
+		if config.Version != utlsExtensionECH {
+			continue ConfigsLoop
+		}
+
+		/**** cloudflare/go original ****/
+		// if !readConfigContents(&contents, &config) {
+		// 	return nil, errors.New("error parsing config contents")
+		// }
+
+		config.Contents, err = UnmarshalECHConfigContents(contents)
+		if err != nil {
+			return nil, fmt.Errorf("error parsing config contents: %s", err)
+		}
+
+		/**** cloudflare/go original ****/
+		// kem := hpke.KEM(config.kemId)
+		// if !kem.IsValid() {
+		// 	continue ConfigsLoop
+		// }
+		// config.pk, err = kem.Scheme().UnmarshalBinaryPublicKey(config.rawPublicKey)
+		// if err != nil {
+		// 	return nil, fmt.Errorf("error parsing public key: %s", err)
+		// }
+
+		config.Contents.ParsePublicKey() // parse the bytes into a public key
+
+		configs = append(configs, config)
+	}
+	return configs, nil
+}
diff --git a/vendor/github.com/refraction-networking/utls/u_fingerprinter.go b/vendor/github.com/refraction-networking/utls/u_fingerprinter.go
index 1e1e1c80..61afc733 100644
--- a/vendor/github.com/refraction-networking/utls/u_fingerprinter.go
+++ b/vendor/github.com/refraction-networking/utls/u_fingerprinter.go
@@ -8,7 +8,6 @@ package tls
 type Fingerprinter struct {
 	// AllowBluntMimicry will ensure that unknown extensions are
 	// passed along into the resulting ClientHelloSpec as-is
-	// It will not ensure that the PSK is passed along, if you require that, use KeepPSK
 	// WARNING: there could be numerous subtle issues with ClientHelloSpecs
 	// that are generated with this flag which could compromise security and/or mimicry
 	AllowBluntMimicry bool
@@ -18,6 +17,8 @@ type Fingerprinter struct {
 	// have any padding, but you suspect that other changes you make to the final hello
 	// (including things like different SNI lengths) would cause padding to be necessary
 	AlwaysAddPadding bool
+
+	RealPSKResumption bool // if set, PSK extension (if any) will be real PSK extension, otherwise it will be fake PSK extension
 }
 
 // FingerprintClientHello returns a ClientHelloSpec which is based on the
@@ -43,7 +44,8 @@ func (f *Fingerprinter) FingerprintClientHello(data []byte) (clientHelloSpec *Cl
 // as a more precise name for the function
 func (f *Fingerprinter) RawClientHello(raw []byte) (clientHelloSpec *ClientHelloSpec, err error) {
 	clientHelloSpec = &ClientHelloSpec{}
-	err = clientHelloSpec.FromRaw(raw, f.AllowBluntMimicry)
+
+	err = clientHelloSpec.FromRaw(raw, f.AllowBluntMimicry, f.RealPSKResumption)
 	if err != nil {
 		return nil, err
 	}
diff --git a/vendor/github.com/refraction-networking/utls/u_handshake_client.go b/vendor/github.com/refraction-networking/utls/u_handshake_client.go
index f59ffde9..ba40a862 100644
--- a/vendor/github.com/refraction-networking/utls/u_handshake_client.go
+++ b/vendor/github.com/refraction-networking/utls/u_handshake_client.go
@@ -97,7 +97,7 @@ func (hs *clientHandshakeStateTLS13) decompressCert(m utlsCompressedCertificateM
 	rawMsg[3] = uint8(m.uncompressedLength)
 
 	n, err := decompressed.Read(rawMsg[4:])
-	if err != nil {
+	if err != nil && !errors.Is(err, io.EOF) {
 		c.sendAlert(alertBadCertificate)
 		return nil, err
 	}
@@ -141,6 +141,7 @@ func (hs *clientHandshakeStateTLS13) sendClientEncryptedExtensions() error {
 func (hs *clientHandshakeStateTLS13) utlsReadServerParameters(encryptedExtensions *encryptedExtensionsMsg) error {
 	hs.c.utls.hasApplicationSettings = encryptedExtensions.utls.hasApplicationSettings
 	hs.c.utls.peerApplicationSettings = encryptedExtensions.utls.applicationSettings
+	hs.c.utls.echRetryConfigs = encryptedExtensions.utls.echRetryConfigs
 
 	if hs.c.utls.hasApplicationSettings {
 		if hs.uconn.vers < VersionTLS13 {
@@ -160,5 +161,174 @@ func (hs *clientHandshakeStateTLS13) utlsReadServerParameters(encryptedExtension
 		}
 	}
 
+	if len(hs.c.utls.echRetryConfigs) > 0 {
+		if hs.uconn.vers < VersionTLS13 {
+			return errors.New("tls: server sent ECH retry configs at invalid version")
+		}
+
+		// find ECH extension in ClientHello
+		var echIncluded bool
+		for _, ext := range hs.uconn.Extensions {
+			if _, ok := ext.(ECHExtension); ok {
+				echIncluded = true
+			}
+		}
+		if !echIncluded {
+			return errors.New("tls: server sent ECH retry configs without client sending ECH extension")
+		}
+	}
+
 	return nil
 }
+
+func (c *Conn) makeClientHelloForApplyPreset() (*clientHelloMsg, clientKeySharePrivate, error) {
+	config := c.config
+
+	// [UTLS SECTION START]
+	if len(config.ServerName) == 0 && !config.InsecureSkipVerify && len(config.InsecureServerNameToVerify) == 0 {
+		return nil, nil, errors.New("tls: at least one of ServerName, InsecureSkipVerify or InsecureServerNameToVerify must be specified in the tls.Config")
+	}
+	// [UTLS SECTION END]
+
+	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")
+	}
+
+	supportedVersions := config.supportedVersions(roleClient)
+	if len(supportedVersions) == 0 {
+		return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
+	}
+
+	clientHelloVersion := config.maxSupportedVersion(roleClient)
+	// 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),
+		extendedMasterSecret:         true,
+		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).
+	//
+	// The session ID is not set for QUIC connections (see RFC 9001, Section 8.4).
+	if c.quic == 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()
+	}
+	if testingOnlyForceClientHelloSignatureAlgorithms != nil {
+		hello.supportedSignatureAlgorithms = testingOnlyForceClientHelloSignatureAlgorithms
+	}
+
+	var secret clientKeySharePrivate // [UTLS]
+	if hello.supportedVersions[0] == VersionTLS13 {
+		// Reset the list of ciphers when the client only supports TLS 1.3.
+		if len(hello.supportedVersions) == 1 {
+			hello.cipherSuites = nil
+		}
+		if hasAESGCMHardwareSupport {
+			hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
+		} else {
+			hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13NoAES...)
+		}
+
+		// curveID := config.curvePreferences()[0]
+		// // [UTLS SECTION BEGINS]
+		// // Ported from cloudflare/go with modifications to preserve crypto/tls compatibility
+		// if scheme := curveIdToCirclScheme(curveID); scheme != nil {
+		// 	pk, sk, err := generateKemKeyPair(scheme, curveID, config.rand())
+		// 	if err != nil {
+		// 		return nil, nil, fmt.Errorf("generateKemKeyPair %s: %w", scheme.Name(), err)
+		// 	}
+		// 	packedPk, err := pk.MarshalBinary()
+		// 	if err != nil {
+		// 		return nil, nil, fmt.Errorf("pack circl public key %s: %w", scheme.Name(), err)
+		// 	}
+		// 	hello.keyShares = []keyShare{{group: curveID, data: packedPk}}
+		// 	secret = sk
+		// } else {
+		// 	if _, ok := curveForCurveID(curveID); !ok {
+		// 		return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve")
+		// 	}
+		// 	key, err := generateECDHEKey(config.rand(), curveID)
+		// 	if err != nil {
+		// 		return nil, nil, err
+		// 	}
+		// 	hello.keyShares = []keyShare{{group: curveID, data: key.PublicKey().Bytes()}}
+		// 	secret = key
+		// }
+		// // [UTLS SECTION ENDS]
+	}
+
+	// [UTLS] We don't need this, since it is not ready yet
+	// if c.quic != nil {
+	// 	p, err := c.quicGetTransportParameters()
+	// 	if err != nil {
+	// 		return nil, nil, err
+	// 	}
+	// 	if p == nil {
+	// 		p = []byte{}
+	// 	}
+	// 	hello.quicTransportParameters = p
+	// }
+
+	return hello, secret, nil
+}
diff --git a/vendor/github.com/refraction-networking/utls/u_handshake_messages.go b/vendor/github.com/refraction-networking/utls/u_handshake_messages.go
index e7ebb151..1c9f460c 100644
--- a/vendor/github.com/refraction-networking/utls/u_handshake_messages.go
+++ b/vendor/github.com/refraction-networking/utls/u_handshake_messages.go
@@ -56,6 +56,7 @@ func (m *utlsCompressedCertificateMsg) unmarshal(data []byte) bool {
 type utlsEncryptedExtensionsMsgExtraFields struct {
 	hasApplicationSettings bool
 	applicationSettings    []byte
+	echRetryConfigs        []ECHConfig
 	customExtension        []byte
 }
 
@@ -64,6 +65,12 @@ func (m *encryptedExtensionsMsg) utlsUnmarshal(extension uint16, extData cryptob
 	case utlsExtensionApplicationSettings:
 		m.utls.hasApplicationSettings = true
 		m.utls.applicationSettings = []byte(extData)
+	case utlsExtensionECH:
+		var err error
+		m.utls.echRetryConfigs, err = UnmarshalECHConfigs([]byte(extData))
+		if err != nil {
+			return false
+		}
 	}
 	return true // success/unknown extension
 }
diff --git a/vendor/github.com/refraction-networking/utls/u_hpke.go b/vendor/github.com/refraction-networking/utls/u_hpke.go
new file mode 100644
index 00000000..08d5eb4f
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/u_hpke.go
@@ -0,0 +1,62 @@
+package tls
+
+import (
+	"errors"
+	"fmt"
+
+	"github.com/cloudflare/circl/hpke"
+	"github.com/cloudflare/circl/kem"
+)
+
+type HPKERawPublicKey = []byte
+type HPKE_KEM_ID = uint16  // RFC 9180
+type HPKE_KDF_ID = uint16  // RFC 9180
+type HPKE_AEAD_ID = uint16 // RFC 9180
+
+type HPKESymmetricCipherSuite struct {
+	KdfId  HPKE_KDF_ID
+	AeadId HPKE_AEAD_ID
+}
+
+type HPKEKeyConfig struct {
+	ConfigId     uint8
+	KemId        HPKE_KEM_ID
+	PublicKey    kem.PublicKey
+	rawPublicKey HPKERawPublicKey
+	CipherSuites []HPKESymmetricCipherSuite
+}
+
+var defaultHPKESuite hpke.Suite
+
+func init() {
+	var err error
+	defaultHPKESuite, err = hpkeAssembleSuite(
+		uint16(hpke.KEM_X25519_HKDF_SHA256),
+		uint16(hpke.KDF_HKDF_SHA256),
+		uint16(hpke.AEAD_AES128GCM),
+	)
+	if err != nil {
+		panic(fmt.Sprintf("hpke: mandatory-to-implement cipher suite not supported: %s", err))
+	}
+}
+
+func hpkeAssembleSuite(kemId, kdfId, aeadId uint16) (hpke.Suite, error) {
+	kem := hpke.KEM(kemId)
+	if !kem.IsValid() {
+		return hpke.Suite{}, errors.New("KEM is not supported")
+	}
+	kdf := hpke.KDF(kdfId)
+	if !kdf.IsValid() {
+		return hpke.Suite{}, errors.New("KDF is not supported")
+	}
+	aead := hpke.AEAD(aeadId)
+	if !aead.IsValid() {
+		return hpke.Suite{}, errors.New("AEAD is not supported")
+	}
+	return hpke.NewSuite(kem, kdf, aead), nil
+}
+
+var dummyX25519PublicKey = []byte{
+	143, 38, 37, 36, 12, 6, 229, 30, 140, 27, 167, 73, 26, 100, 203, 107, 216,
+	81, 163, 222, 52, 211, 54, 210, 46, 37, 78, 216, 157, 97, 241, 244,
+}
diff --git a/vendor/github.com/refraction-networking/utls/u_parrots.go b/vendor/github.com/refraction-networking/utls/u_parrots.go
index 06db67b0..8ac1ca07 100644
--- a/vendor/github.com/refraction-networking/utls/u_parrots.go
+++ b/vendor/github.com/refraction-networking/utls/u_parrots.go
@@ -5,16 +5,24 @@
 package tls
 
 import (
+	"crypto/ecdh"
+	crand "crypto/rand"
 	"crypto/sha256"
 	"encoding/binary"
 	"errors"
 	"fmt"
 	"io"
+	"math"
+	"math/big"
 	"math/rand"
 	"sort"
 	"strconv"
+
+	"github.com/refraction-networking/utls/dicttls"
 )
 
+var ErrUnknownClientHelloID = errors.New("tls: unknown ClientHelloID")
+
 // UTLSIdToSpec converts a ClientHelloID to a corresponding ClientHelloSpec.
 //
 // Exported internal function utlsIdToSpec per request.
@@ -49,7 +57,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 				&UtlsGREASEExtension{},
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&SessionTicketExtension{},
 				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
 					ECDSAWithP256AndSHA256,
@@ -104,7 +112,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 				&UtlsGREASEExtension{},
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&SessionTicketExtension{},
 				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
 					ECDSAWithP256AndSHA256,
@@ -173,7 +181,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			Extensions: []TLSExtension{
 				&UtlsGREASEExtension{},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SupportedCurvesExtension{[]CurveID{
 					CurveID(GREASE_PLACEHOLDER),
@@ -246,7 +254,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			Extensions: []TLSExtension{
 				&UtlsGREASEExtension{},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SupportedCurvesExtension{[]CurveID{
 					CurveID(GREASE_PLACEHOLDER),
@@ -318,7 +326,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			Extensions: []TLSExtension{
 				&UtlsGREASEExtension{},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SupportedCurvesExtension{[]CurveID{
 					CurveID(GREASE_PLACEHOLDER),
@@ -390,7 +398,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			Extensions: []TLSExtension{
 				&UtlsGREASEExtension{},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SupportedCurvesExtension{[]CurveID{
 					CurveID(GREASE_PLACEHOLDER),
@@ -463,7 +471,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			Extensions: []TLSExtension{
 				&UtlsGREASEExtension{},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SupportedCurvesExtension{[]CurveID{
 					GREASE_PLACEHOLDER,
@@ -508,7 +516,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 				&UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle},
 			},
 		}, nil
-	case HelloChrome_100_PSK:
+	case HelloChrome_106_Shuffle:
 		return ClientHelloSpec{
 			CipherSuites: []uint16{
 				GREASE_PLACEHOLDER,
@@ -531,10 +539,10 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			CompressionMethods: []byte{
 				0x00, // compressionNone
 			},
-			Extensions: []TLSExtension{
+			Extensions: ShuffleChromeTLSExtensions([]TLSExtension{
 				&UtlsGREASEExtension{},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SupportedCurvesExtension{[]CurveID{
 					GREASE_PLACEHOLDER,
@@ -576,27 +584,229 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 				}},
 				&ApplicationSettingsExtension{SupportedProtocols: []string{"h2"}},
 				&UtlsGREASEExtension{},
-				&FakePreSharedKeyExtension{},
+				&UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle},
+			}),
+		}, nil
+	// Chrome w/ Post-Quantum Key Agreement
+	case HelloChrome_115_PQ:
+		return ClientHelloSpec{
+			CipherSuites: []uint16{
+				GREASE_PLACEHOLDER,
+				TLS_AES_128_GCM_SHA256,
+				TLS_AES_256_GCM_SHA384,
+				TLS_CHACHA20_POLY1305_SHA256,
+				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,
+				TLS_ECDHE_RSA_WITH_AES_128_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,
+			},
+			CompressionMethods: []byte{
+				0x00, // compressionNone
 			},
+			Extensions: ShuffleChromeTLSExtensions([]TLSExtension{
+				&UtlsGREASEExtension{},
+				&SNIExtension{},
+				&ExtendedMasterSecretExtension{},
+				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
+				&SupportedCurvesExtension{[]CurveID{
+					GREASE_PLACEHOLDER,
+					X25519Kyber768Draft00,
+					X25519,
+					CurveP256,
+					CurveP384,
+				}},
+				&SupportedPointsExtension{SupportedPoints: []byte{
+					0x00, // pointFormatUncompressed
+				}},
+				&SessionTicketExtension{},
+				&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
+				&StatusRequestExtension{},
+				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
+					ECDSAWithP256AndSHA256,
+					PSSWithSHA256,
+					PKCS1WithSHA256,
+					ECDSAWithP384AndSHA384,
+					PSSWithSHA384,
+					PKCS1WithSHA384,
+					PSSWithSHA512,
+					PKCS1WithSHA512,
+				}},
+				&SCTExtension{},
+				&KeyShareExtension{[]KeyShare{
+					{Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}},
+					{Group: X25519Kyber768Draft00},
+					{Group: X25519},
+				}},
+				&PSKKeyExchangeModesExtension{[]uint8{
+					PskModeDHE,
+				}},
+				&SupportedVersionsExtension{[]uint16{
+					GREASE_PLACEHOLDER,
+					VersionTLS13,
+					VersionTLS12,
+				}},
+				&UtlsCompressCertExtension{[]CertCompressionAlgo{
+					CertCompressionBrotli,
+				}},
+				&ApplicationSettingsExtension{SupportedProtocols: []string{"h2"}},
+				&UtlsGREASEExtension{},
+				&UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle},
+			}),
+		}, nil
+	// Chrome ECH
+	case HelloChrome_120:
+		return ClientHelloSpec{
+			CipherSuites: []uint16{
+				GREASE_PLACEHOLDER,
+				TLS_AES_128_GCM_SHA256,
+				TLS_AES_256_GCM_SHA384,
+				TLS_CHACHA20_POLY1305_SHA256,
+				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,
+				TLS_ECDHE_RSA_WITH_AES_128_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,
+			},
+			CompressionMethods: []byte{
+				0x00, // compressionNone
+			},
+			Extensions: ShuffleChromeTLSExtensions([]TLSExtension{
+				&UtlsGREASEExtension{},
+				&SNIExtension{},
+				&ExtendedMasterSecretExtension{},
+				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
+				&SupportedCurvesExtension{Curves: []CurveID{
+					GREASE_PLACEHOLDER,
+					X25519,
+					CurveP256,
+					CurveP384,
+				}},
+				&SupportedPointsExtension{SupportedPoints: []byte{
+					0x00, // pointFormatUncompressed
+				}},
+				&SessionTicketExtension{},
+				&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
+				&StatusRequestExtension{},
+				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
+					ECDSAWithP256AndSHA256,
+					PSSWithSHA256,
+					PKCS1WithSHA256,
+					ECDSAWithP384AndSHA384,
+					PSSWithSHA384,
+					PKCS1WithSHA384,
+					PSSWithSHA512,
+					PKCS1WithSHA512,
+				}},
+				&SCTExtension{},
+				&KeyShareExtension{KeyShares: []KeyShare{
+					{Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}},
+					{Group: X25519},
+				}},
+				&PSKKeyExchangeModesExtension{Modes: []uint8{
+					PskModeDHE,
+				}},
+				&SupportedVersionsExtension{Versions: []uint16{
+					GREASE_PLACEHOLDER,
+					VersionTLS13,
+					VersionTLS12,
+				}},
+				&UtlsCompressCertExtension{Algorithms: []CertCompressionAlgo{
+					CertCompressionBrotli,
+				}},
+				&ApplicationSettingsExtension{SupportedProtocols: []string{"h2"}},
+				BoringGREASEECH(),
+				&UtlsGREASEExtension{},
+			}),
+		}, nil
+	// Chrome w/ Post-Quantum Key Agreement and ECH
+	case HelloChrome_120_PQ:
+		return ClientHelloSpec{
+			CipherSuites: []uint16{
+				GREASE_PLACEHOLDER,
+				TLS_AES_128_GCM_SHA256,
+				TLS_AES_256_GCM_SHA384,
+				TLS_CHACHA20_POLY1305_SHA256,
+				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,
+				TLS_ECDHE_RSA_WITH_AES_128_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,
+			},
+			CompressionMethods: []byte{
+				0x00, // compressionNone
+			},
+			Extensions: ShuffleChromeTLSExtensions([]TLSExtension{
+				&UtlsGREASEExtension{},
+				&SNIExtension{},
+				&ExtendedMasterSecretExtension{},
+				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
+				&SupportedCurvesExtension{[]CurveID{
+					GREASE_PLACEHOLDER,
+					X25519Kyber768Draft00,
+					X25519,
+					CurveP256,
+					CurveP384,
+				}},
+				&SupportedPointsExtension{SupportedPoints: []byte{
+					0x00, // pointFormatUncompressed
+				}},
+				&SessionTicketExtension{},
+				&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
+				&StatusRequestExtension{},
+				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
+					ECDSAWithP256AndSHA256,
+					PSSWithSHA256,
+					PKCS1WithSHA256,
+					ECDSAWithP384AndSHA384,
+					PSSWithSHA384,
+					PKCS1WithSHA384,
+					PSSWithSHA512,
+					PKCS1WithSHA512,
+				}},
+				&SCTExtension{},
+				&KeyShareExtension{[]KeyShare{
+					{Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}},
+					{Group: X25519Kyber768Draft00},
+					{Group: X25519},
+				}},
+				&PSKKeyExchangeModesExtension{[]uint8{
+					PskModeDHE,
+				}},
+				&SupportedVersionsExtension{[]uint16{
+					GREASE_PLACEHOLDER,
+					VersionTLS13,
+					VersionTLS12,
+				}},
+				&UtlsCompressCertExtension{[]CertCompressionAlgo{
+					CertCompressionBrotli,
+				}},
+				&ApplicationSettingsExtension{SupportedProtocols: []string{"h2"}},
+				BoringGREASEECH(),
+				&UtlsGREASEExtension{},
+			}),
 		}, nil
-	case HelloChrome_106_Shuffle:
-		chs, err := utlsIdToSpec(HelloChrome_102)
-		if err != nil {
-			return chs, err
-		}
-
-		// Chrome 107 started shuffling the order of extensions
-		shuffleExtensions(&chs)
-		return chs, err
-	case HelloChrome_112_PSK_Shuf:
-		chs, err := utlsIdToSpec(HelloChrome_100_PSK)
-		if err != nil {
-			return chs, err
-		}
-
-		// Chrome 112 started shuffling the order of extensions
-		shuffleExtensions(&chs)
-		return chs, err
 	case HelloFirefox_55, HelloFirefox_56:
 		return ClientHelloSpec{
 			TLSVersMax: VersionTLS12,
@@ -621,7 +831,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			CompressionMethods: []byte{compressionNone},
 			Extensions: []TLSExtension{
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SupportedCurvesExtension{[]CurveID{X25519, CurveP256, CurveP384, CurveP521}},
 				&SupportedPointsExtension{SupportedPoints: []byte{pointFormatUncompressed}},
@@ -674,7 +884,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			},
 			Extensions: []TLSExtension{
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SupportedCurvesExtension{[]CurveID{
 					X25519,
@@ -744,8 +954,8 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 				compressionNone,
 			},
 			Extensions: []TLSExtension{
-				&SNIExtension{},                      //server_name
-				&UtlsExtendedMasterSecretExtension{}, //extended_master_secret
+				&SNIExtension{},                  //server_name
+				&ExtendedMasterSecretExtension{}, //extended_master_secret
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient}, //extensionRenegotiationInfo
 				&SupportedCurvesExtension{[]CurveID{ //supported_groups
 					X25519,
@@ -825,8 +1035,8 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 				compressionNone,
 			},
 			Extensions: []TLSExtension{
-				&SNIExtension{},                      //server_name
-				&UtlsExtendedMasterSecretExtension{}, //extended_master_secret
+				&SNIExtension{},                  //server_name
+				&ExtendedMasterSecretExtension{}, //extended_master_secret
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient}, //extensionRenegotiationInfo
 				&SupportedCurvesExtension{[]CurveID{ //supported_groups
 					X25519,
@@ -905,7 +1115,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			},
 			Extensions: []TLSExtension{
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{
 					Renegotiation: RenegotiateOnceAsClient,
 				},
@@ -984,52 +1194,167 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 				},
 			},
 		}, nil
-	case HelloIOS_11_1:
+	case HelloFirefox_120:
 		return ClientHelloSpec{
-			TLSVersMax: VersionTLS12,
-			TLSVersMin: VersionTLS10,
+			TLSVersMin: VersionTLS12,
+			TLSVersMax: VersionTLS13,
 			CipherSuites: []uint16{
-				TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+				TLS_AES_128_GCM_SHA256,
+				TLS_CHACHA20_POLY1305_SHA256,
+				TLS_AES_256_GCM_SHA384,
 				TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
-				DISABLED_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
-				TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
-				TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
-				TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
 				TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+				TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
 				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
-				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-				DISABLED_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
-				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
-				TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+				TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+				TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
 				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
-				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
-				TLS_RSA_WITH_AES_256_GCM_SHA384,
+				TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
 				TLS_RSA_WITH_AES_128_GCM_SHA256,
-				DISABLED_TLS_RSA_WITH_AES_256_CBC_SHA256,
-				TLS_RSA_WITH_AES_128_CBC_SHA256,
-				TLS_RSA_WITH_AES_256_CBC_SHA,
+				TLS_RSA_WITH_AES_256_GCM_SHA384,
 				TLS_RSA_WITH_AES_128_CBC_SHA,
+				TLS_RSA_WITH_AES_256_CBC_SHA,
 			},
-			CompressionMethods: []byte{
-				compressionNone,
+			CompressionMethods: []uint8{
+				0x0, // no compression
 			},
 			Extensions: []TLSExtension{
-				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
-				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
-					ECDSAWithP256AndSHA256,
-					PSSWithSHA256,
-					PKCS1WithSHA256,
-					ECDSAWithP384AndSHA384,
-					PSSWithSHA384,
-					PKCS1WithSHA384,
-					PSSWithSHA512,
-					PKCS1WithSHA512,
-					PKCS1WithSHA1,
-				}},
-				&StatusRequestExtension{},
-				&NPNExtension{},
+				&ExtendedMasterSecretExtension{},
+				&RenegotiationInfoExtension{
+					Renegotiation: RenegotiateOnceAsClient,
+				},
+				&SupportedCurvesExtension{
+					Curves: []CurveID{
+						X25519,
+						CurveP256,
+						CurveP384,
+						CurveP521,
+						256,
+						257,
+					},
+				},
+				&SupportedPointsExtension{
+					SupportedPoints: []uint8{
+						0x0, // uncompressed
+					},
+				},
+				&SessionTicketExtension{},
+				&ALPNExtension{
+					AlpnProtocols: []string{
+						"h2",
+						"http/1.1",
+					},
+				},
+				&StatusRequestExtension{},
+				&FakeDelegatedCredentialsExtension{
+					SupportedSignatureAlgorithms: []SignatureScheme{
+						ECDSAWithP256AndSHA256,
+						ECDSAWithP384AndSHA384,
+						ECDSAWithP521AndSHA512,
+						ECDSAWithSHA1,
+					},
+				},
+				&KeyShareExtension{
+					KeyShares: []KeyShare{
+						{
+							Group: X25519,
+						},
+						{
+							Group: CurveP256,
+						},
+					},
+				},
+				&SupportedVersionsExtension{
+					Versions: []uint16{
+						VersionTLS13,
+						VersionTLS12,
+					},
+				},
+				&SignatureAlgorithmsExtension{
+					SupportedSignatureAlgorithms: []SignatureScheme{
+						ECDSAWithP256AndSHA256,
+						ECDSAWithP384AndSHA384,
+						ECDSAWithP521AndSHA512,
+						PSSWithSHA256,
+						PSSWithSHA384,
+						PSSWithSHA512,
+						PKCS1WithSHA256,
+						PKCS1WithSHA384,
+						PKCS1WithSHA512,
+						ECDSAWithSHA1,
+						PKCS1WithSHA1,
+					},
+				},
+				&PSKKeyExchangeModesExtension{[]uint8{
+					PskModeDHE,
+				}},
+				&FakeRecordSizeLimitExtension{
+					Limit: 0x4001,
+				},
+				&GREASEEncryptedClientHelloExtension{
+					CandidateCipherSuites: []HPKESymmetricCipherSuite{
+						{
+							KdfId:  dicttls.HKDF_SHA256,
+							AeadId: dicttls.AEAD_AES_128_GCM,
+						},
+						{
+							KdfId:  dicttls.HKDF_SHA256,
+							AeadId: dicttls.AEAD_CHACHA20_POLY1305,
+						},
+					},
+					CandidatePayloadLens: []uint16{223}, // +16: 239
+				},
+			},
+		}, nil
+	case HelloIOS_11_1:
+		return ClientHelloSpec{
+			TLSVersMax: VersionTLS12,
+			TLSVersMin: VersionTLS10,
+			CipherSuites: []uint16{
+				TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+				TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+				DISABLED_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+				TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+				TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+				TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+				TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+				DISABLED_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+				TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+				TLS_RSA_WITH_AES_256_GCM_SHA384,
+				TLS_RSA_WITH_AES_128_GCM_SHA256,
+				DISABLED_TLS_RSA_WITH_AES_256_CBC_SHA256,
+				TLS_RSA_WITH_AES_128_CBC_SHA256,
+				TLS_RSA_WITH_AES_256_CBC_SHA,
+				TLS_RSA_WITH_AES_128_CBC_SHA,
+			},
+			CompressionMethods: []byte{
+				compressionNone,
+			},
+			Extensions: []TLSExtension{
+				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
+				&SNIExtension{},
+				&ExtendedMasterSecretExtension{},
+				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
+					ECDSAWithP256AndSHA256,
+					PSSWithSHA256,
+					PKCS1WithSHA256,
+					ECDSAWithP384AndSHA384,
+					PSSWithSHA384,
+					PKCS1WithSHA384,
+					PSSWithSHA512,
+					PKCS1WithSHA512,
+					PKCS1WithSHA1,
+				}},
+				&StatusRequestExtension{},
+				&NPNExtension{},
 				&SCTExtension{},
 				&ALPNExtension{AlpnProtocols: []string{"h2", "h2-16", "h2-15", "h2-14", "spdy/3.1", "spdy/3", "http/1.1"}},
 				&SupportedPointsExtension{SupportedPoints: []byte{
@@ -1076,7 +1401,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			Extensions: []TLSExtension{
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
 					ECDSAWithP256AndSHA256,
 					PSSWithSHA256,
@@ -1141,7 +1466,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			Extensions: []TLSExtension{
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
 					ECDSAWithP256AndSHA256,
 					PSSWithSHA256,
@@ -1221,7 +1546,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			Extensions: []TLSExtension{
 				&UtlsGREASEExtension{},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
 				&SupportedCurvesExtension{[]CurveID{
 					CurveID(GREASE_PLACEHOLDER),
@@ -1288,7 +1613,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			},
 			Extensions: []TLSExtension{
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{},
 				// supported_groups
 				&SupportedCurvesExtension{[]CurveID{
@@ -1339,7 +1664,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			Extensions: []TLSExtension{
 				&UtlsGREASEExtension{},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{
 					Renegotiation: RenegotiateOnceAsClient,
 				},
@@ -1444,7 +1769,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			Extensions: []TLSExtension{
 				&UtlsGREASEExtension{},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{
 					Renegotiation: RenegotiateOnceAsClient,
 				},
@@ -1556,7 +1881,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			Extensions: []TLSExtension{
 				&UtlsGREASEExtension{},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{
 					Renegotiation: RenegotiateOnceAsClient,
 				},
@@ -1736,7 +2061,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			Extensions: []TLSExtension{
 				&UtlsGREASEExtension{},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{
 					Renegotiation: RenegotiateOnceAsClient,
 				},
@@ -1844,7 +2169,7 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 			Extensions: []TLSExtension{
 				&UtlsGREASEExtension{},
 				&SNIExtension{},
-				&UtlsExtendedMasterSecretExtension{},
+				&ExtendedMasterSecretExtension{},
 				&RenegotiationInfoExtension{
 					Renegotiation: RenegotiateOnceAsClient,
 				},
@@ -1925,58 +2250,341 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
 				},
 			},
 		}, nil
+	case HelloChrome_100_PSK:
+		return ClientHelloSpec{
+			CipherSuites: []uint16{
+				GREASE_PLACEHOLDER,
+				TLS_AES_128_GCM_SHA256,
+				TLS_AES_256_GCM_SHA384,
+				TLS_CHACHA20_POLY1305_SHA256,
+				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,
+				TLS_ECDHE_RSA_WITH_AES_128_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,
+			},
+			CompressionMethods: []byte{
+				0x00, // compressionNone
+			},
+			Extensions: []TLSExtension{
+				&UtlsGREASEExtension{},
+				&SNIExtension{},
+				&ExtendedMasterSecretExtension{},
+				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
+				&SupportedCurvesExtension{[]CurveID{
+					GREASE_PLACEHOLDER,
+					X25519,
+					CurveP256,
+					CurveP384,
+				}},
+				&SupportedPointsExtension{SupportedPoints: []byte{
+					0x00, // pointFormatUncompressed
+				}},
+				&SessionTicketExtension{},
+				&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
+				&StatusRequestExtension{},
+				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
+					ECDSAWithP256AndSHA256,
+					PSSWithSHA256,
+					PKCS1WithSHA256,
+					ECDSAWithP384AndSHA384,
+					PSSWithSHA384,
+					PKCS1WithSHA384,
+					PSSWithSHA512,
+					PKCS1WithSHA512,
+				}},
+				&SCTExtension{},
+				&KeyShareExtension{[]KeyShare{
+					{Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}},
+					{Group: X25519},
+				}},
+				&PSKKeyExchangeModesExtension{[]uint8{
+					PskModeDHE,
+				}},
+				&SupportedVersionsExtension{[]uint16{
+					GREASE_PLACEHOLDER,
+					VersionTLS13,
+					VersionTLS12,
+				}},
+				&UtlsCompressCertExtension{[]CertCompressionAlgo{
+					CertCompressionBrotli,
+				}},
+				&ApplicationSettingsExtension{SupportedProtocols: []string{"h2"}},
+				&UtlsGREASEExtension{},
+				&UtlsPreSharedKeyExtension{},
+			},
+		}, nil
+	case HelloChrome_112_PSK_Shuf:
+		return ClientHelloSpec{
+			CipherSuites: []uint16{
+				GREASE_PLACEHOLDER,
+				TLS_AES_128_GCM_SHA256,
+				TLS_AES_256_GCM_SHA384,
+				TLS_CHACHA20_POLY1305_SHA256,
+				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,
+				TLS_ECDHE_RSA_WITH_AES_128_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,
+			},
+			CompressionMethods: []byte{
+				0x00, // compressionNone
+			},
+			Extensions: ShuffleChromeTLSExtensions([]TLSExtension{
+				&UtlsGREASEExtension{},
+				&SNIExtension{},
+				&ExtendedMasterSecretExtension{},
+				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
+				&SupportedCurvesExtension{[]CurveID{
+					GREASE_PLACEHOLDER,
+					X25519,
+					CurveP256,
+					CurveP384,
+				}},
+				&SupportedPointsExtension{SupportedPoints: []byte{
+					0x00, // pointFormatUncompressed
+				}},
+				&SessionTicketExtension{},
+				&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
+				&StatusRequestExtension{},
+				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
+					ECDSAWithP256AndSHA256,
+					PSSWithSHA256,
+					PKCS1WithSHA256,
+					ECDSAWithP384AndSHA384,
+					PSSWithSHA384,
+					PKCS1WithSHA384,
+					PSSWithSHA512,
+					PKCS1WithSHA512,
+				}},
+				&SCTExtension{},
+				&KeyShareExtension{[]KeyShare{
+					{Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}},
+					{Group: X25519},
+				}},
+				&PSKKeyExchangeModesExtension{[]uint8{
+					PskModeDHE,
+				}},
+				&SupportedVersionsExtension{[]uint16{
+					GREASE_PLACEHOLDER,
+					VersionTLS13,
+					VersionTLS12,
+				}},
+				&UtlsCompressCertExtension{[]CertCompressionAlgo{
+					CertCompressionBrotli,
+				}},
+				&ApplicationSettingsExtension{SupportedProtocols: []string{"h2"}},
+				&UtlsGREASEExtension{},
+				&UtlsPreSharedKeyExtension{},
+			}),
+		}, nil
+	case HelloChrome_114_Padding_PSK_Shuf:
+		return ClientHelloSpec{
+			CipherSuites: []uint16{
+				GREASE_PLACEHOLDER,
+				TLS_AES_128_GCM_SHA256,
+				TLS_AES_256_GCM_SHA384,
+				TLS_CHACHA20_POLY1305_SHA256,
+				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,
+				TLS_ECDHE_RSA_WITH_AES_128_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,
+			},
+			CompressionMethods: []byte{
+				0x00, // compressionNone
+			},
+			Extensions: ShuffleChromeTLSExtensions([]TLSExtension{
+				&UtlsGREASEExtension{},
+				&SNIExtension{},
+				&ExtendedMasterSecretExtension{},
+				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
+				&SupportedCurvesExtension{[]CurveID{
+					GREASE_PLACEHOLDER,
+					X25519,
+					CurveP256,
+					CurveP384,
+				}},
+				&SupportedPointsExtension{SupportedPoints: []byte{
+					0x00, // pointFormatUncompressed
+				}},
+				&SessionTicketExtension{},
+				&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
+				&StatusRequestExtension{},
+				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
+					ECDSAWithP256AndSHA256,
+					PSSWithSHA256,
+					PKCS1WithSHA256,
+					ECDSAWithP384AndSHA384,
+					PSSWithSHA384,
+					PKCS1WithSHA384,
+					PSSWithSHA512,
+					PKCS1WithSHA512,
+				}},
+				&SCTExtension{},
+				&KeyShareExtension{[]KeyShare{
+					{Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}},
+					{Group: X25519},
+				}},
+				&PSKKeyExchangeModesExtension{[]uint8{
+					PskModeDHE,
+				}},
+				&SupportedVersionsExtension{[]uint16{
+					GREASE_PLACEHOLDER,
+					VersionTLS13,
+					VersionTLS12,
+				}},
+				&UtlsCompressCertExtension{[]CertCompressionAlgo{
+					CertCompressionBrotli,
+				}},
+				&ApplicationSettingsExtension{SupportedProtocols: []string{"h2"}},
+				&UtlsGREASEExtension{},
+				&UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle},
+				&UtlsPreSharedKeyExtension{},
+			}),
+		}, nil
+	// Chrome w/ Post-Quantum Key Agreement
+	case HelloChrome_115_PQ_PSK:
+		return ClientHelloSpec{
+			CipherSuites: []uint16{
+				GREASE_PLACEHOLDER,
+				TLS_AES_128_GCM_SHA256,
+				TLS_AES_256_GCM_SHA384,
+				TLS_CHACHA20_POLY1305_SHA256,
+				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,
+				TLS_ECDHE_RSA_WITH_AES_128_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,
+			},
+			CompressionMethods: []byte{
+				0x00, // compressionNone
+			},
+			Extensions: ShuffleChromeTLSExtensions([]TLSExtension{
+				&UtlsGREASEExtension{},
+				&SNIExtension{},
+				&ExtendedMasterSecretExtension{},
+				&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
+				&SupportedCurvesExtension{[]CurveID{
+					GREASE_PLACEHOLDER,
+					X25519Kyber768Draft00,
+					X25519,
+					CurveP256,
+					CurveP384,
+				}},
+				&SupportedPointsExtension{SupportedPoints: []byte{
+					0x00, // pointFormatUncompressed
+				}},
+				&SessionTicketExtension{},
+				&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
+				&StatusRequestExtension{},
+				&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
+					ECDSAWithP256AndSHA256,
+					PSSWithSHA256,
+					PKCS1WithSHA256,
+					ECDSAWithP384AndSHA384,
+					PSSWithSHA384,
+					PKCS1WithSHA384,
+					PSSWithSHA512,
+					PKCS1WithSHA512,
+				}},
+				&SCTExtension{},
+				&KeyShareExtension{[]KeyShare{
+					{Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}},
+					{Group: X25519Kyber768Draft00},
+					{Group: X25519},
+				}},
+				&PSKKeyExchangeModesExtension{[]uint8{
+					PskModeDHE,
+				}},
+				&SupportedVersionsExtension{[]uint16{
+					GREASE_PLACEHOLDER,
+					VersionTLS13,
+					VersionTLS12,
+				}},
+				&UtlsCompressCertExtension{[]CertCompressionAlgo{
+					CertCompressionBrotli,
+				}},
+				&ApplicationSettingsExtension{SupportedProtocols: []string{"h2"}},
+				&UtlsGREASEExtension{},
+				&UtlsPreSharedKeyExtension{},
+			}),
+		}, nil
 	default:
 		if id.Client == helloRandomized || id.Client == helloRandomizedALPN || id.Client == helloRandomizedNoALPN {
 			// Use empty values as they can be filled later by UConn.ApplyPreset or manually.
-			return generateRandomizedSpec(&id, "", nil, nil)
+			return generateRandomizedSpec(&id, "", nil)
 		}
-		return ClientHelloSpec{}, errors.New("ClientHello ID " + id.Str() + " is unknown")
+
+		return ClientHelloSpec{}, fmt.Errorf("%w: %s", ErrUnknownClientHelloID, id.Str())
 	}
 }
 
-func shuffleExtensions(chs *ClientHelloSpec) error {
-	// Shuffle extensions to avoid fingerprinting -- introduced in Chrome 106
-	var err error = nil
-
-	// unshufCheck checks:
-	// - if the exts[idx] is a GREASE extension, then it should not be shuffled
-	// - if the exts[idx] is a padding/pre_shared_key extension, then it should be the
-	//  last extension in the list and should not be shuffled
-	var unshufCheck = func(idx int, exts []TLSExtension) (donotshuf bool, userErr error) {
+// ShuffleChromeTLSExtensions shuffles the extensions in the ClientHelloSpec to avoid ossification.
+// It shuffles every extension except GREASE, padding and pre_shared_key extensions.
+//
+// This feature was first introduced by Chrome 106.
+func ShuffleChromeTLSExtensions(exts []TLSExtension) []TLSExtension {
+	// unshufCheck checks if the exts[idx] is a GREASE/padding/pre_shared_key extension,
+	// and returns true on success. For these extensions are considered positionally invariant.
+	var skipShuf = func(idx int, exts []TLSExtension) bool {
 		switch exts[idx].(type) {
-		case *UtlsGREASEExtension:
-			donotshuf = true
-		case *UtlsPaddingExtension, *FakePreSharedKeyExtension:
-			donotshuf = true
-			if idx != len(chs.Extensions)-1 {
-				userErr = errors.New("UtlsPaddingExtension or FakePreSharedKeyExtension must be the last extension")
-			}
+		case *UtlsGREASEExtension, *UtlsPaddingExtension, PreSharedKeyExtension:
+			return true
 		default:
-			donotshuf = false
+			return false
 		}
-		return
 	}
 
 	// Shuffle other extensions
-	rand.Shuffle(len(chs.Extensions), func(i, j int) {
-		if unshuf, shuferr := unshufCheck(i, chs.Extensions); unshuf {
-			if shuferr != nil {
-				err = shuferr
+	randInt64, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64))
+	if err != nil {
+		// warning: random could be deterministic
+		rand.Shuffle(len(exts), func(i, j int) {
+			if skipShuf(i, exts) || skipShuf(j, exts) {
+				return // do not shuffle some of the extensions
 			}
-			return
-		}
-
-		if unshuf, shuferr := unshufCheck(j, chs.Extensions); unshuf {
-			if shuferr != nil {
-				err = shuferr
+			exts[i], exts[j] = exts[j], exts[i]
+		})
+		fmt.Println("Warning: failed to use a cryptographically secure random number generator. The shuffle can be deterministic.")
+	} else {
+		rand.New(rand.NewSource(randInt64.Int64())).Shuffle(len(exts), func(i, j int) {
+			if skipShuf(i, exts) || skipShuf(j, exts) {
+				return // do not shuffle some of the extensions
 			}
-			return
-		}
-
-		chs.Extensions[i], chs.Extensions[j] = chs.Extensions[j], chs.Extensions[i]
-	})
+			exts[i], exts[j] = exts[j], exts[i]
+		})
+	}
 
-	return err
+	return exts
 }
 
 func (uconn *UConn) applyPresetByID(id ClientHelloID) (err error) {
@@ -1991,9 +2599,8 @@ func (uconn *UConn) applyPresetByID(id ClientHelloID) (err error) {
 		}
 	case helloCustom:
 		return nil
-
 	default:
-		spec, err = utlsIdToSpec(id)
+		spec, err = UTLSIdToSpec(id)
 		if err != nil {
 			return err
 		}
@@ -2013,15 +2620,18 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
 		return err
 	}
 
-	privateHello, ecdheParams, err := uconn.makeClientHello()
+	privateHello, clientKeySharePrivate, err := uconn.makeClientHelloForApplyPreset()
 	if err != nil {
 		return err
 	}
 	uconn.HandshakeState.Hello = privateHello.getPublicPtr()
-	uconn.HandshakeState.State13.EcdheParams = ecdheParams
-	uconn.HandshakeState.State13.KeySharesEcdheParams = make(KeySharesEcdheParameters, 2)
+	if ecdheKey, ok := clientKeySharePrivate.(*ecdh.PrivateKey); ok {
+		uconn.HandshakeState.State13.EcdheKey = ecdheKey
+	} else if kemKey, ok := clientKeySharePrivate.(*kemPrivateKey); ok {
+		uconn.HandshakeState.State13.KEMKey = kemKey.ToPublic()
+	}
+	uconn.HandshakeState.State13.KeySharesParams = NewKeySharesParameters()
 	hello := uconn.HandshakeState.Hello
-	session := uconn.HandshakeState.Session
 
 	switch len(hello.Random) {
 	case 0:
@@ -2062,7 +2672,21 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
 			hello.CipherSuites[i] = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_cipher)
 		}
 	}
-	uconn.GetSessionID = p.GetSessionID
+
+	// 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).
+	//
+	// The session ID is not set for QUIC connections (see RFC 9001, Section 8.4).
+	if uconn.quic == nil {
+		var sessionID [32]byte
+		_, err = io.ReadFull(uconn.config.rand(), sessionID[:])
+		if err != nil {
+			return err
+		}
+		uconn.HandshakeState.Hello.SessionId = sessionID[:]
+	}
+
 	uconn.Extensions = make([]TLSExtension, len(p.Extensions))
 	copy(uconn.Extensions, p.Extensions)
 
@@ -2087,16 +2711,6 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
 				return errors.New("at most 2 grease extensions are supported")
 			}
 			grease_extensions_seen += 1
-		case *SessionTicketExtension:
-			if session == nil && uconn.config.ClientSessionCache != nil {
-				cacheKey := clientSessionCacheKey(uconn.RemoteAddr(), uconn.config)
-				session, _ = uconn.config.ClientSessionCache.Get(cacheKey)
-				// TODO: use uconn.loadSession(hello.getPrivateObj()) to support TLS 1.3 PSK-style resumption
-			}
-			err := uconn.SetSessionState(session)
-			if err != nil {
-				return err
-			}
 		case *SupportedCurvesExtension:
 			for i := range ext.Curves {
 				if isGREASEUint16(uint16(ext.Curves[i])) {
@@ -2115,17 +2729,37 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
 					continue
 				}
 
-				ecdheParams, err := generateECDHEParameters(uconn.config.rand(), curveID)
-				if err != nil {
-					return fmt.Errorf("unsupported Curve in KeyShareExtension: %v."+
-						"To mimic it, fill the Data(key) field manually", curveID)
-				}
-				uconn.HandshakeState.State13.KeySharesEcdheParams.AddEcdheParams(curveID, ecdheParams)
-				ext.KeyShares[i].Data = ecdheParams.PublicKey()
-				if !preferredCurveIsSet {
-					// only do this once for the first non-grease curve
-					uconn.HandshakeState.State13.EcdheParams = ecdheParams
-					preferredCurveIsSet = true
+				if scheme := curveIdToCirclScheme(curveID); scheme != nil {
+					pk, sk, err := generateKemKeyPair(scheme, curveID, uconn.config.rand())
+					if err != nil {
+						return fmt.Errorf("HRR generateKemKeyPair %s: %w",
+							scheme.Name(), err)
+					}
+					packedPk, err := pk.MarshalBinary()
+					if err != nil {
+						return fmt.Errorf("HRR pack circl public key %s: %w",
+							scheme.Name(), err)
+					}
+					uconn.HandshakeState.State13.KeySharesParams.AddKemKeypair(curveID, sk.secretKey, pk)
+					ext.KeyShares[i].Data = packedPk
+					if !preferredCurveIsSet {
+						// only do this once for the first non-grease curve
+						uconn.HandshakeState.State13.KEMKey = sk.ToPublic()
+						preferredCurveIsSet = true
+					}
+				} else {
+					ecdheKey, err := generateECDHEKey(uconn.config.rand(), curveID)
+					if err != nil {
+						return fmt.Errorf("unsupported Curve in KeyShareExtension: %v."+
+							"To mimic it, fill the Data(key) field manually", curveID)
+					}
+					uconn.HandshakeState.State13.KeySharesParams.AddEcdheKeypair(curveID, ecdheKey, ecdheKey.PublicKey())
+					ext.KeyShares[i].Data = ecdheKey.PublicKey().Bytes()
+					if !preferredCurveIsSet {
+						// only do this once for the first non-grease curve
+						uconn.HandshakeState.State13.EcdheKey = ecdheKey
+						preferredCurveIsSet = true
+					}
 				}
 			}
 		case *SupportedVersionsExtension:
@@ -2143,17 +2777,21 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
 	// but NextProtos is also used by ALPN and our spec nmay not actually have a NPN extension
 	hello.NextProtoNeg = haveNPN
 
+	err = uconn.sessionController.syncSessionExts()
+	if err != nil {
+		return err
+	}
+
 	return nil
 }
 
 func (uconn *UConn) generateRandomizedSpec() (ClientHelloSpec, error) {
-	return generateRandomizedSpec(&uconn.ClientHelloID, uconn.serverName, uconn.HandshakeState.Session, uconn.config.NextProtos)
+	return generateRandomizedSpec(&uconn.ClientHelloID, uconn.serverName, uconn.config.NextProtos)
 }
 
 func generateRandomizedSpec(
 	id *ClientHelloID,
 	serverName string,
-	session *ClientSessionState,
 	nextProtos []string,
 ) (ClientHelloSpec, error) {
 	p := ClientHelloSpec{}
@@ -2219,7 +2857,7 @@ func generateRandomizedSpec(
 	p.CipherSuites = removeRandomCiphers(r, shuffledSuites, id.Weights.CipherSuites_Remove_RandomCiphers)
 
 	sni := SNIExtension{serverName}
-	sessionTicket := SessionTicketExtension{Session: session}
+	sessionTicket := SessionTicketExtension{}
 
 	sigAndHashAlgos := []SignatureScheme{
 		ECDSAWithP256AndSHA256,
@@ -2253,7 +2891,7 @@ func generateRandomizedSpec(
 
 	status := StatusRequestExtension{}
 	sct := SCTExtension{}
-	ems := UtlsExtendedMasterSecretExtension{}
+	ems := ExtendedMasterSecretExtension{}
 	points := SupportedPointsExtension{SupportedPoints: []byte{pointFormatUncompressed}}
 
 	curveIDs := []CurveID{}
diff --git a/vendor/github.com/refraction-networking/utls/u_pre_shared_key.go b/vendor/github.com/refraction-networking/utls/u_pre_shared_key.go
new file mode 100644
index 00000000..65e0bb66
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/u_pre_shared_key.go
@@ -0,0 +1,471 @@
+package tls
+
+import (
+	"encoding/json"
+	"errors"
+	"io"
+
+	"golang.org/x/crypto/cryptobyte"
+)
+
+var ErrEmptyPsk = errors.New("tls: empty psk detected; remove the psk extension for this connection or set OmitEmptyPsk to true to conceal it in utls")
+
+type PreSharedKeyCommon struct {
+	Identities  []PskIdentity
+	Binders     [][]byte
+	BinderKey   []byte // this will be used to compute the binder when hello message is ready
+	EarlySecret []byte
+	Session     *SessionState
+}
+
+// The lifecycle of a PreSharedKeyExtension:
+//
+// Creation Phase:
+//   - The extension is created.
+//
+// Write Phase:
+//
+//   - [writeToUConn() called]:
+//
+//     > - During this phase, it is important to note that implementations should not write any session data to the UConn (Underlying Connection) as the session is not yet loaded. The session context is not active at this point.
+//
+// Initialization Phase:
+//
+//   - [IsInitialized() called]:
+//
+//     If IsInitialized() returns true
+//
+//     > - GetPreSharedKeyCommon() will be called subsequently and the PSK states in handshake/clientHello will be fully initialized.
+//
+//     If IsInitialized() returns false:
+//
+//     > - [conn.loadSession() called]:
+//
+//     >> - Once the session is available:
+//
+//     >>> - [InitializeByUtls() called]:
+//
+//     >>>> - The InitializeByUtls() method is invoked to initialize the extension based on the loaded session data.
+//
+//     >>>> - This step prepares the extension for further processing.
+//
+// Marshal Phase:
+//
+//   - [Len() called], [Read() called]:
+//
+//     > - Implementations should marshal the extension into bytes, using placeholder binders to maintain the correct length.
+//
+// Binders Preparation Phase:
+//
+//   - [PatchBuiltHello(hello) called]:
+//
+//     > - The client hello is already marshaled in the "hello.Raw" format.
+//
+//     > - Implementations are expected to update the binders within the marshaled client hello.
+//
+//   - [GetPreSharedKeyCommon() called]:
+//
+//     > - Implementations should gather and provide the final pre-shared key (PSK) related data.
+//
+//     > - This data will be incorporated into both the clientHello and HandshakeState, ensuring that the PSK-related information is properly set and ready for the handshake process.
+type PreSharedKeyExtension interface {
+	// TLSExtension must be implemented by all PreSharedKeyExtension implementations.
+	TLSExtension
+
+	// If false is returned, utls will invoke `InitializeByUtls()` for the necessary initialization.
+	Initializable
+
+	SetOmitEmptyPsk(val bool)
+
+	// InitializeByUtls is invoked when IsInitialized() returns false.
+	// It initializes the extension using a real and valid TLS 1.3 session.
+	InitializeByUtls(session *SessionState, earlySecret []byte, binderKey []byte, identities []PskIdentity)
+
+	// GetPreSharedKeyCommon retrieves the final PreSharedKey-related states as defined in PreSharedKeyCommon.
+	GetPreSharedKeyCommon() PreSharedKeyCommon
+
+	// PatchBuiltHello is called once the hello message is fully applied and marshaled.
+	// Its purpose is to update the binders of PSK (Pre-Shared Key) identities.
+	PatchBuiltHello(hello *PubClientHelloMsg) error
+
+	mustEmbedUnimplementedPreSharedKeyExtension() // this works like a type guard
+}
+
+type UnimplementedPreSharedKeyExtension struct{}
+
+func (UnimplementedPreSharedKeyExtension) mustEmbedUnimplementedPreSharedKeyExtension() {}
+
+func (*UnimplementedPreSharedKeyExtension) IsInitialized() bool {
+	panic("tls: IsInitialized is not implemented for the PreSharedKeyExtension")
+}
+
+func (*UnimplementedPreSharedKeyExtension) InitializeByUtls(session *SessionState, earlySecret []byte, binderKey []byte, identities []PskIdentity) {
+	panic("tls: Initialize is not implemented for the PreSharedKeyExtension")
+}
+
+func (*UnimplementedPreSharedKeyExtension) writeToUConn(*UConn) error {
+	panic("tls: writeToUConn is not implemented for the PreSharedKeyExtension")
+}
+
+func (*UnimplementedPreSharedKeyExtension) Len() int {
+	panic("tls: Len is not implemented for the PreSharedKeyExtension")
+}
+
+func (*UnimplementedPreSharedKeyExtension) Read([]byte) (int, error) {
+	panic("tls: Read is not implemented for the PreSharedKeyExtension")
+}
+
+func (*UnimplementedPreSharedKeyExtension) GetPreSharedKeyCommon() PreSharedKeyCommon {
+	panic("tls: GetPreSharedKeyCommon is not implemented for the PreSharedKeyExtension")
+}
+
+func (*UnimplementedPreSharedKeyExtension) PatchBuiltHello(hello *PubClientHelloMsg) error {
+	panic("tls: ReadWithRawHello is not implemented for the PreSharedKeyExtension")
+}
+
+func (*UnimplementedPreSharedKeyExtension) SetOmitEmptyPsk(val bool) {
+	panic("tls: SetOmitEmptyPsk is not implemented for the PreSharedKeyExtension")
+}
+
+// UtlsPreSharedKeyExtension is an extension used to set the PSK extension in the
+// ClientHello.
+type UtlsPreSharedKeyExtension struct {
+	UnimplementedPreSharedKeyExtension
+	PreSharedKeyCommon
+	cipherSuite  *cipherSuiteTLS13
+	cachedLength *int
+	// Deprecated: Set OmitEmptyPsk in Config instead.
+	OmitEmptyPsk bool
+}
+
+func (e *UtlsPreSharedKeyExtension) IsInitialized() bool {
+	return e.Session != nil
+}
+
+func (e *UtlsPreSharedKeyExtension) InitializeByUtls(session *SessionState, earlySecret []byte, binderKey []byte, identities []PskIdentity) {
+	e.Session = session
+	e.EarlySecret = earlySecret
+	e.BinderKey = binderKey
+	e.cipherSuite = cipherSuiteTLS13ByID(e.Session.cipherSuite)
+	e.Identities = identities
+	e.Binders = make([][]byte, 0, len(e.Identities))
+	for i := 0; i < len(e.Identities); i++ {
+		e.Binders = append(e.Binders, make([]byte, e.cipherSuite.hash.Size()))
+	}
+}
+
+func (e *UtlsPreSharedKeyExtension) writeToUConn(uc *UConn) error {
+	uc.HandshakeState.Hello.TicketSupported = true // This doesn't matter though, as utls doesn't care about this field. We write this for consistency.
+	return nil
+}
+
+func (e *UtlsPreSharedKeyExtension) GetPreSharedKeyCommon() PreSharedKeyCommon {
+	return e.PreSharedKeyCommon
+}
+
+func pskExtLen(identities []PskIdentity, binders [][]byte) int {
+	if len(identities) == 0 || len(binders) == 0 {
+		// If there isn't psk identities, we don't write this ticket to the client hello, and therefore the length should be 0.
+		return 0
+	}
+	length := 4 // extension type + extension length
+	length += 2 // identities length
+	for _, identity := range identities {
+		length += 2 + len(identity.Label) + 4 // identity length + identity + obfuscated ticket age
+	}
+	length += 2 // binders length
+	for _, binder := range binders {
+		length += len(binder) + 1
+	}
+	return length
+}
+
+func (e *UtlsPreSharedKeyExtension) Len() int {
+	if e.Session == nil {
+		return 0
+	}
+	if e.cachedLength != nil {
+		return *e.cachedLength
+	}
+	length := pskExtLen(e.Identities, e.Binders)
+	e.cachedLength = &length
+	return length
+}
+
+func readPskIntoBytes(b []byte, identities []PskIdentity, binders [][]byte) (int, error) {
+	extLen := pskExtLen(identities, binders)
+	if extLen == 0 {
+		return 0, io.EOF
+	}
+	if len(b) < extLen {
+		return 0, io.ErrShortBuffer
+	}
+
+	b[0] = byte(extensionPreSharedKey >> 8)
+	b[1] = byte(extensionPreSharedKey)
+	b[2] = byte((extLen - 4) >> 8)
+	b[3] = byte(extLen - 4)
+
+	// identities length
+	identitiesLength := 0
+	for _, identity := range identities {
+		identitiesLength += 2 + len(identity.Label) + 4 // identity length + identity + obfuscated ticket age
+	}
+	b[4] = byte(identitiesLength >> 8)
+	b[5] = byte(identitiesLength)
+
+	// identities
+	offset := 6
+	for _, identity := range identities {
+		b[offset] = byte(len(identity.Label) >> 8)
+		b[offset+1] = byte(len(identity.Label))
+		offset += 2
+		copy(b[offset:], identity.Label)
+		offset += len(identity.Label)
+		b[offset] = byte(identity.ObfuscatedTicketAge >> 24)
+		b[offset+1] = byte(identity.ObfuscatedTicketAge >> 16)
+		b[offset+2] = byte(identity.ObfuscatedTicketAge >> 8)
+		b[offset+3] = byte(identity.ObfuscatedTicketAge)
+		offset += 4
+	}
+
+	// binders length
+	bindersLength := 0
+	for _, binder := range binders {
+		// check if binder size is valid
+		bindersLength += len(binder) + 1 // binder length + binder
+	}
+	b[offset] = byte(bindersLength >> 8)
+	b[offset+1] = byte(bindersLength)
+	offset += 2
+
+	// binders
+	for _, binder := range binders {
+		b[offset] = byte(len(binder))
+		offset++
+		copy(b[offset:], binder)
+		offset += len(binder)
+	}
+
+	return extLen, io.EOF
+}
+
+func (e *UtlsPreSharedKeyExtension) SetOmitEmptyPsk(val bool) {
+	e.OmitEmptyPsk = val
+}
+
+func (e *UtlsPreSharedKeyExtension) Read(b []byte) (int, error) {
+	if !e.OmitEmptyPsk && e.Len() == 0 {
+		return 0, ErrEmptyPsk
+	}
+	return readPskIntoBytes(b, e.Identities, e.Binders)
+}
+
+func (e *UtlsPreSharedKeyExtension) PatchBuiltHello(hello *PubClientHelloMsg) error {
+	if e.Len() == 0 {
+		return nil
+	}
+	private := hello.getCachedPrivatePtr()
+	if private == nil {
+		private = hello.getPrivatePtr()
+	}
+	private.raw = hello.Raw
+	private.pskBinders = e.Binders // set the placeholder to the private Hello
+
+	//--- mirror loadSession() begin ---//
+	transcript := e.cipherSuite.hash.New()
+	helloBytes, err := private.marshalWithoutBinders() // no marshal() will be actually called, as we have set the field `raw`
+	if err != nil {
+		return err
+	}
+	transcript.Write(helloBytes)
+	pskBinders := [][]byte{e.cipherSuite.finishedHash(e.BinderKey, transcript)}
+
+	if err := private.updateBinders(pskBinders); err != nil {
+		return err
+	}
+	//--- mirror loadSession() end ---//
+	e.Binders = pskBinders
+
+	// no need to care about other PSK related fields, they will be handled separately
+
+	return io.EOF
+}
+
+func (e *UtlsPreSharedKeyExtension) Write(b []byte) (int, error) {
+	return len(b), nil // ignore the data
+}
+
+func (e *UtlsPreSharedKeyExtension) UnmarshalJSON(_ []byte) error {
+	return nil // ignore the data
+}
+
+// FakePreSharedKeyExtension is an extension used to set the PSK extension in the
+// ClientHello.
+//
+// It does not compute binders based on ClientHello, but uses the binders specified instead.
+// We still need to learn more of the safety
+// of hardcoding both Identities and Binders without recalculating the latter.
+type FakePreSharedKeyExtension struct {
+	UnimplementedPreSharedKeyExtension
+
+	Identities []PskIdentity `json:"identities"`
+	Binders    [][]byte      `json:"binders"`
+	// Deprecated: Set OmitEmptyPsk in Config instead.
+	OmitEmptyPsk bool
+}
+
+func (e *FakePreSharedKeyExtension) IsInitialized() bool {
+	return e.Identities != nil && e.Binders != nil
+}
+
+func (e *FakePreSharedKeyExtension) InitializeByUtls(session *SessionState, earlySecret []byte, binderKey []byte, identities []PskIdentity) {
+	panic("InitializeByUtls failed: don't let utls initialize FakePreSharedKeyExtension; provide your own identities and binders or use UtlsPreSharedKeyExtension")
+}
+
+func (e *FakePreSharedKeyExtension) writeToUConn(uc *UConn) error {
+	if uc.config.ClientSessionCache == nil {
+		return nil // don't write the extension if there is no session cache
+	}
+	if session, ok := uc.config.ClientSessionCache.Get(uc.clientSessionCacheKey()); !ok || session == nil {
+		return nil // don't write the extension if there is no session cache available for this session
+	}
+	uc.HandshakeState.Hello.PskIdentities = e.Identities
+	uc.HandshakeState.Hello.PskBinders = e.Binders
+	return nil
+}
+
+func (e *FakePreSharedKeyExtension) Len() int {
+	return pskExtLen(e.Identities, e.Binders)
+}
+
+func (e *FakePreSharedKeyExtension) SetOmitEmptyPsk(val bool) {
+	e.OmitEmptyPsk = val
+}
+
+func (e *FakePreSharedKeyExtension) Read(b []byte) (int, error) {
+	if !e.OmitEmptyPsk && e.Len() == 0 {
+		return 0, ErrEmptyPsk
+	}
+	for _, b := range e.Binders {
+		if !(anyTrue(validHashLen, func(_ int, valid *int) bool {
+			return len(b) == *valid
+		})) {
+			return 0, errors.New("tls: FakePreSharedKeyExtension.Read failed: invalid binder size")
+		}
+	}
+
+	return readPskIntoBytes(b, e.Identities, e.Binders)
+}
+
+func (e *FakePreSharedKeyExtension) GetPreSharedKeyCommon() PreSharedKeyCommon {
+	return PreSharedKeyCommon{
+		Identities: e.Identities,
+		Binders:    e.Binders,
+	}
+}
+
+var validHashLen = mapSlice(cipherSuitesTLS13, func(c *cipherSuiteTLS13) int {
+	return c.hash.Size()
+})
+
+func (*FakePreSharedKeyExtension) PatchBuiltHello(*PubClientHelloMsg) error {
+	return nil // no need to patch the hello since we don't need to update binders
+}
+
+func (e *FakePreSharedKeyExtension) Write(b []byte) (n int, err error) {
+	fullLen := len(b)
+	s := cryptobyte.String(b)
+
+	var identitiesLength uint16
+	if !s.ReadUint16(&identitiesLength) {
+		return 0, errors.New("tls: invalid PSK extension")
+	}
+
+	// identities
+	for identitiesLength > 0 {
+		var identityLength uint16
+		if !s.ReadUint16(&identityLength) {
+			return 0, errors.New("tls: invalid PSK extension")
+		}
+		identitiesLength -= 2
+
+		if identityLength > identitiesLength {
+			return 0, errors.New("tls: invalid PSK extension")
+		}
+
+		var identity []byte
+		if !s.ReadBytes(&identity, int(identityLength)) {
+			return 0, errors.New("tls: invalid PSK extension")
+		}
+
+		identitiesLength -= identityLength // identity
+
+		var obfuscatedTicketAge uint32
+		if !s.ReadUint32(&obfuscatedTicketAge) {
+			return 0, errors.New("tls: invalid PSK extension")
+		}
+
+		e.Identities = append(e.Identities, PskIdentity{
+			Label:               identity,
+			ObfuscatedTicketAge: obfuscatedTicketAge,
+		})
+
+		identitiesLength -= 4 // obfuscated ticket age
+	}
+
+	var bindersLength uint16
+	if !s.ReadUint16(&bindersLength) {
+		return 0, errors.New("tls: invalid PSK extension")
+	}
+
+	// binders
+	for bindersLength > 0 {
+		var binderLength uint8
+		if !s.ReadUint8(&binderLength) {
+			return 0, errors.New("tls: invalid PSK extension")
+		}
+		bindersLength -= 1
+
+		if uint16(binderLength) > bindersLength {
+			return 0, errors.New("tls: invalid PSK extension")
+		}
+
+		var binder []byte
+		if !s.ReadBytes(&binder, int(binderLength)) {
+			return 0, errors.New("tls: invalid PSK extension")
+		}
+
+		e.Binders = append(e.Binders, binder)
+
+		bindersLength -= uint16(binderLength)
+	}
+
+	return fullLen, nil
+}
+
+func (e *FakePreSharedKeyExtension) UnmarshalJSON(data []byte) error {
+	var pskAccepter struct {
+		PskIdentities []PskIdentity `json:"identities"`
+		PskBinders    [][]byte      `json:"binders"`
+	}
+
+	if err := json.Unmarshal(data, &pskAccepter); err != nil {
+		return err
+	}
+
+	e.Identities = pskAccepter.PskIdentities
+	e.Binders = pskAccepter.PskBinders
+	return nil
+}
+
+// type guard
+var (
+	_ PreSharedKeyExtension = (*UtlsPreSharedKeyExtension)(nil)
+	_ TLSExtensionJSON      = (*UtlsPreSharedKeyExtension)(nil)
+	_ PreSharedKeyExtension = (*FakePreSharedKeyExtension)(nil)
+	_ TLSExtensionJSON      = (*FakePreSharedKeyExtension)(nil)
+	_ TLSExtensionWriter    = (*FakePreSharedKeyExtension)(nil)
+)
+
+// type ExternalPreSharedKeyExtension struct{} // TODO: wait for whoever cares about external PSK to implement it
diff --git a/vendor/github.com/refraction-networking/utls/u_prng.go b/vendor/github.com/refraction-networking/utls/u_prng.go
index e00ab6f0..cbd84081 100644
--- a/vendor/github.com/refraction-networking/utls/u_prng.go
+++ b/vendor/github.com/refraction-networking/utls/u_prng.go
@@ -117,13 +117,13 @@ func (p *prng) Read(b []byte) (int, error) {
 	return len(b), nil
 }
 
-// Int63 is equivilent to math/read.Int63.
+// Int63 is equivalent to math/read.Int63.
 func (p *prng) Int63() int64 {
 	i := p.Uint64()
 	return int64(i & (1<<63 - 1))
 }
 
-// Int63 is equivilent to math/read.Uint64.
+// Int63 is equivalent to math/read.Uint64.
 func (p *prng) Uint64() uint64 {
 	var b [8]byte
 	p.Read(b[:])
@@ -150,7 +150,7 @@ func (p *prng) FlipWeightedCoin(weight float64) bool {
 	return f > 1.0-weight
 }
 
-// Intn is equivilent to math/read.Intn, except it returns 0 if n <= 0
+// Intn is equivalent to math/read.Intn, except it returns 0 if n <= 0
 // instead of panicking.
 func (p *prng) Intn(n int) int {
 	if n <= 0 {
@@ -159,7 +159,7 @@ func (p *prng) Intn(n int) int {
 	return p.rand.Intn(n)
 }
 
-// Int63n is equivilent to math/read.Int63n, except it returns 0 if n <= 0
+// Int63n is equivalent to math/read.Int63n, except it returns 0 if n <= 0
 // instead of panicking.
 func (p *prng) Int63n(n int64) int64 {
 	if n <= 0 {
@@ -168,7 +168,7 @@ func (p *prng) Int63n(n int64) int64 {
 	return p.rand.Int63n(n)
 }
 
-// Intn is equivilent to math/read.Perm.
+// Intn is equivalent to math/read.Perm.
 func (p *prng) Perm(n int) []int {
 	return p.rand.Perm(n)
 }
diff --git a/vendor/github.com/refraction-networking/utls/u_public.go b/vendor/github.com/refraction-networking/utls/u_public.go
index a9d39e26..cdcd6eeb 100644
--- a/vendor/github.com/refraction-networking/utls/u_public.go
+++ b/vendor/github.com/refraction-networking/utls/u_public.go
@@ -6,8 +6,12 @@ package tls
 
 import (
 	"crypto"
+	"crypto/ecdh"
 	"crypto/x509"
 	"hash"
+	"time"
+
+	"github.com/cloudflare/circl/kem"
 )
 
 // ClientHandshakeState includes both TLS 1.3-only and TLS 1.2-only states,
@@ -24,7 +28,7 @@ type PubClientHandshakeState struct {
 	ServerHello  *PubServerHelloMsg
 	Hello        *PubClientHelloMsg
 	MasterSecret []byte
-	Session      *ClientSessionState
+	Session      *SessionState
 
 	State12 TLS12OnlyState
 	State13 TLS13OnlyState
@@ -34,16 +38,17 @@ type PubClientHandshakeState struct {
 
 // TLS 1.3 only
 type TLS13OnlyState struct {
-	Suite                *PubCipherSuiteTLS13
-	EcdheParams          EcdheParameters
-	KeySharesEcdheParams KeySharesEcdheParameters
-	EarlySecret          []byte
-	BinderKey            []byte
-	CertReq              *CertificateRequestMsgTLS13
-	UsingPSK             bool
-	SentDummyCCS         bool
-	Transcript           hash.Hash
-	TrafficSecret        []byte // client_application_traffic_secret_0
+	Suite           *PubCipherSuiteTLS13
+	EcdheKey        *ecdh.PrivateKey
+	KeySharesParams *KeySharesParameters
+	KEMKey          *KemPrivateKey
+	EarlySecret     []byte
+	BinderKey       []byte
+	CertReq         *CertificateRequestMsgTLS13
+	UsingPSK        bool // don't set this field when building client hello
+	SentDummyCCS    bool
+	Transcript      hash.Hash
+	TrafficSecret   []byte // client_application_traffic_secret_0
 }
 
 // TLS 1.2 and before only
@@ -57,11 +62,12 @@ func (chs *PubClientHandshakeState) toPrivate13() *clientHandshakeStateTLS13 {
 		return nil
 	} else {
 		return &clientHandshakeStateTLS13{
-			c:                    chs.C,
-			serverHello:          chs.ServerHello.getPrivatePtr(),
-			hello:                chs.Hello.getPrivatePtr(),
-			ecdheParams:          chs.State13.EcdheParams,
-			keySharesEcdheParams: chs.State13.KeySharesEcdheParams,
+			c:               chs.C,
+			serverHello:     chs.ServerHello.getPrivatePtr(),
+			hello:           chs.Hello.getPrivatePtr(),
+			ecdheKey:        chs.State13.EcdheKey,
+			keySharesParams: chs.State13.KeySharesParams,
+			kemKey:          chs.State13.KEMKey.ToPrivate(),
 
 			session:     chs.Session,
 			earlySecret: chs.State13.EarlySecret,
@@ -85,16 +91,17 @@ func (chs13 *clientHandshakeStateTLS13) toPublic13() *PubClientHandshakeState {
 		return nil
 	} else {
 		tls13State := TLS13OnlyState{
-			KeySharesEcdheParams: chs13.keySharesEcdheParams,
-			EcdheParams:          chs13.ecdheParams,
-			EarlySecret:          chs13.earlySecret,
-			BinderKey:            chs13.binderKey,
-			CertReq:              chs13.certReq.toPublic(),
-			UsingPSK:             chs13.usingPSK,
-			SentDummyCCS:         chs13.sentDummyCCS,
-			Suite:                chs13.suite.toPublic(),
-			TrafficSecret:        chs13.trafficSecret,
-			Transcript:           chs13.transcript,
+			KeySharesParams: chs13.keySharesParams,
+			EcdheKey:        chs13.ecdheKey,
+			KEMKey:          chs13.kemKey.ToPublic(),
+			EarlySecret:     chs13.earlySecret,
+			BinderKey:       chs13.binderKey,
+			CertReq:         chs13.certReq.toPublic(),
+			UsingPSK:        chs13.usingPSK,
+			SentDummyCCS:    chs13.sentDummyCCS,
+			Suite:           chs13.suite.toPublic(),
+			TrafficSecret:   chs13.trafficSecret,
+			Transcript:      chs13.transcript,
 		}
 		return &PubClientHandshakeState{
 			C:           chs13.c,
@@ -156,9 +163,9 @@ func (chs12 *clientHandshakeState) toPublic12() *PubClientHandshakeState {
 	}
 }
 
-type EcdheParameters interface {
-	ecdheParameters
-}
+// type EcdheParameters interface {
+// 	ecdheParameters
+// }
 
 type CertificateRequestMsgTLS13 struct {
 	Raw                              []byte
@@ -243,8 +250,8 @@ type PubServerHelloMsg struct {
 	NextProtos                   []string
 	OcspStapling                 bool
 	Scts                         [][]byte
-	Ems                          bool
-	TicketSupported              bool
+	ExtendedMasterSecret         bool
+	TicketSupported              bool // used by go tls to determine whether to add the session ticket ext
 	SecureRenegotiation          []byte
 	SecureRenegotiationSupported bool
 	AlpnProtocol                 string
@@ -274,7 +281,7 @@ func (shm *PubServerHelloMsg) getPrivatePtr() *serverHelloMsg {
 			nextProtos:                   shm.NextProtos,
 			ocspStapling:                 shm.OcspStapling,
 			scts:                         shm.Scts,
-			ems:                          shm.Ems,
+			extendedMasterSecret:         shm.ExtendedMasterSecret,
 			ticketSupported:              shm.TicketSupported,
 			secureRenegotiation:          shm.SecureRenegotiation,
 			secureRenegotiationSupported: shm.SecureRenegotiationSupported,
@@ -304,7 +311,7 @@ func (shm *serverHelloMsg) getPublicPtr() *PubServerHelloMsg {
 			NextProtos:                   shm.nextProtos,
 			OcspStapling:                 shm.ocspStapling,
 			Scts:                         shm.scts,
-			Ems:                          shm.ems,
+			ExtendedMasterSecret:         shm.extendedMasterSecret,
 			TicketSupported:              shm.ticketSupported,
 			SecureRenegotiation:          shm.secureRenegotiation,
 			SecureRenegotiationSupported: shm.secureRenegotiationSupported,
@@ -349,42 +356,57 @@ type PubClientHelloMsg struct {
 	PskModes                         []uint8
 	PskIdentities                    []PskIdentity
 	PskBinders                       [][]byte
+	QuicTransportParameters          []byte
+
+	cachedPrivateHello *clientHelloMsg // todo: further optimize to reduce clientHelloMsg construction
 }
 
 func (chm *PubClientHelloMsg) getPrivatePtr() *clientHelloMsg {
 	if chm == nil {
 		return nil
 	} else {
-		return &clientHelloMsg{
-			raw:                          chm.Raw,
-			vers:                         chm.Vers,
-			random:                       chm.Random,
-			sessionId:                    chm.SessionId,
-			cipherSuites:                 chm.CipherSuites,
-			compressionMethods:           chm.CompressionMethods,
-			nextProtoNeg:                 chm.NextProtoNeg,
-			serverName:                   chm.ServerName,
-			ocspStapling:                 chm.OcspStapling,
-			scts:                         chm.Scts,
-			ems:                          chm.Ems,
-			supportedCurves:              chm.SupportedCurves,
-			supportedPoints:              chm.SupportedPoints,
-			ticketSupported:              chm.TicketSupported,
-			sessionTicket:                chm.SessionTicket,
-			supportedSignatureAlgorithms: chm.SupportedSignatureAlgorithms,
-			secureRenegotiation:          chm.SecureRenegotiation,
-			secureRenegotiationSupported: chm.SecureRenegotiationSupported,
-			alpnProtocols:                chm.AlpnProtocols,
-
+		private := &clientHelloMsg{
+			raw:                              chm.Raw,
+			vers:                             chm.Vers,
+			random:                           chm.Random,
+			sessionId:                        chm.SessionId,
+			cipherSuites:                     chm.CipherSuites,
+			compressionMethods:               chm.CompressionMethods,
+			serverName:                       chm.ServerName,
+			ocspStapling:                     chm.OcspStapling,
+			supportedCurves:                  chm.SupportedCurves,
+			supportedPoints:                  chm.SupportedPoints,
+			ticketSupported:                  chm.TicketSupported,
+			sessionTicket:                    chm.SessionTicket,
+			supportedSignatureAlgorithms:     chm.SupportedSignatureAlgorithms,
 			supportedSignatureAlgorithmsCert: chm.SupportedSignatureAlgorithmsCert,
-			supportedVersions:                chm.SupportedVersions,
-			cookie:                           chm.Cookie,
-			keyShares:                        KeyShares(chm.KeyShares).ToPrivate(),
-			earlyData:                        chm.EarlyData,
-			pskModes:                         chm.PskModes,
-			pskIdentities:                    PskIdentities(chm.PskIdentities).ToPrivate(),
-			pskBinders:                       chm.PskBinders,
+			secureRenegotiationSupported:     chm.SecureRenegotiationSupported,
+			secureRenegotiation:              chm.SecureRenegotiation,
+			extendedMasterSecret:             chm.Ems,
+			alpnProtocols:                    chm.AlpnProtocols,
+			scts:                             chm.Scts,
+
+			supportedVersions:       chm.SupportedVersions,
+			cookie:                  chm.Cookie,
+			keyShares:               KeyShares(chm.KeyShares).ToPrivate(),
+			earlyData:               chm.EarlyData,
+			pskModes:                chm.PskModes,
+			pskIdentities:           PskIdentities(chm.PskIdentities).ToPrivate(),
+			pskBinders:              chm.PskBinders,
+			quicTransportParameters: chm.QuicTransportParameters,
+
+			nextProtoNeg: chm.NextProtoNeg,
 		}
+		chm.cachedPrivateHello = private
+		return private
+	}
+}
+
+func (chm *PubClientHelloMsg) getCachedPrivatePtr() *clientHelloMsg {
+	if chm == nil {
+		return nil
+	} else {
+		return chm.cachedPrivateHello
 	}
 }
 
@@ -403,7 +425,7 @@ func (chm *clientHelloMsg) getPublicPtr() *PubClientHelloMsg {
 			ServerName:                   chm.serverName,
 			OcspStapling:                 chm.ocspStapling,
 			Scts:                         chm.scts,
-			Ems:                          chm.ems,
+			Ems:                          chm.extendedMasterSecret,
 			SupportedCurves:              chm.supportedCurves,
 			SupportedPoints:              chm.supportedPoints,
 			TicketSupported:              chm.ticketSupported,
@@ -421,6 +443,8 @@ func (chm *clientHelloMsg) getPublicPtr() *PubClientHelloMsg {
 			PskModes:                         chm.pskModes,
 			PskIdentities:                    pskIdentities(chm.pskIdentities).ToPublic(),
 			PskBinders:                       chm.pskBinders,
+			QuicTransportParameters:          chm.quicTransportParameters,
+			cachedPrivateHello:               chm,
 		}
 	}
 }
@@ -593,6 +617,9 @@ func (PSS PskIdentities) ToPrivate() []pskIdentity {
 
 // ClientSessionState is public, but all its fields are private. Let's add setters, getters and constructor
 
+// TODO! can we change this enought (or export SessionState),
+// such that we wouldn't need to fork crypto/tls?
+
 // ClientSessionState contains the state needed by clients to resume TLS sessions.
 func MakeClientSessionState(
 	SessionTicket []uint8,
@@ -601,71 +628,100 @@ func MakeClientSessionState(
 	MasterSecret []byte,
 	ServerCertificates []*x509.Certificate,
 	VerifiedChains [][]*x509.Certificate) *ClientSessionState {
-	css := ClientSessionState{sessionTicket: SessionTicket,
-		vers:               Vers,
-		cipherSuite:        CipherSuite,
-		masterSecret:       MasterSecret,
-		serverCertificates: ServerCertificates,
-		verifiedChains:     VerifiedChains}
-	return &css
+	// TODO: Add EMS to this constructor in uTLS v2
+	css := &ClientSessionState{
+		ticket: SessionTicket,
+		session: &SessionState{
+			version:          Vers,
+			cipherSuite:      CipherSuite,
+			secret:           MasterSecret,
+			peerCertificates: ServerCertificates,
+			verifiedChains:   VerifiedChains,
+		},
+	}
+	return css
 }
 
 // Encrypted ticket used for session resumption with server
 func (css *ClientSessionState) SessionTicket() []uint8 {
-	return css.sessionTicket
+	return css.ticket
 }
 
 // SSL/TLS version negotiated for the session
 func (css *ClientSessionState) Vers() uint16 {
-	return css.vers
+	return css.session.version
 }
 
 // Ciphersuite negotiated for the session
 func (css *ClientSessionState) CipherSuite() uint16 {
-	return css.cipherSuite
+	return css.session.cipherSuite
 }
 
 // MasterSecret generated by client on a full handshake
 func (css *ClientSessionState) MasterSecret() []byte {
-	return css.masterSecret
+	return css.session.secret
+}
+
+func (css *ClientSessionState) EMS() bool {
+	return css.session.extMasterSecret
 }
 
 // Certificate chain presented by the server
 func (css *ClientSessionState) ServerCertificates() []*x509.Certificate {
-	return css.serverCertificates
+	return css.session.peerCertificates
 }
 
 // Certificate chains we built for verification
 func (css *ClientSessionState) VerifiedChains() [][]*x509.Certificate {
-	return css.verifiedChains
+	return css.session.verifiedChains
 }
 
 func (css *ClientSessionState) SetSessionTicket(SessionTicket []uint8) {
-	css.sessionTicket = SessionTicket
+	css.ticket = SessionTicket
 }
 func (css *ClientSessionState) SetVers(Vers uint16) {
-	css.vers = Vers
+	if css.session == nil {
+		css.session = &SessionState{}
+	}
+	css.session.version = Vers
 }
 func (css *ClientSessionState) SetCipherSuite(CipherSuite uint16) {
-	css.cipherSuite = CipherSuite
+	if css.session == nil {
+		css.session = &SessionState{}
+	}
+	css.session.cipherSuite = CipherSuite
 }
 func (css *ClientSessionState) SetMasterSecret(MasterSecret []byte) {
-	css.masterSecret = MasterSecret
+	if css.session == nil {
+		css.session = &SessionState{}
+	}
+	css.session.secret = MasterSecret
+}
+func (css *ClientSessionState) SetEMS(ems bool) {
+	if css.session == nil {
+		css.session = &SessionState{}
+	}
+	css.session.extMasterSecret = ems
 }
 func (css *ClientSessionState) SetServerCertificates(ServerCertificates []*x509.Certificate) {
-	css.serverCertificates = ServerCertificates
+	if css.session == nil {
+		css.session = &SessionState{}
+	}
+	css.session.peerCertificates = ServerCertificates
 }
 func (css *ClientSessionState) SetVerifiedChains(VerifiedChains [][]*x509.Certificate) {
-	css.verifiedChains = VerifiedChains
+	if css.session == nil {
+		css.session = &SessionState{}
+	}
+	css.session.verifiedChains = VerifiedChains
 }
 
 // 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
 }
 
 type TicketKeys []TicketKey
@@ -681,17 +737,17 @@ func TicketKeyFromBytes(b [32]byte) TicketKey {
 
 func (tk ticketKey) ToPublic() TicketKey {
 	return TicketKey{
-		KeyName: tk.keyName,
 		AesKey:  tk.aesKey,
 		HmacKey: tk.hmacKey,
+		Created: tk.created,
 	}
 }
 
 func (TK TicketKey) ToPrivate() ticketKey {
 	return ticketKey{
-		keyName: TK.KeyName,
 		aesKey:  TK.AesKey,
 		hmacKey: TK.HmacKey,
+		created: TK.Created,
 	}
 }
 
@@ -710,3 +766,30 @@ func (TKS TicketKeys) ToPrivate() []ticketKey {
 	}
 	return tks
 }
+
+type KemPrivateKey struct {
+	SecretKey kem.PrivateKey
+	CurveID   CurveID
+}
+
+func (kpk *KemPrivateKey) ToPrivate() *kemPrivateKey {
+	if kpk == nil {
+		return nil
+	} else {
+		return &kemPrivateKey{
+			secretKey: kpk.SecretKey,
+			curveID:   kpk.CurveID,
+		}
+	}
+}
+
+func (kpk *kemPrivateKey) ToPublic() *KemPrivateKey {
+	if kpk == nil {
+		return nil
+	} else {
+		return &KemPrivateKey{
+			SecretKey: kpk.secretKey,
+			CurveID:   kpk.curveID,
+		}
+	}
+}
diff --git a/vendor/github.com/refraction-networking/utls/u_quic.go b/vendor/github.com/refraction-networking/utls/u_quic.go
new file mode 100644
index 00000000..c312522e
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/u_quic.go
@@ -0,0 +1,212 @@
+// Copyright 2023 The uTLS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"context"
+	"errors"
+	"fmt"
+)
+
+// A UQUICConn represents a connection which uses a QUIC implementation as the underlying
+// transport as described in RFC 9001.
+//
+// Methods of UQUICConn are not safe for concurrent use.
+type UQUICConn struct {
+	conn *UConn
+
+	sessionTicketSent bool
+}
+
+// QUICClient returns a new TLS client side connection using QUICTransport as the
+// underlying transport. The config cannot be nil.
+//
+// The config's MinVersion must be at least TLS 1.3.
+func UQUICClient(config *QUICConfig, clientHelloID ClientHelloID) *UQUICConn {
+	return newUQUICConn(UClient(nil, config.TLSConfig, clientHelloID))
+}
+
+func newUQUICConn(uconn *UConn) *UQUICConn {
+	uconn.quic = &quicState{
+		signalc:  make(chan struct{}),
+		blockedc: make(chan struct{}),
+	}
+	uconn.quic.events = uconn.quic.eventArr[:0]
+	return &UQUICConn{
+		conn: uconn,
+	}
+}
+
+// Start starts the client or server handshake protocol.
+// It may produce connection events, which may be read with NextEvent.
+//
+// Start must be called at most once.
+func (q *UQUICConn) Start(ctx context.Context) error {
+	if q.conn.quic.started {
+		return quicError(errors.New("tls: Start called more than once"))
+	}
+	q.conn.quic.started = true
+	if q.conn.config.MinVersion < VersionTLS13 {
+		return quicError(errors.New("tls: Config MinVersion must be at least TLS 1.13"))
+	}
+	go q.conn.HandshakeContext(ctx)
+	if _, ok := <-q.conn.quic.blockedc; !ok {
+		return q.conn.handshakeErr
+	}
+	return nil
+}
+
+func (q *UQUICConn) ApplyPreset(p *ClientHelloSpec) error {
+	return q.conn.ApplyPreset(p)
+}
+
+// NextEvent returns the next event occurring on the connection.
+// It returns an event with a Kind of QUICNoEvent when no events are available.
+func (q *UQUICConn) NextEvent() QUICEvent {
+	qs := q.conn.quic
+	if last := qs.nextEvent - 1; last >= 0 && len(qs.events[last].Data) > 0 {
+		// Write over some of the previous event's data,
+		// to catch callers erroniously retaining it.
+		qs.events[last].Data[0] = 0
+	}
+	if qs.nextEvent >= len(qs.events) {
+		qs.events = qs.events[:0]
+		qs.nextEvent = 0
+		return QUICEvent{Kind: QUICNoEvent}
+	}
+	e := qs.events[qs.nextEvent]
+	qs.events[qs.nextEvent] = QUICEvent{} // zero out references to data
+	qs.nextEvent++
+	return e
+}
+
+// Close closes the connection and stops any in-progress handshake.
+func (q *UQUICConn) Close() error {
+	if q.conn.quic.cancel == nil {
+		return nil // never started
+	}
+	q.conn.quic.cancel()
+	for range q.conn.quic.blockedc {
+		// Wait for the handshake goroutine to return.
+	}
+	return q.conn.handshakeErr
+}
+
+// HandleData handles handshake bytes received from the peer.
+// It may produce connection events, which may be read with NextEvent.
+func (q *UQUICConn) HandleData(level QUICEncryptionLevel, data []byte) error {
+	c := q.conn
+	if c.in.level != level {
+		return quicError(c.in.setErrorLocked(errors.New("tls: handshake data received at wrong level")))
+	}
+	c.quic.readbuf = data
+	<-c.quic.signalc
+	_, ok := <-c.quic.blockedc
+	if ok {
+		// The handshake goroutine is waiting for more data.
+		return nil
+	}
+	// The handshake goroutine has exited.
+	c.handshakeMutex.Lock()
+	defer c.handshakeMutex.Unlock()
+	c.hand.Write(c.quic.readbuf)
+	c.quic.readbuf = nil
+	for q.conn.hand.Len() >= 4 && q.conn.handshakeErr == nil {
+		b := q.conn.hand.Bytes()
+		n := int(b[1])<<16 | int(b[2])<<8 | int(b[3])
+		if n > maxHandshake {
+			q.conn.handshakeErr = fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake)
+			break
+		}
+		if len(b) < 4+n {
+			return nil
+		}
+		if err := q.conn.handlePostHandshakeMessage(); err != nil {
+			q.conn.handshakeErr = err
+		}
+	}
+	if q.conn.handshakeErr != nil {
+		return quicError(q.conn.handshakeErr)
+	}
+	return nil
+}
+
+// SendSessionTicket sends a session ticket to the client.
+// It produces connection events, which may be read with NextEvent.
+// Currently, it can only be called once.
+func (q *UQUICConn) SendSessionTicket(opts QUICSessionTicketOptions) error {
+	c := q.conn
+	if !c.isHandshakeComplete.Load() {
+		return quicError(errors.New("tls: SendSessionTicket called before handshake completed"))
+	}
+	if c.isClient {
+		return quicError(errors.New("tls: SendSessionTicket called on the client"))
+	}
+	if q.sessionTicketSent {
+		return quicError(errors.New("tls: SendSessionTicket called multiple times"))
+	}
+	q.sessionTicketSent = true
+	return quicError(c.sendSessionTicket(opts.EarlyData))
+}
+
+// ConnectionState returns basic TLS details about the connection.
+func (q *UQUICConn) ConnectionState() ConnectionState {
+	return q.conn.ConnectionState()
+}
+
+// SetTransportParameters sets the transport parameters to send to the peer.
+//
+// Server connections may delay setting the transport parameters until after
+// receiving the client's transport parameters. See QUICTransportParametersRequired.
+func (q *UQUICConn) SetTransportParameters(params []byte) {
+	if params == nil {
+		params = []byte{}
+	}
+	q.conn.quic.transportParams = params // this won't be used for building ClientHello when using a preset
+
+	// // instead, we set the transport parameters hold by the ClientHello
+	// for _, ext := range q.conn.Extensions {
+	// 	if qtp, ok := ext.(*QUICTransportParametersExtension); ok {
+	// 		qtp.TransportParametersExtData = params
+	// 	}
+	// }
+
+	if q.conn.quic.started {
+		<-q.conn.quic.signalc
+		<-q.conn.quic.blockedc
+	}
+}
+
+func (uc *UConn) QUICSetReadSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
+	uc.quic.events = append(uc.quic.events, QUICEvent{
+		Kind:  QUICSetReadSecret,
+		Level: level,
+		Suite: suite,
+		Data:  secret,
+	})
+}
+
+func (uc *UConn) QUICSetWriteSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
+	uc.quic.events = append(uc.quic.events, QUICEvent{
+		Kind:  QUICSetWriteSecret,
+		Level: level,
+		Suite: suite,
+		Data:  secret,
+	})
+}
+
+func (uc *UConn) QUICGetTransportParameters() ([]byte, error) {
+	if uc.quic.transportParams == nil {
+		uc.quic.events = append(uc.quic.events, QUICEvent{
+			Kind: QUICTransportParametersRequired,
+		})
+	}
+	for uc.quic.transportParams == nil {
+		if err := uc.quicWaitForSignal(); err != nil {
+			return nil, err
+		}
+	}
+	return uc.quic.transportParams, nil
+}
diff --git a/vendor/github.com/refraction-networking/utls/u_quic_transport_parameters.go b/vendor/github.com/refraction-networking/utls/u_quic_transport_parameters.go
new file mode 100644
index 00000000..53b36cd7
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/u_quic_transport_parameters.go
@@ -0,0 +1,319 @@
+package tls
+
+import (
+	"crypto/rand"
+	"encoding/binary"
+	"math"
+	"math/big"
+
+	"github.com/refraction-networking/utls/internal/quicvarint"
+)
+
+const (
+	// RFC IDs
+	max_idle_timeout                    uint64 = 0x1
+	max_udp_payload_size                uint64 = 0x3
+	initial_max_data                    uint64 = 0x4
+	initial_max_stream_data_bidi_local  uint64 = 0x5
+	initial_max_stream_data_bidi_remote uint64 = 0x6
+	initial_max_stream_data_uni         uint64 = 0x7
+	initial_max_streams_bidi            uint64 = 0x8
+	initial_max_streams_uni             uint64 = 0x9
+	max_ack_delay                       uint64 = 0xb
+	disable_active_migration            uint64 = 0xc
+	active_connection_id_limit          uint64 = 0xe
+	initial_source_connection_id        uint64 = 0xf
+	version_information                 uint64 = 0x11 // RFC 9368
+	padding                             uint64 = 0x15
+	max_datagram_frame_size             uint64 = 0x20 // RFC 9221
+	grease_quic_bit                     uint64 = 0x2ab2
+
+	// Legacy IDs from draft
+	version_information_legacy uint64 = 0xff73db // draft-ietf-quic-version-negotiation-13 and early
+)
+
+type TransportParameters []TransportParameter
+
+func (tps TransportParameters) Marshal() []byte {
+	var b []byte
+	for _, tp := range tps {
+		b = quicvarint.Append(b, tp.ID())
+		b = quicvarint.Append(b, uint64(len(tp.Value())))
+		b = append(b, tp.Value()...)
+	}
+	return b
+}
+
+// TransportParameter represents a QUIC transport parameter.
+//
+// Caller will write the following to the wire:
+//
+//	var b []byte
+//	b = quicvarint.Append(b, ID())
+//	b = quicvarint.Append(b, len(Value()))
+//	b = append(b, Value())
+//
+// Therefore Value() should return the exact bytes to be written to the wire AFTER the length field,
+// i.e., the bytes MAY be a Variable Length Integer per RFC depending on the type of the transport
+// parameter, but MUST NOT including the length field unless the parameter is defined so.
+type TransportParameter interface {
+	ID() uint64
+	Value() []byte
+}
+
+type GREASETransportParameter struct {
+	IdOverride    uint64 // if set to a valid GREASE ID, use this instead of randomly generated one.
+	Length        uint16 // if len(ValueOverride) == 0, will generate random data of this size.
+	ValueOverride []byte // if len(ValueOverride) > 0, use this instead of random bytes.
+}
+
+const (
+	GREASE_MAX_MULTIPLIER = (0x3FFFFFFFFFFFFFFF - 27) / 31
+)
+
+// IsGREASEID returns true if id is a valid GREASE ID for
+// transport parameters.
+func (GREASETransportParameter) IsGREASEID(id uint64) bool {
+	return id >= 27 && (id-27)%31 == 0
+}
+
+// GetGREASEID returns a random valid GREASE ID for transport parameters.
+func (GREASETransportParameter) GetGREASEID() uint64 {
+	max := big.NewInt(GREASE_MAX_MULTIPLIER)
+
+	randMultiply, err := rand.Int(rand.Reader, max)
+	if err != nil {
+		return 27
+	}
+
+	return 27 + randMultiply.Uint64()*31
+}
+
+func (g *GREASETransportParameter) ID() uint64 {
+	if !g.IsGREASEID(g.IdOverride) {
+		g.IdOverride = g.GetGREASEID()
+	}
+	return g.IdOverride
+}
+
+func (g *GREASETransportParameter) Value() []byte {
+	if len(g.ValueOverride) == 0 {
+		g.ValueOverride = make([]byte, g.Length)
+		rand.Read(g.ValueOverride)
+	}
+	return g.ValueOverride
+}
+
+type MaxIdleTimeout uint64 // in milliseconds
+
+func (MaxIdleTimeout) ID() uint64 {
+	return max_idle_timeout
+}
+
+func (m MaxIdleTimeout) Value() []byte {
+	return quicvarint.Append([]byte{}, uint64(m))
+}
+
+type MaxUDPPayloadSize uint64
+
+func (MaxUDPPayloadSize) ID() uint64 {
+	return max_udp_payload_size
+}
+
+func (m MaxUDPPayloadSize) Value() []byte {
+	return quicvarint.Append([]byte{}, uint64(m))
+}
+
+type InitialMaxData uint64
+
+func (InitialMaxData) ID() uint64 {
+	return initial_max_data
+}
+
+func (i InitialMaxData) Value() []byte {
+	return quicvarint.Append([]byte{}, uint64(i))
+}
+
+type InitialMaxStreamDataBidiLocal uint64
+
+func (InitialMaxStreamDataBidiLocal) ID() uint64 {
+	return initial_max_stream_data_bidi_local
+}
+
+func (i InitialMaxStreamDataBidiLocal) Value() []byte {
+	return quicvarint.Append([]byte{}, uint64(i))
+}
+
+type InitialMaxStreamDataBidiRemote uint64
+
+func (InitialMaxStreamDataBidiRemote) ID() uint64 {
+	return initial_max_stream_data_bidi_remote
+}
+
+func (i InitialMaxStreamDataBidiRemote) Value() []byte {
+	return quicvarint.Append([]byte{}, uint64(i))
+}
+
+type InitialMaxStreamDataUni uint64
+
+func (InitialMaxStreamDataUni) ID() uint64 {
+	return initial_max_stream_data_uni
+}
+
+func (i InitialMaxStreamDataUni) Value() []byte {
+	return quicvarint.Append([]byte{}, uint64(i))
+}
+
+type InitialMaxStreamsBidi uint64
+
+func (InitialMaxStreamsBidi) ID() uint64 {
+	return initial_max_streams_bidi
+}
+
+func (i InitialMaxStreamsBidi) Value() []byte {
+	return quicvarint.Append([]byte{}, uint64(i))
+}
+
+type InitialMaxStreamsUni uint64
+
+func (InitialMaxStreamsUni) ID() uint64 {
+	return initial_max_streams_uni
+}
+
+func (i InitialMaxStreamsUni) Value() []byte {
+	return quicvarint.Append([]byte{}, uint64(i))
+}
+
+type MaxAckDelay uint64
+
+func (MaxAckDelay) ID() uint64 {
+	return max_ack_delay
+}
+
+func (m MaxAckDelay) Value() []byte {
+	return quicvarint.Append([]byte{}, uint64(m))
+}
+
+type DisableActiveMigration struct{}
+
+func (*DisableActiveMigration) ID() uint64 {
+	return disable_active_migration
+}
+
+// Its Value MUST ALWAYS be empty.
+func (*DisableActiveMigration) Value() []byte {
+	return []byte{}
+}
+
+type ActiveConnectionIDLimit uint64
+
+func (ActiveConnectionIDLimit) ID() uint64 {
+	return active_connection_id_limit
+}
+
+func (a ActiveConnectionIDLimit) Value() []byte {
+	return quicvarint.Append([]byte{}, uint64(a))
+}
+
+type InitialSourceConnectionID []byte // if empty, will be set to the Connection ID used for the Initial packet.
+
+func (InitialSourceConnectionID) ID() uint64 {
+	return initial_source_connection_id
+}
+
+func (i InitialSourceConnectionID) Value() []byte {
+	return []byte(i)
+}
+
+type VersionInformation struct {
+	ChoosenVersion    uint32
+	AvailableVersions []uint32 // Also known as "Other Versions" in early drafts.
+
+	LegacyID bool // If true, use the legacy-assigned ID (0xff73db) instead of the RFC-assigned one (0x11).
+}
+
+const (
+	VERSION_NEGOTIATION uint32 = 0x00000000 // rfc9000
+	VERSION_1           uint32 = 0x00000001 // rfc9000
+	VERSION_2           uint32 = 0x6b3343cf // rfc9369
+
+	VERSION_GREASE uint32 = 0x0a0a0a0a // -> 0x?a?a?a?a
+)
+
+func (v *VersionInformation) ID() uint64 {
+	if v.LegacyID {
+		return version_information_legacy
+	}
+	return version_information
+}
+
+func (v *VersionInformation) Value() []byte {
+	var b []byte
+	b = binary.BigEndian.AppendUint32(b, v.ChoosenVersion)
+	for _, version := range v.AvailableVersions {
+		if version != VERSION_GREASE {
+			b = binary.BigEndian.AppendUint32(b, version)
+		} else {
+			b = binary.BigEndian.AppendUint32(b, v.GetGREASEVersion())
+		}
+	}
+	return b
+}
+
+func (*VersionInformation) GetGREASEVersion() uint32 {
+	// get a random uint32
+	max := big.NewInt(math.MaxUint32)
+	randVal, err := rand.Int(rand.Reader, max)
+	if err != nil {
+		return VERSION_GREASE
+	}
+
+	return uint32(randVal.Uint64()&math.MaxUint32) | 0x0a0a0a0a // all GREASE versions are in 0x?a?a?a?a
+}
+
+type PaddingTransportParameter []byte
+
+func (PaddingTransportParameter) ID() uint64 {
+	return padding
+}
+
+func (p PaddingTransportParameter) Value() []byte {
+	return p
+}
+
+type MaxDatagramFrameSize uint64
+
+func (MaxDatagramFrameSize) ID() uint64 {
+	return max_datagram_frame_size
+}
+
+func (m MaxDatagramFrameSize) Value() []byte {
+	return quicvarint.Append([]byte{}, uint64(m))
+}
+
+type GREASEQUICBit struct{}
+
+func (*GREASEQUICBit) ID() uint64 {
+	return grease_quic_bit
+}
+
+// Its Value MUST ALWAYS be empty.
+func (*GREASEQUICBit) Value() []byte {
+	return []byte{}
+}
+
+type FakeQUICTransportParameter struct {
+	Id  uint64
+	Val []byte
+}
+
+func (f *FakeQUICTransportParameter) ID() uint64 {
+	if f.Id == 0 {
+		panic("it is not allowed to use a FakeQUICTransportParameter without setting the ID")
+	}
+	return f.Id
+}
+
+func (f *FakeQUICTransportParameter) Value() []byte {
+	return f.Val
+}
diff --git a/vendor/github.com/refraction-networking/utls/u_session_controller.go b/vendor/github.com/refraction-networking/utls/u_session_controller.go
new file mode 100644
index 00000000..4c6a79cd
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/u_session_controller.go
@@ -0,0 +1,359 @@
+package tls
+
+import (
+	"errors"
+	"fmt"
+)
+
+// Tracking the state of calling conn.loadSession
+type LoadSessionTrackerState int
+
+const NeverCalled LoadSessionTrackerState = 0
+const UtlsAboutToCall LoadSessionTrackerState = 1
+const CalledByULoadSession LoadSessionTrackerState = 2
+const CalledByGoTLS LoadSessionTrackerState = 3
+
+// The state of the session controller
+type sessionControllerState int
+
+const NoSession sessionControllerState = 0
+const SessionTicketExtInitialized sessionControllerState = 1
+const SessionTicketExtAllSet sessionControllerState = 2
+const PskExtInitialized sessionControllerState = 3
+const PskExtAllSet sessionControllerState = 4
+
+// sessionController is responsible for managing and controlling all session related states. It manages the lifecycle of the session ticket extension and the psk extension, including initialization, removal if the client hello spec doesn't contain any of them, and setting the prepared state to the client hello.
+//
+// Users should never directly modify the underlying state. Violations will result in undefined behaviors.
+//
+// Users should never construct sessionController by themselves, use the function `newSessionController` instead.
+type sessionController struct {
+	// sessionTicketExt logically owns the session ticket extension
+	sessionTicketExt ISessionTicketExtension
+
+	// pskExtension logically owns the psk extension
+	pskExtension PreSharedKeyExtension
+
+	// uconnRef is a reference to the uconn
+	uconnRef *UConn
+
+	// state represents the internal state of the sessionController. Users are advised to modify the state only through designated methods and avoid direct manipulation, as doing so may result in undefined behavior.
+	state sessionControllerState
+
+	// loadSessionTracker keeps track of how the conn.loadSession method is being utilized.
+	loadSessionTracker LoadSessionTrackerState
+
+	// callingLoadSession is a boolean flag that indicates whether the `conn.loadSession` function is currently being invoked.
+	callingLoadSession bool
+
+	// locked is a boolean flag that becomes true once all states are appropriately set. Once `locked` is true, further modifications are disallowed, except for the binders.
+	locked bool
+}
+
+// newSessionController constructs a new SessionController
+func newSessionController(uconn *UConn) *sessionController {
+	return &sessionController{
+		uconnRef:           uconn,
+		sessionTicketExt:   nil,
+		pskExtension:       nil,
+		state:              NoSession,
+		locked:             false,
+		callingLoadSession: false,
+		loadSessionTracker: NeverCalled,
+	}
+}
+
+func (s *sessionController) isSessionLocked() bool {
+	return s.locked
+}
+
+type shouldLoadSessionResult int
+
+const shouldReturn shouldLoadSessionResult = 0
+const shouldSetTicket shouldLoadSessionResult = 1
+const shouldSetPsk shouldLoadSessionResult = 2
+const shouldLoad shouldLoadSessionResult = 3
+
+// shouldLoadSession determines the appropriate action to take when it is time to load the session for the clientHello.
+// There are several possible scenarios:
+//   - If a session ticket is already initialized, typically via the `initSessionTicketExt()` function, the ticket should be set in the client hello.
+//   - If a pre-shared key (PSK) is already initialized, typically via the `overridePskExt()` function, the PSK should be set in the client hello.
+//   - If both the `sessionTicketExt` and `pskExtension` are nil, which might occur if the client hello spec does not include them, we should skip the loadSession().
+//   - In all other cases, the function proceeds to load the session.
+func (s *sessionController) shouldLoadSession() shouldLoadSessionResult {
+	if s.sessionTicketExt == nil && s.pskExtension == nil || s.uconnRef.clientHelloBuildStatus != NotBuilt {
+		// No need to load session since we don't have the related extensions.
+		return shouldReturn
+	}
+	if s.state == SessionTicketExtInitialized {
+		return shouldSetTicket
+	}
+	if s.state == PskExtInitialized {
+		return shouldSetPsk
+	}
+	return shouldLoad
+}
+
+// utlsAboutToLoadSession updates the loadSessionTracker to `UtlsAboutToCall` to signal the initiation of a session loading operation,
+// provided that the preconditions are met. If the preconditions are not met (due to incorrect utls implementation), this function triggers a panic.
+func (s *sessionController) utlsAboutToLoadSession() {
+	uAssert(s.state == NoSession && !s.locked, "tls: aboutToLoadSession failed: must only load session when the session of the client hello is not locked and when there's currently no session")
+	s.loadSessionTracker = UtlsAboutToCall
+}
+
+func (s *sessionController) assertHelloNotBuilt(caller string) {
+	if s.uconnRef.clientHelloBuildStatus != NotBuilt {
+		panic(fmt.Sprintf("tls: %s failed: we can't modify the session after the clientHello is built", caller))
+	}
+}
+
+func (s *sessionController) assertControllerState(caller string, desired sessionControllerState, moreDesiredStates ...sessionControllerState) {
+	if s.state != desired && !anyTrue(moreDesiredStates, func(_ int, state *sessionControllerState) bool {
+		return s.state == *state
+	}) {
+		panic(fmt.Sprintf("tls: %s failed: undesired controller state %d", caller, s.state))
+	}
+}
+
+func (s *sessionController) assertNotLocked(caller string) {
+	if s.locked {
+		panic(fmt.Sprintf("tls: %s failed: you must not modify the session after it's locked", caller))
+	}
+}
+
+func (s *sessionController) assertCanSkip(caller, extensionName string) {
+	if !s.uconnRef.skipResumptionOnNilExtension {
+		panic(fmt.Sprintf("tls: %s failed: session resumption is enabled, but there is no %s in the ClientHelloSpec; Please consider provide one in the ClientHelloSpec; If this is intentional, you may consider disable resumption by setting Config.SessionTicketsDisabled to true, or set Config.PreferSkipResumptionOnNilExtension to true to suppress this exception", caller, extensionName))
+	}
+}
+
+// finalCheck performs a comprehensive check on the updated state to ensure the correctness of the changes.
+// If the checks pass successfully, the sessionController's state will be locked.
+// Any failure in passing the tests indicates incorrect implementations in the utls, which will result in triggering a panic.
+// Refer to the documentation for the `locked` field for more detailed information.
+func (s *sessionController) finalCheck() {
+	s.assertControllerState("SessionController.finalCheck", PskExtAllSet, SessionTicketExtAllSet, NoSession)
+	s.locked = true
+}
+
+func initializationGuard[E Initializable, I func(E)](extension E, initializer I) {
+	uAssert(!extension.IsInitialized(), "tls: initialization failed: the extension is already initialized")
+	initializer(extension)
+	uAssert(extension.IsInitialized(), "tls: initialization failed: the extension is not initialized after initialization")
+}
+
+// initSessionTicketExt initializes the ticket and sets the state to `TicketInitialized`.
+func (s *sessionController) initSessionTicketExt(session *SessionState, ticket []byte) {
+	s.assertNotLocked("initSessionTicketExt")
+	s.assertHelloNotBuilt("initSessionTicketExt")
+	s.assertControllerState("initSessionTicketExt", NoSession)
+	panicOnNil("initSessionTicketExt", session, ticket)
+	if s.sessionTicketExt == nil {
+		s.assertCanSkip("initSessionTicketExt", "session ticket extension")
+		return
+	}
+	initializationGuard(s.sessionTicketExt, func(e ISessionTicketExtension) {
+		s.sessionTicketExt.InitializeByUtls(session, ticket)
+	})
+	s.state = SessionTicketExtInitialized
+}
+
+// initPSK initializes the PSK extension using a valid session. The PSK extension
+// should not be initialized previously, and the parameters must not be nil;
+// otherwise, this function will trigger a panic.
+func (s *sessionController) initPskExt(session *SessionState, earlySecret []byte, binderKey []byte, pskIdentities []pskIdentity) {
+	s.assertNotLocked("initPskExt")
+	s.assertHelloNotBuilt("initPskExt")
+	s.assertControllerState("initPskExt", NoSession)
+	panicOnNil("initPskExt", session, earlySecret, pskIdentities)
+	if s.pskExtension == nil {
+		s.assertCanSkip("initPskExt", "pre-shared key extension")
+		return
+	}
+	initializationGuard(s.pskExtension, func(e PreSharedKeyExtension) {
+		publicPskIdentities := mapSlice(pskIdentities, func(private pskIdentity) PskIdentity {
+			return PskIdentity{
+				Label:               private.label,
+				ObfuscatedTicketAge: private.obfuscatedTicketAge,
+			}
+		})
+		e.InitializeByUtls(session, earlySecret, binderKey, publicPskIdentities)
+	})
+
+	s.state = PskExtInitialized
+}
+
+// setSessionTicketToUConn write the ticket states from the session ticket extension to the client hello and handshake state.
+func (s *sessionController) setSessionTicketToUConn() {
+	uAssert(s.sessionTicketExt != nil && s.state == SessionTicketExtInitialized, "tls: setSessionTicketExt failed: invalid state")
+	s.uconnRef.HandshakeState.Session = s.sessionTicketExt.GetSession()
+	s.uconnRef.HandshakeState.Hello.SessionTicket = s.sessionTicketExt.GetTicket()
+	s.state = SessionTicketExtAllSet
+}
+
+// setPskToUConn sets the psk to the handshake state and client hello.
+func (s *sessionController) setPskToUConn() {
+	uAssert(s.pskExtension != nil && (s.state == PskExtInitialized || s.state == PskExtAllSet), "tls: setPskToUConn failed: invalid state")
+	pskCommon := s.pskExtension.GetPreSharedKeyCommon()
+	if s.state == PskExtInitialized {
+		s.uconnRef.HandshakeState.State13.EarlySecret = pskCommon.EarlySecret
+		s.uconnRef.HandshakeState.Session = pskCommon.Session
+		s.uconnRef.HandshakeState.Hello.PskIdentities = pskCommon.Identities
+		s.uconnRef.HandshakeState.Hello.PskBinders = pskCommon.Binders
+	} else if s.state == PskExtAllSet {
+		uAssert(s.uconnRef.HandshakeState.Session == pskCommon.Session && sliceEq(s.uconnRef.HandshakeState.State13.EarlySecret, pskCommon.EarlySecret) &&
+			allTrue(s.uconnRef.HandshakeState.Hello.PskIdentities, func(i int, psk *PskIdentity) bool {
+				return pskCommon.Identities[i].ObfuscatedTicketAge == psk.ObfuscatedTicketAge && sliceEq(pskCommon.Identities[i].Label, psk.Label)
+			}), "tls: setPskToUConn failed: only binders are allowed to change on state `PskAllSet`")
+	}
+	s.uconnRef.HandshakeState.State13.BinderKey = pskCommon.BinderKey
+	s.state = PskExtAllSet
+}
+
+// shouldUpdateBinders determines whether binders should be updated based on the presence of an initialized psk extension.
+// This function returns true if an initialized psk extension exists. Binders are allowed to be updated when the state is `PskAllSet`,
+// as the `BuildHandshakeState` function can be called multiple times in this case. However, it's important to note that
+// the session state, apart from binders, should not be altered more than once.
+func (s *sessionController) shouldUpdateBinders() bool {
+	if s.pskExtension == nil {
+		return false
+	}
+	return (s.state == PskExtInitialized || s.state == PskExtAllSet)
+}
+
+func (s *sessionController) updateBinders() {
+	uAssert(s.shouldUpdateBinders(), "tls: updateBinders failed: shouldn't update binders")
+	s.pskExtension.PatchBuiltHello(s.uconnRef.HandshakeState.Hello)
+}
+
+func (s *sessionController) overrideExtension(extension Initializable, override func(), initializedState sessionControllerState) error {
+	panicOnNil("overrideExtension", extension)
+	s.assertNotLocked("overrideExtension")
+	s.assertControllerState("overrideExtension", NoSession)
+	override()
+	if extension.IsInitialized() {
+		s.state = initializedState
+	}
+	return nil
+}
+
+// overridePskExt allows the user of utls to customize the psk extension.
+func (s *sessionController) overridePskExt(pskExt PreSharedKeyExtension) error {
+	return s.overrideExtension(pskExt, func() { s.pskExtension = pskExt }, PskExtInitialized)
+}
+
+// overridePskExt allows the user of utls to customize the session ticket extension.
+func (s *sessionController) overrideSessionTicketExt(sessionTicketExt ISessionTicketExtension) error {
+	return s.overrideExtension(sessionTicketExt, func() { s.sessionTicketExt = sessionTicketExt }, SessionTicketExtInitialized)
+}
+
+// syncSessionExts synchronizes the sessionController with the session-related
+// extensions from the extension list after applying client hello specs.
+//
+//   - If the extension list is missing the session ticket extension or PSK
+//     extension, owned extensions are dropped and states are reset.
+//   - If the user provides a session ticket extension or PSK extension, the
+//     corresponding extension from the extension list will be replaced.
+//   - If the user doesn't provide session-related extensions, the extensions
+//     from the extension list will be utilized.
+//
+// This function ensures that there is only one session ticket extension or PSK
+// extension, and that the PSK extension is the last extension in the extension
+// list.
+func (s *sessionController) syncSessionExts() error {
+	uAssert(s.uconnRef.clientHelloBuildStatus == NotBuilt, "tls: checkSessionExts failed: we can't modify the session after the clientHello is built")
+	s.assertNotLocked("checkSessionExts")
+	s.assertHelloNotBuilt("checkSessionExts")
+	s.assertControllerState("checkSessionExts", NoSession, SessionTicketExtInitialized, PskExtInitialized)
+	numSessionExt := 0
+	hasPskExt := false
+	for i, e := range s.uconnRef.Extensions {
+		switch ext := e.(type) {
+		case ISessionTicketExtension:
+			uAssert(numSessionExt == 0, "tls: checkSessionExts failed: multiple ISessionTicketExtensions in the extension list")
+			if s.sessionTicketExt == nil {
+				// If there isn't a user-provided session ticket extension, use the one from the spec
+				s.sessionTicketExt = ext
+			} else {
+				// Otherwise, replace the one in the extension list with the user-provided one
+				s.uconnRef.Extensions[i] = s.sessionTicketExt
+			}
+			numSessionExt += 1
+		case PreSharedKeyExtension:
+			uAssert(i == len(s.uconnRef.Extensions)-1, "tls: checkSessionExts failed: PreSharedKeyExtension must be the last extension")
+			if s.pskExtension == nil {
+				// If there isn't a user-provided psk extension, use the one from the spec
+				s.pskExtension = ext
+			} else {
+				// Otherwise, replace the one in the extension list with the user-provided one
+				s.uconnRef.Extensions[i] = s.pskExtension
+			}
+			s.pskExtension.SetOmitEmptyPsk(s.uconnRef.config.OmitEmptyPsk)
+			hasPskExt = true
+		}
+	}
+	if numSessionExt == 0 {
+		if s.state == SessionTicketExtInitialized {
+			return errors.New("tls: checkSessionExts failed: the user provided a session ticket, but the specification doesn't contain one")
+		}
+		s.sessionTicketExt = nil
+		s.uconnRef.HandshakeState.Session = nil
+		s.uconnRef.HandshakeState.Hello.SessionTicket = nil
+	}
+	if !hasPskExt {
+		if s.state == PskExtInitialized {
+			return errors.New("tls: checkSessionExts failed: the user provided a psk, but the specification doesn't contain one")
+		}
+		s.pskExtension = nil
+		s.uconnRef.HandshakeState.State13.BinderKey = nil
+		s.uconnRef.HandshakeState.State13.EarlySecret = nil
+		s.uconnRef.HandshakeState.Session = nil
+		s.uconnRef.HandshakeState.Hello.PskIdentities = nil
+	}
+	return nil
+}
+
+// onEnterLoadSessionCheck is intended to be invoked upon entering the `conn.loadSession` function.
+// It is designed to ensure the correctness of the utls implementation. If the utls implementation is found to be incorrect, this function will trigger a panic.
+func (s *sessionController) onEnterLoadSessionCheck() {
+	uAssert(!s.locked, "tls: LoadSessionCoordinator.onEnterLoadSessionCheck failed: session is set and locked, no call to loadSession is allowed")
+	switch s.loadSessionTracker {
+	case UtlsAboutToCall, NeverCalled:
+		s.callingLoadSession = true
+	case CalledByULoadSession, CalledByGoTLS:
+		panic("tls: LoadSessionCoordinator.onEnterLoadSessionCheck failed: you must not call loadSession() twice")
+	default:
+		panic("tls: LoadSessionCoordinator.onEnterLoadSessionCheck failed: unimplemented state")
+	}
+}
+
+// onLoadSessionReturn is intended to be invoked upon returning from the `conn.loadSession` function.
+// It serves as a validation step for the correctness of the underlying utls implementation.
+// If the utls implementation is incorrect, this function will trigger a panic.
+func (s *sessionController) onLoadSessionReturn() {
+	uAssert(s.callingLoadSession, "tls: LoadSessionCoordinator.onLoadSessionReturn failed: it's not loading sessions, perhaps this function is not being called by loadSession.")
+	switch s.loadSessionTracker {
+	case NeverCalled:
+		s.loadSessionTracker = CalledByGoTLS
+	case UtlsAboutToCall:
+		s.loadSessionTracker = CalledByULoadSession
+	default:
+		panic("tls: LoadSessionCoordinator.onLoadSessionReturn failed: unimplemented state")
+	}
+	s.callingLoadSession = false
+}
+
+// shouldLoadSessionWriteBinders checks if `conn.loadSession` should proceed to write binders and marshal the client hello. If the utls implementation
+// is incorrect, this function will trigger a panic.
+func (s *sessionController) shouldLoadSessionWriteBinders() bool {
+	uAssert(s.callingLoadSession, "tls: shouldWriteBinders failed: LoadSessionCoordinator isn't loading sessions, perhaps this function is not being called by loadSession.")
+
+	switch s.loadSessionTracker {
+	case NeverCalled:
+		return true
+	case UtlsAboutToCall:
+		return false
+	default:
+		panic("tls: shouldWriteBinders failed: unimplemented state")
+	}
+}
diff --git a/vendor/github.com/refraction-networking/utls/u_session_ticket.go b/vendor/github.com/refraction-networking/utls/u_session_ticket.go
new file mode 100644
index 00000000..caefd065
--- /dev/null
+++ b/vendor/github.com/refraction-networking/utls/u_session_ticket.go
@@ -0,0 +1,82 @@
+package tls
+
+import "io"
+
+type ISessionTicketExtension interface {
+	TLSExtension
+
+	// If false is returned, utls will invoke `InitializeByUtls()` for the necessary initialization.
+	Initializable
+
+	// InitializeByUtls is invoked when IsInitialized() returns false.
+	// It initializes the extension using a real and valid TLS 1.2 session.
+	InitializeByUtls(session *SessionState, ticket []byte)
+
+	GetSession() *SessionState
+
+	GetTicket() []byte
+}
+
+// SessionTicketExtension implements session_ticket (35)
+type SessionTicketExtension struct {
+	Session     *SessionState
+	Ticket      []byte
+	Initialized bool
+}
+
+func (e *SessionTicketExtension) writeToUConn(uc *UConn) error {
+	// session states are handled later. At this point tickets aren't
+	// being loaded by utls, so don't write anything to the UConn.
+	uc.HandshakeState.Hello.TicketSupported = true // This doesn't really matter, this field is only used to add session ticket ext in go tls.
+	return nil
+}
+
+func (e *SessionTicketExtension) Len() int {
+	return 4 + len(e.Ticket)
+}
+
+func (e *SessionTicketExtension) Read(b []byte) (int, error) {
+	if len(b) < e.Len() {
+		return 0, io.ErrShortBuffer
+	}
+
+	extBodyLen := e.Len() - 4
+
+	b[0] = byte(extensionSessionTicket >> 8)
+	b[1] = byte(extensionSessionTicket)
+	b[2] = byte(extBodyLen >> 8)
+	b[3] = byte(extBodyLen)
+	if extBodyLen > 0 {
+		copy(b[4:], e.Ticket)
+	}
+	return e.Len(), io.EOF
+}
+
+func (e *SessionTicketExtension) IsInitialized() bool {
+	return e.Initialized
+}
+
+func (e *SessionTicketExtension) InitializeByUtls(session *SessionState, ticket []byte) {
+	uAssert(!e.Initialized, "tls: InitializeByUtls failed: the SessionTicketExtension is initialized")
+	uAssert(session.version == VersionTLS12 && session != nil && ticket != nil, "tls: InitializeByUtls failed: the session is not a tls 1.2 session")
+	e.Session = session
+	e.Ticket = ticket
+	e.Initialized = true
+}
+
+func (e *SessionTicketExtension) UnmarshalJSON(_ []byte) error {
+	return nil // no-op
+}
+
+func (e *SessionTicketExtension) Write(_ []byte) (int, error) {
+	// RFC 5077, Section 3.2
+	return 0, nil
+}
+
+func (e *SessionTicketExtension) GetSession() *SessionState {
+	return e.Session
+}
+
+func (e *SessionTicketExtension) GetTicket() []byte {
+	return e.Ticket
+}
diff --git a/vendor/github.com/refraction-networking/utls/u_tls_extensions.go b/vendor/github.com/refraction-networking/utls/u_tls_extensions.go
index 22cfdc27..f68e7b6e 100644
--- a/vendor/github.com/refraction-networking/utls/u_tls_extensions.go
+++ b/vendor/github.com/refraction-networking/utls/u_tls_extensions.go
@@ -11,7 +11,7 @@ import (
 	"io"
 	"strings"
 
-	"github.com/gaukas/godicttls"
+	"github.com/refraction-networking/utls/dicttls"
 	"golang.org/x/crypto/cryptobyte"
 )
 
@@ -37,18 +37,20 @@ func ExtensionFromID(id uint16) TLSExtension {
 		return &SCTExtension{}
 	case utlsExtensionPadding:
 		return &UtlsPaddingExtension{}
-	case utlsExtensionExtendedMasterSecret:
-		return &UtlsExtendedMasterSecretExtension{}
+	case extensionExtendedMasterSecret:
+		return &ExtendedMasterSecretExtension{}
 	case fakeExtensionTokenBinding:
 		return &FakeTokenBindingExtension{}
 	case utlsExtensionCompressCertificate:
 		return &UtlsCompressCertExtension{}
+	case fakeRecordSizeLimit:
+		return &FakeRecordSizeLimitExtension{}
 	case fakeExtensionDelegatedCredentials:
 		return &FakeDelegatedCredentialsExtension{}
 	case extensionSessionTicket:
 		return &SessionTicketExtension{}
-	case fakeExtensionPreSharedKey:
-		return &FakePreSharedKeyExtension{}
+	case extensionPreSharedKey:
+		return (PreSharedKeyExtension)(&FakePreSharedKeyExtension{}) // To use the result, caller needs further inspection to decide between Fake or Utls.
 	// case extensionEarlyData:
 	// 	return &EarlyDataExtension{}
 	case extensionSupportedVersions:
@@ -63,6 +65,8 @@ func ExtensionFromID(id uint16) TLSExtension {
 		return &SignatureAlgorithmsCertExtension{}
 	case extensionKeyShare:
 		return &KeyShareExtension{}
+	case extensionQUICTransportParameters:
+		return &QUICTransportParametersExtension{}
 	case extensionNextProtoNeg:
 		return &NPNExtension{}
 	case utlsExtensionApplicationSettings:
@@ -71,8 +75,8 @@ func ExtensionFromID(id uint16) TLSExtension {
 		return &FakeChannelIDExtension{true}
 	case fakeExtensionChannelID:
 		return &FakeChannelIDExtension{}
-	case fakeRecordSizeLimit:
-		return &FakeRecordSizeLimitExtension{}
+	case utlsExtensionECH:
+		return &GREASEEncryptedClientHelloExtension{}
 	case extensionRenegotiationInfo:
 		return &RenegotiationInfoExtension{}
 	default:
@@ -98,8 +102,11 @@ type TLSExtension interface {
 type TLSExtensionWriter interface {
 	TLSExtension
 
-	// Write writes up to len(b) bytes from b.
+	// Write writes the extension data as a byte slice, up to len(b) bytes from b.
 	// It returns the number of bytes written (0 <= n <= len(b)) and any error encountered.
+	//
+	// The implementation MUST NOT silently drop data if consumed less than len(b) bytes,
+	// instead, it MUST return an error.
 	Write(b []byte) (n int, err error)
 }
 
@@ -289,7 +296,7 @@ func (e *SupportedCurvesExtension) UnmarshalJSON(data []byte) error {
 			continue
 		}
 
-		if group, ok := godicttls.DictSupportedGroupsNameIndexed[namedGroup]; ok {
+		if group, ok := dicttls.DictSupportedGroupsNameIndexed[namedGroup]; ok {
 			e.Curves = append(e.Curves, CurveID(group))
 		} else {
 			return fmt.Errorf("unknown named group: %s", namedGroup)
@@ -358,7 +365,7 @@ func (e *SupportedPointsExtension) UnmarshalJSON(data []byte) error {
 	}
 
 	for _, pointFormat := range pointFormatList.ECPointFormatList {
-		if format, ok := godicttls.DictECPointFormatNameIndexed[pointFormat]; ok {
+		if format, ok := dicttls.DictECPointFormatNameIndexed[pointFormat]; ok {
 			e.SupportedPoints = append(e.SupportedPoints, format)
 		} else {
 			return fmt.Errorf("unknown point format: %s", pointFormat)
@@ -426,7 +433,7 @@ func (e *SignatureAlgorithmsExtension) UnmarshalJSON(data []byte) error {
 			continue
 		}
 
-		if scheme, ok := godicttls.DictSignatureSchemeNameIndexed[sigScheme]; ok {
+		if scheme, ok := dicttls.DictSignatureSchemeNameIndexed[sigScheme]; ok {
 			e.SupportedSignatureAlgorithms = append(e.SupportedSignatureAlgorithms, SignatureScheme(scheme))
 		} else {
 			return fmt.Errorf("unknown signature scheme: %s", sigScheme)
@@ -499,11 +506,7 @@ func (e *StatusRequestV2Extension) Write(b []byte) (int, error) {
 	// RFC 4366, Section 3.6
 	var statusType uint8
 	var ignored cryptobyte.String
-	if !extData.ReadUint16LengthPrefixed(&ignored) ||
-		!extData.ReadUint8(&statusType) ||
-		!extData.ReadUint16LengthPrefixed(&ignored) ||
-		!extData.ReadUint16LengthPrefixed(&ignored) ||
-		!extData.ReadUint16LengthPrefixed(&ignored) {
+	if !extData.ReadUint16LengthPrefixed(&ignored) || !ignored.ReadUint8(&statusType) {
 		return fullLen, errors.New("unable to read status request v2 extension data")
 	}
 
@@ -560,7 +563,7 @@ func (e *SignatureAlgorithmsCertExtension) UnmarshalJSON(data []byte) error {
 			continue
 		}
 
-		if scheme, ok := godicttls.DictSignatureSchemeNameIndexed[sigScheme]; ok {
+		if scheme, ok := dicttls.DictSignatureSchemeNameIndexed[sigScheme]; ok {
 			e.SupportedSignatureAlgorithms = append(e.SupportedSignatureAlgorithms, SignatureScheme(scheme))
 		} else {
 			return fmt.Errorf("unknown cert signature scheme: %s", sigScheme)
@@ -795,52 +798,6 @@ func (e *SCTExtension) Write(_ []byte) (int, error) {
 	return 0, nil
 }
 
-// SessionTicketExtension implements session_ticket (35)
-type SessionTicketExtension struct {
-	Session *ClientSessionState
-}
-
-func (e *SessionTicketExtension) writeToUConn(uc *UConn) error {
-	if e.Session != nil {
-		uc.HandshakeState.Session = e.Session
-		uc.HandshakeState.Hello.SessionTicket = e.Session.sessionTicket
-	}
-	return nil
-}
-
-func (e *SessionTicketExtension) Len() int {
-	if e.Session != nil {
-		return 4 + len(e.Session.sessionTicket)
-	}
-	return 4
-}
-
-func (e *SessionTicketExtension) Read(b []byte) (int, error) {
-	if len(b) < e.Len() {
-		return 0, io.ErrShortBuffer
-	}
-
-	extBodyLen := e.Len() - 4
-
-	b[0] = byte(extensionSessionTicket >> 8)
-	b[1] = byte(extensionSessionTicket)
-	b[2] = byte(extBodyLen >> 8)
-	b[3] = byte(extBodyLen)
-	if extBodyLen > 0 {
-		copy(b[4:], e.Session.sessionTicket)
-	}
-	return e.Len(), io.EOF
-}
-
-func (e *SessionTicketExtension) UnmarshalJSON(_ []byte) error {
-	return nil // no-op
-}
-
-func (e *SessionTicketExtension) Write(_ []byte) (int, error) {
-	// RFC 5077, Section 3.2
-	return 0, nil
-}
-
 // GenericExtension allows to include in ClientHello arbitrary unsupported extensions.
 // It is not defined in TLS RFCs nor by IANA.
 // If a server echoes this extension back, the handshake will likely fail due to no further support.
@@ -882,7 +839,7 @@ func (e *GenericExtension) UnmarshalJSON(b []byte) error {
 	}
 
 	// lookup extension ID by name
-	if id, ok := godicttls.DictExtTypeNameIndexed[genericExtension.Name]; ok {
+	if id, ok := dicttls.DictExtTypeNameIndexed[genericExtension.Name]; ok {
 		e.Id = id
 	} else {
 		return fmt.Errorf("unknown extension name %s", genericExtension.Name)
@@ -891,42 +848,45 @@ func (e *GenericExtension) UnmarshalJSON(b []byte) error {
 	return nil
 }
 
-// UtlsExtendedMasterSecretExtension implements extended_master_secret (23)
-type UtlsExtendedMasterSecretExtension struct {
+// ExtendedMasterSecretExtension implements extended_master_secret (23)
+//
+// Was named as ExtendedMasterSecretExtension, renamed due to crypto/tls
+// implemented this extension's support.
+type ExtendedMasterSecretExtension struct {
 }
 
 // TODO: update when this extension is implemented in crypto/tls
 // but we probably won't have to enable it in Config
-func (e *UtlsExtendedMasterSecretExtension) writeToUConn(uc *UConn) error {
+func (e *ExtendedMasterSecretExtension) writeToUConn(uc *UConn) error {
 	uc.HandshakeState.Hello.Ems = true
 	return nil
 }
 
-func (e *UtlsExtendedMasterSecretExtension) Len() int {
+func (e *ExtendedMasterSecretExtension) Len() int {
 	return 4
 }
 
-func (e *UtlsExtendedMasterSecretExtension) Read(b []byte) (int, error) {
+func (e *ExtendedMasterSecretExtension) Read(b []byte) (int, error) {
 	if len(b) < e.Len() {
 		return 0, io.ErrShortBuffer
 	}
 	// https://tools.ietf.org/html/rfc7627
-	b[0] = byte(utlsExtensionExtendedMasterSecret >> 8)
-	b[1] = byte(utlsExtensionExtendedMasterSecret)
+	b[0] = byte(extensionExtendedMasterSecret >> 8)
+	b[1] = byte(extensionExtendedMasterSecret)
 	// The length is 0
 	return e.Len(), io.EOF
 }
 
-func (e *UtlsExtendedMasterSecretExtension) UnmarshalJSON(_ []byte) error {
+func (e *ExtendedMasterSecretExtension) UnmarshalJSON(_ []byte) error {
 	return nil // no-op
 }
 
-func (e *UtlsExtendedMasterSecretExtension) Write(_ []byte) (int, error) {
+func (e *ExtendedMasterSecretExtension) Write(_ []byte) (int, error) {
 	// https://tools.ietf.org/html/rfc7627
 	return 0, nil
 }
 
-var extendedMasterSecretLabel = []byte("extended master secret")
+// var extendedMasterSecretLabel = []byte("extended master secret")
 
 // extendedMasterFromPreMasterSecret generates the master secret from the pre-master
 // secret and session hash. See https://tools.ietf.org/html/rfc7627#section-4
@@ -1104,6 +1064,23 @@ func BoringPaddingStyle(unpaddedLen int) (int, bool) {
 	return 0, false
 }
 
+// AlwaysPadToLen could be used for parsed ClientHello, since some fingerprints
+// might not use BoringSSL padding style and we want to pad to a the same length.
+func AlwaysPadToLen(padToLen int) func(int) (int, bool) {
+	return func(unpaddedLen int) (int, bool) {
+		if unpaddedLen < padToLen {
+			paddingLen := padToLen - unpaddedLen
+			if paddingLen >= 4+1 {
+				paddingLen -= 4
+			} else {
+				paddingLen = 1
+			}
+			return paddingLen, true
+		}
+		return 0, false
+	}
+}
+
 // UtlsCompressCertExtension implements compress_certificate (27) and is only implemented client-side
 // for server certificates. Alternate certificate message formats
 // (https://datatracker.ietf.org/doc/html/rfc7250) are not supported.
@@ -1179,7 +1156,7 @@ func (e *UtlsCompressCertExtension) UnmarshalJSON(b []byte) error {
 	}
 
 	for _, algorithm := range certificateCompressionAlgorithms.Algorithms {
-		if alg, ok := godicttls.DictCertificateCompressionAlgorithmNameIndexed[algorithm]; ok {
+		if alg, ok := dicttls.DictCertificateCompressionAlgorithmNameIndexed[algorithm]; ok {
 			e.Algorithms = append(e.Algorithms, CertCompressionAlgo(alg))
 		} else {
 			return fmt.Errorf("unknown certificate compression algorithm %s", algorithm)
@@ -1285,7 +1262,7 @@ func (e *KeyShareExtension) UnmarshalJSON(b []byte) error {
 			continue
 		}
 
-		if groupID, ok := godicttls.DictSupportedGroupsNameIndexed[clientShare.Group]; ok {
+		if groupID, ok := dicttls.DictSupportedGroupsNameIndexed[clientShare.Group]; ok {
 			ks := KeyShare{
 				Group: CurveID(groupID),
 				Data:  clientShare.KeyExchange,
@@ -1298,6 +1275,44 @@ func (e *KeyShareExtension) UnmarshalJSON(b []byte) error {
 	return nil
 }
 
+// QUICTransportParametersExtension implements quic_transport_parameters (57).
+//
+// Currently, it works as a fake extension and does not support parsing, since
+// the QUICConn provided by this package does not really understand these
+// parameters.
+type QUICTransportParametersExtension struct {
+	TransportParameters TransportParameters
+
+	marshalResult []byte // TransportParameters will be marshaled into this slice
+}
+
+func (e *QUICTransportParametersExtension) Len() int {
+	if e.marshalResult == nil {
+		e.marshalResult = e.TransportParameters.Marshal()
+	}
+	return 4 + len(e.marshalResult)
+}
+
+func (e *QUICTransportParametersExtension) Read(b []byte) (int, error) {
+	if len(b) < e.Len() {
+		return 0, io.ErrShortBuffer
+	}
+
+	b[0] = byte(extensionQUICTransportParameters >> 8)
+	b[1] = byte(extensionQUICTransportParameters)
+	// e.Len() is called before so that e.marshalResult is set
+	b[2] = byte((len(e.marshalResult)) >> 8)
+	b[3] = byte(len(e.marshalResult))
+	copy(b[4:], e.marshalResult)
+
+	return e.Len(), io.EOF
+}
+
+func (e *QUICTransportParametersExtension) writeToUConn(*UConn) error {
+	// no need to set *UConn.quic.transportParams, since it is unused
+	return nil
+}
+
 // PSKKeyExchangeModesExtension implements psk_key_exchange_modes (45).
 type PSKKeyExchangeModesExtension struct {
 	Modes []uint8
@@ -1361,7 +1376,7 @@ func (e *PSKKeyExchangeModesExtension) UnmarshalJSON(b []byte) error {
 	}
 
 	for _, mode := range pskKeyExchangeModes.Modes {
-		if modeID, ok := godicttls.DictPSKKeyExchangeModeNameIndexed[mode]; ok {
+		if modeID, ok := dicttls.DictPSKKeyExchangeModeNameIndexed[mode]; ok {
 			e.Modes = append(e.Modes, modeID)
 		} else {
 			return fmt.Errorf("unknown PSK Key Exchange Mode %s", mode)
@@ -1548,11 +1563,11 @@ type RenegotiationInfoExtension struct {
 	// If this is the initial handshake for a connection, then the
 	// "renegotiated_connection" field is of zero length in both the
 	// ClientHello and the ServerHello.
-	// RenegotiatedConnection []byte
+	RenegotiatedConnection []byte
 }
 
 func (e *RenegotiationInfoExtension) Len() int {
-	return 5 // + len(e.RenegotiatedConnection)
+	return 5 + len(e.RenegotiatedConnection)
 }
 
 func (e *RenegotiationInfoExtension) Read(b []byte) (int, error) {
@@ -1560,15 +1575,15 @@ func (e *RenegotiationInfoExtension) Read(b []byte) (int, error) {
 		return 0, io.ErrShortBuffer
 	}
 
-	// dataLen := len(e.RenegotiatedConnection)
-	extBodyLen := 1 // + len(dataLen)
+	dataLen := len(e.RenegotiatedConnection)
+	extBodyLen := 1 + dataLen
 
 	b[0] = byte(extensionRenegotiationInfo >> 8)
 	b[1] = byte(extensionRenegotiationInfo & 0xff)
 	b[2] = byte(extBodyLen >> 8)
 	b[3] = byte(extBodyLen)
-	// b[4] = byte(dataLen)
-	// copy(b[5:], e.RenegotiatedConnection)
+	b[4] = byte(dataLen)
+	copy(b[5:], e.RenegotiatedConnection)
 
 	return e.Len(), io.EOF
 }
@@ -1578,7 +1593,7 @@ func (e *RenegotiationInfoExtension) UnmarshalJSON(_ []byte) error {
 	return nil
 }
 
-func (e *RenegotiationInfoExtension) Write(_ []byte) (int, error) {
+func (e *RenegotiationInfoExtension) Write(b []byte) (int, error) {
 	e.Renegotiation = RenegotiateOnceAsClient // none empty or other modes are unsupported
 	// extData := cryptobyte.String(b)
 	// var renegotiatedConnection cryptobyte.String
@@ -1587,7 +1602,10 @@ func (e *RenegotiationInfoExtension) Write(_ []byte) (int, error) {
 	// }
 	// e.RenegotiatedConnection = make([]byte, len(renegotiatedConnection))
 	// copy(e.RenegotiatedConnection, renegotiatedConnection)
-	return 0, nil
+
+	// we don't really want to parse it at all.
+
+	return len(b), nil
 }
 
 func (e *RenegotiationInfoExtension) writeToUConn(uc *UConn) error {
@@ -1597,6 +1615,10 @@ func (e *RenegotiationInfoExtension) writeToUConn(uc *UConn) error {
 		fallthrough
 	case RenegotiateFreelyAsClient:
 		uc.HandshakeState.Hello.SecureRenegotiationSupported = true
+		// TODO: don't do backward propagation here
+		if uc.handshakes > 0 {
+			e.RenegotiatedConnection = uc.clientFinished[:]
+		}
 	case RenegotiateNever:
 	default:
 	}
@@ -1839,7 +1861,7 @@ func (e *FakeDelegatedCredentialsExtension) UnmarshalJSON(data []byte) error {
 			continue
 		}
 
-		if scheme, ok := godicttls.DictSignatureSchemeNameIndexed[sigScheme]; ok {
+		if scheme, ok := dicttls.DictSignatureSchemeNameIndexed[sigScheme]; ok {
 			e.SupportedSignatureAlgorithms = append(e.SupportedSignatureAlgorithms, SignatureScheme(scheme))
 		} else {
 			return fmt.Errorf("unknown delegated credentials signature scheme: %s", sigScheme)
@@ -1847,175 +1869,3 @@ func (e *FakeDelegatedCredentialsExtension) UnmarshalJSON(data []byte) error {
 	}
 	return nil
 }
-
-// FakePreSharedKeyExtension is an extension used to set the PSK extension in the
-// ClientHello.
-//
-// Unfortunately, even when the PSK extension is set, there will be no PSK-based
-// resumption since crypto/tls does not implement PSK.
-type FakePreSharedKeyExtension struct {
-	PskIdentities []PskIdentity `json:"identities"`
-	PskBinders    [][]byte      `json:"binders"`
-}
-
-func (e *FakePreSharedKeyExtension) writeToUConn(uc *UConn) error {
-	if uc.config.ClientSessionCache == nil {
-		return nil // don't write the extension if there is no session cache
-	}
-	if session, ok := uc.config.ClientSessionCache.Get(clientSessionCacheKey(uc.conn.RemoteAddr(), uc.config)); !ok || session == nil {
-		return nil // don't write the extension if there is no session cache available for this session
-	}
-	uc.HandshakeState.Hello.PskIdentities = e.PskIdentities
-	uc.HandshakeState.Hello.PskBinders = e.PskBinders
-	return nil
-}
-
-func (e *FakePreSharedKeyExtension) Len() int {
-	length := 4 // extension type + extension length
-	length += 2 // identities length
-	for _, identity := range e.PskIdentities {
-		length += 2 + len(identity.Label) + 4 // identity length + identity + obfuscated ticket age
-	}
-	length += 2 // binders length
-	for _, binder := range e.PskBinders {
-		length += len(binder)
-	}
-	return length
-}
-
-func (e *FakePreSharedKeyExtension) Read(b []byte) (int, error) {
-	if len(b) < e.Len() {
-		return 0, io.ErrShortBuffer
-	}
-
-	b[0] = byte(extensionPreSharedKey >> 8)
-	b[1] = byte(extensionPreSharedKey)
-	b[2] = byte((e.Len() - 4) >> 8)
-	b[3] = byte(e.Len() - 4)
-
-	// identities length
-	identitiesLength := 0
-	for _, identity := range e.PskIdentities {
-		identitiesLength += 2 + len(identity.Label) + 4 // identity length + identity + obfuscated ticket age
-	}
-	b[4] = byte(identitiesLength >> 8)
-	b[5] = byte(identitiesLength)
-
-	// identities
-	offset := 6
-	for _, identity := range e.PskIdentities {
-		b[offset] = byte(len(identity.Label) >> 8)
-		b[offset+1] = byte(len(identity.Label))
-		offset += 2
-		copy(b[offset:], identity.Label)
-		offset += len(identity.Label)
-		b[offset] = byte(identity.ObfuscatedTicketAge >> 24)
-		b[offset+1] = byte(identity.ObfuscatedTicketAge >> 16)
-		b[offset+2] = byte(identity.ObfuscatedTicketAge >> 8)
-		b[offset+3] = byte(identity.ObfuscatedTicketAge)
-		offset += 4
-	}
-
-	// binders length
-	bindersLength := 0
-	for _, binder := range e.PskBinders {
-		bindersLength += len(binder)
-	}
-	b[offset] = byte(bindersLength >> 8)
-	b[offset+1] = byte(bindersLength)
-	offset += 2
-
-	// binders
-	for _, binder := range e.PskBinders {
-		copy(b[offset:], binder)
-		offset += len(binder)
-	}
-
-	return e.Len(), io.EOF
-}
-
-func (e *FakePreSharedKeyExtension) Write(b []byte) (n int, err error) {
-	fullLen := len(b)
-	s := cryptobyte.String(b)
-
-	var identitiesLength uint16
-	if !s.ReadUint16(&identitiesLength) {
-		return 0, errors.New("tls: invalid PSK extension")
-	}
-
-	// identities
-	for identitiesLength > 0 {
-		var identityLength uint16
-		if !s.ReadUint16(&identityLength) {
-			return 0, errors.New("tls: invalid PSK extension")
-		}
-		identitiesLength -= 2
-
-		if identityLength > identitiesLength {
-			return 0, errors.New("tls: invalid PSK extension")
-		}
-
-		var identity []byte
-		if !s.ReadBytes(&identity, int(identityLength)) {
-			return 0, errors.New("tls: invalid PSK extension")
-		}
-
-		identitiesLength -= identityLength // identity
-
-		var obfuscatedTicketAge uint32
-		if !s.ReadUint32(&obfuscatedTicketAge) {
-			return 0, errors.New("tls: invalid PSK extension")
-		}
-
-		e.PskIdentities = append(e.PskIdentities, PskIdentity{
-			Label:               identity,
-			ObfuscatedTicketAge: obfuscatedTicketAge,
-		})
-
-		identitiesLength -= 4 // obfuscated ticket age
-	}
-
-	var bindersLength uint16
-	if !s.ReadUint16(&bindersLength) {
-		return 0, errors.New("tls: invalid PSK extension")
-	}
-
-	// binders
-	for bindersLength > 0 {
-		var binderLength uint8
-		if !s.ReadUint8(&binderLength) {
-			return 0, errors.New("tls: invalid PSK extension")
-		}
-		bindersLength -= 1
-
-		if uint16(binderLength) > bindersLength {
-			return 0, errors.New("tls: invalid PSK extension")
-		}
-
-		var binder []byte
-		if !s.ReadBytes(&binder, int(binderLength)) {
-			return 0, errors.New("tls: invalid PSK extension")
-		}
-
-		e.PskBinders = append(e.PskBinders, binder)
-
-		bindersLength -= uint16(binderLength)
-	}
-
-	return fullLen, nil
-}
-
-func (e *FakePreSharedKeyExtension) UnmarshalJSON(data []byte) error {
-	var pskAccepter struct {
-		PskIdentities []PskIdentity `json:"identities"`
-		PskBinders    [][]byte      `json:"binders"`
-	}
-
-	if err := json.Unmarshal(data, &pskAccepter); err != nil {
-		return err
-	}
-
-	e.PskIdentities = pskAccepter.PskIdentities
-	e.PskBinders = pskAccepter.PskBinders
-	return nil
-}
diff --git a/vendor/github.com/rs/zerolog/README.md b/vendor/github.com/rs/zerolog/README.md
index afa61569..1306a6c1 100644
--- a/vendor/github.com/rs/zerolog/README.md
+++ b/vendor/github.com/rs/zerolog/README.md
@@ -60,7 +60,7 @@ func main() {
 // Output: {"time":1516134303,"level":"debug","message":"hello world"}
 ```
 > Note: By default log writes to `os.Stderr`
-> Note: The default log level for `log.Print` is *debug*
+> Note: The default log level for `log.Print` is *trace*
 
 ### Contextual Logging
 
@@ -412,15 +412,7 @@ Equivalent of `Lshortfile`:
 
 ```go
 zerolog.CallerMarshalFunc = func(pc uintptr, file string, line int) string {
-    short := file
-    for i := len(file) - 1; i > 0; i-- {
-        if file[i] == '/' {
-            short = file[i+1:]
-            break
-        }
-    }
-    file = short
-    return file + ":" + strconv.Itoa(line)
+    return filepath.Base(file) + ":" + strconv.Itoa(line)
 }
 log.Logger = log.With().Caller().Logger()
 log.Info().Msg("hello world")
@@ -646,10 +638,14 @@ Some settings can be changed and will be applied to all loggers:
 * `zerolog.LevelFieldName`: Can be set to customize level field name.
 * `zerolog.MessageFieldName`: Can be set to customize message field name.
 * `zerolog.ErrorFieldName`: Can be set to customize `Err` field name.
-* `zerolog.TimeFieldFormat`: Can be set to customize `Time` field value formatting. If set with `zerolog.TimeFormatUnix`, `zerolog.TimeFormatUnixMs` or `zerolog.TimeFormatUnixMicro`, times are formated as UNIX timestamp.
+* `zerolog.TimeFieldFormat`: Can be set to customize `Time` field value formatting. If set with `zerolog.TimeFormatUnix`, `zerolog.TimeFormatUnixMs` or `zerolog.TimeFormatUnixMicro`, times are formatted as UNIX timestamp.
 * `zerolog.DurationFieldUnit`: Can be set to customize the unit for time.Duration type fields added by `Dur` (default: `time.Millisecond`).
 * `zerolog.DurationFieldInteger`: If set to `true`, `Dur` fields are formatted as integers instead of floats (default: `false`). 
 * `zerolog.ErrorHandler`: Called whenever zerolog fails to write an event on its output. If not set, an error is printed on the stderr. This handler must be thread safe and non-blocking.
+* `zerolog.FloatingPointPrecision`: If set to a value other than -1, controls the number
+of digits when formatting float numbers in JSON. See
+[strconv.FormatFloat](https://pkg.go.dev/strconv#FormatFloat)
+for more details.
 
 ## Field Types
 
diff --git a/vendor/github.com/rs/zerolog/array.go b/vendor/github.com/rs/zerolog/array.go
index 99612ee9..ba35b283 100644
--- a/vendor/github.com/rs/zerolog/array.go
+++ b/vendor/github.com/rs/zerolog/array.go
@@ -183,13 +183,13 @@ func (a *Array) Uint64(i uint64) *Array {
 
 // Float32 appends f as a float32 to the array.
 func (a *Array) Float32(f float32) *Array {
-	a.buf = enc.AppendFloat32(enc.AppendArrayDelim(a.buf), f)
+	a.buf = enc.AppendFloat32(enc.AppendArrayDelim(a.buf), f, FloatingPointPrecision)
 	return a
 }
 
 // Float64 appends f as a float64 to the array.
 func (a *Array) Float64(f float64) *Array {
-	a.buf = enc.AppendFloat64(enc.AppendArrayDelim(a.buf), f)
+	a.buf = enc.AppendFloat64(enc.AppendArrayDelim(a.buf), f, FloatingPointPrecision)
 	return a
 }
 
@@ -201,7 +201,7 @@ func (a *Array) Time(t time.Time) *Array {
 
 // Dur appends d to the array.
 func (a *Array) Dur(d time.Duration) *Array {
-	a.buf = enc.AppendDuration(enc.AppendArrayDelim(a.buf), d, DurationFieldUnit, DurationFieldInteger)
+	a.buf = enc.AppendDuration(enc.AppendArrayDelim(a.buf), d, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
 	return a
 }
 
diff --git a/vendor/github.com/rs/zerolog/console.go b/vendor/github.com/rs/zerolog/console.go
index cc6d623e..7e65e86f 100644
--- a/vendor/github.com/rs/zerolog/console.go
+++ b/vendor/github.com/rs/zerolog/console.go
@@ -28,6 +28,8 @@ const (
 
 	colorBold     = 1
 	colorDarkGray = 90
+
+	unknownLevel = "???"
 )
 
 var (
@@ -57,12 +59,21 @@ type ConsoleWriter struct {
 	// TimeFormat specifies the format for timestamp in output.
 	TimeFormat string
 
+	// TimeLocation tells ConsoleWriter’s default FormatTimestamp
+	// how to localize the time.
+	TimeLocation *time.Location
+
 	// PartsOrder defines the order of parts in output.
 	PartsOrder []string
 
 	// PartsExclude defines parts to not display in output.
 	PartsExclude []string
 
+	// FieldsOrder defines the order of contextual fields in output.
+	FieldsOrder []string
+
+	fieldIsOrdered map[string]int
+
 	// FieldsExclude defines contextual fields to not display in output.
 	FieldsExclude []string
 
@@ -83,9 +94,9 @@ type ConsoleWriter struct {
 // NewConsoleWriter creates and initializes a new ConsoleWriter.
 func NewConsoleWriter(options ...func(w *ConsoleWriter)) ConsoleWriter {
 	w := ConsoleWriter{
-		Out:        os.Stdout,
-		TimeFormat: consoleDefaultTimeFormat,
-		PartsOrder: consoleDefaultPartsOrder(),
+		Out:          os.Stdout,
+		TimeFormat:   consoleDefaultTimeFormat,
+		PartsOrder:   consoleDefaultPartsOrder(),
 	}
 
 	for _, opt := range options {
@@ -185,7 +196,12 @@ func (w ConsoleWriter) writeFields(evt map[string]interface{}, buf *bytes.Buffer
 		}
 		fields = append(fields, field)
 	}
-	sort.Strings(fields)
+
+	if len(w.FieldsOrder) > 0 {
+		w.orderFields(fields)
+	} else {
+		sort.Strings(fields)
+	}
 
 	// Write space only if something has already been written to the buffer, and if there are fields.
 	if buf.Len() > 0 && len(fields) > 0 {
@@ -284,7 +300,7 @@ func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{},
 		}
 	case TimestampFieldName:
 		if w.FormatTimestamp == nil {
-			f = consoleDefaultFormatTimestamp(w.TimeFormat, w.NoColor)
+			f = consoleDefaultFormatTimestamp(w.TimeFormat, w.TimeLocation, w.NoColor)
 		} else {
 			f = w.FormatTimestamp
 		}
@@ -318,6 +334,32 @@ func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{},
 	}
 }
 
+// orderFields takes an array of field names and an array representing field order
+// and returns an array with any ordered fields at the beginning, in order,
+// and the remaining fields after in their original order.
+func (w ConsoleWriter) orderFields(fields []string) {
+	if w.fieldIsOrdered == nil {
+		w.fieldIsOrdered = make(map[string]int)
+		for i, fieldName := range w.FieldsOrder {
+			w.fieldIsOrdered[fieldName] = i
+		}
+	}
+	sort.Slice(fields, func(i, j int) bool {
+		ii, iOrdered := w.fieldIsOrdered[fields[i]]
+		jj, jOrdered := w.fieldIsOrdered[fields[j]]
+		if iOrdered && jOrdered {
+			return ii < jj
+		}
+		if iOrdered {
+			return true
+		}
+		if jOrdered {
+			return false
+		}
+		return fields[i] < fields[j]
+	})
+}
+
 // needsQuote returns true when the string s should be quoted in output.
 func needsQuote(s string) bool {
 	for i := range s {
@@ -352,19 +394,23 @@ func consoleDefaultPartsOrder() []string {
 	}
 }
 
-func consoleDefaultFormatTimestamp(timeFormat string, noColor bool) Formatter {
+func consoleDefaultFormatTimestamp(timeFormat string, location *time.Location, noColor bool) Formatter {
 	if timeFormat == "" {
 		timeFormat = consoleDefaultTimeFormat
 	}
+	if location == nil {
+		location = time.Local
+	}
+
 	return func(i interface{}) string {
 		t := "<nil>"
 		switch tt := i.(type) {
 		case string:
-			ts, err := time.ParseInLocation(TimeFieldFormat, tt, time.Local)
+			ts, err := time.ParseInLocation(TimeFieldFormat, tt, location)
 			if err != nil {
 				t = tt
 			} else {
-				t = ts.Local().Format(timeFormat)
+				t = ts.In(location).Format(timeFormat)
 			}
 		case json.Number:
 			i, err := tt.Int64()
@@ -385,32 +431,37 @@ func consoleDefaultFormatTimestamp(timeFormat string, noColor bool) Formatter {
 				}
 
 				ts := time.Unix(sec, nsec)
-				t = ts.Format(timeFormat)
+				t = ts.In(location).Format(timeFormat)
 			}
 		}
 		return colorize(t, colorDarkGray, noColor)
 	}
 }
 
+func stripLevel(ll string) string {
+	if len(ll) == 0 {
+		return unknownLevel
+	}
+	if len(ll) > 3 {
+		ll = ll[:3]
+	}
+	return strings.ToUpper(ll)
+}
+
 func consoleDefaultFormatLevel(noColor bool) Formatter {
 	return func(i interface{}) string {
-		var l string
 		if ll, ok := i.(string); ok {
 			level, _ := ParseLevel(ll)
 			fl, ok := FormattedLevels[level]
 			if ok {
-				l = colorize(fl, LevelColors[level], noColor)
-			} else {
-				l = strings.ToUpper(ll)[0:3]
-			}
-		} else {
-			if i == nil {
-				l = "???"
-			} else {
-				l = strings.ToUpper(fmt.Sprintf("%s", i))[0:3]
+				return colorize(fl, LevelColors[level], noColor)
 			}
+			return stripLevel(ll)
+		}
+		if i == nil {
+			return unknownLevel
 		}
-		return l
+		return stripLevel(fmt.Sprintf("%s", i))
 	}
 }
 
diff --git a/vendor/github.com/rs/zerolog/context.go b/vendor/github.com/rs/zerolog/context.go
index df352eb6..ff9a3ae2 100644
--- a/vendor/github.com/rs/zerolog/context.go
+++ b/vendor/github.com/rs/zerolog/context.go
@@ -325,25 +325,25 @@ func (c Context) Uints64(key string, i []uint64) Context {
 
 // Float32 adds the field key with f as a float32 to the logger context.
 func (c Context) Float32(key string, f float32) Context {
-	c.l.context = enc.AppendFloat32(enc.AppendKey(c.l.context, key), f)
+	c.l.context = enc.AppendFloat32(enc.AppendKey(c.l.context, key), f, FloatingPointPrecision)
 	return c
 }
 
 // Floats32 adds the field key with f as a []float32 to the logger context.
 func (c Context) Floats32(key string, f []float32) Context {
-	c.l.context = enc.AppendFloats32(enc.AppendKey(c.l.context, key), f)
+	c.l.context = enc.AppendFloats32(enc.AppendKey(c.l.context, key), f, FloatingPointPrecision)
 	return c
 }
 
 // Float64 adds the field key with f as a float64 to the logger context.
 func (c Context) Float64(key string, f float64) Context {
-	c.l.context = enc.AppendFloat64(enc.AppendKey(c.l.context, key), f)
+	c.l.context = enc.AppendFloat64(enc.AppendKey(c.l.context, key), f, FloatingPointPrecision)
 	return c
 }
 
 // Floats64 adds the field key with f as a []float64 to the logger context.
 func (c Context) Floats64(key string, f []float64) Context {
-	c.l.context = enc.AppendFloats64(enc.AppendKey(c.l.context, key), f)
+	c.l.context = enc.AppendFloats64(enc.AppendKey(c.l.context, key), f, FloatingPointPrecision)
 	return c
 }
 
@@ -365,13 +365,13 @@ func (c Context) Timestamp() Context {
 	return c
 }
 
-// Time adds the field key with t formated as string using zerolog.TimeFieldFormat.
+// Time adds the field key with t formatted as string using zerolog.TimeFieldFormat.
 func (c Context) Time(key string, t time.Time) Context {
 	c.l.context = enc.AppendTime(enc.AppendKey(c.l.context, key), t, TimeFieldFormat)
 	return c
 }
 
-// Times adds the field key with t formated as string using zerolog.TimeFieldFormat.
+// Times adds the field key with t formatted as string using zerolog.TimeFieldFormat.
 func (c Context) Times(key string, t []time.Time) Context {
 	c.l.context = enc.AppendTimes(enc.AppendKey(c.l.context, key), t, TimeFieldFormat)
 	return c
@@ -379,13 +379,13 @@ func (c Context) Times(key string, t []time.Time) Context {
 
 // Dur adds the fields key with d divided by unit and stored as a float.
 func (c Context) Dur(key string, d time.Duration) Context {
-	c.l.context = enc.AppendDuration(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger)
+	c.l.context = enc.AppendDuration(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
 	return c
 }
 
 // Durs adds the fields key with d divided by unit and stored as a float.
 func (c Context) Durs(key string, d []time.Duration) Context {
-	c.l.context = enc.AppendDurations(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger)
+	c.l.context = enc.AppendDurations(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
 	return c
 }
 
@@ -409,6 +409,12 @@ func (c Context) Any(key string, i interface{}) Context {
 	return c.Interface(key, i)
 }
 
+// Reset removes all the context fields.
+func (c Context) Reset() Context {
+	c.l.context = enc.AppendBeginMarker(make([]byte, 0, 500))
+	return c
+}
+
 type callerHook struct {
 	callerSkipFrameCount int
 }
diff --git a/vendor/github.com/rs/zerolog/encoder.go b/vendor/github.com/rs/zerolog/encoder.go
index 09b24e80..4dbaf380 100644
--- a/vendor/github.com/rs/zerolog/encoder.go
+++ b/vendor/github.com/rs/zerolog/encoder.go
@@ -13,13 +13,13 @@ type encoder interface {
 	AppendBool(dst []byte, val bool) []byte
 	AppendBools(dst []byte, vals []bool) []byte
 	AppendBytes(dst, s []byte) []byte
-	AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte
-	AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte
+	AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool, precision int) []byte
+	AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool, precision int) []byte
 	AppendEndMarker(dst []byte) []byte
-	AppendFloat32(dst []byte, val float32) []byte
-	AppendFloat64(dst []byte, val float64) []byte
-	AppendFloats32(dst []byte, vals []float32) []byte
-	AppendFloats64(dst []byte, vals []float64) []byte
+	AppendFloat32(dst []byte, val float32, precision int) []byte
+	AppendFloat64(dst []byte, val float64, precision int) []byte
+	AppendFloats32(dst []byte, vals []float32, precision int) []byte
+	AppendFloats64(dst []byte, vals []float64, precision int) []byte
 	AppendHex(dst, s []byte) []byte
 	AppendIPAddr(dst []byte, ip net.IP) []byte
 	AppendIPPrefix(dst []byte, pfx net.IPNet) []byte
diff --git a/vendor/github.com/rs/zerolog/event.go b/vendor/github.com/rs/zerolog/event.go
index 5c949f8a..56de6061 100644
--- a/vendor/github.com/rs/zerolog/event.go
+++ b/vendor/github.com/rs/zerolog/event.go
@@ -644,7 +644,7 @@ func (e *Event) Float32(key string, f float32) *Event {
 	if e == nil {
 		return e
 	}
-	e.buf = enc.AppendFloat32(enc.AppendKey(e.buf, key), f)
+	e.buf = enc.AppendFloat32(enc.AppendKey(e.buf, key), f, FloatingPointPrecision)
 	return e
 }
 
@@ -653,7 +653,7 @@ func (e *Event) Floats32(key string, f []float32) *Event {
 	if e == nil {
 		return e
 	}
-	e.buf = enc.AppendFloats32(enc.AppendKey(e.buf, key), f)
+	e.buf = enc.AppendFloats32(enc.AppendKey(e.buf, key), f, FloatingPointPrecision)
 	return e
 }
 
@@ -662,7 +662,7 @@ func (e *Event) Float64(key string, f float64) *Event {
 	if e == nil {
 		return e
 	}
-	e.buf = enc.AppendFloat64(enc.AppendKey(e.buf, key), f)
+	e.buf = enc.AppendFloat64(enc.AppendKey(e.buf, key), f, FloatingPointPrecision)
 	return e
 }
 
@@ -671,7 +671,7 @@ func (e *Event) Floats64(key string, f []float64) *Event {
 	if e == nil {
 		return e
 	}
-	e.buf = enc.AppendFloats64(enc.AppendKey(e.buf, key), f)
+	e.buf = enc.AppendFloats64(enc.AppendKey(e.buf, key), f, FloatingPointPrecision)
 	return e
 }
 
@@ -713,7 +713,7 @@ func (e *Event) Dur(key string, d time.Duration) *Event {
 	if e == nil {
 		return e
 	}
-	e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)
+	e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
 	return e
 }
 
@@ -724,7 +724,7 @@ func (e *Event) Durs(key string, d []time.Duration) *Event {
 	if e == nil {
 		return e
 	}
-	e.buf = enc.AppendDurations(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)
+	e.buf = enc.AppendDurations(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
 	return e
 }
 
@@ -739,7 +739,7 @@ func (e *Event) TimeDiff(key string, t time.Time, start time.Time) *Event {
 	if t.After(start) {
 		d = t.Sub(start)
 	}
-	e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)
+	e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
 	return e
 }
 
diff --git a/vendor/github.com/rs/zerolog/fields.go b/vendor/github.com/rs/zerolog/fields.go
index 23606ddd..99f52718 100644
--- a/vendor/github.com/rs/zerolog/fields.go
+++ b/vendor/github.com/rs/zerolog/fields.go
@@ -139,13 +139,13 @@ func appendFieldList(dst []byte, kvList []interface{}, stack bool) []byte {
 		case uint64:
 			dst = enc.AppendUint64(dst, val)
 		case float32:
-			dst = enc.AppendFloat32(dst, val)
+			dst = enc.AppendFloat32(dst, val, FloatingPointPrecision)
 		case float64:
-			dst = enc.AppendFloat64(dst, val)
+			dst = enc.AppendFloat64(dst, val, FloatingPointPrecision)
 		case time.Time:
 			dst = enc.AppendTime(dst, val, TimeFieldFormat)
 		case time.Duration:
-			dst = enc.AppendDuration(dst, val, DurationFieldUnit, DurationFieldInteger)
+			dst = enc.AppendDuration(dst, val, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
 		case *string:
 			if val != nil {
 				dst = enc.AppendString(dst, *val)
@@ -220,13 +220,13 @@ func appendFieldList(dst []byte, kvList []interface{}, stack bool) []byte {
 			}
 		case *float32:
 			if val != nil {
-				dst = enc.AppendFloat32(dst, *val)
+				dst = enc.AppendFloat32(dst, *val, FloatingPointPrecision)
 			} else {
 				dst = enc.AppendNil(dst)
 			}
 		case *float64:
 			if val != nil {
-				dst = enc.AppendFloat64(dst, *val)
+				dst = enc.AppendFloat64(dst, *val, FloatingPointPrecision)
 			} else {
 				dst = enc.AppendNil(dst)
 			}
@@ -238,7 +238,7 @@ func appendFieldList(dst []byte, kvList []interface{}, stack bool) []byte {
 			}
 		case *time.Duration:
 			if val != nil {
-				dst = enc.AppendDuration(dst, *val, DurationFieldUnit, DurationFieldInteger)
+				dst = enc.AppendDuration(dst, *val, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
 			} else {
 				dst = enc.AppendNil(dst)
 			}
@@ -267,13 +267,13 @@ func appendFieldList(dst []byte, kvList []interface{}, stack bool) []byte {
 		case []uint64:
 			dst = enc.AppendUints64(dst, val)
 		case []float32:
-			dst = enc.AppendFloats32(dst, val)
+			dst = enc.AppendFloats32(dst, val, FloatingPointPrecision)
 		case []float64:
-			dst = enc.AppendFloats64(dst, val)
+			dst = enc.AppendFloats64(dst, val, FloatingPointPrecision)
 		case []time.Time:
 			dst = enc.AppendTimes(dst, val, TimeFieldFormat)
 		case []time.Duration:
-			dst = enc.AppendDurations(dst, val, DurationFieldUnit, DurationFieldInteger)
+			dst = enc.AppendDurations(dst, val, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
 		case nil:
 			dst = enc.AppendNil(dst)
 		case net.IP:
diff --git a/vendor/github.com/rs/zerolog/globals.go b/vendor/github.com/rs/zerolog/globals.go
index b38a7fce..9a9be713 100644
--- a/vendor/github.com/rs/zerolog/globals.go
+++ b/vendor/github.com/rs/zerolog/globals.go
@@ -1,6 +1,7 @@
 package zerolog
 
 import (
+	"bytes"
 	"encoding/json"
 	"strconv"
 	"sync/atomic"
@@ -81,8 +82,22 @@ var (
 	}
 
 	// InterfaceMarshalFunc allows customization of interface marshaling.
-	// Default: "encoding/json.Marshal"
-	InterfaceMarshalFunc = json.Marshal
+	// Default: "encoding/json.Marshal" with disabled HTML escaping
+	InterfaceMarshalFunc = func(v interface{}) ([]byte, error) {
+		var buf bytes.Buffer
+		encoder := json.NewEncoder(&buf)
+		encoder.SetEscapeHTML(false)
+		err := encoder.Encode(v)
+		if err != nil {
+			return nil, err
+		}
+		b := buf.Bytes()
+		if len(b) > 0 {
+			// Remove trailing \n which is added by Encode.
+			return b[:len(b)-1], nil
+		}
+		return b, nil
+	}
 
 	// TimeFieldFormat defines the time format of the Time field type. If set to
 	// TimeFormatUnix, TimeFormatUnixMs, TimeFormatUnixMicro or TimeFormatUnixNano, the time is formatted as a UNIX
@@ -136,6 +151,11 @@ var (
 	// TriggerLevelWriterBufferReuseLimit is a limit in bytes that a buffer is dropped
 	// from the TriggerLevelWriter buffer pool if the buffer grows above the limit.
 	TriggerLevelWriterBufferReuseLimit = 64 * 1024
+
+	// FloatingPointPrecision, if set to a value other than -1, controls the number
+	// of digits when formatting float numbers in JSON. See strconv.FormatFloat for
+	// more details.
+	FloatingPointPrecision = -1
 )
 
 var (
diff --git a/vendor/github.com/rs/zerolog/internal/cbor/decode_stream.go b/vendor/github.com/rs/zerolog/internal/cbor/decode_stream.go
index 616bed65..5633e666 100644
--- a/vendor/github.com/rs/zerolog/internal/cbor/decode_stream.go
+++ b/vendor/github.com/rs/zerolog/internal/cbor/decode_stream.go
@@ -95,7 +95,7 @@ func decodeFloat(src *bufio.Reader) (float64, int) {
 
 	switch minor {
 	case additionalTypeFloat16:
-		panic(fmt.Errorf("float16 is not suppported in decodeFloat"))
+		panic(fmt.Errorf("float16 is not supported in decodeFloat"))
 
 	case additionalTypeFloat32:
 		pb := readNBytes(src, 4)
diff --git a/vendor/github.com/rs/zerolog/internal/cbor/time.go b/vendor/github.com/rs/zerolog/internal/cbor/time.go
index d81fb125..7c0eccee 100644
--- a/vendor/github.com/rs/zerolog/internal/cbor/time.go
+++ b/vendor/github.com/rs/zerolog/internal/cbor/time.go
@@ -29,7 +29,7 @@ func (e Encoder) appendFloatTimestamp(dst []byte, t time.Time) []byte {
 	nanos := t.Nanosecond()
 	var val float64
 	val = float64(secs)*1.0 + float64(nanos)*1e-9
-	return e.AppendFloat64(dst, val)
+	return e.AppendFloat64(dst, val, -1)
 }
 
 // AppendTime encodes and adds a timestamp to the dst byte array.
@@ -64,17 +64,17 @@ func (e Encoder) AppendTimes(dst []byte, vals []time.Time, unused string) []byte
 // AppendDuration encodes and adds a duration to the dst byte array.
 // useInt field indicates whether to store the duration as seconds (integer) or
 // as seconds+nanoseconds (float).
-func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte {
+func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool, unused int) []byte {
 	if useInt {
 		return e.AppendInt64(dst, int64(d/unit))
 	}
-	return e.AppendFloat64(dst, float64(d)/float64(unit))
+	return e.AppendFloat64(dst, float64(d)/float64(unit), unused)
 }
 
 // AppendDurations encodes and adds an array of durations to the dst byte array.
 // useInt field indicates whether to store the duration as seconds (integer) or
 // as seconds+nanoseconds (float).
-func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte {
+func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool, unused int) []byte {
 	major := majorTypeArray
 	l := len(vals)
 	if l == 0 {
@@ -87,7 +87,7 @@ func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Dur
 		dst = appendCborTypePrefix(dst, major, uint64(l))
 	}
 	for _, d := range vals {
-		dst = e.AppendDuration(dst, d, unit, useInt)
+		dst = e.AppendDuration(dst, d, unit, useInt, unused)
 	}
 	return dst
 }
diff --git a/vendor/github.com/rs/zerolog/internal/cbor/types.go b/vendor/github.com/rs/zerolog/internal/cbor/types.go
index 6f538328..454d68bd 100644
--- a/vendor/github.com/rs/zerolog/internal/cbor/types.go
+++ b/vendor/github.com/rs/zerolog/internal/cbor/types.go
@@ -352,7 +352,7 @@ func (e Encoder) AppendUints64(dst []byte, vals []uint64) []byte {
 }
 
 // AppendFloat32 encodes and inserts a single precision float value into the dst byte array.
-func (Encoder) AppendFloat32(dst []byte, val float32) []byte {
+func (Encoder) AppendFloat32(dst []byte, val float32, unused int) []byte {
 	switch {
 	case math.IsNaN(float64(val)):
 		return append(dst, "\xfa\x7f\xc0\x00\x00"...)
@@ -372,7 +372,7 @@ func (Encoder) AppendFloat32(dst []byte, val float32) []byte {
 }
 
 // AppendFloats32 encodes and inserts an array of single precision float value into the dst byte array.
-func (e Encoder) AppendFloats32(dst []byte, vals []float32) []byte {
+func (e Encoder) AppendFloats32(dst []byte, vals []float32, unused int) []byte {
 	major := majorTypeArray
 	l := len(vals)
 	if l == 0 {
@@ -385,13 +385,13 @@ func (e Encoder) AppendFloats32(dst []byte, vals []float32) []byte {
 		dst = appendCborTypePrefix(dst, major, uint64(l))
 	}
 	for _, v := range vals {
-		dst = e.AppendFloat32(dst, v)
+		dst = e.AppendFloat32(dst, v, unused)
 	}
 	return dst
 }
 
 // AppendFloat64 encodes and inserts a double precision float value into the dst byte array.
-func (Encoder) AppendFloat64(dst []byte, val float64) []byte {
+func (Encoder) AppendFloat64(dst []byte, val float64, unused int) []byte {
 	switch {
 	case math.IsNaN(val):
 		return append(dst, "\xfb\x7f\xf8\x00\x00\x00\x00\x00\x00"...)
@@ -412,7 +412,7 @@ func (Encoder) AppendFloat64(dst []byte, val float64) []byte {
 }
 
 // AppendFloats64 encodes and inserts an array of double precision float values into the dst byte array.
-func (e Encoder) AppendFloats64(dst []byte, vals []float64) []byte {
+func (e Encoder) AppendFloats64(dst []byte, vals []float64, unused int) []byte {
 	major := majorTypeArray
 	l := len(vals)
 	if l == 0 {
@@ -425,7 +425,7 @@ func (e Encoder) AppendFloats64(dst []byte, vals []float64) []byte {
 		dst = appendCborTypePrefix(dst, major, uint64(l))
 	}
 	for _, v := range vals {
-		dst = e.AppendFloat64(dst, v)
+		dst = e.AppendFloat64(dst, v, unused)
 	}
 	return dst
 }
diff --git a/vendor/github.com/rs/zerolog/internal/json/time.go b/vendor/github.com/rs/zerolog/internal/json/time.go
index 6a8dc912..08cbbd9b 100644
--- a/vendor/github.com/rs/zerolog/internal/json/time.go
+++ b/vendor/github.com/rs/zerolog/internal/json/time.go
@@ -88,24 +88,24 @@ func appendUnixNanoTimes(dst []byte, vals []time.Time, div int64) []byte {
 
 // AppendDuration formats the input duration with the given unit & format
 // and appends the encoded string to the input byte slice.
-func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte {
+func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool, precision int) []byte {
 	if useInt {
 		return strconv.AppendInt(dst, int64(d/unit), 10)
 	}
-	return e.AppendFloat64(dst, float64(d)/float64(unit))
+	return e.AppendFloat64(dst, float64(d)/float64(unit), precision)
 }
 
 // AppendDurations formats the input durations with the given unit & format
 // and appends the encoded string list to the input byte slice.
-func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte {
+func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool, precision int) []byte {
 	if len(vals) == 0 {
 		return append(dst, '[', ']')
 	}
 	dst = append(dst, '[')
-	dst = e.AppendDuration(dst, vals[0], unit, useInt)
+	dst = e.AppendDuration(dst, vals[0], unit, useInt, precision)
 	if len(vals) > 1 {
 		for _, d := range vals[1:] {
-			dst = e.AppendDuration(append(dst, ','), d, unit, useInt)
+			dst = e.AppendDuration(append(dst, ','), d, unit, useInt, precision)
 		}
 	}
 	dst = append(dst, ']')
diff --git a/vendor/github.com/rs/zerolog/internal/json/types.go b/vendor/github.com/rs/zerolog/internal/json/types.go
index ef3a2a7a..7930491a 100644
--- a/vendor/github.com/rs/zerolog/internal/json/types.go
+++ b/vendor/github.com/rs/zerolog/internal/json/types.go
@@ -299,7 +299,7 @@ func (Encoder) AppendUints64(dst []byte, vals []uint64) []byte {
 	return dst
 }
 
-func appendFloat(dst []byte, val float64, bitSize int) []byte {
+func appendFloat(dst []byte, val float64, bitSize, precision int) []byte {
 	// JSON does not permit NaN or Infinity. A typical JSON encoder would fail
 	// with an error, but a logging library wants the data to get through so we
 	// make a tradeoff and store those types as string.
@@ -311,26 +311,47 @@ func appendFloat(dst []byte, val float64, bitSize int) []byte {
 	case math.IsInf(val, -1):
 		return append(dst, `"-Inf"`...)
 	}
-	return strconv.AppendFloat(dst, val, 'f', -1, bitSize)
+	// convert as if by es6 number to string conversion
+	// see also https://cs.opensource.google/go/go/+/refs/tags/go1.20.3:src/encoding/json/encode.go;l=573
+	strFmt := byte('f')
+	// If precision is set to a value other than -1, we always just format the float using that precision.
+	if precision == -1 {
+		// Use float32 comparisons for underlying float32 value to get precise cutoffs right.
+		if abs := math.Abs(val); abs != 0 {
+			if bitSize == 64 && (abs < 1e-6 || abs >= 1e21) || bitSize == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
+				strFmt = 'e'
+			}
+		}
+	}
+	dst = strconv.AppendFloat(dst, val, strFmt, precision, bitSize)
+	if strFmt == 'e' {
+		// Clean up e-09 to e-9
+		n := len(dst)
+		if n >= 4 && dst[n-4] == 'e' && dst[n-3] == '-' && dst[n-2] == '0' {
+			dst[n-2] = dst[n-1]
+			dst = dst[:n-1]
+		}
+	}
+	return dst
 }
 
 // AppendFloat32 converts the input float32 to a string and
 // appends the encoded string to the input byte slice.
-func (Encoder) AppendFloat32(dst []byte, val float32) []byte {
-	return appendFloat(dst, float64(val), 32)
+func (Encoder) AppendFloat32(dst []byte, val float32, precision int) []byte {
+	return appendFloat(dst, float64(val), 32, precision)
 }
 
 // AppendFloats32 encodes the input float32s to json and
 // appends the encoded string list to the input byte slice.
-func (Encoder) AppendFloats32(dst []byte, vals []float32) []byte {
+func (Encoder) AppendFloats32(dst []byte, vals []float32, precision int) []byte {
 	if len(vals) == 0 {
 		return append(dst, '[', ']')
 	}
 	dst = append(dst, '[')
-	dst = appendFloat(dst, float64(vals[0]), 32)
+	dst = appendFloat(dst, float64(vals[0]), 32, precision)
 	if len(vals) > 1 {
 		for _, val := range vals[1:] {
-			dst = appendFloat(append(dst, ','), float64(val), 32)
+			dst = appendFloat(append(dst, ','), float64(val), 32, precision)
 		}
 	}
 	dst = append(dst, ']')
@@ -339,21 +360,21 @@ func (Encoder) AppendFloats32(dst []byte, vals []float32) []byte {
 
 // AppendFloat64 converts the input float64 to a string and
 // appends the encoded string to the input byte slice.
-func (Encoder) AppendFloat64(dst []byte, val float64) []byte {
-	return appendFloat(dst, val, 64)
+func (Encoder) AppendFloat64(dst []byte, val float64, precision int) []byte {
+	return appendFloat(dst, val, 64, precision)
 }
 
 // AppendFloats64 encodes the input float64s to json and
 // appends the encoded string list to the input byte slice.
-func (Encoder) AppendFloats64(dst []byte, vals []float64) []byte {
+func (Encoder) AppendFloats64(dst []byte, vals []float64, precision int) []byte {
 	if len(vals) == 0 {
 		return append(dst, '[', ']')
 	}
 	dst = append(dst, '[')
-	dst = appendFloat(dst, vals[0], 64)
+	dst = appendFloat(dst, vals[0], 64, precision)
 	if len(vals) > 1 {
 		for _, val := range vals[1:] {
-			dst = appendFloat(append(dst, ','), val, 64)
+			dst = appendFloat(append(dst, ','), val, 64, precision)
 		}
 	}
 	dst = append(dst, ']')
diff --git a/vendor/github.com/rs/zerolog/log.go b/vendor/github.com/rs/zerolog/log.go
index 9fec7cc3..6c1d4ead 100644
--- a/vendor/github.com/rs/zerolog/log.go
+++ b/vendor/github.com/rs/zerolog/log.go
@@ -24,7 +24,7 @@
 //
 // Sub-loggers let you chain loggers with additional context:
 //
-//     sublogger := log.With().Str("component": "foo").Logger()
+//     sublogger := log.With().Str("component", "foo").Logger()
 //     sublogger.Info().Msg("hello world")
 //     // Output: {"time":1494567715,"level":"info","message":"hello world","component":"foo"}
 //
diff --git a/vendor/github.com/rs/zerolog/sampler.go b/vendor/github.com/rs/zerolog/sampler.go
index 1be98c4f..83ce2ed3 100644
--- a/vendor/github.com/rs/zerolog/sampler.go
+++ b/vendor/github.com/rs/zerolog/sampler.go
@@ -84,7 +84,7 @@ func (s *BurstSampler) Sample(lvl Level) bool {
 }
 
 func (s *BurstSampler) inc() uint32 {
-	now := time.Now().UnixNano()
+	now := TimestampFunc().UnixNano()
 	resetAt := atomic.LoadInt64(&s.resetAt)
 	var c uint32
 	if now > resetAt {
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_compare.go b/vendor/github.com/stretchr/testify/assert/assertion_compare.go
index b774da88..4d4b4aad 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_compare.go
+++ b/vendor/github.com/stretchr/testify/assert/assertion_compare.go
@@ -28,6 +28,8 @@ var (
 	uint32Type = reflect.TypeOf(uint32(1))
 	uint64Type = reflect.TypeOf(uint64(1))
 
+	uintptrType = reflect.TypeOf(uintptr(1))
+
 	float32Type = reflect.TypeOf(float32(1))
 	float64Type = reflect.TypeOf(float64(1))
 
@@ -308,11 +310,11 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
 	case reflect.Struct:
 		{
 			// All structs enter here. We're not interested in most types.
-			if !canConvert(obj1Value, timeType) {
+			if !obj1Value.CanConvert(timeType) {
 				break
 			}
 
-			// time.Time can compared!
+			// time.Time can be compared!
 			timeObj1, ok := obj1.(time.Time)
 			if !ok {
 				timeObj1 = obj1Value.Convert(timeType).Interface().(time.Time)
@@ -328,7 +330,7 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
 	case reflect.Slice:
 		{
 			// We only care about the []byte type.
-			if !canConvert(obj1Value, bytesType) {
+			if !obj1Value.CanConvert(bytesType) {
 				break
 			}
 
@@ -345,6 +347,26 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
 
 			return CompareType(bytes.Compare(bytesObj1, bytesObj2)), true
 		}
+	case reflect.Uintptr:
+		{
+			uintptrObj1, ok := obj1.(uintptr)
+			if !ok {
+				uintptrObj1 = obj1Value.Convert(uintptrType).Interface().(uintptr)
+			}
+			uintptrObj2, ok := obj2.(uintptr)
+			if !ok {
+				uintptrObj2 = obj2Value.Convert(uintptrType).Interface().(uintptr)
+			}
+			if uintptrObj1 > uintptrObj2 {
+				return compareGreater, true
+			}
+			if uintptrObj1 == uintptrObj2 {
+				return compareEqual, true
+			}
+			if uintptrObj1 < uintptrObj2 {
+				return compareLess, true
+			}
+		}
 	}
 
 	return compareEqual, false
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_compare_can_convert.go b/vendor/github.com/stretchr/testify/assert/assertion_compare_can_convert.go
deleted file mode 100644
index da867903..00000000
--- a/vendor/github.com/stretchr/testify/assert/assertion_compare_can_convert.go
+++ /dev/null
@@ -1,16 +0,0 @@
-//go:build go1.17
-// +build go1.17
-
-// TODO: once support for Go 1.16 is dropped, this file can be
-//       merged/removed with assertion_compare_go1.17_test.go and
-//       assertion_compare_legacy.go
-
-package assert
-
-import "reflect"
-
-// Wrapper around reflect.Value.CanConvert, for compatibility
-// reasons.
-func canConvert(value reflect.Value, to reflect.Type) bool {
-	return value.CanConvert(to)
-}
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_compare_legacy.go b/vendor/github.com/stretchr/testify/assert/assertion_compare_legacy.go
deleted file mode 100644
index 1701af2a..00000000
--- a/vendor/github.com/stretchr/testify/assert/assertion_compare_legacy.go
+++ /dev/null
@@ -1,16 +0,0 @@
-//go:build !go1.17
-// +build !go1.17
-
-// TODO: once support for Go 1.16 is dropped, this file can be
-//       merged/removed with assertion_compare_go1.17_test.go and
-//       assertion_compare_can_convert.go
-
-package assert
-
-import "reflect"
-
-// Older versions of Go does not have the reflect.Value.CanConvert
-// method.
-func canConvert(value reflect.Value, to reflect.Type) bool {
-	return false
-}
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go
index 84dbd6c7..3ddab109 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_format.go
+++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go
@@ -1,7 +1,4 @@
-/*
-* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
-* THIS FILE MUST NOT BE EDITED BY HAND
- */
+// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.
 
 package assert
 
@@ -107,7 +104,7 @@ func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{},
 	return EqualExportedValues(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
-// EqualValuesf asserts that two objects are equal or convertable to the same types
+// EqualValuesf asserts that two objects are equal or convertible to the same types
 // and equal.
 //
 //	assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted")
@@ -616,6 +613,16 @@ func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interf
 	return NotErrorIs(t, err, target, append([]interface{}{msg}, args...)...)
 }
 
+// NotImplementsf asserts that an object does not implement the specified interface.
+//
+//	assert.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted")
+func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return NotImplements(t, interfaceObject, object, append([]interface{}{msg}, args...)...)
+}
+
 // NotNilf asserts that the specified object is not nil.
 //
 //	assert.NotNilf(t, err, "error message %s", "formatted")
@@ -660,10 +667,12 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string,
 	return NotSame(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
-// NotSubsetf asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubsetf asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
+//	assert.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted")
+//	assert.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
 func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
@@ -747,10 +756,11 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg
 	return Same(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
-// Subsetf asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subsetf asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
+//	assert.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted")
+//	assert.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
 func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go
index b1d94aec..a84e09bd 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go
+++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go
@@ -1,7 +1,4 @@
-/*
-* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
-* THIS FILE MUST NOT BE EDITED BY HAND
- */
+// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.
 
 package assert
 
@@ -189,7 +186,7 @@ func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface
 	return EqualExportedValuesf(a.t, expected, actual, msg, args...)
 }
 
-// EqualValues asserts that two objects are equal or convertable to the same types
+// EqualValues asserts that two objects are equal or convertible to the same types
 // and equal.
 //
 //	a.EqualValues(uint32(123), int32(123))
@@ -200,7 +197,7 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn
 	return EqualValues(a.t, expected, actual, msgAndArgs...)
 }
 
-// EqualValuesf asserts that two objects are equal or convertable to the same types
+// EqualValuesf asserts that two objects are equal or convertible to the same types
 // and equal.
 //
 //	a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted")
@@ -1221,6 +1218,26 @@ func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...in
 	return NotErrorIsf(a.t, err, target, msg, args...)
 }
 
+// NotImplements asserts that an object does not implement the specified interface.
+//
+//	a.NotImplements((*MyInterface)(nil), new(MyObject))
+func (a *Assertions) NotImplements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return NotImplements(a.t, interfaceObject, object, msgAndArgs...)
+}
+
+// NotImplementsf asserts that an object does not implement the specified interface.
+//
+//	a.NotImplementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted")
+func (a *Assertions) NotImplementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return NotImplementsf(a.t, interfaceObject, object, msg, args...)
+}
+
 // NotNil asserts that the specified object is not nil.
 //
 //	a.NotNil(err)
@@ -1309,10 +1326,12 @@ func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg stri
 	return NotSamef(a.t, expected, actual, msg, args...)
 }
 
-// NotSubset asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubset asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
+//	a.NotSubset([1, 3, 4], [1, 2])
+//	a.NotSubset({"x": 1, "y": 2}, {"z": 3})
 func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
@@ -1320,10 +1339,12 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs
 	return NotSubset(a.t, list, subset, msgAndArgs...)
 }
 
-// NotSubsetf asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubsetf asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
+//	a.NotSubsetf([1, 3, 4], [1, 2], "error message %s", "formatted")
+//	a.NotSubsetf({"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
 func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
@@ -1483,10 +1504,11 @@ func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string,
 	return Samef(a.t, expected, actual, msg, args...)
 }
 
-// Subset asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subset asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
+//	a.Subset([1, 2, 3], [1, 2])
+//	a.Subset({"x": 1, "y": 2}, {"x": 1})
 func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
@@ -1494,10 +1516,11 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...
 	return Subset(a.t, list, subset, msgAndArgs...)
 }
 
-// Subsetf asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subsetf asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
+//	a.Subsetf([1, 2, 3], [1, 2], "error message %s", "formatted")
+//	a.Subsetf({"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
 func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go
index a55d1bba..0b7570f2 100644
--- a/vendor/github.com/stretchr/testify/assert/assertions.go
+++ b/vendor/github.com/stretchr/testify/assert/assertions.go
@@ -19,7 +19,7 @@ import (
 
 	"github.com/davecgh/go-spew/spew"
 	"github.com/pmezard/go-difflib/difflib"
-	yaml "gopkg.in/yaml.v3"
+	"gopkg.in/yaml.v3"
 )
 
 //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl"
@@ -110,7 +110,12 @@ func copyExportedFields(expected interface{}) interface{} {
 		return result.Interface()
 
 	case reflect.Array, reflect.Slice:
-		result := reflect.MakeSlice(expectedType, expectedValue.Len(), expectedValue.Len())
+		var result reflect.Value
+		if expectedKind == reflect.Array {
+			result = reflect.New(reflect.ArrayOf(expectedValue.Len(), expectedType.Elem())).Elem()
+		} else {
+			result = reflect.MakeSlice(expectedType, expectedValue.Len(), expectedValue.Len())
+		}
 		for i := 0; i < expectedValue.Len(); i++ {
 			index := expectedValue.Index(i)
 			if isNil(index) {
@@ -140,6 +145,8 @@ func copyExportedFields(expected interface{}) interface{} {
 // structures.
 //
 // This function does no assertion of any kind.
+//
+// Deprecated: Use [EqualExportedValues] instead.
 func ObjectsExportedFieldsAreEqual(expected, actual interface{}) bool {
 	expectedCleaned := copyExportedFields(expected)
 	actualCleaned := copyExportedFields(actual)
@@ -153,17 +160,40 @@ func ObjectsAreEqualValues(expected, actual interface{}) bool {
 		return true
 	}
 
-	actualType := reflect.TypeOf(actual)
-	if actualType == nil {
+	expectedValue := reflect.ValueOf(expected)
+	actualValue := reflect.ValueOf(actual)
+	if !expectedValue.IsValid() || !actualValue.IsValid() {
 		return false
 	}
-	expectedValue := reflect.ValueOf(expected)
-	if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) {
+
+	expectedType := expectedValue.Type()
+	actualType := actualValue.Type()
+	if !expectedType.ConvertibleTo(actualType) {
+		return false
+	}
+
+	if !isNumericType(expectedType) || !isNumericType(actualType) {
 		// Attempt comparison after type conversion
-		return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual)
+		return reflect.DeepEqual(
+			expectedValue.Convert(actualType).Interface(), actual,
+		)
 	}
 
-	return false
+	// If BOTH values are numeric, there are chances of false positives due
+	// to overflow or underflow. So, we need to make sure to always convert
+	// the smaller type to a larger type before comparing.
+	if expectedType.Size() >= actualType.Size() {
+		return actualValue.Convert(expectedType).Interface() == expected
+	}
+
+	return expectedValue.Convert(actualType).Interface() == actual
+}
+
+// isNumericType returns true if the type is one of:
+// int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64,
+// float32, float64, complex64, complex128
+func isNumericType(t reflect.Type) bool {
+	return t.Kind() >= reflect.Int && t.Kind() <= reflect.Complex128
 }
 
 /* CallerInfo is necessary because the assert functions use the testing object
@@ -266,7 +296,7 @@ func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
 
 // Aligns the provided message so that all lines after the first line start at the same location as the first line.
 // Assumes that the first line starts at the correct location (after carriage return, tab, label, spacer and tab).
-// The longestLabelLen parameter specifies the length of the longest label in the output (required becaues this is the
+// The longestLabelLen parameter specifies the length of the longest label in the output (required because this is the
 // basis on which the alignment occurs).
 func indentMessageLines(message string, longestLabelLen int) string {
 	outBuf := new(bytes.Buffer)
@@ -382,6 +412,25 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg
 	return true
 }
 
+// NotImplements asserts that an object does not implement the specified interface.
+//
+//	assert.NotImplements(t, (*MyInterface)(nil), new(MyObject))
+func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	interfaceType := reflect.TypeOf(interfaceObject).Elem()
+
+	if object == nil {
+		return Fail(t, fmt.Sprintf("Cannot check if nil does not implement %v", interfaceType), msgAndArgs...)
+	}
+	if reflect.TypeOf(object).Implements(interfaceType) {
+		return Fail(t, fmt.Sprintf("%T implements %v", object, interfaceType), msgAndArgs...)
+	}
+
+	return true
+}
+
 // IsType asserts that the specified objects are of the same type.
 func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
 	if h, ok := t.(tHelper); ok {
@@ -496,7 +545,7 @@ func samePointers(first, second interface{}) bool {
 // representations appropriate to be presented to the user.
 //
 // If the values are not of like type, the returned strings will be prefixed
-// with the type name, and the value will be enclosed in parenthesis similar
+// with the type name, and the value will be enclosed in parentheses similar
 // to a type conversion in the Go grammar.
 func formatUnequalValues(expected, actual interface{}) (e string, a string) {
 	if reflect.TypeOf(expected) != reflect.TypeOf(actual) {
@@ -523,7 +572,7 @@ func truncatingFormat(data interface{}) string {
 	return value
 }
 
-// EqualValues asserts that two objects are equal or convertable to the same types
+// EqualValues asserts that two objects are equal or convertible to the same types
 // and equal.
 //
 //	assert.EqualValues(t, uint32(123), int32(123))
@@ -566,12 +615,19 @@ func EqualExportedValues(t TestingT, expected, actual interface{}, msgAndArgs ..
 		return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...)
 	}
 
+	if aType.Kind() == reflect.Ptr {
+		aType = aType.Elem()
+	}
+	if bType.Kind() == reflect.Ptr {
+		bType = bType.Elem()
+	}
+
 	if aType.Kind() != reflect.Struct {
-		return Fail(t, fmt.Sprintf("Types expected to both be struct \n\t%v != %v", aType.Kind(), reflect.Struct), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", aType.Kind(), reflect.Struct), msgAndArgs...)
 	}
 
 	if bType.Kind() != reflect.Struct {
-		return Fail(t, fmt.Sprintf("Types expected to both be struct \n\t%v != %v", bType.Kind(), reflect.Struct), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", bType.Kind(), reflect.Struct), msgAndArgs...)
 	}
 
 	expected = copyExportedFields(expected)
@@ -620,17 +676,6 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
 	return Fail(t, "Expected value not to be nil.", msgAndArgs...)
 }
 
-// containsKind checks if a specified kind in the slice of kinds.
-func containsKind(kinds []reflect.Kind, kind reflect.Kind) bool {
-	for i := 0; i < len(kinds); i++ {
-		if kind == kinds[i] {
-			return true
-		}
-	}
-
-	return false
-}
-
 // isNil checks if a specified object is nil or not, without Failing.
 func isNil(object interface{}) bool {
 	if object == nil {
@@ -638,16 +683,13 @@ func isNil(object interface{}) bool {
 	}
 
 	value := reflect.ValueOf(object)
-	kind := value.Kind()
-	isNilableKind := containsKind(
-		[]reflect.Kind{
-			reflect.Chan, reflect.Func,
-			reflect.Interface, reflect.Map,
-			reflect.Ptr, reflect.Slice, reflect.UnsafePointer},
-		kind)
-
-	if isNilableKind && value.IsNil() {
-		return true
+	switch value.Kind() {
+	case
+		reflect.Chan, reflect.Func,
+		reflect.Interface, reflect.Map,
+		reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
+
+		return value.IsNil()
 	}
 
 	return false
@@ -731,16 +773,14 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
 
 }
 
-// getLen try to get length of object.
-// return (false, 0) if impossible.
-func getLen(x interface{}) (ok bool, length int) {
+// getLen tries to get the length of an object.
+// It returns (0, false) if impossible.
+func getLen(x interface{}) (length int, ok bool) {
 	v := reflect.ValueOf(x)
 	defer func() {
-		if e := recover(); e != nil {
-			ok = false
-		}
+		ok = recover() == nil
 	}()
-	return true, v.Len()
+	return v.Len(), true
 }
 
 // Len asserts that the specified object has specific length.
@@ -751,13 +791,13 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{})
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
-	ok, l := getLen(object)
+	l, ok := getLen(object)
 	if !ok {
-		return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("\"%v\" could not be applied builtin len()", object), msgAndArgs...)
 	}
 
 	if l != length {
-		return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("\"%v\" should have %d item(s), but has %d", object, length, l), msgAndArgs...)
 	}
 	return true
 }
@@ -919,10 +959,11 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{})
 
 }
 
-// Subset asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subset asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
+//	assert.Subset(t, [1, 2, 3], [1, 2])
+//	assert.Subset(t, {"x": 1, "y": 2}, {"x": 1})
 func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
@@ -975,10 +1016,12 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
 	return true
 }
 
-// NotSubset asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubset asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
+//	assert.NotSubset(t, [1, 3, 4], [1, 2])
+//	assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3})
 func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
@@ -1439,7 +1482,7 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd
 		h.Helper()
 	}
 	if math.IsNaN(epsilon) {
-		return Fail(t, "epsilon must not be NaN")
+		return Fail(t, "epsilon must not be NaN", msgAndArgs...)
 	}
 	actualEpsilon, err := calcRelativeError(expected, actual)
 	if err != nil {
@@ -1458,19 +1501,26 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
-	if expected == nil || actual == nil ||
-		reflect.TypeOf(actual).Kind() != reflect.Slice ||
-		reflect.TypeOf(expected).Kind() != reflect.Slice {
+
+	if expected == nil || actual == nil {
 		return Fail(t, "Parameters must be slice", msgAndArgs...)
 	}
 
-	actualSlice := reflect.ValueOf(actual)
 	expectedSlice := reflect.ValueOf(expected)
+	actualSlice := reflect.ValueOf(actual)
 
-	for i := 0; i < actualSlice.Len(); i++ {
-		result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), epsilon)
-		if !result {
-			return result
+	if expectedSlice.Type().Kind() != reflect.Slice {
+		return Fail(t, "Expected value must be slice", msgAndArgs...)
+	}
+
+	expectedLen := expectedSlice.Len()
+	if !IsType(t, expected, actual) || !Len(t, actual, expectedLen) {
+		return false
+	}
+
+	for i := 0; i < expectedLen; i++ {
+		if !InEpsilon(t, expectedSlice.Index(i).Interface(), actualSlice.Index(i).Interface(), epsilon, "at index %d", i) {
+			return false
 		}
 	}
 
@@ -1870,23 +1920,18 @@ func (c *CollectT) Errorf(format string, args ...interface{}) {
 }
 
 // FailNow panics.
-func (c *CollectT) FailNow() {
+func (*CollectT) FailNow() {
 	panic("Assertion failed")
 }
 
-// Reset clears the collected errors.
-func (c *CollectT) Reset() {
-	c.errors = nil
+// Deprecated: That was a method for internal usage that should not have been published. Now just panics.
+func (*CollectT) Reset() {
+	panic("Reset() is deprecated")
 }
 
-// Copy copies the collected errors to the supplied t.
-func (c *CollectT) Copy(t TestingT) {
-	if tt, ok := t.(tHelper); ok {
-		tt.Helper()
-	}
-	for _, err := range c.errors {
-		t.Errorf("%v", err)
-	}
+// Deprecated: That was a method for internal usage that should not have been published. Now just panics.
+func (*CollectT) Copy(TestingT) {
+	panic("Copy() is deprecated")
 }
 
 // EventuallyWithT asserts that given condition will be met in waitFor time,
@@ -1912,8 +1957,8 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time
 		h.Helper()
 	}
 
-	collect := new(CollectT)
-	ch := make(chan bool, 1)
+	var lastFinishedTickErrs []error
+	ch := make(chan []error, 1)
 
 	timer := time.NewTimer(waitFor)
 	defer timer.Stop()
@@ -1924,19 +1969,25 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time
 	for tick := ticker.C; ; {
 		select {
 		case <-timer.C:
-			collect.Copy(t)
+			for _, err := range lastFinishedTickErrs {
+				t.Errorf("%v", err)
+			}
 			return Fail(t, "Condition never satisfied", msgAndArgs...)
 		case <-tick:
 			tick = nil
-			collect.Reset()
 			go func() {
+				collect := new(CollectT)
+				defer func() {
+					ch <- collect.errors
+				}()
 				condition(collect)
-				ch <- len(collect.errors) == 0
 			}()
-		case v := <-ch:
-			if v {
+		case errs := <-ch:
+			if len(errs) == 0 {
 				return true
 			}
+			// Keep the errors from the last ended condition, so that they can be copied to t if timeout is reached.
+			lastFinishedTickErrs = errs
 			tick = ticker.C
 		}
 	}
diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions.go b/vendor/github.com/stretchr/testify/assert/http_assertions.go
index d8038c28..861ed4b7 100644
--- a/vendor/github.com/stretchr/testify/assert/http_assertions.go
+++ b/vendor/github.com/stretchr/testify/assert/http_assertions.go
@@ -12,7 +12,7 @@ import (
 // an error if building a new request fails.
 func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) {
 	w := httptest.NewRecorder()
-	req, err := http.NewRequest(method, url, nil)
+	req, err := http.NewRequest(method, url, http.NoBody)
 	if err != nil {
 		return -1, err
 	}
@@ -32,12 +32,12 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, value
 	}
 	code, err := httpCode(handler, method, url, values)
 	if err != nil {
-		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
+		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...)
 	}
 
 	isSuccessCode := code >= http.StatusOK && code <= http.StatusPartialContent
 	if !isSuccessCode {
-		Fail(t, fmt.Sprintf("Expected HTTP success status code for %q but received %d", url+"?"+values.Encode(), code))
+		Fail(t, fmt.Sprintf("Expected HTTP success status code for %q but received %d", url+"?"+values.Encode(), code), msgAndArgs...)
 	}
 
 	return isSuccessCode
@@ -54,12 +54,12 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, valu
 	}
 	code, err := httpCode(handler, method, url, values)
 	if err != nil {
-		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
+		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...)
 	}
 
 	isRedirectCode := code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect
 	if !isRedirectCode {
-		Fail(t, fmt.Sprintf("Expected HTTP redirect status code for %q but received %d", url+"?"+values.Encode(), code))
+		Fail(t, fmt.Sprintf("Expected HTTP redirect status code for %q but received %d", url+"?"+values.Encode(), code), msgAndArgs...)
 	}
 
 	return isRedirectCode
@@ -76,12 +76,12 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values
 	}
 	code, err := httpCode(handler, method, url, values)
 	if err != nil {
-		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
+		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...)
 	}
 
 	isErrorCode := code >= http.StatusBadRequest
 	if !isErrorCode {
-		Fail(t, fmt.Sprintf("Expected HTTP error status code for %q but received %d", url+"?"+values.Encode(), code))
+		Fail(t, fmt.Sprintf("Expected HTTP error status code for %q but received %d", url+"?"+values.Encode(), code), msgAndArgs...)
 	}
 
 	return isErrorCode
@@ -98,12 +98,12 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, va
 	}
 	code, err := httpCode(handler, method, url, values)
 	if err != nil {
-		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
+		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...)
 	}
 
 	successful := code == statuscode
 	if !successful {
-		Fail(t, fmt.Sprintf("Expected HTTP status code %d for %q but received %d", statuscode, url+"?"+values.Encode(), code))
+		Fail(t, fmt.Sprintf("Expected HTTP status code %d for %q but received %d", statuscode, url+"?"+values.Encode(), code), msgAndArgs...)
 	}
 
 	return successful
@@ -113,7 +113,10 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, va
 // empty string if building a new request fails.
 func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string {
 	w := httptest.NewRecorder()
-	req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
+	if len(values) > 0 {
+		url += "?" + values.Encode()
+	}
+	req, err := http.NewRequest(method, url, http.NoBody)
 	if err != nil {
 		return ""
 	}
@@ -135,7 +138,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string,
 
 	contains := strings.Contains(body, fmt.Sprint(str))
 	if !contains {
-		Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body))
+		Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body), msgAndArgs...)
 	}
 
 	return contains
@@ -155,7 +158,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url strin
 
 	contains := strings.Contains(body, fmt.Sprint(str))
 	if contains {
-		Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body))
+		Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body), msgAndArgs...)
 	}
 
 	return !contains
diff --git a/vendor/github.com/stretchr/testify/require/require.go b/vendor/github.com/stretchr/testify/require/require.go
index 63f85214..506a82f8 100644
--- a/vendor/github.com/stretchr/testify/require/require.go
+++ b/vendor/github.com/stretchr/testify/require/require.go
@@ -1,7 +1,4 @@
-/*
-* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
-* THIS FILE MUST NOT BE EDITED BY HAND
- */
+// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.
 
 package require
 
@@ -235,7 +232,7 @@ func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{},
 	t.FailNow()
 }
 
-// EqualValues asserts that two objects are equal or convertable to the same types
+// EqualValues asserts that two objects are equal or convertible to the same types
 // and equal.
 //
 //	assert.EqualValues(t, uint32(123), int32(123))
@@ -249,7 +246,7 @@ func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArg
 	t.FailNow()
 }
 
-// EqualValuesf asserts that two objects are equal or convertable to the same types
+// EqualValuesf asserts that two objects are equal or convertible to the same types
 // and equal.
 //
 //	assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted")
@@ -1546,6 +1543,32 @@ func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interf
 	t.FailNow()
 }
 
+// NotImplements asserts that an object does not implement the specified interface.
+//
+//	assert.NotImplements(t, (*MyInterface)(nil), new(MyObject))
+func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if assert.NotImplements(t, interfaceObject, object, msgAndArgs...) {
+		return
+	}
+	t.FailNow()
+}
+
+// NotImplementsf asserts that an object does not implement the specified interface.
+//
+//	assert.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted")
+func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if assert.NotImplementsf(t, interfaceObject, object, msg, args...) {
+		return
+	}
+	t.FailNow()
+}
+
 // NotNil asserts that the specified object is not nil.
 //
 //	assert.NotNil(t, err)
@@ -1658,10 +1681,12 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string,
 	t.FailNow()
 }
 
-// NotSubset asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubset asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
+//	assert.NotSubset(t, [1, 3, 4], [1, 2])
+//	assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3})
 func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
@@ -1672,10 +1697,12 @@ func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...i
 	t.FailNow()
 }
 
-// NotSubsetf asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubsetf asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
+//	assert.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted")
+//	assert.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
 func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
@@ -1880,10 +1907,11 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg
 	t.FailNow()
 }
 
-// Subset asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subset asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
+//	assert.Subset(t, [1, 2, 3], [1, 2])
+//	assert.Subset(t, {"x": 1, "y": 2}, {"x": 1})
 func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
@@ -1894,10 +1922,11 @@ func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...inte
 	t.FailNow()
 }
 
-// Subsetf asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subsetf asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
+//	assert.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted")
+//	assert.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
 func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
diff --git a/vendor/github.com/stretchr/testify/require/require_forward.go b/vendor/github.com/stretchr/testify/require/require_forward.go
index 3b5b0933..eee8310a 100644
--- a/vendor/github.com/stretchr/testify/require/require_forward.go
+++ b/vendor/github.com/stretchr/testify/require/require_forward.go
@@ -1,7 +1,4 @@
-/*
-* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
-* THIS FILE MUST NOT BE EDITED BY HAND
- */
+// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.
 
 package require
 
@@ -190,7 +187,7 @@ func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface
 	EqualExportedValuesf(a.t, expected, actual, msg, args...)
 }
 
-// EqualValues asserts that two objects are equal or convertable to the same types
+// EqualValues asserts that two objects are equal or convertible to the same types
 // and equal.
 //
 //	a.EqualValues(uint32(123), int32(123))
@@ -201,7 +198,7 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn
 	EqualValues(a.t, expected, actual, msgAndArgs...)
 }
 
-// EqualValuesf asserts that two objects are equal or convertable to the same types
+// EqualValuesf asserts that two objects are equal or convertible to the same types
 // and equal.
 //
 //	a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted")
@@ -1222,6 +1219,26 @@ func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...in
 	NotErrorIsf(a.t, err, target, msg, args...)
 }
 
+// NotImplements asserts that an object does not implement the specified interface.
+//
+//	a.NotImplements((*MyInterface)(nil), new(MyObject))
+func (a *Assertions) NotImplements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	NotImplements(a.t, interfaceObject, object, msgAndArgs...)
+}
+
+// NotImplementsf asserts that an object does not implement the specified interface.
+//
+//	a.NotImplementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted")
+func (a *Assertions) NotImplementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	NotImplementsf(a.t, interfaceObject, object, msg, args...)
+}
+
 // NotNil asserts that the specified object is not nil.
 //
 //	a.NotNil(err)
@@ -1310,10 +1327,12 @@ func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg stri
 	NotSamef(a.t, expected, actual, msg, args...)
 }
 
-// NotSubset asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubset asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
+//	a.NotSubset([1, 3, 4], [1, 2])
+//	a.NotSubset({"x": 1, "y": 2}, {"z": 3})
 func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
@@ -1321,10 +1340,12 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs
 	NotSubset(a.t, list, subset, msgAndArgs...)
 }
 
-// NotSubsetf asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubsetf asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
+//	a.NotSubsetf([1, 3, 4], [1, 2], "error message %s", "formatted")
+//	a.NotSubsetf({"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
 func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
@@ -1484,10 +1505,11 @@ func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string,
 	Samef(a.t, expected, actual, msg, args...)
 }
 
-// Subset asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subset asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
+//	a.Subset([1, 2, 3], [1, 2])
+//	a.Subset({"x": 1, "y": 2}, {"x": 1})
 func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
@@ -1495,10 +1517,11 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...
 	Subset(a.t, list, subset, msgAndArgs...)
 }
 
-// Subsetf asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subsetf asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
+//	a.Subsetf([1, 2, 3], [1, 2], "error message %s", "formatted")
+//	a.Subsetf({"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
 func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
diff --git a/vendor/github.com/xtaci/kcp-go/v5/fec.go b/vendor/github.com/xtaci/kcp-go/v5/fec.go
index 88f5a9c4..e2a4ab6f 100644
--- a/vendor/github.com/xtaci/kcp-go/v5/fec.go
+++ b/vendor/github.com/xtaci/kcp-go/v5/fec.go
@@ -3,6 +3,7 @@ package kcp
 import (
 	"encoding/binary"
 	"sync/atomic"
+	"time"
 
 	"github.com/klauspost/reedsolomon"
 )
@@ -45,7 +46,8 @@ type fecDecoder struct {
 	codec reedsolomon.Encoder
 
 	// auto tune fec parameter
-	autoTune autoTune
+	autoTune   autoTune
+	shouldTune bool
 }
 
 func newFECDecoder(dataShards, parityShards int) *fecDecoder {
@@ -78,18 +80,17 @@ func (dec *fecDecoder) decode(in fecPacket) (recovered [][]byte) {
 	}
 
 	// check if FEC parameters is out of sync
-	var shouldTune bool
 	if int(in.seqid())%dec.shardSize < dec.dataShards {
 		if in.flag() != typeData { // expect typeData
-			shouldTune = true
+			dec.shouldTune = true
 		}
 	} else {
 		if in.flag() != typeParity {
-			shouldTune = true
+			dec.shouldTune = true
 		}
 	}
 
-	if shouldTune {
+	if dec.shouldTune {
 		autoDS := dec.autoTune.FindPeriod(true)
 		autoPS := dec.autoTune.FindPeriod(false)
 
@@ -108,11 +109,17 @@ func (dec *fecDecoder) decode(in fecPacket) (recovered [][]byte) {
 				dec.codec = codec
 				dec.decodeCache = make([][]byte, dec.shardSize)
 				dec.flagCache = make([]bool, dec.shardSize)
+				dec.shouldTune = false
 				//log.Println("autotune to :", dec.dataShards, dec.parityShards)
 			}
 		}
 	}
 
+	// parameters in tuning
+	if dec.shouldTune {
+		return nil
+	}
+
 	// insertion
 	n := len(dec.rx) - 1
 	insertIdx := 0
@@ -272,8 +279,9 @@ type (
 		payloadOffset int // FEC payload offset
 
 		// caches
-		shardCache  [][]byte
-		encodeCache [][]byte
+		shardCache     [][]byte
+		encodeCache    [][]byte
+		tsLatestPacket int64
 
 		// RS encoder
 		codec reedsolomon.Encoder
@@ -309,7 +317,7 @@ func newFECEncoder(dataShards, parityShards, offset int) *fecEncoder {
 
 // encodes the packet, outputs parity shards if we have collected quorum datashards
 // notice: the contents of 'ps' will be re-written in successive calling
-func (enc *fecEncoder) encode(b []byte) (ps [][]byte) {
+func (enc *fecEncoder) encode(b []byte, rto uint32) (ps [][]byte) {
 	// The header format:
 	// | FEC SEQID(4B) | FEC TYPE(2B) | SIZE (2B) | PAYLOAD(SIZE-2) |
 	// |<-headerOffset                |<-payloadOffset
@@ -328,26 +336,30 @@ func (enc *fecEncoder) encode(b []byte) (ps [][]byte) {
 	}
 
 	//  Generation of Reed-Solomon Erasure Code
+	now := time.Now().UnixMilli()
 	if enc.shardCount == enc.dataShards {
-		// fill '0' into the tail of each datashard
-		for i := 0; i < enc.dataShards; i++ {
-			shard := enc.shardCache[i]
-			slen := len(shard)
-			clear(shard[slen:enc.maxSize])
-		}
+		// generate the rs-code only if the data is continuous.
+		if now-enc.tsLatestPacket < int64(rto) {
+			// fill '0' into the tail of each datashard
+			for i := 0; i < enc.dataShards; i++ {
+				shard := enc.shardCache[i]
+				slen := len(shard)
+				clear(shard[slen:enc.maxSize])
+			}
 
-		// construct equal-sized slice with stripped header
-		cache := enc.encodeCache
-		for k := range cache {
-			cache[k] = enc.shardCache[k][enc.payloadOffset:enc.maxSize]
-		}
+			// construct equal-sized slice with stripped header
+			cache := enc.encodeCache
+			for k := range cache {
+				cache[k] = enc.shardCache[k][enc.payloadOffset:enc.maxSize]
+			}
 
-		// encoding
-		if err := enc.codec.Encode(cache); err == nil {
-			ps = enc.shardCache[enc.dataShards:]
-			for k := range ps {
-				enc.markParity(ps[k][enc.headerOffset:])
-				ps[k] = ps[k][:enc.maxSize]
+			// encoding
+			if err := enc.codec.Encode(cache); err == nil {
+				ps = enc.shardCache[enc.dataShards:]
+				for k := range ps {
+					enc.markParity(ps[k][enc.headerOffset:])
+					ps[k] = ps[k][:enc.maxSize]
+				}
 			}
 		}
 
@@ -356,6 +368,8 @@ func (enc *fecEncoder) encode(b []byte) (ps [][]byte) {
 		enc.maxSize = 0
 	}
 
+	enc.tsLatestPacket = now
+
 	return
 }
 
diff --git a/vendor/github.com/xtaci/kcp-go/v5/sess.go b/vendor/github.com/xtaci/kcp-go/v5/sess.go
index 35e7b804..4e32399c 100644
--- a/vendor/github.com/xtaci/kcp-go/v5/sess.go
+++ b/vendor/github.com/xtaci/kcp-go/v5/sess.go
@@ -195,6 +195,7 @@ func newUDPSession(conv uint32, dataShards, parityShards int, l *Listener, conn
 
 // Read implements net.Conn
 func (s *UDPSession) Read(b []byte) (n int, err error) {
+RESET_TIMER:
 	var timeout *time.Timer
 	// deadline for current reading operation
 	var c <-chan time.Time
@@ -243,6 +244,10 @@ func (s *UDPSession) Read(b []byte) (n int, err error) {
 		// wait for read event or timeout or error
 		select {
 		case <-s.chReadEvent:
+			if timeout != nil {
+				timeout.Stop()
+				goto RESET_TIMER
+			}
 		case <-c:
 			return 0, errors.WithStack(errTimeout)
 		case <-s.chSocketReadError:
@@ -258,6 +263,7 @@ func (s *UDPSession) Write(b []byte) (n int, err error) { return s.WriteBuffers(
 
 // WriteBuffers write a vector of byte slices to the underlying connection
 func (s *UDPSession) WriteBuffers(v [][]byte) (n int, err error) {
+RESET_TIMER:
 	var timeout *time.Timer
 	var c <-chan time.Time
 	if !s.wd.IsZero() {
@@ -308,6 +314,10 @@ func (s *UDPSession) WriteBuffers(v [][]byte) (n int, err error) {
 
 		select {
 		case <-s.chWriteEvent:
+			if timeout != nil {
+				timeout.Stop()
+				goto RESET_TIMER
+			}
 		case <-c:
 			return 0, errors.WithStack(errTimeout)
 		case <-s.chSocketWriteError:
@@ -375,9 +385,9 @@ func (s *UDPSession) RemoteAddr() net.Addr { return s.remote }
 // SetDeadline sets the deadline associated with the listener. A zero time value disables the deadline.
 func (s *UDPSession) SetDeadline(t time.Time) error {
 	s.mu.Lock()
-	defer s.mu.Unlock()
 	s.rd = t
 	s.wd = t
+	s.mu.Unlock()
 	s.notifyReadEvent()
 	s.notifyWriteEvent()
 	return nil
@@ -386,8 +396,8 @@ func (s *UDPSession) SetDeadline(t time.Time) error {
 // SetReadDeadline implements the Conn SetReadDeadline method.
 func (s *UDPSession) SetReadDeadline(t time.Time) error {
 	s.mu.Lock()
-	defer s.mu.Unlock()
 	s.rd = t
+	s.mu.Unlock()
 	s.notifyReadEvent()
 	return nil
 }
@@ -395,8 +405,8 @@ func (s *UDPSession) SetReadDeadline(t time.Time) error {
 // SetWriteDeadline implements the Conn SetWriteDeadline method.
 func (s *UDPSession) SetWriteDeadline(t time.Time) error {
 	s.mu.Lock()
-	defer s.mu.Unlock()
 	s.wd = t
+	s.mu.Unlock()
 	s.notifyWriteEvent()
 	return nil
 }
@@ -531,7 +541,7 @@ func (s *UDPSession) output(buf []byte) {
 
 	// 1. FEC encoding
 	if s.fecEncoder != nil {
-		ecc = s.fecEncoder.encode(buf)
+		ecc = s.fecEncoder.encode(buf, s.kcp.rx_rto)
 	}
 
 	// 2&3. crc32 & encryption
diff --git a/vendor/go.etcd.io/bbolt/.go-version b/vendor/go.etcd.io/bbolt/.go-version
new file mode 100644
index 00000000..f124bfa1
--- /dev/null
+++ b/vendor/go.etcd.io/bbolt/.go-version
@@ -0,0 +1 @@
+1.21.9
diff --git a/vendor/go.etcd.io/bbolt/README.md b/vendor/go.etcd.io/bbolt/README.md
index 2be669a6..495a93ef 100644
--- a/vendor/go.etcd.io/bbolt/README.md
+++ b/vendor/go.etcd.io/bbolt/README.md
@@ -421,10 +421,19 @@ Prev()   Move to the previous key.
 ```
 
 Each of those functions has a return signature of `(key []byte, value []byte)`.
-When you have iterated to the end of the cursor then `Next()` will return a
-`nil` key.  You must seek to a position using `First()`, `Last()`, or `Seek()`
-before calling `Next()` or `Prev()`. If you do not seek to a position then
-these functions will return a `nil` key.
+You must seek to a position using `First()`, `Last()`, or `Seek()` before calling
+`Next()` or `Prev()`. If you do not seek to a position then these functions will
+return a `nil` key.
+
+When you have iterated to the end of the cursor, then `Next()` will return a
+`nil` key and the cursor still points to the last element if present. When you
+have iterated to the beginning of the cursor, then `Prev()` will return a `nil`
+key and the cursor still points to the first element if present.
+
+If you remove key/value pairs during iteration, the cursor may automatically
+move to the next position if present in current node each time removing a key.
+When you call `c.Next()` after removing a key, it may skip one key/value pair.
+Refer to [pull/611](https://github.com/etcd-io/bbolt/pull/611) to get more detailed info.
 
 During iteration, if the key is non-`nil` but the value is `nil`, that means
 the key refers to a bucket rather than a value.  Use `Bucket.Bucket()` to
@@ -850,6 +859,12 @@ Here are a few things to note when evaluating and using Bolt:
   to grow. However, it's important to note that deleting large chunks of data
   will not allow you to reclaim that space on disk.
 
+* Removing key/values pairs in a bucket during iteration on the bucket using
+  cursor may not work properly. Each time when removing a key/value pair, the
+  cursor may automatically move to the next position if present. When users
+  call `c.Next()` after removing a key, it may skip one key/value pair.
+  Refer to https://github.com/etcd-io/bbolt/pull/611 for more detailed info.
+
   For more information on page allocation, [see this comment][page-allocation].
 
 [page-allocation]: https://github.com/boltdb/bolt/issues/308#issuecomment-74811638
diff --git a/vendor/go.etcd.io/bbolt/bolt_openbsd.go b/vendor/go.etcd.io/bbolt/bolt_openbsd.go
index d7f50358..bf47aa1a 100644
--- a/vendor/go.etcd.io/bbolt/bolt_openbsd.go
+++ b/vendor/go.etcd.io/bbolt/bolt_openbsd.go
@@ -1,22 +1,11 @@
 package bbolt
 
 import (
-	"syscall"
-	"unsafe"
-)
-
-const (
-	msAsync      = 1 << iota // perform asynchronous writes
-	msSync                   // perform synchronous writes
-	msInvalidate             // invalidate cached data
+	"golang.org/x/sys/unix"
 )
 
 func msync(db *DB) error {
-	_, _, errno := syscall.Syscall(syscall.SYS_MSYNC, uintptr(unsafe.Pointer(db.data)), uintptr(db.datasz), msInvalidate)
-	if errno != 0 {
-		return errno
-	}
-	return nil
+	return unix.Msync(db.data[:db.datasz], unix.MS_INVALIDATE)
 }
 
 func fdatasync(db *DB) error {
diff --git a/vendor/go.etcd.io/bbolt/bucket.go b/vendor/go.etcd.io/bbolt/bucket.go
index 054467af..f3533d34 100644
--- a/vendor/go.etcd.io/bbolt/bucket.go
+++ b/vendor/go.etcd.io/bbolt/bucket.go
@@ -162,12 +162,17 @@ func (b *Bucket) CreateBucket(key []byte) (*Bucket, error) {
 		return nil, ErrBucketNameRequired
 	}
 
+	// Insert into node.
+	// Tip: Use a new variable `newKey` instead of reusing the existing `key` to prevent
+	// it from being marked as leaking, and accordingly cannot be allocated on stack.
+	newKey := cloneBytes(key)
+
 	// Move cursor to correct position.
 	c := b.Cursor()
-	k, _, flags := c.seek(key)
+	k, _, flags := c.seek(newKey)
 
 	// Return an error if there is an existing key.
-	if bytes.Equal(key, k) {
+	if bytes.Equal(newKey, k) {
 		if (flags & bucketLeafFlag) != 0 {
 			return nil, ErrBucketExists
 		}
@@ -182,16 +187,14 @@ func (b *Bucket) CreateBucket(key []byte) (*Bucket, error) {
 	}
 	var value = bucket.write()
 
-	// Insert into node.
-	key = cloneBytes(key)
-	c.node().put(key, key, value, 0, bucketLeafFlag)
+	c.node().put(newKey, newKey, value, 0, bucketLeafFlag)
 
 	// Since subbuckets are not allowed on inline buckets, we need to
 	// dereference the inline page, if it exists. This will cause the bucket
 	// to be treated as a regular, non-inline bucket for the rest of the tx.
 	b.page = nil
 
-	return b.Bucket(key), nil
+	return b.Bucket(newKey), nil
 }
 
 // CreateBucketIfNotExists creates a new bucket if it doesn't already exist and returns a reference to it.
@@ -288,18 +291,23 @@ func (b *Bucket) Put(key []byte, value []byte) error {
 		return ErrValueTooLarge
 	}
 
+	// Insert into node.
+	// Tip: Use a new variable `newKey` instead of reusing the existing `key` to prevent
+	// it from being marked as leaking, and accordingly cannot be allocated on stack.
+	newKey := cloneBytes(key)
+
 	// Move cursor to correct position.
 	c := b.Cursor()
-	k, _, flags := c.seek(key)
+	k, _, flags := c.seek(newKey)
 
 	// Return an error if there is an existing key with a bucket value.
-	if bytes.Equal(key, k) && (flags&bucketLeafFlag) != 0 {
+	if bytes.Equal(newKey, k) && (flags&bucketLeafFlag) != 0 {
 		return ErrIncompatibleValue
 	}
 
-	// Insert into node.
-	key = cloneBytes(key)
-	c.node().put(key, key, value, 0, 0)
+	// gofail: var beforeBucketPut struct{}
+
+	c.node().put(newKey, newKey, value, 0, 0)
 
 	return nil
 }
diff --git a/vendor/go.etcd.io/bbolt/cursor.go b/vendor/go.etcd.io/bbolt/cursor.go
index 5dafb0ca..bbfd92a9 100644
--- a/vendor/go.etcd.io/bbolt/cursor.go
+++ b/vendor/go.etcd.io/bbolt/cursor.go
@@ -71,7 +71,7 @@ func (c *Cursor) Last() (key []byte, value []byte) {
 
 	// If this is an empty page (calling Delete may result in empty pages)
 	// we call prev to find the last page that is not empty
-	for len(c.stack) > 0 && c.stack[len(c.stack)-1].count() == 0 {
+	for len(c.stack) > 1 && c.stack[len(c.stack)-1].count() == 0 {
 		c.prev()
 	}
 
@@ -254,6 +254,15 @@ func (c *Cursor) prev() (key []byte, value []byte, flags uint32) {
 			elem.index--
 			break
 		}
+		// If we've hit the beginning, we should stop moving the cursor,
+		// and stay at the first element, so that users can continue to
+		// iterate over the elements in reverse direction by calling `Next`.
+		// We should return nil in such case.
+		// Refer to https://github.com/etcd-io/bbolt/issues/733
+		if len(c.stack) == 1 {
+			c.first()
+			return nil, nil, 0
+		}
 		c.stack = c.stack[:i]
 	}
 
diff --git a/vendor/go.etcd.io/bbolt/db.go b/vendor/go.etcd.io/bbolt/db.go
index c9422127..4175bdf3 100644
--- a/vendor/go.etcd.io/bbolt/db.go
+++ b/vendor/go.etcd.io/bbolt/db.go
@@ -57,6 +57,12 @@ const (
 // All data access is performed through transactions which can be obtained through the DB.
 // All the functions on DB will return a ErrDatabaseNotOpen if accessed before Open() is called.
 type DB struct {
+	// Put `stats` at the first field to ensure it's 64-bit aligned. Note that
+	// the first word in an allocated struct can be relied upon to be 64-bit
+	// aligned. Refer to https://pkg.go.dev/sync/atomic#pkg-note-BUG. Also
+	// refer to discussion in https://github.com/etcd-io/bbolt/issues/577.
+	stats Stats
+
 	// When enabled, the database will perform a Check() after every commit.
 	// A panic is issued if the database is in an inconsistent state. This
 	// flag has a large performance impact so it should only be used for
@@ -147,7 +153,6 @@ type DB struct {
 	opened   bool
 	rwtx     *Tx
 	txs      []*Tx
-	stats    Stats
 
 	freelist     *freelist
 	freelistLoad sync.Once
@@ -424,7 +429,7 @@ func (db *DB) hasSyncedFreelist() bool {
 
 // mmap opens the underlying memory-mapped file and initializes the meta references.
 // minsz is the minimum size that the new mmap can be.
-func (db *DB) mmap(minsz int) error {
+func (db *DB) mmap(minsz int) (err error) {
 	db.mmaplock.Lock()
 	defer db.mmaplock.Unlock()
 
@@ -459,17 +464,27 @@ func (db *DB) mmap(minsz int) error {
 	}
 
 	// Unmap existing data before continuing.
-	if err := db.munmap(); err != nil {
+	if err = db.munmap(); err != nil {
 		return err
 	}
 
 	// Memory-map the data file as a byte slice.
 	// gofail: var mapError string
 	// return errors.New(mapError)
-	if err := mmap(db, size); err != nil {
+	if err = mmap(db, size); err != nil {
 		return err
 	}
 
+	// Perform unmmap on any error to reset all data fields:
+	// dataref, data, datasz, meta0 and meta1.
+	defer func() {
+		if err != nil {
+			if unmapErr := db.munmap(); unmapErr != nil {
+				err = fmt.Errorf("%w; rollback unmap also failed: %v", err, unmapErr)
+			}
+		}
+	}()
+
 	if db.Mlock {
 		// Don't allow swapping of data file
 		if err := db.mlock(fileSize); err != nil {
@@ -553,6 +568,8 @@ func (db *DB) mmapSize(size int) (int, error) {
 }
 
 func (db *DB) munlock(fileSize int) error {
+	// gofail: var munlockError string
+	// return errors.New(munlockError)
 	if err := munlock(db, fileSize); err != nil {
 		return fmt.Errorf("munlock error: " + err.Error())
 	}
@@ -560,6 +577,8 @@ func (db *DB) munlock(fileSize int) error {
 }
 
 func (db *DB) mlock(fileSize int) error {
+	// gofail: var mlockError string
+	// return errors.New(mlockError)
 	if err := mlock(db, fileSize); err != nil {
 		return fmt.Errorf("mlock error: " + err.Error())
 	}
@@ -649,9 +668,10 @@ func (db *DB) close() error {
 	// Clear ops.
 	db.ops.writeAt = nil
 
+	var errs []error
 	// Close the mmap.
 	if err := db.munmap(); err != nil {
-		return err
+		errs = append(errs, err)
 	}
 
 	// Close file handles.
@@ -660,18 +680,22 @@ func (db *DB) close() error {
 		if !db.readOnly {
 			// Unlock the file.
 			if err := funlock(db); err != nil {
-				return fmt.Errorf("bolt.Close(): funlock error: %w", err)
+				errs = append(errs, fmt.Errorf("bolt.Close(): funlock error: %w", err))
 			}
 		}
 
 		// Close the file descriptor.
 		if err := db.file.Close(); err != nil {
-			return fmt.Errorf("db file close: %s", err)
+			errs = append(errs, fmt.Errorf("db file close: %w", err))
 		}
 		db.file = nil
 	}
 
 	db.path = ""
+
+	if len(errs) > 0 {
+		return errs[0]
+	}
 	return nil
 }
 
@@ -1263,6 +1287,12 @@ var DefaultOptions = &Options{
 
 // Stats represents statistics about the database.
 type Stats struct {
+	// Put `TxStats` at the first field to ensure it's 64-bit aligned. Note
+	// that the first word in an allocated struct can be relied upon to be
+	// 64-bit aligned. Refer to https://pkg.go.dev/sync/atomic#pkg-note-BUG.
+	// Also refer to discussion in https://github.com/etcd-io/bbolt/issues/577.
+	TxStats TxStats // global, ongoing stats.
+
 	// Freelist stats
 	FreePageN     int // total number of free pages on the freelist
 	PendingPageN  int // total number of pending pages on the freelist
@@ -1272,8 +1302,6 @@ type Stats struct {
 	// Transaction stats
 	TxN     int // total number of started read transactions
 	OpenTxN int // number of currently open read transactions
-
-	TxStats TxStats // global, ongoing stats.
 }
 
 // Sub calculates and returns the difference between two sets of database stats.
diff --git a/vendor/go.etcd.io/bbolt/freelist.go b/vendor/go.etcd.io/bbolt/freelist.go
index 50f2d0e1..61d43f81 100644
--- a/vendor/go.etcd.io/bbolt/freelist.go
+++ b/vendor/go.etcd.io/bbolt/freelist.go
@@ -282,9 +282,8 @@ func (f *freelist) read(p *page) {
 	if count == 0 {
 		f.ids = nil
 	} else {
-		var ids []pgid
-		data := unsafeIndex(unsafe.Pointer(p), unsafe.Sizeof(*p), unsafe.Sizeof(ids[0]), idx)
-		unsafeSlice(unsafe.Pointer(&ids), data, count)
+		data := unsafeIndex(unsafe.Pointer(p), unsafe.Sizeof(*p), unsafe.Sizeof(pgid(0)), idx)
+		ids := unsafe.Slice((*pgid)(data), count)
 
 		// copy the ids, so we don't modify on the freelist page directly
 		idsCopy := make([]pgid, count)
@@ -322,15 +321,13 @@ func (f *freelist) write(p *page) error {
 		p.count = uint16(l)
 	} else if l < 0xFFFF {
 		p.count = uint16(l)
-		var ids []pgid
 		data := unsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p))
-		unsafeSlice(unsafe.Pointer(&ids), data, l)
+		ids := unsafe.Slice((*pgid)(data), l)
 		f.copyall(ids)
 	} else {
 		p.count = 0xFFFF
-		var ids []pgid
 		data := unsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p))
-		unsafeSlice(unsafe.Pointer(&ids), data, l+1)
+		ids := unsafe.Slice((*pgid)(data), l+1)
 		ids[0] = pgid(l)
 		f.copyall(ids[1:])
 	}
diff --git a/vendor/go.etcd.io/bbolt/page.go b/vendor/go.etcd.io/bbolt/page.go
index 379645c9..bb081b03 100644
--- a/vendor/go.etcd.io/bbolt/page.go
+++ b/vendor/go.etcd.io/bbolt/page.go
@@ -74,9 +74,8 @@ func (p *page) leafPageElements() []leafPageElement {
 	if p.count == 0 {
 		return nil
 	}
-	var elems []leafPageElement
 	data := unsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p))
-	unsafeSlice(unsafe.Pointer(&elems), data, int(p.count))
+	elems := unsafe.Slice((*leafPageElement)(data), int(p.count))
 	return elems
 }
 
@@ -91,9 +90,8 @@ func (p *page) branchPageElements() []branchPageElement {
 	if p.count == 0 {
 		return nil
 	}
-	var elems []branchPageElement
 	data := unsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p))
-	unsafeSlice(unsafe.Pointer(&elems), data, int(p.count))
+	elems := unsafe.Slice((*branchPageElement)(data), int(p.count))
 	return elems
 }
 
diff --git a/vendor/go.etcd.io/bbolt/unsafe.go b/vendor/go.etcd.io/bbolt/unsafe.go
index c0e50375..7745d32c 100644
--- a/vendor/go.etcd.io/bbolt/unsafe.go
+++ b/vendor/go.etcd.io/bbolt/unsafe.go
@@ -1,7 +1,6 @@
 package bbolt
 
 import (
-	"reflect"
 	"unsafe"
 )
 
@@ -26,14 +25,3 @@ func unsafeByteSlice(base unsafe.Pointer, offset uintptr, i, j int) []byte {
 	// all), so this is believed to be correct.
 	return (*[maxAllocSize]byte)(unsafeAdd(base, offset))[i:j:j]
 }
-
-// unsafeSlice modifies the data, len, and cap of a slice variable pointed to by
-// the slice parameter.  This helper should be used over other direct
-// manipulation of reflect.SliceHeader to prevent misuse, namely, converting
-// from reflect.SliceHeader to a Go slice type.
-func unsafeSlice(slice, data unsafe.Pointer, len int) {
-	s := (*reflect.SliceHeader)(slice)
-	s.Data = uintptr(data)
-	s.Cap = len
-	s.Len = len
-}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go
index 4e24f9ee..652aa48b 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/array_codec.go
@@ -14,17 +14,22 @@ import (
 )
 
 // ArrayCodec is the Codec used for bsoncore.Array values.
+//
+// Deprecated: ArrayCodec will not be directly accessible in Go Driver 2.0.
 type ArrayCodec struct{}
 
 var defaultArrayCodec = NewArrayCodec()
 
 // NewArrayCodec returns an ArrayCodec.
+//
+// Deprecated: NewArrayCodec will not be available in Go Driver 2.0. See
+// [ArrayCodec] for more details.
 func NewArrayCodec() *ArrayCodec {
 	return &ArrayCodec{}
 }
 
 // EncodeValue is the ValueEncoder for bsoncore.Array values.
-func (ac *ArrayCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (ac *ArrayCodec) EncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tCoreArray {
 		return ValueEncoderError{Name: "CoreArrayEncodeValue", Types: []reflect.Type{tCoreArray}, Received: val}
 	}
@@ -34,7 +39,7 @@ func (ac *ArrayCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val r
 }
 
 // DecodeValue is the ValueDecoder for bsoncore.Array values.
-func (ac *ArrayCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+func (ac *ArrayCodec) DecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tCoreArray {
 		return ValueDecoderError{Name: "CoreArrayDecodeValue", Types: []reflect.Type{tCoreArray}, Received: val}
 	}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go
index 098ed69f..0693bd43 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go
@@ -23,6 +23,8 @@ var (
 // Marshaler is an interface implemented by types that can marshal themselves
 // into a BSON document represented as bytes. The bytes returned must be a valid
 // BSON document if the error is nil.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Marshaler] instead.
 type Marshaler interface {
 	MarshalBSON() ([]byte, error)
 }
@@ -31,6 +33,8 @@ type Marshaler interface {
 // themselves into a BSON value as bytes. The type must be the valid type for
 // the bytes returned. The bytes and byte type together must be valid if the
 // error is nil.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.ValueMarshaler] instead.
 type ValueMarshaler interface {
 	MarshalBSONValue() (bsontype.Type, []byte, error)
 }
@@ -39,6 +43,8 @@ type ValueMarshaler interface {
 // document representation of themselves. The BSON bytes can be assumed to be
 // valid. UnmarshalBSON must copy the BSON bytes if it wishes to retain the data
 // after returning.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Unmarshaler] instead.
 type Unmarshaler interface {
 	UnmarshalBSON([]byte) error
 }
@@ -47,6 +53,8 @@ type Unmarshaler interface {
 // BSON value representation of themselves. The BSON bytes and type can be
 // assumed to be valid. UnmarshalBSONValue must copy the BSON value bytes if it
 // wishes to retain the data after returning.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.ValueUnmarshaler] instead.
 type ValueUnmarshaler interface {
 	UnmarshalBSONValue(bsontype.Type, []byte) error
 }
@@ -111,13 +119,93 @@ func (vde ValueDecoderError) Error() string {
 // value.
 type EncodeContext struct {
 	*Registry
+
+	// MinSize causes the Encoder to marshal Go integer values (int, int8, int16, int32, int64,
+	// uint, uint8, uint16, uint32, or uint64) as the minimum BSON int size (either 32 or 64 bits)
+	// that can represent the integer value.
+	//
+	// Deprecated: Use bson.Encoder.IntMinSize instead.
 	MinSize bool
+
+	errorOnInlineDuplicates bool
+	stringifyMapKeysWithFmt bool
+	nilMapAsEmpty           bool
+	nilSliceAsEmpty         bool
+	nilByteSliceAsEmpty     bool
+	omitZeroStruct          bool
+	useJSONStructTags       bool
+}
+
+// ErrorOnInlineDuplicates causes the Encoder to return an error if there is a duplicate field in
+// the marshaled BSON when the "inline" struct tag option is set.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.ErrorOnInlineDuplicates] instead.
+func (ec *EncodeContext) ErrorOnInlineDuplicates() {
+	ec.errorOnInlineDuplicates = true
+}
+
+// StringifyMapKeysWithFmt causes the Encoder to convert Go map keys to BSON document field name
+// strings using fmt.Sprintf() instead of the default string conversion logic.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.StringifyMapKeysWithFmt] instead.
+func (ec *EncodeContext) StringifyMapKeysWithFmt() {
+	ec.stringifyMapKeysWithFmt = true
+}
+
+// NilMapAsEmpty causes the Encoder to marshal nil Go maps as empty BSON documents instead of BSON
+// null.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilMapAsEmpty] instead.
+func (ec *EncodeContext) NilMapAsEmpty() {
+	ec.nilMapAsEmpty = true
+}
+
+// NilSliceAsEmpty causes the Encoder to marshal nil Go slices as empty BSON arrays instead of BSON
+// null.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilSliceAsEmpty] instead.
+func (ec *EncodeContext) NilSliceAsEmpty() {
+	ec.nilSliceAsEmpty = true
+}
+
+// NilByteSliceAsEmpty causes the Encoder to marshal nil Go byte slices as empty BSON binary values
+// instead of BSON null.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilByteSliceAsEmpty] instead.
+func (ec *EncodeContext) NilByteSliceAsEmpty() {
+	ec.nilByteSliceAsEmpty = true
+}
+
+// OmitZeroStruct causes the Encoder to consider the zero value for a struct (e.g. MyStruct{})
+// as empty and omit it from the marshaled BSON when the "omitempty" struct tag option is set.
+//
+// Note that the Encoder only examines exported struct fields when determining if a struct is the
+// zero value. It considers pointers to a zero struct value (e.g. &MyStruct{}) not empty.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.OmitZeroStruct] instead.
+func (ec *EncodeContext) OmitZeroStruct() {
+	ec.omitZeroStruct = true
+}
+
+// UseJSONStructTags causes the Encoder to fall back to using the "json" struct tag if a "bson"
+// struct tag is not specified.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.UseJSONStructTags] instead.
+func (ec *EncodeContext) UseJSONStructTags() {
+	ec.useJSONStructTags = true
 }
 
 // DecodeContext is the contextual information required for a Codec to decode a
 // value.
 type DecodeContext struct {
 	*Registry
+
+	// Truncate, if true, instructs decoders to to truncate the fractional part of BSON "double"
+	// values when attempting to unmarshal them into a Go integer (int, int8, int16, int32, int64,
+	// uint, uint8, uint16, uint32, or uint64) struct field. The truncation logic does not apply to
+	// BSON "decimal128" values.
+	//
+	// Deprecated: Use bson.Decoder.AllowTruncatingDoubles instead.
 	Truncate bool
 
 	// Ancestor is the type of a containing document. This is mainly used to determine what type
@@ -125,7 +213,7 @@ type DecodeContext struct {
 	// Ancestor is a bson.M, BSON embedded document values being decoded into an empty interface
 	// will be decoded into a bson.M.
 	//
-	// Deprecated: Use DefaultDocumentM or DefaultDocumentD instead.
+	// Deprecated: Use bson.Decoder.DefaultDocumentM or bson.Decoder.DefaultDocumentD instead.
 	Ancestor reflect.Type
 
 	// defaultDocumentType specifies the Go type to decode top-level and nested BSON documents into. In particular, the
@@ -133,22 +221,74 @@ type DecodeContext struct {
 	// set to a type that a BSON document cannot be unmarshaled into (e.g. "string"), unmarshalling will result in an
 	// error. DocumentType overrides the Ancestor field.
 	defaultDocumentType reflect.Type
+
+	binaryAsSlice     bool
+	useJSONStructTags bool
+	useLocalTimeZone  bool
+	zeroMaps          bool
+	zeroStructs       bool
 }
 
-// DefaultDocumentM will decode empty documents using the primitive.M type. This behavior is restricted to data typed as
-// "interface{}" or "map[string]interface{}".
+// BinaryAsSlice causes the Decoder to unmarshal BSON binary field values that are the "Generic" or
+// "Old" BSON binary subtype as a Go byte slice instead of a primitive.Binary.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.BinaryAsSlice] instead.
+func (dc *DecodeContext) BinaryAsSlice() {
+	dc.binaryAsSlice = true
+}
+
+// UseJSONStructTags causes the Decoder to fall back to using the "json" struct tag if a "bson"
+// struct tag is not specified.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.UseJSONStructTags] instead.
+func (dc *DecodeContext) UseJSONStructTags() {
+	dc.useJSONStructTags = true
+}
+
+// UseLocalTimeZone causes the Decoder to unmarshal time.Time values in the local timezone instead
+// of the UTC timezone.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.UseLocalTimeZone] instead.
+func (dc *DecodeContext) UseLocalTimeZone() {
+	dc.useLocalTimeZone = true
+}
+
+// ZeroMaps causes the Decoder to delete any existing values from Go maps in the destination value
+// passed to Decode before unmarshaling BSON documents into them.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.ZeroMaps] instead.
+func (dc *DecodeContext) ZeroMaps() {
+	dc.zeroMaps = true
+}
+
+// ZeroStructs causes the Decoder to delete any existing values from Go structs in the destination
+// value passed to Decode before unmarshaling BSON documents into them.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.ZeroStructs] instead.
+func (dc *DecodeContext) ZeroStructs() {
+	dc.zeroStructs = true
+}
+
+// DefaultDocumentM causes the Decoder to always unmarshal documents into the primitive.M type. This
+// behavior is restricted to data typed as "interface{}" or "map[string]interface{}".
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.DefaultDocumentM] instead.
 func (dc *DecodeContext) DefaultDocumentM() {
 	dc.defaultDocumentType = reflect.TypeOf(primitive.M{})
 }
 
-// DefaultDocumentD will decode empty documents using the primitive.D type. This behavior is restricted to data typed as
-// "interface{}" or "map[string]interface{}".
+// DefaultDocumentD causes the Decoder to always unmarshal documents into the primitive.D type. This
+// behavior is restricted to data typed as "interface{}" or "map[string]interface{}".
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.DefaultDocumentD] instead.
 func (dc *DecodeContext) DefaultDocumentD() {
 	dc.defaultDocumentType = reflect.TypeOf(primitive.D{})
 }
 
-// ValueCodec is the interface that groups the methods to encode and decode
+// ValueCodec is an interface for encoding and decoding a reflect.Value.
 // values.
+//
+// Deprecated: Use [ValueEncoder] and [ValueDecoder] instead.
 type ValueCodec interface {
 	ValueEncoder
 	ValueDecoder
@@ -233,6 +373,10 @@ func decodeTypeOrValueWithInfo(vd ValueDecoder, td typeDecoder, dc DecodeContext
 
 // CodecZeroer is the interface implemented by Codecs that can also determine if
 // a value of the type that would be encoded is zero.
+//
+// Deprecated: Defining custom rules for the zero/empty value will not be supported in Go Driver
+// 2.0. Users who want to omit empty complex values should use a pointer field and set the value to
+// nil instead.
 type CodecZeroer interface {
 	IsTypeZero(interface{}) bool
 }
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go
index 5a916cc1..0134b5a9 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go
@@ -16,18 +16,45 @@ import (
 )
 
 // ByteSliceCodec is the Codec used for []byte values.
+//
+// Deprecated: ByteSliceCodec will not be directly configurable in Go Driver
+// 2.0. To configure the byte slice encode and decode behavior, use the
+// configuration methods on a [go.mongodb.org/mongo-driver/bson.Encoder] or
+// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the byte slice
+// encode and decode behavior for a mongo.Client, use
+// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions].
+//
+// For example, to configure a mongo.Client to encode nil byte slices as empty
+// BSON binary values, use:
+//
+//	opt := options.Client().SetBSONOptions(&options.BSONOptions{
+//	    NilByteSliceAsEmpty: true,
+//	})
+//
+// See the deprecation notice for each field in ByteSliceCodec for the
+// corresponding settings.
 type ByteSliceCodec struct {
+	// EncodeNilAsEmpty causes EncodeValue to marshal nil Go byte slices as empty BSON binary values
+	// instead of BSON null.
+	//
+	// Deprecated: Use bson.Encoder.NilByteSliceAsEmpty or options.BSONOptions.NilByteSliceAsEmpty
+	// instead.
 	EncodeNilAsEmpty bool
 }
 
 var (
 	defaultByteSliceCodec = NewByteSliceCodec()
 
-	_ ValueCodec  = defaultByteSliceCodec
+	// Assert that defaultByteSliceCodec satisfies the typeDecoder interface, which allows it to be
+	// used by collection type decoders (e.g. map, slice, etc) to set individual values in a
+	// collection.
 	_ typeDecoder = defaultByteSliceCodec
 )
 
-// NewByteSliceCodec returns a StringCodec with options opts.
+// NewByteSliceCodec returns a ByteSliceCodec with options opts.
+//
+// Deprecated: NewByteSliceCodec will not be available in Go Driver 2.0. See
+// [ByteSliceCodec] for more details.
 func NewByteSliceCodec(opts ...*bsonoptions.ByteSliceCodecOptions) *ByteSliceCodec {
 	byteSliceOpt := bsonoptions.MergeByteSliceCodecOptions(opts...)
 	codec := ByteSliceCodec{}
@@ -42,13 +69,13 @@ func (bsc *ByteSliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter,
 	if !val.IsValid() || val.Type() != tByteSlice {
 		return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
 	}
-	if val.IsNil() && !bsc.EncodeNilAsEmpty {
+	if val.IsNil() && !bsc.EncodeNilAsEmpty && !ec.nilByteSliceAsEmpty {
 		return vw.WriteNull()
 	}
 	return vw.WriteBinary(val.Interface().([]byte))
 }
 
-func (bsc *ByteSliceCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (bsc *ByteSliceCodec) decodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tByteSlice {
 		return emptyValue, ValueDecoderError{
 			Name:     "ByteSliceDecodeValue",
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/codec_cache.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/codec_cache.go
new file mode 100644
index 00000000..844b5029
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/codec_cache.go
@@ -0,0 +1,166 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// 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
+
+package bsoncodec
+
+import (
+	"reflect"
+	"sync"
+	"sync/atomic"
+)
+
+// Runtime check that the kind encoder and decoder caches can store any valid
+// reflect.Kind constant.
+func init() {
+	if s := reflect.Kind(len(kindEncoderCache{}.entries)).String(); s != "kind27" {
+		panic("The capacity of kindEncoderCache is too small.\n" +
+			"This is due to a new type being added to reflect.Kind.")
+	}
+}
+
+// statically assert array size
+var _ = (kindEncoderCache{}).entries[reflect.UnsafePointer]
+var _ = (kindDecoderCache{}).entries[reflect.UnsafePointer]
+
+type typeEncoderCache struct {
+	cache sync.Map // map[reflect.Type]ValueEncoder
+}
+
+func (c *typeEncoderCache) Store(rt reflect.Type, enc ValueEncoder) {
+	c.cache.Store(rt, enc)
+}
+
+func (c *typeEncoderCache) Load(rt reflect.Type) (ValueEncoder, bool) {
+	if v, _ := c.cache.Load(rt); v != nil {
+		return v.(ValueEncoder), true
+	}
+	return nil, false
+}
+
+func (c *typeEncoderCache) LoadOrStore(rt reflect.Type, enc ValueEncoder) ValueEncoder {
+	if v, loaded := c.cache.LoadOrStore(rt, enc); loaded {
+		enc = v.(ValueEncoder)
+	}
+	return enc
+}
+
+func (c *typeEncoderCache) Clone() *typeEncoderCache {
+	cc := new(typeEncoderCache)
+	c.cache.Range(func(k, v interface{}) bool {
+		if k != nil && v != nil {
+			cc.cache.Store(k, v)
+		}
+		return true
+	})
+	return cc
+}
+
+type typeDecoderCache struct {
+	cache sync.Map // map[reflect.Type]ValueDecoder
+}
+
+func (c *typeDecoderCache) Store(rt reflect.Type, dec ValueDecoder) {
+	c.cache.Store(rt, dec)
+}
+
+func (c *typeDecoderCache) Load(rt reflect.Type) (ValueDecoder, bool) {
+	if v, _ := c.cache.Load(rt); v != nil {
+		return v.(ValueDecoder), true
+	}
+	return nil, false
+}
+
+func (c *typeDecoderCache) LoadOrStore(rt reflect.Type, dec ValueDecoder) ValueDecoder {
+	if v, loaded := c.cache.LoadOrStore(rt, dec); loaded {
+		dec = v.(ValueDecoder)
+	}
+	return dec
+}
+
+func (c *typeDecoderCache) Clone() *typeDecoderCache {
+	cc := new(typeDecoderCache)
+	c.cache.Range(func(k, v interface{}) bool {
+		if k != nil && v != nil {
+			cc.cache.Store(k, v)
+		}
+		return true
+	})
+	return cc
+}
+
+// atomic.Value requires that all calls to Store() have the same concrete type
+// so we wrap the ValueEncoder with a kindEncoderCacheEntry to ensure the type
+// is always the same (since different concrete types may implement the
+// ValueEncoder interface).
+type kindEncoderCacheEntry struct {
+	enc ValueEncoder
+}
+
+type kindEncoderCache struct {
+	entries [reflect.UnsafePointer + 1]atomic.Value // *kindEncoderCacheEntry
+}
+
+func (c *kindEncoderCache) Store(rt reflect.Kind, enc ValueEncoder) {
+	if enc != nil && rt < reflect.Kind(len(c.entries)) {
+		c.entries[rt].Store(&kindEncoderCacheEntry{enc: enc})
+	}
+}
+
+func (c *kindEncoderCache) Load(rt reflect.Kind) (ValueEncoder, bool) {
+	if rt < reflect.Kind(len(c.entries)) {
+		if ent, ok := c.entries[rt].Load().(*kindEncoderCacheEntry); ok {
+			return ent.enc, ent.enc != nil
+		}
+	}
+	return nil, false
+}
+
+func (c *kindEncoderCache) Clone() *kindEncoderCache {
+	cc := new(kindEncoderCache)
+	for i, v := range c.entries {
+		if val := v.Load(); val != nil {
+			cc.entries[i].Store(val)
+		}
+	}
+	return cc
+}
+
+// atomic.Value requires that all calls to Store() have the same concrete type
+// so we wrap the ValueDecoder with a kindDecoderCacheEntry to ensure the type
+// is always the same (since different concrete types may implement the
+// ValueDecoder interface).
+type kindDecoderCacheEntry struct {
+	dec ValueDecoder
+}
+
+type kindDecoderCache struct {
+	entries [reflect.UnsafePointer + 1]atomic.Value // *kindDecoderCacheEntry
+}
+
+func (c *kindDecoderCache) Store(rt reflect.Kind, dec ValueDecoder) {
+	if rt < reflect.Kind(len(c.entries)) {
+		c.entries[rt].Store(&kindDecoderCacheEntry{dec: dec})
+	}
+}
+
+func (c *kindDecoderCache) Load(rt reflect.Kind) (ValueDecoder, bool) {
+	if rt < reflect.Kind(len(c.entries)) {
+		if ent, ok := c.entries[rt].Load().(*kindDecoderCacheEntry); ok {
+			return ent.dec, ent.dec != nil
+		}
+	}
+	return nil, false
+}
+
+func (c *kindDecoderCache) Clone() *kindDecoderCache {
+	cc := new(kindDecoderCache)
+	for i, v := range c.entries {
+		if val := v.Load(); val != nil {
+			cc.entries[i].Store(val)
+		}
+	}
+	return cc
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go
index e95cab58..fc4a7b1d 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go
@@ -24,7 +24,7 @@ import (
 
 var (
 	defaultValueDecoders DefaultValueDecoders
-	errCannotTruncate    = errors.New("float64 can only be truncated to an integer type when truncation is enabled")
+	errCannotTruncate    = errors.New("float64 can only be truncated to a lower precision type when truncation is enabled")
 )
 
 type decodeBinaryError struct {
@@ -41,13 +41,16 @@ func newDefaultStructCodec() *StructCodec {
 	if err != nil {
 		// This function is called from the codec registration path, so errors can't be propagated. If there's an error
 		// constructing the StructCodec, we panic to avoid losing it.
-		panic(fmt.Errorf("error creating default StructCodec: %v", err))
+		panic(fmt.Errorf("error creating default StructCodec: %w", err))
 	}
 	return codec
 }
 
 // DefaultValueDecoders is a namespace type for the default ValueDecoders used
 // when creating a registry.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 type DefaultValueDecoders struct{}
 
 // RegisterDefaultDecoders will register the decoder methods attached to DefaultValueDecoders with
@@ -56,6 +59,9 @@ type DefaultValueDecoders struct{}
 // There is no support for decoding map[string]interface{} because there is no decoder for
 // interface{}, so users must either register this decoder themselves or use the
 // EmptyInterfaceDecoder available in the bson package.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) RegisterDefaultDecoders(rb *RegistryBuilder) {
 	if rb == nil {
 		panic(errors.New("argument to RegisterDefaultDecoders must not be nil"))
@@ -132,6 +138,9 @@ func (dvd DefaultValueDecoders) RegisterDefaultDecoders(rb *RegistryBuilder) {
 }
 
 // DDecodeValue is the ValueDecoderFunc for primitive.D instances.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) DDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.IsValid() || !val.CanSet() || val.Type() != tD {
 		return ValueDecoderError{Name: "DDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
@@ -169,7 +178,7 @@ func (dvd DefaultValueDecoders) DDecodeValue(dc DecodeContext, vr bsonrw.ValueRe
 
 	for {
 		key, elemVr, err := dr.ReadElement()
-		if err == bsonrw.ErrEOD {
+		if errors.Is(err, bsonrw.ErrEOD) {
 			break
 		} else if err != nil {
 			return err
@@ -188,7 +197,7 @@ func (dvd DefaultValueDecoders) DDecodeValue(dc DecodeContext, vr bsonrw.ValueRe
 	return nil
 }
 
-func (dvd DefaultValueDecoders) booleanDecodeType(dctx DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (dvd DefaultValueDecoders) booleanDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t.Kind() != reflect.Bool {
 		return emptyValue, ValueDecoderError{
 			Name:     "BooleanDecodeValue",
@@ -235,6 +244,9 @@ func (dvd DefaultValueDecoders) booleanDecodeType(dctx DecodeContext, vr bsonrw.
 }
 
 // BooleanDecodeValue is the ValueDecoderFunc for bool types.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) BooleanDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.IsValid() || !val.CanSet() || val.Kind() != reflect.Bool {
 		return ValueDecoderError{Name: "BooleanDecodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val}
@@ -318,7 +330,7 @@ func (DefaultValueDecoders) intDecodeType(dc DecodeContext, vr bsonrw.ValueReade
 	case reflect.Int64:
 		return reflect.ValueOf(i64), nil
 	case reflect.Int:
-		if int64(int(i64)) != i64 { // Can we fit this inside of an int
+		if i64 > math.MaxInt { // Can we fit this inside of an int
 			return emptyValue, fmt.Errorf("%d overflows int", i64)
 		}
 
@@ -333,6 +345,9 @@ func (DefaultValueDecoders) intDecodeType(dc DecodeContext, vr bsonrw.ValueReade
 }
 
 // IntDecodeValue is the ValueDecoderFunc for int types.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) IntDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() {
 		return ValueDecoderError{
@@ -419,7 +434,7 @@ func (dvd DefaultValueDecoders) UintDecodeValue(dc DecodeContext, vr bsonrw.Valu
 			return fmt.Errorf("%d overflows uint64", i64)
 		}
 	case reflect.Uint:
-		if i64 < 0 || int64(uint(i64)) != i64 { // Can we fit this inside of an uint
+		if i64 < 0 || uint64(i64) > uint64(math.MaxUint) { // Can we fit this inside of an uint
 			return fmt.Errorf("%d overflows uint", i64)
 		}
 	default:
@@ -434,7 +449,7 @@ func (dvd DefaultValueDecoders) UintDecodeValue(dc DecodeContext, vr bsonrw.Valu
 	return nil
 }
 
-func (dvd DefaultValueDecoders) floatDecodeType(ec DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (dvd DefaultValueDecoders) floatDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	var f float64
 	var err error
 	switch vrType := vr.Type(); vrType {
@@ -477,7 +492,7 @@ func (dvd DefaultValueDecoders) floatDecodeType(ec DecodeContext, vr bsonrw.Valu
 
 	switch t.Kind() {
 	case reflect.Float32:
-		if !ec.Truncate && float64(float32(f)) != f {
+		if !dc.Truncate && float64(float32(f)) != f {
 			return emptyValue, errCannotTruncate
 		}
 
@@ -494,6 +509,9 @@ func (dvd DefaultValueDecoders) floatDecodeType(ec DecodeContext, vr bsonrw.Valu
 }
 
 // FloatDecodeValue is the ValueDecoderFunc for float types.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) FloatDecodeValue(ec DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() {
 		return ValueDecoderError{
@@ -515,7 +533,7 @@ func (dvd DefaultValueDecoders) FloatDecodeValue(ec DecodeContext, vr bsonrw.Val
 // StringDecodeValue is the ValueDecoderFunc for string types.
 //
 // Deprecated: StringDecodeValue is not registered by default. Use StringCodec.DecodeValue instead.
-func (dvd DefaultValueDecoders) StringDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+func (dvd DefaultValueDecoders) StringDecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	var str string
 	var err error
 	switch vr.Type() {
@@ -536,7 +554,7 @@ func (dvd DefaultValueDecoders) StringDecodeValue(dctx DecodeContext, vr bsonrw.
 	return nil
 }
 
-func (DefaultValueDecoders) javaScriptDecodeType(dctx DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (DefaultValueDecoders) javaScriptDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tJavaScript {
 		return emptyValue, ValueDecoderError{
 			Name:     "JavaScriptDecodeValue",
@@ -565,6 +583,9 @@ func (DefaultValueDecoders) javaScriptDecodeType(dctx DecodeContext, vr bsonrw.V
 }
 
 // JavaScriptDecodeValue is the ValueDecoderFunc for the primitive.JavaScript type.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) JavaScriptDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tJavaScript {
 		return ValueDecoderError{Name: "JavaScriptDecodeValue", Types: []reflect.Type{tJavaScript}, Received: val}
@@ -579,7 +600,7 @@ func (dvd DefaultValueDecoders) JavaScriptDecodeValue(dctx DecodeContext, vr bso
 	return nil
 }
 
-func (DefaultValueDecoders) symbolDecodeType(dctx DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (DefaultValueDecoders) symbolDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tSymbol {
 		return emptyValue, ValueDecoderError{
 			Name:     "SymbolDecodeValue",
@@ -620,6 +641,9 @@ func (DefaultValueDecoders) symbolDecodeType(dctx DecodeContext, vr bsonrw.Value
 }
 
 // SymbolDecodeValue is the ValueDecoderFunc for the primitive.Symbol type.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) SymbolDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tSymbol {
 		return ValueDecoderError{Name: "SymbolDecodeValue", Types: []reflect.Type{tSymbol}, Received: val}
@@ -634,7 +658,7 @@ func (dvd DefaultValueDecoders) SymbolDecodeValue(dctx DecodeContext, vr bsonrw.
 	return nil
 }
 
-func (DefaultValueDecoders) binaryDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (DefaultValueDecoders) binaryDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tBinary {
 		return emptyValue, ValueDecoderError{
 			Name:     "BinaryDecodeValue",
@@ -664,6 +688,9 @@ func (DefaultValueDecoders) binaryDecodeType(dc DecodeContext, vr bsonrw.ValueRe
 }
 
 // BinaryDecodeValue is the ValueDecoderFunc for Binary.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) BinaryDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tBinary {
 		return ValueDecoderError{Name: "BinaryDecodeValue", Types: []reflect.Type{tBinary}, Received: val}
@@ -678,7 +705,7 @@ func (dvd DefaultValueDecoders) BinaryDecodeValue(dc DecodeContext, vr bsonrw.Va
 	return nil
 }
 
-func (DefaultValueDecoders) undefinedDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (DefaultValueDecoders) undefinedDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tUndefined {
 		return emptyValue, ValueDecoderError{
 			Name:     "UndefinedDecodeValue",
@@ -704,6 +731,9 @@ func (DefaultValueDecoders) undefinedDecodeType(dc DecodeContext, vr bsonrw.Valu
 }
 
 // UndefinedDecodeValue is the ValueDecoderFunc for Undefined.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) UndefinedDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tUndefined {
 		return ValueDecoderError{Name: "UndefinedDecodeValue", Types: []reflect.Type{tUndefined}, Received: val}
@@ -719,7 +749,7 @@ func (dvd DefaultValueDecoders) UndefinedDecodeValue(dc DecodeContext, vr bsonrw
 }
 
 // Accept both 12-byte string and pretty-printed 24-byte hex string formats.
-func (dvd DefaultValueDecoders) objectIDDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (dvd DefaultValueDecoders) objectIDDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tOID {
 		return emptyValue, ValueDecoderError{
 			Name:     "ObjectIDDecodeValue",
@@ -765,6 +795,9 @@ func (dvd DefaultValueDecoders) objectIDDecodeType(dc DecodeContext, vr bsonrw.V
 }
 
 // ObjectIDDecodeValue is the ValueDecoderFunc for primitive.ObjectID.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) ObjectIDDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tOID {
 		return ValueDecoderError{Name: "ObjectIDDecodeValue", Types: []reflect.Type{tOID}, Received: val}
@@ -779,7 +812,7 @@ func (dvd DefaultValueDecoders) ObjectIDDecodeValue(dc DecodeContext, vr bsonrw.
 	return nil
 }
 
-func (DefaultValueDecoders) dateTimeDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (DefaultValueDecoders) dateTimeDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tDateTime {
 		return emptyValue, ValueDecoderError{
 			Name:     "DateTimeDecodeValue",
@@ -808,6 +841,9 @@ func (DefaultValueDecoders) dateTimeDecodeType(dc DecodeContext, vr bsonrw.Value
 }
 
 // DateTimeDecodeValue is the ValueDecoderFunc for DateTime.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) DateTimeDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tDateTime {
 		return ValueDecoderError{Name: "DateTimeDecodeValue", Types: []reflect.Type{tDateTime}, Received: val}
@@ -822,7 +858,7 @@ func (dvd DefaultValueDecoders) DateTimeDecodeValue(dc DecodeContext, vr bsonrw.
 	return nil
 }
 
-func (DefaultValueDecoders) nullDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (DefaultValueDecoders) nullDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tNull {
 		return emptyValue, ValueDecoderError{
 			Name:     "NullDecodeValue",
@@ -848,6 +884,9 @@ func (DefaultValueDecoders) nullDecodeType(dc DecodeContext, vr bsonrw.ValueRead
 }
 
 // NullDecodeValue is the ValueDecoderFunc for Null.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) NullDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tNull {
 		return ValueDecoderError{Name: "NullDecodeValue", Types: []reflect.Type{tNull}, Received: val}
@@ -862,7 +901,7 @@ func (dvd DefaultValueDecoders) NullDecodeValue(dc DecodeContext, vr bsonrw.Valu
 	return nil
 }
 
-func (DefaultValueDecoders) regexDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (DefaultValueDecoders) regexDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tRegex {
 		return emptyValue, ValueDecoderError{
 			Name:     "RegexDecodeValue",
@@ -891,6 +930,9 @@ func (DefaultValueDecoders) regexDecodeType(dc DecodeContext, vr bsonrw.ValueRea
 }
 
 // RegexDecodeValue is the ValueDecoderFunc for Regex.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) RegexDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tRegex {
 		return ValueDecoderError{Name: "RegexDecodeValue", Types: []reflect.Type{tRegex}, Received: val}
@@ -905,7 +947,7 @@ func (dvd DefaultValueDecoders) RegexDecodeValue(dc DecodeContext, vr bsonrw.Val
 	return nil
 }
 
-func (DefaultValueDecoders) dBPointerDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (DefaultValueDecoders) dBPointerDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tDBPointer {
 		return emptyValue, ValueDecoderError{
 			Name:     "DBPointerDecodeValue",
@@ -935,6 +977,9 @@ func (DefaultValueDecoders) dBPointerDecodeType(dc DecodeContext, vr bsonrw.Valu
 }
 
 // DBPointerDecodeValue is the ValueDecoderFunc for DBPointer.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) DBPointerDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tDBPointer {
 		return ValueDecoderError{Name: "DBPointerDecodeValue", Types: []reflect.Type{tDBPointer}, Received: val}
@@ -949,7 +994,7 @@ func (dvd DefaultValueDecoders) DBPointerDecodeValue(dc DecodeContext, vr bsonrw
 	return nil
 }
 
-func (DefaultValueDecoders) timestampDecodeType(dc DecodeContext, vr bsonrw.ValueReader, reflectType reflect.Type) (reflect.Value, error) {
+func (DefaultValueDecoders) timestampDecodeType(_ DecodeContext, vr bsonrw.ValueReader, reflectType reflect.Type) (reflect.Value, error) {
 	if reflectType != tTimestamp {
 		return emptyValue, ValueDecoderError{
 			Name:     "TimestampDecodeValue",
@@ -978,6 +1023,9 @@ func (DefaultValueDecoders) timestampDecodeType(dc DecodeContext, vr bsonrw.Valu
 }
 
 // TimestampDecodeValue is the ValueDecoderFunc for Timestamp.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) TimestampDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tTimestamp {
 		return ValueDecoderError{Name: "TimestampDecodeValue", Types: []reflect.Type{tTimestamp}, Received: val}
@@ -992,7 +1040,7 @@ func (dvd DefaultValueDecoders) TimestampDecodeValue(dc DecodeContext, vr bsonrw
 	return nil
 }
 
-func (DefaultValueDecoders) minKeyDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (DefaultValueDecoders) minKeyDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tMinKey {
 		return emptyValue, ValueDecoderError{
 			Name:     "MinKeyDecodeValue",
@@ -1020,6 +1068,9 @@ func (DefaultValueDecoders) minKeyDecodeType(dc DecodeContext, vr bsonrw.ValueRe
 }
 
 // MinKeyDecodeValue is the ValueDecoderFunc for MinKey.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) MinKeyDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tMinKey {
 		return ValueDecoderError{Name: "MinKeyDecodeValue", Types: []reflect.Type{tMinKey}, Received: val}
@@ -1034,7 +1085,7 @@ func (dvd DefaultValueDecoders) MinKeyDecodeValue(dc DecodeContext, vr bsonrw.Va
 	return nil
 }
 
-func (DefaultValueDecoders) maxKeyDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (DefaultValueDecoders) maxKeyDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tMaxKey {
 		return emptyValue, ValueDecoderError{
 			Name:     "MaxKeyDecodeValue",
@@ -1062,6 +1113,9 @@ func (DefaultValueDecoders) maxKeyDecodeType(dc DecodeContext, vr bsonrw.ValueRe
 }
 
 // MaxKeyDecodeValue is the ValueDecoderFunc for MaxKey.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) MaxKeyDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tMaxKey {
 		return ValueDecoderError{Name: "MaxKeyDecodeValue", Types: []reflect.Type{tMaxKey}, Received: val}
@@ -1076,7 +1130,7 @@ func (dvd DefaultValueDecoders) MaxKeyDecodeValue(dc DecodeContext, vr bsonrw.Va
 	return nil
 }
 
-func (dvd DefaultValueDecoders) decimal128DecodeType(dctx DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (dvd DefaultValueDecoders) decimal128DecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tDecimal {
 		return emptyValue, ValueDecoderError{
 			Name:     "Decimal128DecodeValue",
@@ -1105,6 +1159,9 @@ func (dvd DefaultValueDecoders) decimal128DecodeType(dctx DecodeContext, vr bson
 }
 
 // Decimal128DecodeValue is the ValueDecoderFunc for primitive.Decimal128.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) Decimal128DecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tDecimal {
 		return ValueDecoderError{Name: "Decimal128DecodeValue", Types: []reflect.Type{tDecimal}, Received: val}
@@ -1119,7 +1176,7 @@ func (dvd DefaultValueDecoders) Decimal128DecodeValue(dctx DecodeContext, vr bso
 	return nil
 }
 
-func (dvd DefaultValueDecoders) jsonNumberDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (dvd DefaultValueDecoders) jsonNumberDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tJSONNumber {
 		return emptyValue, ValueDecoderError{
 			Name:     "JSONNumberDecodeValue",
@@ -1164,6 +1221,9 @@ func (dvd DefaultValueDecoders) jsonNumberDecodeType(dc DecodeContext, vr bsonrw
 }
 
 // JSONNumberDecodeValue is the ValueDecoderFunc for json.Number.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) JSONNumberDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tJSONNumber {
 		return ValueDecoderError{Name: "JSONNumberDecodeValue", Types: []reflect.Type{tJSONNumber}, Received: val}
@@ -1178,7 +1238,7 @@ func (dvd DefaultValueDecoders) JSONNumberDecodeValue(dc DecodeContext, vr bsonr
 	return nil
 }
 
-func (dvd DefaultValueDecoders) urlDecodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (dvd DefaultValueDecoders) urlDecodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t != tURL {
 		return emptyValue, ValueDecoderError{
 			Name:     "URLDecodeValue",
@@ -1213,6 +1273,9 @@ func (dvd DefaultValueDecoders) urlDecodeType(dc DecodeContext, vr bsonrw.ValueR
 }
 
 // URLDecodeValue is the ValueDecoderFunc for url.URL.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) URLDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tURL {
 		return ValueDecoderError{Name: "URLDecodeValue", Types: []reflect.Type{tURL}, Received: val}
@@ -1230,7 +1293,7 @@ func (dvd DefaultValueDecoders) URLDecodeValue(dc DecodeContext, vr bsonrw.Value
 // TimeDecodeValue is the ValueDecoderFunc for time.Time.
 //
 // Deprecated: TimeDecodeValue is not registered by default. Use TimeCodec.DecodeValue instead.
-func (dvd DefaultValueDecoders) TimeDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+func (dvd DefaultValueDecoders) TimeDecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if vr.Type() != bsontype.DateTime {
 		return fmt.Errorf("cannot decode %v into a time.Time", vr.Type())
 	}
@@ -1251,7 +1314,7 @@ func (dvd DefaultValueDecoders) TimeDecodeValue(dc DecodeContext, vr bsonrw.Valu
 // ByteSliceDecodeValue is the ValueDecoderFunc for []byte.
 //
 // Deprecated: ByteSliceDecodeValue is not registered by default. Use ByteSliceCodec.DecodeValue instead.
-func (dvd DefaultValueDecoders) ByteSliceDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+func (dvd DefaultValueDecoders) ByteSliceDecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if vr.Type() != bsontype.Binary && vr.Type() != bsontype.Null {
 		return fmt.Errorf("cannot decode %v into a []byte", vr.Type())
 	}
@@ -1316,7 +1379,7 @@ func (dvd DefaultValueDecoders) MapDecodeValue(dc DecodeContext, vr bsonrw.Value
 	keyType := val.Type().Key()
 	for {
 		key, vr, err := dr.ReadElement()
-		if err == bsonrw.ErrEOD {
+		if errors.Is(err, bsonrw.ErrEOD) {
 			break
 		}
 		if err != nil {
@@ -1336,6 +1399,9 @@ func (dvd DefaultValueDecoders) MapDecodeValue(dc DecodeContext, vr bsonrw.Value
 }
 
 // ArrayDecodeValue is the ValueDecoderFunc for array types.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) ArrayDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.IsValid() || val.Kind() != reflect.Array {
 		return ValueDecoderError{Name: "ArrayDecodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val}
@@ -1447,7 +1513,10 @@ func (dvd DefaultValueDecoders) SliceDecodeValue(dc DecodeContext, vr bsonrw.Val
 }
 
 // ValueUnmarshalerDecodeValue is the ValueDecoderFunc for ValueUnmarshaler implementations.
-func (dvd DefaultValueDecoders) ValueUnmarshalerDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
+func (dvd DefaultValueDecoders) ValueUnmarshalerDecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.IsValid() || (!val.Type().Implements(tValueUnmarshaler) && !reflect.PtrTo(val.Type()).Implements(tValueUnmarshaler)) {
 		return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val}
 	}
@@ -1471,16 +1540,19 @@ func (dvd DefaultValueDecoders) ValueUnmarshalerDecodeValue(dc DecodeContext, vr
 		return err
 	}
 
-	fn := val.Convert(tValueUnmarshaler).MethodByName("UnmarshalBSONValue")
-	errVal := fn.Call([]reflect.Value{reflect.ValueOf(t), reflect.ValueOf(src)})[0]
-	if !errVal.IsNil() {
-		return errVal.Interface().(error)
+	m, ok := val.Interface().(ValueUnmarshaler)
+	if !ok {
+		// NB: this error should be unreachable due to the above checks
+		return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val}
 	}
-	return nil
+	return m.UnmarshalBSONValue(t, src)
 }
 
 // UnmarshalerDecodeValue is the ValueDecoderFunc for Unmarshaler implementations.
-func (dvd DefaultValueDecoders) UnmarshalerDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
+func (dvd DefaultValueDecoders) UnmarshalerDecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.IsValid() || (!val.Type().Implements(tUnmarshaler) && !reflect.PtrTo(val.Type()).Implements(tUnmarshaler)) {
 		return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val}
 	}
@@ -1516,12 +1588,12 @@ func (dvd DefaultValueDecoders) UnmarshalerDecodeValue(dc DecodeContext, vr bson
 		val = val.Addr() // If the type doesn't implement the interface, a pointer to it must.
 	}
 
-	fn := val.Convert(tUnmarshaler).MethodByName("UnmarshalBSON")
-	errVal := fn.Call([]reflect.Value{reflect.ValueOf(src)})[0]
-	if !errVal.IsNil() {
-		return errVal.Interface().(error)
+	m, ok := val.Interface().(Unmarshaler)
+	if !ok {
+		// NB: this error should be unreachable due to the above checks
+		return ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: val}
 	}
-	return nil
+	return m.UnmarshalBSON(src)
 }
 
 // EmptyInterfaceDecodeValue is the ValueDecoderFunc for interface{}.
@@ -1565,7 +1637,10 @@ func (dvd DefaultValueDecoders) EmptyInterfaceDecodeValue(dc DecodeContext, vr b
 }
 
 // CoreDocumentDecodeValue is the ValueDecoderFunc for bsoncore.Document.
-func (DefaultValueDecoders) CoreDocumentDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
+func (DefaultValueDecoders) CoreDocumentDecodeValue(_ DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tCoreDocument {
 		return ValueDecoderError{Name: "CoreDocumentDecodeValue", Types: []reflect.Type{tCoreDocument}, Received: val}
 	}
@@ -1600,7 +1675,7 @@ func (dvd DefaultValueDecoders) decodeDefault(dc DecodeContext, vr bsonrw.ValueR
 	idx := 0
 	for {
 		vr, err := ar.ReadValue()
-		if err == bsonrw.ErrEOA {
+		if errors.Is(err, bsonrw.ErrEOA) {
 			break
 		}
 		if err != nil {
@@ -1671,6 +1746,9 @@ func (dvd DefaultValueDecoders) codeWithScopeDecodeType(dc DecodeContext, vr bso
 }
 
 // CodeWithScopeDecodeValue is the ValueDecoderFunc for CodeWithScope.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value decoders registered.
 func (dvd DefaultValueDecoders) CodeWithScopeDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tCodeWithScope {
 		return ValueDecoderError{Name: "CodeWithScopeDecodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val}
@@ -1709,7 +1787,7 @@ func (DefaultValueDecoders) decodeElemsFromDocumentReader(dc DecodeContext, dr b
 	elems := make([]reflect.Value, 0)
 	for {
 		key, vr, err := dr.ReadElement()
-		if err == bsonrw.ErrEOD {
+		if errors.Is(err, bsonrw.ErrEOD) {
 			break
 		}
 		if err != nil {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go
index 6bdb43cb..4751ae99 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go
@@ -58,10 +58,16 @@ func encodeElement(ec EncodeContext, dw bsonrw.DocumentWriter, e primitive.E) er
 
 // DefaultValueEncoders is a namespace type for the default ValueEncoders used
 // when creating a registry.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
 type DefaultValueEncoders struct{}
 
 // RegisterDefaultEncoders will register the encoder methods attached to DefaultValueEncoders with
 // the provided RegistryBuilder.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
 func (dve DefaultValueEncoders) RegisterDefaultEncoders(rb *RegistryBuilder) {
 	if rb == nil {
 		panic(errors.New("argument to RegisterDefaultEncoders must not be nil"))
@@ -113,7 +119,10 @@ func (dve DefaultValueEncoders) RegisterDefaultEncoders(rb *RegistryBuilder) {
 }
 
 // BooleanEncodeValue is the ValueEncoderFunc for bool types.
-func (dve DefaultValueEncoders) BooleanEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (dve DefaultValueEncoders) BooleanEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Kind() != reflect.Bool {
 		return ValueEncoderError{Name: "BooleanEncodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val}
 	}
@@ -125,6 +134,9 @@ func fitsIn32Bits(i int64) bool {
 }
 
 // IntEncodeValue is the ValueEncoderFunc for int types.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
 func (dve DefaultValueEncoders) IntEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	switch val.Kind() {
 	case reflect.Int8, reflect.Int16, reflect.Int32:
@@ -176,7 +188,10 @@ func (dve DefaultValueEncoders) UintEncodeValue(ec EncodeContext, vw bsonrw.Valu
 }
 
 // FloatEncodeValue is the ValueEncoderFunc for float types.
-func (dve DefaultValueEncoders) FloatEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (dve DefaultValueEncoders) FloatEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	switch val.Kind() {
 	case reflect.Float32, reflect.Float64:
 		return vw.WriteDouble(val.Float())
@@ -188,7 +203,7 @@ func (dve DefaultValueEncoders) FloatEncodeValue(ec EncodeContext, vw bsonrw.Val
 // StringEncodeValue is the ValueEncoderFunc for string types.
 //
 // Deprecated: StringEncodeValue is not registered by default. Use StringCodec.EncodeValue instead.
-func (dve DefaultValueEncoders) StringEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (dve DefaultValueEncoders) StringEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if val.Kind() != reflect.String {
 		return ValueEncoderError{
 			Name:     "StringEncodeValue",
@@ -201,7 +216,10 @@ func (dve DefaultValueEncoders) StringEncodeValue(ectx EncodeContext, vw bsonrw.
 }
 
 // ObjectIDEncodeValue is the ValueEncoderFunc for primitive.ObjectID.
-func (dve DefaultValueEncoders) ObjectIDEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (dve DefaultValueEncoders) ObjectIDEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tOID {
 		return ValueEncoderError{Name: "ObjectIDEncodeValue", Types: []reflect.Type{tOID}, Received: val}
 	}
@@ -209,7 +227,10 @@ func (dve DefaultValueEncoders) ObjectIDEncodeValue(ec EncodeContext, vw bsonrw.
 }
 
 // Decimal128EncodeValue is the ValueEncoderFunc for primitive.Decimal128.
-func (dve DefaultValueEncoders) Decimal128EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (dve DefaultValueEncoders) Decimal128EncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tDecimal {
 		return ValueEncoderError{Name: "Decimal128EncodeValue", Types: []reflect.Type{tDecimal}, Received: val}
 	}
@@ -217,6 +238,9 @@ func (dve DefaultValueEncoders) Decimal128EncodeValue(ec EncodeContext, vw bsonr
 }
 
 // JSONNumberEncodeValue is the ValueEncoderFunc for json.Number.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
 func (dve DefaultValueEncoders) JSONNumberEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tJSONNumber {
 		return ValueEncoderError{Name: "JSONNumberEncodeValue", Types: []reflect.Type{tJSONNumber}, Received: val}
@@ -237,7 +261,10 @@ func (dve DefaultValueEncoders) JSONNumberEncodeValue(ec EncodeContext, vw bsonr
 }
 
 // URLEncodeValue is the ValueEncoderFunc for url.URL.
-func (dve DefaultValueEncoders) URLEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (dve DefaultValueEncoders) URLEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tURL {
 		return ValueEncoderError{Name: "URLEncodeValue", Types: []reflect.Type{tURL}, Received: val}
 	}
@@ -248,7 +275,7 @@ func (dve DefaultValueEncoders) URLEncodeValue(ec EncodeContext, vw bsonrw.Value
 // TimeEncodeValue is the ValueEncoderFunc for time.TIme.
 //
 // Deprecated: TimeEncodeValue is not registered by default. Use TimeCodec.EncodeValue instead.
-func (dve DefaultValueEncoders) TimeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (dve DefaultValueEncoders) TimeEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tTime {
 		return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val}
 	}
@@ -260,7 +287,7 @@ func (dve DefaultValueEncoders) TimeEncodeValue(ec EncodeContext, vw bsonrw.Valu
 // ByteSliceEncodeValue is the ValueEncoderFunc for []byte.
 //
 // Deprecated: ByteSliceEncodeValue is not registered by default. Use ByteSliceCodec.EncodeValue instead.
-func (dve DefaultValueEncoders) ByteSliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (dve DefaultValueEncoders) ByteSliceEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tByteSlice {
 		return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
 	}
@@ -316,7 +343,7 @@ func (dve DefaultValueEncoders) mapEncodeValue(ec EncodeContext, dw bsonrw.Docum
 		}
 
 		currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.MapIndex(key))
-		if lookupErr != nil && lookupErr != errInvalidValue {
+		if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) {
 			return lookupErr
 		}
 
@@ -325,7 +352,7 @@ func (dve DefaultValueEncoders) mapEncodeValue(ec EncodeContext, dw bsonrw.Docum
 			return err
 		}
 
-		if lookupErr == errInvalidValue {
+		if errors.Is(lookupErr, errInvalidValue) {
 			err = vw.WriteNull()
 			if err != nil {
 				return err
@@ -343,6 +370,9 @@ func (dve DefaultValueEncoders) mapEncodeValue(ec EncodeContext, dw bsonrw.Docum
 }
 
 // ArrayEncodeValue is the ValueEncoderFunc for array types.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
 func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Kind() != reflect.Array {
 		return ValueEncoderError{Name: "ArrayEncodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val}
@@ -388,7 +418,7 @@ func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.Val
 
 	for idx := 0; idx < val.Len(); idx++ {
 		currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.Index(idx))
-		if lookupErr != nil && lookupErr != errInvalidValue {
+		if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) {
 			return lookupErr
 		}
 
@@ -397,7 +427,7 @@ func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.Val
 			return err
 		}
 
-		if lookupErr == errInvalidValue {
+		if errors.Is(lookupErr, errInvalidValue) {
 			err = vw.WriteNull()
 			if err != nil {
 				return err
@@ -457,7 +487,7 @@ func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.Val
 
 	for idx := 0; idx < val.Len(); idx++ {
 		currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.Index(idx))
-		if lookupErr != nil && lookupErr != errInvalidValue {
+		if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) {
 			return lookupErr
 		}
 
@@ -466,7 +496,7 @@ func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.Val
 			return err
 		}
 
-		if lookupErr == errInvalidValue {
+		if errors.Is(lookupErr, errInvalidValue) {
 			err = vw.WriteNull()
 			if err != nil {
 				return err
@@ -515,7 +545,10 @@ func (dve DefaultValueEncoders) EmptyInterfaceEncodeValue(ec EncodeContext, vw b
 }
 
 // ValueMarshalerEncodeValue is the ValueEncoderFunc for ValueMarshaler implementations.
-func (dve DefaultValueEncoders) ValueMarshalerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (dve DefaultValueEncoders) ValueMarshalerEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	// Either val or a pointer to val must implement ValueMarshaler
 	switch {
 	case !val.IsValid():
@@ -531,17 +564,22 @@ func (dve DefaultValueEncoders) ValueMarshalerEncodeValue(ec EncodeContext, vw b
 		return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val}
 	}
 
-	fn := val.Convert(tValueMarshaler).MethodByName("MarshalBSONValue")
-	returns := fn.Call(nil)
-	if !returns[2].IsNil() {
-		return returns[2].Interface().(error)
+	m, ok := val.Interface().(ValueMarshaler)
+	if !ok {
+		return vw.WriteNull()
+	}
+	t, data, err := m.MarshalBSONValue()
+	if err != nil {
+		return err
 	}
-	t, data := returns[0].Interface().(bsontype.Type), returns[1].Interface().([]byte)
 	return bsonrw.Copier{}.CopyValueFromBytes(vw, t, data)
 }
 
 // MarshalerEncodeValue is the ValueEncoderFunc for Marshaler implementations.
-func (dve DefaultValueEncoders) MarshalerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (dve DefaultValueEncoders) MarshalerEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	// Either val or a pointer to val must implement Marshaler
 	switch {
 	case !val.IsValid():
@@ -557,16 +595,21 @@ func (dve DefaultValueEncoders) MarshalerEncodeValue(ec EncodeContext, vw bsonrw
 		return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val}
 	}
 
-	fn := val.Convert(tMarshaler).MethodByName("MarshalBSON")
-	returns := fn.Call(nil)
-	if !returns[1].IsNil() {
-		return returns[1].Interface().(error)
+	m, ok := val.Interface().(Marshaler)
+	if !ok {
+		return vw.WriteNull()
+	}
+	data, err := m.MarshalBSON()
+	if err != nil {
+		return err
 	}
-	data := returns[0].Interface().([]byte)
 	return bsonrw.Copier{}.CopyValueFromBytes(vw, bsontype.EmbeddedDocument, data)
 }
 
 // ProxyEncodeValue is the ValueEncoderFunc for Proxy implementations.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
 func (dve DefaultValueEncoders) ProxyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	// Either val or a pointer to val must implement Proxy
 	switch {
@@ -583,27 +626,38 @@ func (dve DefaultValueEncoders) ProxyEncodeValue(ec EncodeContext, vw bsonrw.Val
 		return ValueEncoderError{Name: "ProxyEncodeValue", Types: []reflect.Type{tProxy}, Received: val}
 	}
 
-	fn := val.Convert(tProxy).MethodByName("ProxyBSON")
-	returns := fn.Call(nil)
-	if !returns[1].IsNil() {
-		return returns[1].Interface().(error)
+	m, ok := val.Interface().(Proxy)
+	if !ok {
+		return vw.WriteNull()
 	}
-	data := returns[0]
-	var encoder ValueEncoder
-	var err error
-	if data.Elem().IsValid() {
-		encoder, err = ec.LookupEncoder(data.Elem().Type())
-	} else {
-		encoder, err = ec.LookupEncoder(nil)
+	v, err := m.ProxyBSON()
+	if err != nil {
+		return err
 	}
+	if v == nil {
+		encoder, err := ec.LookupEncoder(nil)
+		if err != nil {
+			return err
+		}
+		return encoder.EncodeValue(ec, vw, reflect.ValueOf(nil))
+	}
+	vv := reflect.ValueOf(v)
+	switch vv.Kind() {
+	case reflect.Ptr, reflect.Interface:
+		vv = vv.Elem()
+	}
+	encoder, err := ec.LookupEncoder(vv.Type())
 	if err != nil {
 		return err
 	}
-	return encoder.EncodeValue(ec, vw, data.Elem())
+	return encoder.EncodeValue(ec, vw, vv)
 }
 
 // JavaScriptEncodeValue is the ValueEncoderFunc for the primitive.JavaScript type.
-func (DefaultValueEncoders) JavaScriptEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (DefaultValueEncoders) JavaScriptEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tJavaScript {
 		return ValueEncoderError{Name: "JavaScriptEncodeValue", Types: []reflect.Type{tJavaScript}, Received: val}
 	}
@@ -612,7 +666,10 @@ func (DefaultValueEncoders) JavaScriptEncodeValue(ectx EncodeContext, vw bsonrw.
 }
 
 // SymbolEncodeValue is the ValueEncoderFunc for the primitive.Symbol type.
-func (DefaultValueEncoders) SymbolEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (DefaultValueEncoders) SymbolEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tSymbol {
 		return ValueEncoderError{Name: "SymbolEncodeValue", Types: []reflect.Type{tSymbol}, Received: val}
 	}
@@ -621,7 +678,10 @@ func (DefaultValueEncoders) SymbolEncodeValue(ectx EncodeContext, vw bsonrw.Valu
 }
 
 // BinaryEncodeValue is the ValueEncoderFunc for Binary.
-func (DefaultValueEncoders) BinaryEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (DefaultValueEncoders) BinaryEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tBinary {
 		return ValueEncoderError{Name: "BinaryEncodeValue", Types: []reflect.Type{tBinary}, Received: val}
 	}
@@ -631,7 +691,10 @@ func (DefaultValueEncoders) BinaryEncodeValue(ec EncodeContext, vw bsonrw.ValueW
 }
 
 // UndefinedEncodeValue is the ValueEncoderFunc for Undefined.
-func (DefaultValueEncoders) UndefinedEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (DefaultValueEncoders) UndefinedEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tUndefined {
 		return ValueEncoderError{Name: "UndefinedEncodeValue", Types: []reflect.Type{tUndefined}, Received: val}
 	}
@@ -640,7 +703,10 @@ func (DefaultValueEncoders) UndefinedEncodeValue(ec EncodeContext, vw bsonrw.Val
 }
 
 // DateTimeEncodeValue is the ValueEncoderFunc for DateTime.
-func (DefaultValueEncoders) DateTimeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (DefaultValueEncoders) DateTimeEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tDateTime {
 		return ValueEncoderError{Name: "DateTimeEncodeValue", Types: []reflect.Type{tDateTime}, Received: val}
 	}
@@ -649,7 +715,10 @@ func (DefaultValueEncoders) DateTimeEncodeValue(ec EncodeContext, vw bsonrw.Valu
 }
 
 // NullEncodeValue is the ValueEncoderFunc for Null.
-func (DefaultValueEncoders) NullEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (DefaultValueEncoders) NullEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tNull {
 		return ValueEncoderError{Name: "NullEncodeValue", Types: []reflect.Type{tNull}, Received: val}
 	}
@@ -658,7 +727,10 @@ func (DefaultValueEncoders) NullEncodeValue(ec EncodeContext, vw bsonrw.ValueWri
 }
 
 // RegexEncodeValue is the ValueEncoderFunc for Regex.
-func (DefaultValueEncoders) RegexEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (DefaultValueEncoders) RegexEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tRegex {
 		return ValueEncoderError{Name: "RegexEncodeValue", Types: []reflect.Type{tRegex}, Received: val}
 	}
@@ -669,7 +741,10 @@ func (DefaultValueEncoders) RegexEncodeValue(ec EncodeContext, vw bsonrw.ValueWr
 }
 
 // DBPointerEncodeValue is the ValueEncoderFunc for DBPointer.
-func (DefaultValueEncoders) DBPointerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (DefaultValueEncoders) DBPointerEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tDBPointer {
 		return ValueEncoderError{Name: "DBPointerEncodeValue", Types: []reflect.Type{tDBPointer}, Received: val}
 	}
@@ -680,7 +755,10 @@ func (DefaultValueEncoders) DBPointerEncodeValue(ec EncodeContext, vw bsonrw.Val
 }
 
 // TimestampEncodeValue is the ValueEncoderFunc for Timestamp.
-func (DefaultValueEncoders) TimestampEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (DefaultValueEncoders) TimestampEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tTimestamp {
 		return ValueEncoderError{Name: "TimestampEncodeValue", Types: []reflect.Type{tTimestamp}, Received: val}
 	}
@@ -691,7 +769,10 @@ func (DefaultValueEncoders) TimestampEncodeValue(ec EncodeContext, vw bsonrw.Val
 }
 
 // MinKeyEncodeValue is the ValueEncoderFunc for MinKey.
-func (DefaultValueEncoders) MinKeyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (DefaultValueEncoders) MinKeyEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tMinKey {
 		return ValueEncoderError{Name: "MinKeyEncodeValue", Types: []reflect.Type{tMinKey}, Received: val}
 	}
@@ -700,7 +781,10 @@ func (DefaultValueEncoders) MinKeyEncodeValue(ec EncodeContext, vw bsonrw.ValueW
 }
 
 // MaxKeyEncodeValue is the ValueEncoderFunc for MaxKey.
-func (DefaultValueEncoders) MaxKeyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (DefaultValueEncoders) MaxKeyEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tMaxKey {
 		return ValueEncoderError{Name: "MaxKeyEncodeValue", Types: []reflect.Type{tMaxKey}, Received: val}
 	}
@@ -709,7 +793,10 @@ func (DefaultValueEncoders) MaxKeyEncodeValue(ec EncodeContext, vw bsonrw.ValueW
 }
 
 // CoreDocumentEncodeValue is the ValueEncoderFunc for bsoncore.Document.
-func (DefaultValueEncoders) CoreDocumentEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
+func (DefaultValueEncoders) CoreDocumentEncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tCoreDocument {
 		return ValueEncoderError{Name: "CoreDocumentEncodeValue", Types: []reflect.Type{tCoreDocument}, Received: val}
 	}
@@ -720,6 +807,9 @@ func (DefaultValueEncoders) CoreDocumentEncodeValue(ec EncodeContext, vw bsonrw.
 }
 
 // CodeWithScopeEncodeValue is the ValueEncoderFunc for CodeWithScope.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.NewRegistry] to get a registry with all default
+// value encoders registered.
 func (dve DefaultValueEncoders) CodeWithScopeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tCodeWithScope {
 		return ValueEncoderError{Name: "CodeWithScopeEncodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go
index 5f903ebe..4613e5a1 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go
@@ -31,35 +31,39 @@
 // allow the use of a function with the correct signature as a ValueDecoder. A DecodeContext
 // instance is provided and serves similar functionality to the EncodeContext.
 //
-// # Registry and RegistryBuilder
-//
-// A Registry is an immutable store for ValueEncoders, ValueDecoders, and a type map. See the Registry type
-// documentation for examples of registering various custom encoders and decoders. A Registry can be constructed using a
-// RegistryBuilder, which handles three main types of codecs:
-//
-// 1. Type encoders/decoders - These can be registered using the RegisterTypeEncoder and RegisterTypeDecoder methods.
-// The registered codec will be invoked when encoding/decoding a value whose type matches the registered type exactly.
-// If the registered type is an interface, the codec will be invoked when encoding or decoding values whose type is the
-// interface, but not for values with concrete types that implement the interface.
-//
-// 2. Hook encoders/decoders - These can be registered using the RegisterHookEncoder and RegisterHookDecoder methods.
-// These methods only accept interface types and the registered codecs will be invoked when encoding or decoding values
-// whose types implement the interface. An example of a hook defined by the driver is bson.Marshaler. The driver will
-// call the MarshalBSON method for any value whose type implements bson.Marshaler, regardless of the value's concrete
-// type.
-//
-// 3. Type map entries - This can be used to associate a BSON type with a Go type. These type associations are used when
-// decoding into a bson.D/bson.M or a struct field of type interface{}. For example, by default, BSON int32 and int64
-// values decode as Go int32 and int64 instances, respectively, when decoding into a bson.D. The following code would
-// change the behavior so these values decode as Go int instances instead:
+// # Registry
+//
+// A Registry is a store for ValueEncoders, ValueDecoders, and a type map. See the Registry type
+// documentation for examples of registering various custom encoders and decoders. A Registry can
+// have three main types of codecs:
+//
+// 1. Type encoders/decoders - These can be registered using the RegisterTypeEncoder and
+// RegisterTypeDecoder methods. The registered codec will be invoked when encoding/decoding a value
+// whose type matches the registered type exactly.
+// If the registered type is an interface, the codec will be invoked when encoding or decoding
+// values whose type is the interface, but not for values with concrete types that implement the
+// interface.
+//
+// 2. Hook encoders/decoders - These can be registered using the RegisterHookEncoder and
+// RegisterHookDecoder methods. These methods only accept interface types and the registered codecs
+// will be invoked when encoding or decoding values whose types implement the interface. An example
+// of a hook defined by the driver is bson.Marshaler. The driver will call the MarshalBSON method
+// for any value whose type implements bson.Marshaler, regardless of the value's concrete type.
+//
+// 3. Type map entries - This can be used to associate a BSON type with a Go type. These type
+// associations are used when decoding into a bson.D/bson.M or a struct field of type interface{}.
+// For example, by default, BSON int32 and int64 values decode as Go int32 and int64 instances,
+// respectively, when decoding into a bson.D. The following code would change the behavior so these
+// values decode as Go int instances instead:
 //
 //	intType := reflect.TypeOf(int(0))
-//	registryBuilder.RegisterTypeMapEntry(bsontype.Int32, intType).RegisterTypeMapEntry(bsontype.Int64, intType)
+//	registry.RegisterTypeMapEntry(bsontype.Int32, intType).RegisterTypeMapEntry(bsontype.Int64, intType)
 //
-// 4. Kind encoder/decoders - These can be registered using the RegisterDefaultEncoder and RegisterDefaultDecoder
-// methods. The registered codec will be invoked when encoding or decoding values whose reflect.Kind matches the
-// registered reflect.Kind as long as the value's type doesn't match a registered type or hook encoder/decoder first.
-// These methods should be used to change the behavior for all values for a specific kind.
+// 4. Kind encoder/decoders - These can be registered using the RegisterDefaultEncoder and
+// RegisterDefaultDecoder methods. The registered codec will be invoked when encoding or decoding
+// values whose reflect.Kind matches the registered reflect.Kind as long as the value's type doesn't
+// match a registered type or hook encoder/decoder first. These methods should be used to change the
+// behavior for all values for a specific kind.
 //
 // # Registry Lookup Procedure
 //
@@ -67,17 +71,18 @@
 //
 // 1. A type encoder registered for the exact type of the value.
 //
-// 2. A hook encoder registered for an interface that is implemented by the value or by a pointer to the value. If the
-// value matches multiple hooks (e.g. the type implements bsoncodec.Marshaler and bsoncodec.ValueMarshaler), the first
-// one registered will be selected. Note that registries constructed using bson.NewRegistryBuilder have driver-defined
-// hooks registered for the bsoncodec.Marshaler, bsoncodec.ValueMarshaler, and bsoncodec.Proxy interfaces, so those
-// will take precedence over any new hooks.
+// 2. A hook encoder registered for an interface that is implemented by the value or by a pointer to
+// the value. If the value matches multiple hooks (e.g. the type implements bsoncodec.Marshaler and
+// bsoncodec.ValueMarshaler), the first one registered will be selected. Note that registries
+// constructed using bson.NewRegistry have driver-defined hooks registered for the
+// bsoncodec.Marshaler, bsoncodec.ValueMarshaler, and bsoncodec.Proxy interfaces, so those will take
+// precedence over any new hooks.
 //
 // 3. A kind encoder registered for the value's kind.
 //
-// If all of these lookups fail to find an encoder, an error of type ErrNoEncoder is returned. The same precedence
-// rules apply for decoders, with the exception that an error of type ErrNoDecoder will be returned if no decoder is
-// found.
+// If all of these lookups fail to find an encoder, an error of type ErrNoEncoder is returned. The
+// same precedence rules apply for decoders, with the exception that an error of type ErrNoDecoder
+// will be returned if no decoder is found.
 //
 // # DefaultValueEncoders and DefaultValueDecoders
 //
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/empty_interface_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/empty_interface_codec.go
index eda417cf..098368f0 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/empty_interface_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/empty_interface_codec.go
@@ -16,18 +16,44 @@ import (
 )
 
 // EmptyInterfaceCodec is the Codec used for interface{} values.
+//
+// Deprecated: EmptyInterfaceCodec will not be directly configurable in Go
+// Driver 2.0. To configure the empty interface encode and decode behavior, use
+// the configuration methods on a [go.mongodb.org/mongo-driver/bson.Encoder] or
+// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the empty interface
+// encode and decode behavior for a mongo.Client, use
+// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions].
+//
+// For example, to configure a mongo.Client to unmarshal BSON binary field
+// values as a Go byte slice, use:
+//
+//	opt := options.Client().SetBSONOptions(&options.BSONOptions{
+//	    BinaryAsSlice: true,
+//	})
+//
+// See the deprecation notice for each field in EmptyInterfaceCodec for the
+// corresponding settings.
 type EmptyInterfaceCodec struct {
+	// DecodeBinaryAsSlice causes DecodeValue to unmarshal BSON binary field values that are the
+	// "Generic" or "Old" BSON binary subtype as a Go byte slice instead of a primitive.Binary.
+	//
+	// Deprecated: Use bson.Decoder.BinaryAsSlice or options.BSONOptions.BinaryAsSlice instead.
 	DecodeBinaryAsSlice bool
 }
 
 var (
 	defaultEmptyInterfaceCodec = NewEmptyInterfaceCodec()
 
-	_ ValueCodec  = defaultEmptyInterfaceCodec
+	// Assert that defaultEmptyInterfaceCodec satisfies the typeDecoder interface, which allows it
+	// to be used by collection type decoders (e.g. map, slice, etc) to set individual values in a
+	// collection.
 	_ typeDecoder = defaultEmptyInterfaceCodec
 )
 
 // NewEmptyInterfaceCodec returns a EmptyInterfaceCodec with options opts.
+//
+// Deprecated: NewEmptyInterfaceCodec will not be available in Go Driver 2.0. See
+// [EmptyInterfaceCodec] for more details.
 func NewEmptyInterfaceCodec(opts ...*bsonoptions.EmptyInterfaceCodecOptions) *EmptyInterfaceCodec {
 	interfaceOpt := bsonoptions.MergeEmptyInterfaceCodecOptions(opts...)
 
@@ -121,7 +147,7 @@ func (eic EmptyInterfaceCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReade
 		return emptyValue, err
 	}
 
-	if eic.DecodeBinaryAsSlice && rtype == tBinary {
+	if (eic.DecodeBinaryAsSlice || dc.binaryAsSlice) && rtype == tBinary {
 		binElem := elem.Interface().(primitive.Binary)
 		if binElem.Subtype == bsontype.BinaryGeneric || binElem.Subtype == bsontype.BinaryBinaryOld {
 			elem = reflect.ValueOf(binElem.Data)
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go
index e1fbef9c..d7e00ffa 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go
@@ -8,6 +8,7 @@ package bsoncodec
 
 import (
 	"encoding"
+	"errors"
 	"fmt"
 	"reflect"
 	"strconv"
@@ -20,14 +21,44 @@ import (
 var defaultMapCodec = NewMapCodec()
 
 // MapCodec is the Codec used for map values.
+//
+// Deprecated: MapCodec will not be directly configurable in Go Driver 2.0. To
+// configure the map encode and decode behavior, use the configuration methods
+// on a [go.mongodb.org/mongo-driver/bson.Encoder] or
+// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the map encode and
+// decode behavior for a mongo.Client, use
+// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions].
+//
+// For example, to configure a mongo.Client to marshal nil Go maps as empty BSON
+// documents, use:
+//
+//	opt := options.Client().SetBSONOptions(&options.BSONOptions{
+//	    NilMapAsEmpty: true,
+//	})
+//
+// See the deprecation notice for each field in MapCodec for the corresponding
+// settings.
 type MapCodec struct {
-	DecodeZerosMap         bool
-	EncodeNilAsEmpty       bool
+	// DecodeZerosMap causes DecodeValue to delete any existing values from Go maps in the destination
+	// value passed to Decode before unmarshaling BSON documents into them.
+	//
+	// Deprecated: Use bson.Decoder.ZeroMaps or options.BSONOptions.ZeroMaps instead.
+	DecodeZerosMap bool
+
+	// EncodeNilAsEmpty causes EncodeValue to marshal nil Go maps as empty BSON documents instead of
+	// BSON null.
+	//
+	// Deprecated: Use bson.Encoder.NilMapAsEmpty or options.BSONOptions.NilMapAsEmpty instead.
+	EncodeNilAsEmpty bool
+
+	// EncodeKeysWithStringer causes the Encoder to convert Go map keys to BSON document field name
+	// strings using fmt.Sprintf() instead of the default string conversion logic.
+	//
+	// Deprecated: Use bson.Encoder.StringifyMapKeysWithFmt or
+	// options.BSONOptions.StringifyMapKeysWithFmt instead.
 	EncodeKeysWithStringer bool
 }
 
-var _ ValueCodec = &MapCodec{}
-
 // KeyMarshaler is the interface implemented by an object that can marshal itself into a string key.
 // This applies to types used as map keys and is similar to encoding.TextMarshaler.
 type KeyMarshaler interface {
@@ -45,6 +76,9 @@ type KeyUnmarshaler interface {
 }
 
 // NewMapCodec returns a MapCodec with options opts.
+//
+// Deprecated: NewMapCodec will not be available in Go Driver 2.0. See
+// [MapCodec] for more details.
 func NewMapCodec(opts ...*bsonoptions.MapCodecOptions) *MapCodec {
 	mapOpt := bsonoptions.MergeMapCodecOptions(opts...)
 
@@ -67,7 +101,7 @@ func (mc *MapCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val ref
 		return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val}
 	}
 
-	if val.IsNil() && !mc.EncodeNilAsEmpty {
+	if val.IsNil() && !mc.EncodeNilAsEmpty && !ec.nilMapAsEmpty {
 		// If we have a nil map but we can't WriteNull, that means we're probably trying to encode
 		// to a TopLevel document. We can't currently tell if this is what actually happened, but if
 		// there's a deeper underlying problem, the error will also be returned from WriteDocument,
@@ -100,7 +134,7 @@ func (mc *MapCodec) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, v
 
 	keys := val.MapKeys()
 	for _, key := range keys {
-		keyStr, err := mc.encodeKey(key)
+		keyStr, err := mc.encodeKey(key, ec.stringifyMapKeysWithFmt)
 		if err != nil {
 			return err
 		}
@@ -110,7 +144,7 @@ func (mc *MapCodec) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, v
 		}
 
 		currEncoder, currVal, lookupErr := defaultValueEncoders.lookupElementEncoder(ec, encoder, val.MapIndex(key))
-		if lookupErr != nil && lookupErr != errInvalidValue {
+		if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) {
 			return lookupErr
 		}
 
@@ -119,7 +153,7 @@ func (mc *MapCodec) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, v
 			return err
 		}
 
-		if lookupErr == errInvalidValue {
+		if errors.Is(lookupErr, errInvalidValue) {
 			err = vw.WriteNull()
 			if err != nil {
 				return err
@@ -163,7 +197,7 @@ func (mc *MapCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val ref
 		val.Set(reflect.MakeMap(val.Type()))
 	}
 
-	if val.Len() > 0 && mc.DecodeZerosMap {
+	if val.Len() > 0 && (mc.DecodeZerosMap || dc.zeroMaps) {
 		clearMap(val)
 	}
 
@@ -182,7 +216,7 @@ func (mc *MapCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val ref
 
 	for {
 		key, vr, err := dr.ReadElement()
-		if err == bsonrw.ErrEOD {
+		if errors.Is(err, bsonrw.ErrEOD) {
 			break
 		}
 		if err != nil {
@@ -211,8 +245,8 @@ func clearMap(m reflect.Value) {
 	}
 }
 
-func (mc *MapCodec) encodeKey(val reflect.Value) (string, error) {
-	if mc.EncodeKeysWithStringer {
+func (mc *MapCodec) encodeKey(val reflect.Value, encodeKeysWithStringer bool) (string, error) {
+	if mc.EncodeKeysWithStringer || encodeKeysWithStringer {
 		return fmt.Sprint(val), nil
 	}
 
@@ -295,7 +329,7 @@ func (mc *MapCodec) decodeKey(key string, keyType reflect.Type) (reflect.Value,
 			if mc.EncodeKeysWithStringer {
 				parsed, err := strconv.ParseFloat(key, 64)
 				if err != nil {
-					return keyVal, fmt.Errorf("Map key is defined to be a decimal type (%v) but got error %v", keyType.Kind(), err)
+					return keyVal, fmt.Errorf("Map key is defined to be a decimal type (%v) but got error %w", keyType.Kind(), err)
 				}
 				keyVal = reflect.ValueOf(parsed)
 				break
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go
index 616a3e70..ddfa4a33 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/pointer_codec.go
@@ -8,7 +8,6 @@ package bsoncodec
 
 import (
 	"reflect"
-	"sync"
 
 	"go.mongodb.org/mongo-driver/bson/bsonrw"
 	"go.mongodb.org/mongo-driver/bson/bsontype"
@@ -18,18 +17,28 @@ var _ ValueEncoder = &PointerCodec{}
 var _ ValueDecoder = &PointerCodec{}
 
 // PointerCodec is the Codec used for pointers.
+//
+// Deprecated: PointerCodec will not be directly accessible in Go Driver 2.0. To
+// override the default pointer encode and decode behavior, create a new registry
+// with [go.mongodb.org/mongo-driver/bson.NewRegistry] and register a new
+// encoder and decoder for pointers.
+//
+// For example,
+//
+//	reg := bson.NewRegistry()
+//	reg.RegisterKindEncoder(reflect.Ptr, myPointerEncoder)
+//	reg.RegisterKindDecoder(reflect.Ptr, myPointerDecoder)
 type PointerCodec struct {
-	ecache map[reflect.Type]ValueEncoder
-	dcache map[reflect.Type]ValueDecoder
-	l      sync.RWMutex
+	ecache typeEncoderCache
+	dcache typeDecoderCache
 }
 
 // NewPointerCodec returns a PointerCodec that has been initialized.
+//
+// Deprecated: NewPointerCodec will not be available in Go Driver 2.0. See
+// [PointerCodec] for more details.
 func NewPointerCodec() *PointerCodec {
-	return &PointerCodec{
-		ecache: make(map[reflect.Type]ValueEncoder),
-		dcache: make(map[reflect.Type]ValueDecoder),
-	}
+	return &PointerCodec{}
 }
 
 // EncodeValue handles encoding a pointer by either encoding it to BSON Null if the pointer is nil
@@ -46,24 +55,19 @@ func (pc *PointerCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val
 		return vw.WriteNull()
 	}
 
-	pc.l.RLock()
-	enc, ok := pc.ecache[val.Type()]
-	pc.l.RUnlock()
-	if ok {
-		if enc == nil {
-			return ErrNoEncoder{Type: val.Type()}
+	typ := val.Type()
+	if v, ok := pc.ecache.Load(typ); ok {
+		if v == nil {
+			return ErrNoEncoder{Type: typ}
 		}
-		return enc.EncodeValue(ec, vw, val.Elem())
+		return v.EncodeValue(ec, vw, val.Elem())
 	}
-
-	enc, err := ec.LookupEncoder(val.Type().Elem())
-	pc.l.Lock()
-	pc.ecache[val.Type()] = enc
-	pc.l.Unlock()
+	// TODO(charlie): handle concurrent requests for the same type
+	enc, err := ec.LookupEncoder(typ.Elem())
+	enc = pc.ecache.LoadOrStore(typ, enc)
 	if err != nil {
 		return err
 	}
-
 	return enc.EncodeValue(ec, vw, val.Elem())
 }
 
@@ -74,36 +78,31 @@ func (pc *PointerCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val
 		return ValueDecoderError{Name: "PointerCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Ptr}, Received: val}
 	}
 
+	typ := val.Type()
 	if vr.Type() == bsontype.Null {
-		val.Set(reflect.Zero(val.Type()))
+		val.Set(reflect.Zero(typ))
 		return vr.ReadNull()
 	}
 	if vr.Type() == bsontype.Undefined {
-		val.Set(reflect.Zero(val.Type()))
+		val.Set(reflect.Zero(typ))
 		return vr.ReadUndefined()
 	}
 
 	if val.IsNil() {
-		val.Set(reflect.New(val.Type().Elem()))
+		val.Set(reflect.New(typ.Elem()))
 	}
 
-	pc.l.RLock()
-	dec, ok := pc.dcache[val.Type()]
-	pc.l.RUnlock()
-	if ok {
-		if dec == nil {
-			return ErrNoDecoder{Type: val.Type()}
+	if v, ok := pc.dcache.Load(typ); ok {
+		if v == nil {
+			return ErrNoDecoder{Type: typ}
 		}
-		return dec.DecodeValue(dc, vr, val.Elem())
+		return v.DecodeValue(dc, vr, val.Elem())
 	}
-
-	dec, err := dc.LookupDecoder(val.Type().Elem())
-	pc.l.Lock()
-	pc.dcache[val.Type()] = dec
-	pc.l.Unlock()
+	// TODO(charlie): handle concurrent requests for the same type
+	dec, err := dc.LookupDecoder(typ.Elem())
+	dec = pc.dcache.LoadOrStore(typ, dec)
 	if err != nil {
 		return err
 	}
-
 	return dec.DecodeValue(dc, vr, val.Elem())
 }
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go
index 80644023..196c491b 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go
@@ -16,12 +16,18 @@ import (
 )
 
 // ErrNilType is returned when nil is passed to either LookupEncoder or LookupDecoder.
+//
+// Deprecated: ErrNilType will not be supported in Go Driver 2.0.
 var ErrNilType = errors.New("cannot perform a decoder lookup on <nil>")
 
 // ErrNotPointer is returned when a non-pointer type is provided to LookupDecoder.
+//
+// Deprecated: ErrNotPointer will not be supported in Go Driver 2.0.
 var ErrNotPointer = errors.New("non-pointer provided to LookupDecoder")
 
 // ErrNoEncoder is returned when there wasn't an encoder available for a type.
+//
+// Deprecated: ErrNoEncoder will not be supported in Go Driver 2.0.
 type ErrNoEncoder struct {
 	Type reflect.Type
 }
@@ -34,6 +40,8 @@ func (ene ErrNoEncoder) Error() string {
 }
 
 // ErrNoDecoder is returned when there wasn't a decoder available for a type.
+//
+// Deprecated: ErrNoDecoder will not be supported in Go Driver 2.0.
 type ErrNoDecoder struct {
 	Type reflect.Type
 }
@@ -43,6 +51,8 @@ func (end ErrNoDecoder) Error() string {
 }
 
 // ErrNoTypeMapEntry is returned when there wasn't a type available for the provided BSON type.
+//
+// Deprecated: ErrNoTypeMapEntry will not be supported in Go Driver 2.0.
 type ErrNoTypeMapEntry struct {
 	Type bsontype.Type
 }
@@ -52,63 +62,30 @@ func (entme ErrNoTypeMapEntry) Error() string {
 }
 
 // ErrNotInterface is returned when the provided type is not an interface.
+//
+// Deprecated: ErrNotInterface will not be supported in Go Driver 2.0.
 var ErrNotInterface = errors.New("The provided type is not an interface")
 
 // A RegistryBuilder is used to build a Registry. This type is not goroutine
 // safe.
+//
+// Deprecated: Use Registry instead.
 type RegistryBuilder struct {
-	typeEncoders      map[reflect.Type]ValueEncoder
-	interfaceEncoders []interfaceValueEncoder
-	kindEncoders      map[reflect.Kind]ValueEncoder
-
-	typeDecoders      map[reflect.Type]ValueDecoder
-	interfaceDecoders []interfaceValueDecoder
-	kindDecoders      map[reflect.Kind]ValueDecoder
-
-	typeMap map[bsontype.Type]reflect.Type
-}
-
-// A Registry is used to store and retrieve codecs for types and interfaces. This type is the main
-// typed passed around and Encoders and Decoders are constructed from it.
-type Registry struct {
-	typeEncoders map[reflect.Type]ValueEncoder
-	typeDecoders map[reflect.Type]ValueDecoder
-
-	interfaceEncoders []interfaceValueEncoder
-	interfaceDecoders []interfaceValueDecoder
-
-	kindEncoders map[reflect.Kind]ValueEncoder
-	kindDecoders map[reflect.Kind]ValueDecoder
-
-	typeMap map[bsontype.Type]reflect.Type
-
-	mu sync.RWMutex
+	registry *Registry
 }
 
 // NewRegistryBuilder creates a new empty RegistryBuilder.
+//
+// Deprecated: Use NewRegistry instead.
 func NewRegistryBuilder() *RegistryBuilder {
 	return &RegistryBuilder{
-		typeEncoders: make(map[reflect.Type]ValueEncoder),
-		typeDecoders: make(map[reflect.Type]ValueDecoder),
-
-		interfaceEncoders: make([]interfaceValueEncoder, 0),
-		interfaceDecoders: make([]interfaceValueDecoder, 0),
-
-		kindEncoders: make(map[reflect.Kind]ValueEncoder),
-		kindDecoders: make(map[reflect.Kind]ValueDecoder),
-
-		typeMap: make(map[bsontype.Type]reflect.Type),
+		registry: NewRegistry(),
 	}
 }
 
-func buildDefaultRegistry() *Registry {
-	rb := NewRegistryBuilder()
-	defaultValueEncoders.RegisterDefaultEncoders(rb)
-	defaultValueDecoders.RegisterDefaultDecoders(rb)
-	return rb.Build()
-}
-
 // RegisterCodec will register the provided ValueCodec for the provided type.
+//
+// Deprecated: Use Registry.RegisterTypeEncoder and Registry.RegisterTypeDecoder instead.
 func (rb *RegistryBuilder) RegisterCodec(t reflect.Type, codec ValueCodec) *RegistryBuilder {
 	rb.RegisterTypeEncoder(t, codec)
 	rb.RegisterTypeDecoder(t, codec)
@@ -120,31 +97,22 @@ func (rb *RegistryBuilder) RegisterCodec(t reflect.Type, codec ValueCodec) *Regi
 // The type will be used directly, so an encoder can be registered for a type and a different encoder can be registered
 // for a pointer to that type.
 //
-// If the given type is an interface, the encoder will be called when marshalling a type that is that interface. It
-// will not be called when marshalling a non-interface type that implements the interface.
+// If the given type is an interface, the encoder will be called when marshaling a type that is that interface. It
+// will not be called when marshaling a non-interface type that implements the interface.
+//
+// Deprecated: Use Registry.RegisterTypeEncoder instead.
 func (rb *RegistryBuilder) RegisterTypeEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
-	rb.typeEncoders[t] = enc
+	rb.registry.RegisterTypeEncoder(t, enc)
 	return rb
 }
 
 // RegisterHookEncoder will register an encoder for the provided interface type t. This encoder will be called when
-// marshalling a type if the type implements t or a pointer to the type implements t. If the provided type is not
+// marshaling a type if the type implements t or a pointer to the type implements t. If the provided type is not
 // an interface (i.e. t.Kind() != reflect.Interface), this method will panic.
+//
+// Deprecated: Use Registry.RegisterInterfaceEncoder instead.
 func (rb *RegistryBuilder) RegisterHookEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
-	if t.Kind() != reflect.Interface {
-		panicStr := fmt.Sprintf("RegisterHookEncoder expects a type with kind reflect.Interface, "+
-			"got type %s with kind %s", t, t.Kind())
-		panic(panicStr)
-	}
-
-	for idx, encoder := range rb.interfaceEncoders {
-		if encoder.i == t {
-			rb.interfaceEncoders[idx].ve = enc
-			return rb
-		}
-	}
-
-	rb.interfaceEncoders = append(rb.interfaceEncoders, interfaceValueEncoder{i: t, ve: enc})
+	rb.registry.RegisterInterfaceEncoder(t, enc)
 	return rb
 }
 
@@ -153,97 +121,78 @@ func (rb *RegistryBuilder) RegisterHookEncoder(t reflect.Type, enc ValueEncoder)
 // The type will be used directly, so a decoder can be registered for a type and a different decoder can be registered
 // for a pointer to that type.
 //
-// If the given type is an interface, the decoder will be called when unmarshalling into a type that is that interface.
-// It will not be called when unmarshalling into a non-interface type that implements the interface.
+// If the given type is an interface, the decoder will be called when unmarshaling into a type that is that interface.
+// It will not be called when unmarshaling into a non-interface type that implements the interface.
+//
+// Deprecated: Use Registry.RegisterTypeDecoder instead.
 func (rb *RegistryBuilder) RegisterTypeDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
-	rb.typeDecoders[t] = dec
+	rb.registry.RegisterTypeDecoder(t, dec)
 	return rb
 }
 
 // RegisterHookDecoder will register an decoder for the provided interface type t. This decoder will be called when
-// unmarshalling into a type if the type implements t or a pointer to the type implements t. If the provided type is not
+// unmarshaling into a type if the type implements t or a pointer to the type implements t. If the provided type is not
 // an interface (i.e. t.Kind() != reflect.Interface), this method will panic.
+//
+// Deprecated: Use Registry.RegisterInterfaceDecoder instead.
 func (rb *RegistryBuilder) RegisterHookDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
-	if t.Kind() != reflect.Interface {
-		panicStr := fmt.Sprintf("RegisterHookDecoder expects a type with kind reflect.Interface, "+
-			"got type %s with kind %s", t, t.Kind())
-		panic(panicStr)
-	}
-
-	for idx, decoder := range rb.interfaceDecoders {
-		if decoder.i == t {
-			rb.interfaceDecoders[idx].vd = dec
-			return rb
-		}
-	}
-
-	rb.interfaceDecoders = append(rb.interfaceDecoders, interfaceValueDecoder{i: t, vd: dec})
+	rb.registry.RegisterInterfaceDecoder(t, dec)
 	return rb
 }
 
 // RegisterEncoder registers the provided type and encoder pair.
 //
-// Deprecated: Use RegisterTypeEncoder or RegisterHookEncoder instead.
+// Deprecated: Use Registry.RegisterTypeEncoder or Registry.RegisterInterfaceEncoder instead.
 func (rb *RegistryBuilder) RegisterEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
 	if t == tEmpty {
-		rb.typeEncoders[t] = enc
+		rb.registry.RegisterTypeEncoder(t, enc)
 		return rb
 	}
 	switch t.Kind() {
 	case reflect.Interface:
-		for idx, ir := range rb.interfaceEncoders {
-			if ir.i == t {
-				rb.interfaceEncoders[idx].ve = enc
-				return rb
-			}
-		}
-
-		rb.interfaceEncoders = append(rb.interfaceEncoders, interfaceValueEncoder{i: t, ve: enc})
+		rb.registry.RegisterInterfaceEncoder(t, enc)
 	default:
-		rb.typeEncoders[t] = enc
+		rb.registry.RegisterTypeEncoder(t, enc)
 	}
 	return rb
 }
 
 // RegisterDecoder registers the provided type and decoder pair.
 //
-// Deprecated: Use RegisterTypeDecoder or RegisterHookDecoder instead.
+// Deprecated: Use Registry.RegisterTypeDecoder or Registry.RegisterInterfaceDecoder instead.
 func (rb *RegistryBuilder) RegisterDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
 	if t == nil {
-		rb.typeDecoders[nil] = dec
+		rb.registry.RegisterTypeDecoder(t, dec)
 		return rb
 	}
 	if t == tEmpty {
-		rb.typeDecoders[t] = dec
+		rb.registry.RegisterTypeDecoder(t, dec)
 		return rb
 	}
 	switch t.Kind() {
 	case reflect.Interface:
-		for idx, ir := range rb.interfaceDecoders {
-			if ir.i == t {
-				rb.interfaceDecoders[idx].vd = dec
-				return rb
-			}
-		}
-
-		rb.interfaceDecoders = append(rb.interfaceDecoders, interfaceValueDecoder{i: t, vd: dec})
+		rb.registry.RegisterInterfaceDecoder(t, dec)
 	default:
-		rb.typeDecoders[t] = dec
+		rb.registry.RegisterTypeDecoder(t, dec)
 	}
 	return rb
 }
 
-// RegisterDefaultEncoder will registr the provided ValueEncoder to the provided
+// RegisterDefaultEncoder will register the provided ValueEncoder to the provided
 // kind.
+//
+// Deprecated: Use Registry.RegisterKindEncoder instead.
 func (rb *RegistryBuilder) RegisterDefaultEncoder(kind reflect.Kind, enc ValueEncoder) *RegistryBuilder {
-	rb.kindEncoders[kind] = enc
+	rb.registry.RegisterKindEncoder(kind, enc)
 	return rb
 }
 
 // RegisterDefaultDecoder will register the provided ValueDecoder to the
 // provided kind.
+//
+// Deprecated: Use Registry.RegisterKindDecoder instead.
 func (rb *RegistryBuilder) RegisterDefaultDecoder(kind reflect.Kind, dec ValueDecoder) *RegistryBuilder {
-	rb.kindDecoders[kind] = dec
+	rb.registry.RegisterKindDecoder(kind, dec)
 	return rb
 }
 
@@ -256,120 +205,233 @@ func (rb *RegistryBuilder) RegisterDefaultDecoder(kind reflect.Kind, dec ValueDe
 // to decode to bson.Raw, use the following code:
 //
 //	rb.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(bson.Raw{}))
+//
+// Deprecated: Use Registry.RegisterTypeMapEntry instead.
 func (rb *RegistryBuilder) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) *RegistryBuilder {
-	rb.typeMap[bt] = rt
+	rb.registry.RegisterTypeMapEntry(bt, rt)
 	return rb
 }
 
 // Build creates a Registry from the current state of this RegistryBuilder.
+//
+// Deprecated: Use NewRegistry instead.
 func (rb *RegistryBuilder) Build() *Registry {
-	registry := new(Registry)
-
-	registry.typeEncoders = make(map[reflect.Type]ValueEncoder)
-	for t, enc := range rb.typeEncoders {
-		registry.typeEncoders[t] = enc
+	r := &Registry{
+		interfaceEncoders: append([]interfaceValueEncoder(nil), rb.registry.interfaceEncoders...),
+		interfaceDecoders: append([]interfaceValueDecoder(nil), rb.registry.interfaceDecoders...),
+		typeEncoders:      rb.registry.typeEncoders.Clone(),
+		typeDecoders:      rb.registry.typeDecoders.Clone(),
+		kindEncoders:      rb.registry.kindEncoders.Clone(),
+		kindDecoders:      rb.registry.kindDecoders.Clone(),
 	}
+	rb.registry.typeMap.Range(func(k, v interface{}) bool {
+		if k != nil && v != nil {
+			r.typeMap.Store(k, v)
+		}
+		return true
+	})
+	return r
+}
 
-	registry.typeDecoders = make(map[reflect.Type]ValueDecoder)
-	for t, dec := range rb.typeDecoders {
-		registry.typeDecoders[t] = dec
+// A Registry is used to store and retrieve codecs for types and interfaces. This type is the main
+// typed passed around and Encoders and Decoders are constructed from it.
+type Registry struct {
+	interfaceEncoders []interfaceValueEncoder
+	interfaceDecoders []interfaceValueDecoder
+	typeEncoders      *typeEncoderCache
+	typeDecoders      *typeDecoderCache
+	kindEncoders      *kindEncoderCache
+	kindDecoders      *kindDecoderCache
+	typeMap           sync.Map // map[bsontype.Type]reflect.Type
+}
+
+// NewRegistry creates a new empty Registry.
+func NewRegistry() *Registry {
+	return &Registry{
+		typeEncoders: new(typeEncoderCache),
+		typeDecoders: new(typeDecoderCache),
+		kindEncoders: new(kindEncoderCache),
+		kindDecoders: new(kindDecoderCache),
 	}
+}
+
+// RegisterTypeEncoder registers the provided ValueEncoder for the provided type.
+//
+// The type will be used as provided, so an encoder can be registered for a type and a different
+// encoder can be registered for a pointer to that type.
+//
+// If the given type is an interface, the encoder will be called when marshaling a type that is
+// that interface. It will not be called when marshaling a non-interface type that implements the
+// interface. To get the latter behavior, call RegisterHookEncoder instead.
+//
+// RegisterTypeEncoder should not be called concurrently with any other Registry method.
+func (r *Registry) RegisterTypeEncoder(valueType reflect.Type, enc ValueEncoder) {
+	r.typeEncoders.Store(valueType, enc)
+}
+
+// RegisterTypeDecoder registers the provided ValueDecoder for the provided type.
+//
+// The type will be used as provided, so a decoder can be registered for a type and a different
+// decoder can be registered for a pointer to that type.
+//
+// If the given type is an interface, the decoder will be called when unmarshaling into a type that
+// is that interface. It will not be called when unmarshaling into a non-interface type that
+// implements the interface. To get the latter behavior, call RegisterHookDecoder instead.
+//
+// RegisterTypeDecoder should not be called concurrently with any other Registry method.
+func (r *Registry) RegisterTypeDecoder(valueType reflect.Type, dec ValueDecoder) {
+	r.typeDecoders.Store(valueType, dec)
+}
 
-	registry.interfaceEncoders = make([]interfaceValueEncoder, len(rb.interfaceEncoders))
-	copy(registry.interfaceEncoders, rb.interfaceEncoders)
+// RegisterKindEncoder registers the provided ValueEncoder for the provided kind.
+//
+// Use RegisterKindEncoder to register an encoder for any type with the same underlying kind. For
+// example, consider the type MyInt defined as
+//
+//	type MyInt int32
+//
+// To define an encoder for MyInt and int32, use RegisterKindEncoder like
+//
+//	reg.RegisterKindEncoder(reflect.Int32, myEncoder)
+//
+// RegisterKindEncoder should not be called concurrently with any other Registry method.
+func (r *Registry) RegisterKindEncoder(kind reflect.Kind, enc ValueEncoder) {
+	r.kindEncoders.Store(kind, enc)
+}
 
-	registry.interfaceDecoders = make([]interfaceValueDecoder, len(rb.interfaceDecoders))
-	copy(registry.interfaceDecoders, rb.interfaceDecoders)
+// RegisterKindDecoder registers the provided ValueDecoder for the provided kind.
+//
+// Use RegisterKindDecoder to register a decoder for any type with the same underlying kind. For
+// example, consider the type MyInt defined as
+//
+//	type MyInt int32
+//
+// To define an decoder for MyInt and int32, use RegisterKindDecoder like
+//
+//	reg.RegisterKindDecoder(reflect.Int32, myDecoder)
+//
+// RegisterKindDecoder should not be called concurrently with any other Registry method.
+func (r *Registry) RegisterKindDecoder(kind reflect.Kind, dec ValueDecoder) {
+	r.kindDecoders.Store(kind, dec)
+}
 
-	registry.kindEncoders = make(map[reflect.Kind]ValueEncoder)
-	for kind, enc := range rb.kindEncoders {
-		registry.kindEncoders[kind] = enc
+// RegisterInterfaceEncoder registers an encoder for the provided interface type iface. This encoder will
+// be called when marshaling a type if the type implements iface or a pointer to the type
+// implements iface. If the provided type is not an interface
+// (i.e. iface.Kind() != reflect.Interface), this method will panic.
+//
+// RegisterInterfaceEncoder should not be called concurrently with any other Registry method.
+func (r *Registry) RegisterInterfaceEncoder(iface reflect.Type, enc ValueEncoder) {
+	if iface.Kind() != reflect.Interface {
+		panicStr := fmt.Errorf("RegisterInterfaceEncoder expects a type with kind reflect.Interface, "+
+			"got type %s with kind %s", iface, iface.Kind())
+		panic(panicStr)
 	}
 
-	registry.kindDecoders = make(map[reflect.Kind]ValueDecoder)
-	for kind, dec := range rb.kindDecoders {
-		registry.kindDecoders[kind] = dec
+	for idx, encoder := range r.interfaceEncoders {
+		if encoder.i == iface {
+			r.interfaceEncoders[idx].ve = enc
+			return
+		}
+	}
+
+	r.interfaceEncoders = append(r.interfaceEncoders, interfaceValueEncoder{i: iface, ve: enc})
+}
+
+// RegisterInterfaceDecoder registers an decoder for the provided interface type iface. This decoder will
+// be called when unmarshaling into a type if the type implements iface or a pointer to the type
+// implements iface. If the provided type is not an interface (i.e. iface.Kind() != reflect.Interface),
+// this method will panic.
+//
+// RegisterInterfaceDecoder should not be called concurrently with any other Registry method.
+func (r *Registry) RegisterInterfaceDecoder(iface reflect.Type, dec ValueDecoder) {
+	if iface.Kind() != reflect.Interface {
+		panicStr := fmt.Errorf("RegisterInterfaceDecoder expects a type with kind reflect.Interface, "+
+			"got type %s with kind %s", iface, iface.Kind())
+		panic(panicStr)
 	}
 
-	registry.typeMap = make(map[bsontype.Type]reflect.Type)
-	for bt, rt := range rb.typeMap {
-		registry.typeMap[bt] = rt
+	for idx, decoder := range r.interfaceDecoders {
+		if decoder.i == iface {
+			r.interfaceDecoders[idx].vd = dec
+			return
+		}
 	}
 
-	return registry
+	r.interfaceDecoders = append(r.interfaceDecoders, interfaceValueDecoder{i: iface, vd: dec})
 }
 
-// LookupEncoder inspects the registry for an encoder for the given type. The lookup precedence works as follows:
+// RegisterTypeMapEntry will register the provided type to the BSON type. The primary usage for this
+// mapping is decoding situations where an empty interface is used and a default type needs to be
+// created and decoded into.
 //
-// 1. An encoder registered for the exact type. If the given type represents an interface, an encoder registered using
-// RegisterTypeEncoder for the interface will be selected.
+// By default, BSON documents will decode into interface{} values as bson.D. To change the default type for BSON
+// documents, a type map entry for bsontype.EmbeddedDocument should be registered. For example, to force BSON documents
+// to decode to bson.Raw, use the following code:
 //
-// 2. An encoder registered using RegisterHookEncoder for an interface implemented by the type or by a pointer to the
-// type.
+//	reg.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(bson.Raw{}))
+func (r *Registry) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) {
+	r.typeMap.Store(bt, rt)
+}
+
+// LookupEncoder returns the first matching encoder in the Registry. It uses the following lookup
+// order:
+//
+// 1. An encoder registered for the exact type. If the given type is an interface, an encoder
+// registered using RegisterTypeEncoder for that interface will be selected.
 //
-// 3. An encoder registered for the reflect.Kind of the value.
+// 2. An encoder registered using RegisterInterfaceEncoder for an interface implemented by the type
+// or by a pointer to the type.
 //
-// If no encoder is found, an error of type ErrNoEncoder is returned.
-func (r *Registry) LookupEncoder(t reflect.Type) (ValueEncoder, error) {
-	encodererr := ErrNoEncoder{Type: t}
-	r.mu.RLock()
-	enc, found := r.lookupTypeEncoder(t)
-	r.mu.RUnlock()
+// 3. An encoder registered using RegisterKindEncoder for the kind of value.
+//
+// If no encoder is found, an error of type ErrNoEncoder is returned. LookupEncoder is safe for
+// concurrent use by multiple goroutines after all codecs and encoders are registered.
+func (r *Registry) LookupEncoder(valueType reflect.Type) (ValueEncoder, error) {
+	if valueType == nil {
+		return nil, ErrNoEncoder{Type: valueType}
+	}
+	enc, found := r.lookupTypeEncoder(valueType)
 	if found {
 		if enc == nil {
-			return nil, ErrNoEncoder{Type: t}
+			return nil, ErrNoEncoder{Type: valueType}
 		}
 		return enc, nil
 	}
 
-	enc, found = r.lookupInterfaceEncoder(t, true)
+	enc, found = r.lookupInterfaceEncoder(valueType, true)
 	if found {
-		r.mu.Lock()
-		r.typeEncoders[t] = enc
-		r.mu.Unlock()
-		return enc, nil
-	}
-
-	if t == nil {
-		r.mu.Lock()
-		r.typeEncoders[t] = nil
-		r.mu.Unlock()
-		return nil, encodererr
+		return r.typeEncoders.LoadOrStore(valueType, enc), nil
 	}
 
-	enc, found = r.kindEncoders[t.Kind()]
-	if !found {
-		r.mu.Lock()
-		r.typeEncoders[t] = nil
-		r.mu.Unlock()
-		return nil, encodererr
+	if v, ok := r.kindEncoders.Load(valueType.Kind()); ok {
+		return r.storeTypeEncoder(valueType, v), nil
 	}
+	return nil, ErrNoEncoder{Type: valueType}
+}
 
-	r.mu.Lock()
-	r.typeEncoders[t] = enc
-	r.mu.Unlock()
-	return enc, nil
+func (r *Registry) storeTypeEncoder(rt reflect.Type, enc ValueEncoder) ValueEncoder {
+	return r.typeEncoders.LoadOrStore(rt, enc)
 }
 
-func (r *Registry) lookupTypeEncoder(t reflect.Type) (ValueEncoder, bool) {
-	enc, found := r.typeEncoders[t]
-	return enc, found
+func (r *Registry) lookupTypeEncoder(rt reflect.Type) (ValueEncoder, bool) {
+	return r.typeEncoders.Load(rt)
 }
 
-func (r *Registry) lookupInterfaceEncoder(t reflect.Type, allowAddr bool) (ValueEncoder, bool) {
-	if t == nil {
+func (r *Registry) lookupInterfaceEncoder(valueType reflect.Type, allowAddr bool) (ValueEncoder, bool) {
+	if valueType == nil {
 		return nil, false
 	}
 	for _, ienc := range r.interfaceEncoders {
-		if t.Implements(ienc.i) {
+		if valueType.Implements(ienc.i) {
 			return ienc.ve, true
 		}
-		if allowAddr && t.Kind() != reflect.Ptr && reflect.PtrTo(t).Implements(ienc.i) {
-			// if *t implements an interface, this will catch if t implements an interface further ahead
-			// in interfaceEncoders
-			defaultEnc, found := r.lookupInterfaceEncoder(t, false)
+		if allowAddr && valueType.Kind() != reflect.Ptr && reflect.PtrTo(valueType).Implements(ienc.i) {
+			// if *t implements an interface, this will catch if t implements an interface further
+			// ahead in interfaceEncoders
+			defaultEnc, found := r.lookupInterfaceEncoder(valueType, false)
 			if !found {
-				defaultEnc = r.kindEncoders[t.Kind()]
+				defaultEnc, _ = r.kindEncoders.Load(valueType.Kind())
 			}
 			return newCondAddrEncoder(ienc.ve, defaultEnc), true
 		}
@@ -377,70 +439,61 @@ func (r *Registry) lookupInterfaceEncoder(t reflect.Type, allowAddr bool) (Value
 	return nil, false
 }
 
-// LookupDecoder inspects the registry for an decoder for the given type. The lookup precedence works as follows:
+// LookupDecoder returns the first matching decoder in the Registry. It uses the following lookup
+// order:
 //
-// 1. A decoder registered for the exact type. If the given type represents an interface, a decoder registered using
-// RegisterTypeDecoder for the interface will be selected.
+// 1. A decoder registered for the exact type. If the given type is an interface, a decoder
+// registered using RegisterTypeDecoder for that interface will be selected.
 //
-// 2. A decoder registered using RegisterHookDecoder for an interface implemented by the type or by a pointer to the
-// type.
+// 2. A decoder registered using RegisterInterfaceDecoder for an interface implemented by the type or by
+// a pointer to the type.
 //
-// 3. A decoder registered for the reflect.Kind of the value.
+// 3. A decoder registered using RegisterKindDecoder for the kind of value.
 //
-// If no decoder is found, an error of type ErrNoDecoder is returned.
-func (r *Registry) LookupDecoder(t reflect.Type) (ValueDecoder, error) {
-	if t == nil {
+// If no decoder is found, an error of type ErrNoDecoder is returned. LookupDecoder is safe for
+// concurrent use by multiple goroutines after all codecs and decoders are registered.
+func (r *Registry) LookupDecoder(valueType reflect.Type) (ValueDecoder, error) {
+	if valueType == nil {
 		return nil, ErrNilType
 	}
-	decodererr := ErrNoDecoder{Type: t}
-	r.mu.RLock()
-	dec, found := r.lookupTypeDecoder(t)
-	r.mu.RUnlock()
+	dec, found := r.lookupTypeDecoder(valueType)
 	if found {
 		if dec == nil {
-			return nil, ErrNoDecoder{Type: t}
+			return nil, ErrNoDecoder{Type: valueType}
 		}
 		return dec, nil
 	}
 
-	dec, found = r.lookupInterfaceDecoder(t, true)
+	dec, found = r.lookupInterfaceDecoder(valueType, true)
 	if found {
-		r.mu.Lock()
-		r.typeDecoders[t] = dec
-		r.mu.Unlock()
-		return dec, nil
+		return r.storeTypeDecoder(valueType, dec), nil
 	}
 
-	dec, found = r.kindDecoders[t.Kind()]
-	if !found {
-		r.mu.Lock()
-		r.typeDecoders[t] = nil
-		r.mu.Unlock()
-		return nil, decodererr
+	if v, ok := r.kindDecoders.Load(valueType.Kind()); ok {
+		return r.storeTypeDecoder(valueType, v), nil
 	}
+	return nil, ErrNoDecoder{Type: valueType}
+}
 
-	r.mu.Lock()
-	r.typeDecoders[t] = dec
-	r.mu.Unlock()
-	return dec, nil
+func (r *Registry) lookupTypeDecoder(valueType reflect.Type) (ValueDecoder, bool) {
+	return r.typeDecoders.Load(valueType)
 }
 
-func (r *Registry) lookupTypeDecoder(t reflect.Type) (ValueDecoder, bool) {
-	dec, found := r.typeDecoders[t]
-	return dec, found
+func (r *Registry) storeTypeDecoder(typ reflect.Type, dec ValueDecoder) ValueDecoder {
+	return r.typeDecoders.LoadOrStore(typ, dec)
 }
 
-func (r *Registry) lookupInterfaceDecoder(t reflect.Type, allowAddr bool) (ValueDecoder, bool) {
+func (r *Registry) lookupInterfaceDecoder(valueType reflect.Type, allowAddr bool) (ValueDecoder, bool) {
 	for _, idec := range r.interfaceDecoders {
-		if t.Implements(idec.i) {
+		if valueType.Implements(idec.i) {
 			return idec.vd, true
 		}
-		if allowAddr && t.Kind() != reflect.Ptr && reflect.PtrTo(t).Implements(idec.i) {
-			// if *t implements an interface, this will catch if t implements an interface further ahead
-			// in interfaceDecoders
-			defaultDec, found := r.lookupInterfaceDecoder(t, false)
+		if allowAddr && valueType.Kind() != reflect.Ptr && reflect.PtrTo(valueType).Implements(idec.i) {
+			// if *t implements an interface, this will catch if t implements an interface further
+			// ahead in interfaceDecoders
+			defaultDec, found := r.lookupInterfaceDecoder(valueType, false)
 			if !found {
-				defaultDec = r.kindDecoders[t.Kind()]
+				defaultDec, _ = r.kindDecoders.Load(valueType.Kind())
 			}
 			return newCondAddrDecoder(idec.vd, defaultDec), true
 		}
@@ -450,12 +503,14 @@ func (r *Registry) lookupInterfaceDecoder(t reflect.Type, allowAddr bool) (Value
 
 // LookupTypeMapEntry inspects the registry's type map for a Go type for the corresponding BSON
 // type. If no type is found, ErrNoTypeMapEntry is returned.
+//
+// LookupTypeMapEntry should not be called concurrently with any other Registry method.
 func (r *Registry) LookupTypeMapEntry(bt bsontype.Type) (reflect.Type, error) {
-	t, ok := r.typeMap[bt]
-	if !ok || t == nil {
+	v, ok := r.typeMap.Load(bt)
+	if v == nil || !ok {
 		return nil, ErrNoTypeMapEntry{Type: bt}
 	}
-	return t, nil
+	return v.(reflect.Type), nil
 }
 
 type interfaceValueEncoder struct {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go
index 3c1b6b86..14c9fd25 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go
@@ -7,6 +7,7 @@
 package bsoncodec
 
 import (
+	"errors"
 	"fmt"
 	"reflect"
 
@@ -19,13 +20,35 @@ import (
 var defaultSliceCodec = NewSliceCodec()
 
 // SliceCodec is the Codec used for slice values.
+//
+// Deprecated: SliceCodec will not be directly configurable in Go Driver 2.0. To
+// configure the slice encode and decode behavior, use the configuration methods
+// on a [go.mongodb.org/mongo-driver/bson.Encoder] or
+// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the slice encode and
+// decode behavior for a mongo.Client, use
+// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions].
+//
+// For example, to configure a mongo.Client to marshal nil Go slices as empty
+// BSON arrays, use:
+//
+//	opt := options.Client().SetBSONOptions(&options.BSONOptions{
+//	    NilSliceAsEmpty: true,
+//	})
+//
+// See the deprecation notice for each field in SliceCodec for the corresponding
+// settings.
 type SliceCodec struct {
+	// EncodeNilAsEmpty causes EncodeValue to marshal nil Go slices as empty BSON arrays instead of
+	// BSON null.
+	//
+	// Deprecated: Use bson.Encoder.NilSliceAsEmpty instead.
 	EncodeNilAsEmpty bool
 }
 
-var _ ValueCodec = &MapCodec{}
-
 // NewSliceCodec returns a MapCodec with options opts.
+//
+// Deprecated: NewSliceCodec will not be available in Go Driver 2.0. See
+// [SliceCodec] for more details.
 func NewSliceCodec(opts ...*bsonoptions.SliceCodecOptions) *SliceCodec {
 	sliceOpt := bsonoptions.MergeSliceCodecOptions(opts...)
 
@@ -42,21 +65,19 @@ func (sc SliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val re
 		return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
 	}
 
-	if val.IsNil() && !sc.EncodeNilAsEmpty {
+	if val.IsNil() && !sc.EncodeNilAsEmpty && !ec.nilSliceAsEmpty {
 		return vw.WriteNull()
 	}
 
 	// If we have a []byte we want to treat it as a binary instead of as an array.
 	if val.Type().Elem() == tByte {
-		var byteSlice []byte
-		for idx := 0; idx < val.Len(); idx++ {
-			byteSlice = append(byteSlice, val.Index(idx).Interface().(byte))
-		}
+		byteSlice := make([]byte, val.Len())
+		reflect.Copy(reflect.ValueOf(byteSlice), val)
 		return vw.WriteBinary(byteSlice)
 	}
 
 	// If we have a []primitive.E we want to treat it as a document instead of as an array.
-	if val.Type().ConvertibleTo(tD) {
+	if val.Type() == tD || val.Type().ConvertibleTo(tD) {
 		d := val.Convert(tD).Interface().(primitive.D)
 
 		dw, err := vw.WriteDocument()
@@ -87,7 +108,7 @@ func (sc SliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val re
 
 	for idx := 0; idx < val.Len(); idx++ {
 		currEncoder, currVal, lookupErr := defaultValueEncoders.lookupElementEncoder(ec, encoder, val.Index(idx))
-		if lookupErr != nil && lookupErr != errInvalidValue {
+		if lookupErr != nil && !errors.Is(lookupErr, errInvalidValue) {
 			return lookupErr
 		}
 
@@ -96,7 +117,7 @@ func (sc SliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val re
 			return err
 		}
 
-		if lookupErr == errInvalidValue {
+		if errors.Is(lookupErr, errInvalidValue) {
 			err = vw.WriteNull()
 			if err != nil {
 				return err
@@ -145,11 +166,8 @@ func (sc *SliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val r
 		if val.IsNil() {
 			val.Set(reflect.MakeSlice(val.Type(), 0, len(data)))
 		}
-
 		val.SetLen(0)
-		for _, elem := range data {
-			val.Set(reflect.Append(val, reflect.ValueOf(elem)))
-		}
+		val.Set(reflect.AppendSlice(val, reflect.ValueOf(data)))
 		return nil
 	case bsontype.String:
 		if sliceType := val.Type().Elem(); sliceType != tByte {
@@ -164,11 +182,8 @@ func (sc *SliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val r
 		if val.IsNil() {
 			val.Set(reflect.MakeSlice(val.Type(), 0, len(byteStr)))
 		}
-
 		val.SetLen(0)
-		for _, elem := range byteStr {
-			val.Set(reflect.Append(val, reflect.ValueOf(elem)))
-		}
+		val.Set(reflect.AppendSlice(val, reflect.ValueOf(byteStr)))
 		return nil
 	default:
 		return fmt.Errorf("cannot decode %v into a slice", vrType)
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go
index 5332b7c3..a8f885a8 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go
@@ -15,26 +15,46 @@ import (
 	"go.mongodb.org/mongo-driver/bson/bsontype"
 )
 
-// StringCodec is the Codec used for struct values.
+// StringCodec is the Codec used for string values.
+//
+// Deprecated: StringCodec will not be directly accessible in Go Driver 2.0. To
+// override the default string encode and decode behavior, create a new registry
+// with [go.mongodb.org/mongo-driver/bson.NewRegistry] and register a new
+// encoder and decoder for strings.
+//
+// For example,
+//
+//	reg := bson.NewRegistry()
+//	reg.RegisterKindEncoder(reflect.String, myStringEncoder)
+//	reg.RegisterKindDecoder(reflect.String, myStringDecoder)
 type StringCodec struct {
+	// DecodeObjectIDAsHex specifies if object IDs should be decoded as their hex representation.
+	// If false, a string made from the raw object ID bytes will be used. Defaults to true.
+	//
+	// Deprecated: Decoding object IDs as raw bytes will not be supported in Go Driver 2.0.
 	DecodeObjectIDAsHex bool
 }
 
 var (
 	defaultStringCodec = NewStringCodec()
 
-	_ ValueCodec  = defaultStringCodec
+	// Assert that defaultStringCodec satisfies the typeDecoder interface, which allows it to be
+	// used by collection type decoders (e.g. map, slice, etc) to set individual values in a
+	// collection.
 	_ typeDecoder = defaultStringCodec
 )
 
 // NewStringCodec returns a StringCodec with options opts.
+//
+// Deprecated: NewStringCodec will not be available in Go Driver 2.0. See
+// [StringCodec] for more details.
 func NewStringCodec(opts ...*bsonoptions.StringCodecOptions) *StringCodec {
 	stringOpt := bsonoptions.MergeStringCodecOptions(opts...)
 	return &StringCodec{*stringOpt.DecodeObjectIDAsHex}
 }
 
 // EncodeValue is the ValueEncoder for string types.
-func (sc *StringCodec) EncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (sc *StringCodec) EncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if val.Kind() != reflect.String {
 		return ValueEncoderError{
 			Name:     "StringEncodeValue",
@@ -46,7 +66,7 @@ func (sc *StringCodec) EncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, va
 	return vw.WriteString(val.String())
 }
 
-func (sc *StringCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
+func (sc *StringCodec) decodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
 	if t.Kind() != reflect.String {
 		return emptyValue, ValueDecoderError{
 			Name:     "StringDecodeValue",
@@ -71,6 +91,7 @@ func (sc *StringCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t ref
 		if sc.DecodeObjectIDAsHex {
 			str = oid.Hex()
 		} else {
+			// TODO(GODRIVER-2796): Return an error here instead of decoding to a garbled string.
 			byteArray := [12]byte(oid)
 			str = string(byteArray[:])
 		}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go
index be3f2081..f8d9690c 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go
@@ -59,14 +59,58 @@ type Zeroer interface {
 }
 
 // StructCodec is the Codec used for struct values.
+//
+// Deprecated: StructCodec will not be directly configurable in Go Driver 2.0.
+// To configure the struct encode and decode behavior, use the configuration
+// methods on a [go.mongodb.org/mongo-driver/bson.Encoder] or
+// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the struct encode
+// and decode behavior for a mongo.Client, use
+// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions].
+//
+// For example, to configure a mongo.Client to omit zero-value structs when
+// using the "omitempty" struct tag, use:
+//
+//	opt := options.Client().SetBSONOptions(&options.BSONOptions{
+//	    OmitZeroStruct: true,
+//	})
+//
+// See the deprecation notice for each field in StructCodec for the corresponding
+// settings.
 type StructCodec struct {
-	cache                            map[reflect.Type]*structDescription
-	l                                sync.RWMutex
-	parser                           StructTagParser
-	DecodeZeroStruct                 bool
-	DecodeDeepZeroInline             bool
-	EncodeOmitDefaultStruct          bool
-	AllowUnexportedFields            bool
+	cache  sync.Map // map[reflect.Type]*structDescription
+	parser StructTagParser
+
+	// DecodeZeroStruct causes DecodeValue to delete any existing values from Go structs in the
+	// destination value passed to Decode before unmarshaling BSON documents into them.
+	//
+	// Deprecated: Use bson.Decoder.ZeroStructs or options.BSONOptions.ZeroStructs instead.
+	DecodeZeroStruct bool
+
+	// DecodeDeepZeroInline causes DecodeValue to delete any existing values from Go structs in the
+	// destination value passed to Decode before unmarshaling BSON documents into them.
+	//
+	// Deprecated: DecodeDeepZeroInline will not be supported in Go Driver 2.0.
+	DecodeDeepZeroInline bool
+
+	// EncodeOmitDefaultStruct causes the Encoder to consider the zero value for a struct (e.g.
+	// MyStruct{}) as empty and omit it from the marshaled BSON when the "omitempty" struct tag
+	// option is set.
+	//
+	// Deprecated: Use bson.Encoder.OmitZeroStruct or options.BSONOptions.OmitZeroStruct instead.
+	EncodeOmitDefaultStruct bool
+
+	// AllowUnexportedFields allows encoding and decoding values from un-exported struct fields.
+	//
+	// Deprecated: AllowUnexportedFields does not work on recent versions of Go and will not be
+	// supported in Go Driver 2.0.
+	AllowUnexportedFields bool
+
+	// OverwriteDuplicatedInlinedFields, if false, causes EncodeValue to return an error if there is
+	// a duplicate field in the marshaled BSON when the "inline" struct tag option is set. The
+	// default value is true.
+	//
+	// Deprecated: Use bson.Encoder.ErrorOnInlineDuplicates or
+	// options.BSONOptions.ErrorOnInlineDuplicates instead.
 	OverwriteDuplicatedInlinedFields bool
 }
 
@@ -74,6 +118,9 @@ var _ ValueEncoder = &StructCodec{}
 var _ ValueDecoder = &StructCodec{}
 
 // NewStructCodec returns a StructCodec that uses p for struct tag parsing.
+//
+// Deprecated: NewStructCodec will not be available in Go Driver 2.0. See
+// [StructCodec] for more details.
 func NewStructCodec(p StructTagParser, opts ...*bsonoptions.StructCodecOptions) (*StructCodec, error) {
 	if p == nil {
 		return nil, errors.New("a StructTagParser must be provided to NewStructCodec")
@@ -82,7 +129,6 @@ func NewStructCodec(p StructTagParser, opts ...*bsonoptions.StructCodecOptions)
 	structOpt := bsonoptions.MergeStructCodecOptions(opts...)
 
 	codec := &StructCodec{
-		cache:  make(map[reflect.Type]*structDescription),
 		parser: p,
 	}
 
@@ -106,12 +152,12 @@ func NewStructCodec(p StructTagParser, opts ...*bsonoptions.StructCodecOptions)
 }
 
 // EncodeValue handles encoding generic struct types.
-func (sc *StructCodec) EncodeValue(r EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (sc *StructCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Kind() != reflect.Struct {
 		return ValueEncoderError{Name: "StructCodec.EncodeValue", Kinds: []reflect.Kind{reflect.Struct}, Received: val}
 	}
 
-	sd, err := sc.describeStruct(r.Registry, val.Type())
+	sd, err := sc.describeStruct(ec.Registry, val.Type(), ec.useJSONStructTags, ec.errorOnInlineDuplicates)
 	if err != nil {
 		return err
 	}
@@ -131,13 +177,13 @@ func (sc *StructCodec) EncodeValue(r EncodeContext, vw bsonrw.ValueWriter, val r
 			}
 		}
 
-		desc.encoder, rv, err = defaultValueEncoders.lookupElementEncoder(r, desc.encoder, rv)
+		desc.encoder, rv, err = defaultValueEncoders.lookupElementEncoder(ec, desc.encoder, rv)
 
-		if err != nil && err != errInvalidValue {
+		if err != nil && !errors.Is(err, errInvalidValue) {
 			return err
 		}
 
-		if err == errInvalidValue {
+		if errors.Is(err, errInvalidValue) {
 			if desc.omitEmpty {
 				continue
 			}
@@ -158,17 +204,17 @@ func (sc *StructCodec) EncodeValue(r EncodeContext, vw bsonrw.ValueWriter, val r
 
 		encoder := desc.encoder
 
-		var isZero bool
-		rvInterface := rv.Interface()
+		var empty bool
 		if cz, ok := encoder.(CodecZeroer); ok {
-			isZero = cz.IsTypeZero(rvInterface)
+			empty = cz.IsTypeZero(rv.Interface())
 		} else if rv.Kind() == reflect.Interface {
-			// sc.isZero will not treat an interface rv as an interface, so we need to check for the zero interface separately.
-			isZero = rv.IsNil()
+			// isEmpty will not treat an interface rv as an interface, so we need to check for the
+			// nil interface separately.
+			empty = rv.IsNil()
 		} else {
-			isZero = sc.isZero(rvInterface)
+			empty = isEmpty(rv, sc.EncodeOmitDefaultStruct || ec.omitZeroStruct)
 		}
-		if desc.omitEmpty && isZero {
+		if desc.omitEmpty && empty {
 			continue
 		}
 
@@ -177,7 +223,17 @@ func (sc *StructCodec) EncodeValue(r EncodeContext, vw bsonrw.ValueWriter, val r
 			return err
 		}
 
-		ectx := EncodeContext{Registry: r.Registry, MinSize: desc.minSize}
+		ectx := EncodeContext{
+			Registry:                ec.Registry,
+			MinSize:                 desc.minSize || ec.MinSize,
+			errorOnInlineDuplicates: ec.errorOnInlineDuplicates,
+			stringifyMapKeysWithFmt: ec.stringifyMapKeysWithFmt,
+			nilMapAsEmpty:           ec.nilMapAsEmpty,
+			nilSliceAsEmpty:         ec.nilSliceAsEmpty,
+			nilByteSliceAsEmpty:     ec.nilByteSliceAsEmpty,
+			omitZeroStruct:          ec.omitZeroStruct,
+			useJSONStructTags:       ec.useJSONStructTags,
+		}
 		err = encoder.EncodeValue(ectx, vw2, rv)
 		if err != nil {
 			return err
@@ -191,15 +247,15 @@ func (sc *StructCodec) EncodeValue(r EncodeContext, vw bsonrw.ValueWriter, val r
 			return exists
 		}
 
-		return defaultMapCodec.mapEncodeValue(r, dw, rv, collisionFn)
+		return defaultMapCodec.mapEncodeValue(ec, dw, rv, collisionFn)
 	}
 
 	return dw.WriteDocumentEnd()
 }
 
 func newDecodeError(key string, original error) error {
-	de, ok := original.(*DecodeError)
-	if !ok {
+	var de *DecodeError
+	if !errors.As(original, &de) {
 		return &DecodeError{
 			keys:    []string{key},
 			wrapped: original,
@@ -213,7 +269,7 @@ func newDecodeError(key string, original error) error {
 // DecodeValue implements the Codec interface.
 // By default, map types in val will not be cleared. If a map has existing key/value pairs, it will be extended with the new ones from vr.
 // For slices, the decoder will set the length of the slice to zero and append all elements. The underlying array will not be cleared.
-func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+func (sc *StructCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Kind() != reflect.Struct {
 		return ValueDecoderError{Name: "StructCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Struct}, Received: val}
 	}
@@ -238,12 +294,12 @@ func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val r
 		return fmt.Errorf("cannot decode %v into a %s", vrType, val.Type())
 	}
 
-	sd, err := sc.describeStruct(r.Registry, val.Type())
+	sd, err := sc.describeStruct(dc.Registry, val.Type(), dc.useJSONStructTags, false)
 	if err != nil {
 		return err
 	}
 
-	if sc.DecodeZeroStruct {
+	if sc.DecodeZeroStruct || dc.zeroStructs {
 		val.Set(reflect.Zero(val.Type()))
 	}
 	if sc.DecodeDeepZeroInline && sd.inline {
@@ -254,7 +310,7 @@ func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val r
 	var inlineMap reflect.Value
 	if sd.inlineMap >= 0 {
 		inlineMap = val.Field(sd.inlineMap)
-		decoder, err = r.LookupDecoder(inlineMap.Type().Elem())
+		decoder, err = dc.LookupDecoder(inlineMap.Type().Elem())
 		if err != nil {
 			return err
 		}
@@ -267,7 +323,7 @@ func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val r
 
 	for {
 		name, vr, err := dr.ReadElement()
-		if err == bsonrw.ErrEOD {
+		if errors.Is(err, bsonrw.ErrEOD) {
 			break
 		}
 		if err != nil {
@@ -298,8 +354,8 @@ func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val r
 			}
 
 			elem := reflect.New(inlineMap.Type().Elem()).Elem()
-			r.Ancestor = inlineMap.Type()
-			err = decoder.DecodeValue(r, vr, elem)
+			dc.Ancestor = inlineMap.Type()
+			err = decoder.DecodeValue(dc, vr, elem)
 			if err != nil {
 				return err
 			}
@@ -326,7 +382,17 @@ func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val r
 		}
 		field = field.Addr()
 
-		dctx := DecodeContext{Registry: r.Registry, Truncate: fd.truncate || r.Truncate}
+		dctx := DecodeContext{
+			Registry:            dc.Registry,
+			Truncate:            fd.truncate || dc.Truncate,
+			defaultDocumentType: dc.defaultDocumentType,
+			binaryAsSlice:       dc.binaryAsSlice,
+			useJSONStructTags:   dc.useJSONStructTags,
+			useLocalTimeZone:    dc.useLocalTimeZone,
+			zeroMaps:            dc.zeroMaps,
+			zeroStructs:         dc.zeroStructs,
+		}
+
 		if fd.decoder == nil {
 			return newDecodeError(fd.name, ErrNoDecoder{Type: field.Elem().Type()})
 		}
@@ -340,51 +406,35 @@ func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val r
 	return nil
 }
 
-func (sc *StructCodec) isZero(i interface{}) bool {
-	v := reflect.ValueOf(i)
-
-	// check the value validity
-	if !v.IsValid() {
-		return true
-	}
-
-	if z, ok := v.Interface().(Zeroer); ok && (v.Kind() != reflect.Ptr || !v.IsNil()) {
-		return z.IsZero()
+func isEmpty(v reflect.Value, omitZeroStruct bool) bool {
+	kind := v.Kind()
+	if (kind != reflect.Ptr || !v.IsNil()) && v.Type().Implements(tZeroer) {
+		return v.Interface().(Zeroer).IsZero()
 	}
-
-	switch v.Kind() {
+	switch kind {
 	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
 		return v.Len() == 0
-	case reflect.Bool:
-		return !v.Bool()
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return v.Int() == 0
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return v.Uint() == 0
-	case reflect.Float32, reflect.Float64:
-		return v.Float() == 0
-	case reflect.Interface, reflect.Ptr:
-		return v.IsNil()
 	case reflect.Struct:
-		if sc.EncodeOmitDefaultStruct {
-			vt := v.Type()
-			if vt == tTime {
-				return v.Interface().(time.Time).IsZero()
+		if !omitZeroStruct {
+			return false
+		}
+		vt := v.Type()
+		if vt == tTime {
+			return v.Interface().(time.Time).IsZero()
+		}
+		numField := vt.NumField()
+		for i := 0; i < numField; i++ {
+			ff := vt.Field(i)
+			if ff.PkgPath != "" && !ff.Anonymous {
+				continue // Private field
 			}
-			for i := 0; i < v.NumField(); i++ {
-				if vt.Field(i).PkgPath != "" && !vt.Field(i).Anonymous {
-					continue // Private field
-				}
-				fld := v.Field(i)
-				if !sc.isZero(fld.Interface()) {
-					return false
-				}
+			if !isEmpty(v.Field(i), omitZeroStruct) {
+				return false
 			}
-			return true
 		}
+		return true
 	}
-
-	return false
+	return !v.IsValid() || v.IsZero()
 }
 
 type structDescription struct {
@@ -435,16 +485,35 @@ func (bi byIndex) Less(i, j int) bool {
 	return len(bi[i].inline) < len(bi[j].inline)
 }
 
-func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescription, error) {
+func (sc *StructCodec) describeStruct(
+	r *Registry,
+	t reflect.Type,
+	useJSONStructTags bool,
+	errorOnDuplicates bool,
+) (*structDescription, error) {
 	// We need to analyze the struct, including getting the tags, collecting
 	// information about inlining, and create a map of the field name to the field.
-	sc.l.RLock()
-	ds, exists := sc.cache[t]
-	sc.l.RUnlock()
-	if exists {
-		return ds, nil
+	if v, ok := sc.cache.Load(t); ok {
+		return v.(*structDescription), nil
 	}
+	// TODO(charlie): Only describe the struct once when called
+	// concurrently with the same type.
+	ds, err := sc.describeStructSlow(r, t, useJSONStructTags, errorOnDuplicates)
+	if err != nil {
+		return nil, err
+	}
+	if v, loaded := sc.cache.LoadOrStore(t, ds); loaded {
+		ds = v.(*structDescription)
+	}
+	return ds, nil
+}
 
+func (sc *StructCodec) describeStructSlow(
+	r *Registry,
+	t reflect.Type,
+	useJSONStructTags bool,
+	errorOnDuplicates bool,
+) (*structDescription, error) {
 	numFields := t.NumField()
 	sd := &structDescription{
 		fm:        make(map[string]fieldDescription, numFields),
@@ -477,7 +546,14 @@ func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescr
 			decoder:   decoder,
 		}
 
-		stags, err := sc.parser.ParseStructTags(sf)
+		var stags StructTags
+		// If the caller requested that we use JSON struct tags, use the JSONFallbackStructTagParser
+		// instead of the parser defined on the codec.
+		if useJSONStructTags {
+			stags, err = JSONFallbackStructTagParser.ParseStructTags(sf)
+		} else {
+			stags, err = sc.parser.ParseStructTags(sf)
+		}
 		if err != nil {
 			return nil, err
 		}
@@ -507,7 +583,7 @@ func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescr
 				}
 				fallthrough
 			case reflect.Struct:
-				inlinesf, err := sc.describeStruct(r, sfType)
+				inlinesf, err := sc.describeStruct(r, sfType, useJSONStructTags, errorOnDuplicates)
 				if err != nil {
 					return nil, err
 				}
@@ -559,7 +635,7 @@ func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescr
 			continue
 		}
 		dominant, ok := dominantField(fields[i : i+advance])
-		if !ok || !sc.OverwriteDuplicatedInlinedFields {
+		if !ok || !sc.OverwriteDuplicatedInlinedFields || errorOnDuplicates {
 			return nil, fmt.Errorf("struct %s has duplicated key %s", t.String(), name)
 		}
 		sd.fl = append(sd.fl, dominant)
@@ -568,10 +644,6 @@ func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescr
 
 	sort.Sort(byIndex(sd.fl))
 
-	sc.l.Lock()
-	sc.cache[t] = sd
-	sc.l.Unlock()
-
 	return sd, nil
 }
 
@@ -629,21 +701,21 @@ func getInlineField(val reflect.Value, index []int) (reflect.Value, error) {
 
 // DeepZero returns recursive zero object
 func deepZero(st reflect.Type) (result reflect.Value) {
-	result = reflect.Indirect(reflect.New(st))
-
-	if result.Kind() == reflect.Struct {
-		for i := 0; i < result.NumField(); i++ {
-			if f := result.Field(i); f.Kind() == reflect.Ptr {
-				if f.CanInterface() {
-					if ft := reflect.TypeOf(f.Interface()); ft.Elem().Kind() == reflect.Struct {
-						result.Field(i).Set(recursivePointerTo(deepZero(ft.Elem())))
-					}
+	if st.Kind() == reflect.Struct {
+		numField := st.NumField()
+		for i := 0; i < numField; i++ {
+			if result == emptyValue {
+				result = reflect.Indirect(reflect.New(st))
+			}
+			f := result.Field(i)
+			if f.CanInterface() {
+				if f.Type().Kind() == reflect.Struct {
+					result.Field(i).Set(recursivePointerTo(deepZero(f.Type().Elem())))
 				}
 			}
 		}
 	}
-
-	return
+	return result
 }
 
 // recursivePointerTo calls reflect.New(v.Type) but recursively for its fields inside
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go
index 62708c5c..18d85bfb 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_tag_parser.go
@@ -12,12 +12,16 @@ import (
 )
 
 // StructTagParser returns the struct tags for a given struct field.
+//
+// Deprecated: Defining custom BSON struct tag parsers will not be supported in Go Driver 2.0.
 type StructTagParser interface {
 	ParseStructTags(reflect.StructField) (StructTags, error)
 }
 
 // StructTagParserFunc is an adapter that allows a generic function to be used
 // as a StructTagParser.
+//
+// Deprecated: Defining custom BSON struct tag parsers will not be supported in Go Driver 2.0.
 type StructTagParserFunc func(reflect.StructField) (StructTags, error)
 
 // ParseStructTags implements the StructTagParser interface.
@@ -50,7 +54,7 @@ func (stpf StructTagParserFunc) ParseStructTags(sf reflect.StructField) (StructT
 //	Skip       This struct field should be skipped. This is usually denoted by parsing a "-"
 //	           for the name.
 //
-// TODO(skriptble): Add tags for undefined as nil and for null as nil.
+// Deprecated: Defining custom BSON struct tag parsers will not be supported in Go Driver 2.0.
 type StructTags struct {
 	Name      string
 	OmitEmpty bool
@@ -85,6 +89,8 @@ type StructTags struct {
 // A struct tag either consisting entirely of '-' or with a bson key with a
 // value consisting entirely of '-' will return a StructTags with Skip true and
 // the remaining fields will be their default values.
+//
+// Deprecated: DefaultStructTagParser will be removed in Go Driver 2.0.
 var DefaultStructTagParser StructTagParserFunc = func(sf reflect.StructField) (StructTags, error) {
 	key := strings.ToLower(sf.Name)
 	tag, ok := sf.Tag.Lookup("bson")
@@ -125,6 +131,9 @@ func parseTags(key string, tag string) (StructTags, error) {
 // JSONFallbackStructTagParser has the same behavior as DefaultStructTagParser
 // but will also fallback to parsing the json tag instead on a field where the
 // bson tag isn't available.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.UseJSONStructTags] and
+// [go.mongodb.org/mongo-driver/bson.Decoder.UseJSONStructTags] instead.
 var JSONFallbackStructTagParser StructTagParserFunc = func(sf reflect.StructField) (StructTags, error) {
 	key := strings.ToLower(sf.Name)
 	tag, ok := sf.Tag.Lookup("bson")
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go
index ec7e30f7..22fb762c 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go
@@ -22,18 +22,42 @@ const (
 )
 
 // TimeCodec is the Codec used for time.Time values.
+//
+// Deprecated: TimeCodec will not be directly configurable in Go Driver 2.0.
+// To configure the time.Time encode and decode behavior, use the configuration
+// methods on a [go.mongodb.org/mongo-driver/bson.Encoder] or
+// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the time.Time encode
+// and decode behavior for a mongo.Client, use
+// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions].
+//
+// For example, to configure a mongo.Client to ..., use:
+//
+//	opt := options.Client().SetBSONOptions(&options.BSONOptions{
+//	    UseLocalTimeZone: true,
+//	})
+//
+// See the deprecation notice for each field in TimeCodec for the corresponding
+// settings.
 type TimeCodec struct {
+	// UseLocalTimeZone specifies if we should decode into the local time zone. Defaults to false.
+	//
+	// Deprecated: Use bson.Decoder.UseLocalTimeZone or options.BSONOptions.UseLocalTimeZone
+	// instead.
 	UseLocalTimeZone bool
 }
 
 var (
 	defaultTimeCodec = NewTimeCodec()
 
-	_ ValueCodec  = defaultTimeCodec
+	// Assert that defaultTimeCodec satisfies the typeDecoder interface, which allows it to be used
+	// by collection type decoders (e.g. map, slice, etc) to set individual values in a collection.
 	_ typeDecoder = defaultTimeCodec
 )
 
 // NewTimeCodec returns a TimeCodec with options opts.
+//
+// Deprecated: NewTimeCodec will not be available in Go Driver 2.0. See
+// [TimeCodec] for more details.
 func NewTimeCodec(opts ...*bsonoptions.TimeCodecOptions) *TimeCodec {
 	timeOpt := bsonoptions.MergeTimeCodecOptions(opts...)
 
@@ -95,7 +119,7 @@ func (tc *TimeCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t refle
 		return emptyValue, fmt.Errorf("cannot decode %v into a time.Time", vrType)
 	}
 
-	if !tc.UseLocalTimeZone {
+	if !tc.UseLocalTimeZone && !dc.useLocalTimeZone {
 		timeVal = timeVal.UTC()
 	}
 	return reflect.ValueOf(timeVal), nil
@@ -117,7 +141,7 @@ func (tc *TimeCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val re
 }
 
 // EncodeValue is the ValueEncoderFunc for time.TIme.
-func (tc *TimeCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+func (tc *TimeCodec) EncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tTime {
 		return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val}
 	}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go
index 07f4b70e..6ade17b7 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go
@@ -34,6 +34,7 @@ var tValueUnmarshaler = reflect.TypeOf((*ValueUnmarshaler)(nil)).Elem()
 var tMarshaler = reflect.TypeOf((*Marshaler)(nil)).Elem()
 var tUnmarshaler = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
 var tProxy = reflect.TypeOf((*Proxy)(nil)).Elem()
+var tZeroer = reflect.TypeOf((*Zeroer)(nil)).Elem()
 
 var tBinary = reflect.TypeOf(primitive.Binary{})
 var tUndefined = reflect.TypeOf(primitive.Undefined{})
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go
index 0b21ce99..39b07135 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go
@@ -17,18 +17,43 @@ import (
 )
 
 // UIntCodec is the Codec used for uint values.
+//
+// Deprecated: UIntCodec will not be directly configurable in Go Driver 2.0. To
+// configure the uint encode and decode behavior, use the configuration methods
+// on a [go.mongodb.org/mongo-driver/bson.Encoder] or
+// [go.mongodb.org/mongo-driver/bson.Decoder]. To configure the uint encode and
+// decode behavior for a mongo.Client, use
+// [go.mongodb.org/mongo-driver/mongo/options.ClientOptions.SetBSONOptions].
+//
+// For example, to configure a mongo.Client to marshal Go uint values as the
+// minimum BSON int size that can represent the value, use:
+//
+//	opt := options.Client().SetBSONOptions(&options.BSONOptions{
+//	    IntMinSize: true,
+//	})
+//
+// See the deprecation notice for each field in UIntCodec for the corresponding
+// settings.
 type UIntCodec struct {
+	// EncodeToMinSize causes EncodeValue to marshal Go uint values (excluding uint64) as the
+	// minimum BSON int size (either 32-bit or 64-bit) that can represent the integer value.
+	//
+	// Deprecated: Use bson.Encoder.IntMinSize or options.BSONOptions.IntMinSize instead.
 	EncodeToMinSize bool
 }
 
 var (
 	defaultUIntCodec = NewUIntCodec()
 
-	_ ValueCodec  = defaultUIntCodec
+	// Assert that defaultUIntCodec satisfies the typeDecoder interface, which allows it to be used
+	// by collection type decoders (e.g. map, slice, etc) to set individual values in a collection.
 	_ typeDecoder = defaultUIntCodec
 )
 
 // NewUIntCodec returns a UIntCodec with options opts.
+//
+// Deprecated: NewUIntCodec will not be available in Go Driver 2.0. See
+// [UIntCodec] for more details.
 func NewUIntCodec(opts ...*bsonoptions.UIntCodecOptions) *UIntCodec {
 	uintOpt := bsonoptions.MergeUIntCodecOptions(opts...)
 
@@ -139,11 +164,15 @@ func (uic *UIntCodec) decodeType(dc DecodeContext, vr bsonrw.ValueReader, t refl
 
 		return reflect.ValueOf(uint64(i64)), nil
 	case reflect.Uint:
-		if i64 < 0 || int64(uint(i64)) != i64 { // Can we fit this inside of an uint
+		if i64 < 0 {
+			return emptyValue, fmt.Errorf("%d overflows uint", i64)
+		}
+		v := uint64(i64)
+		if v > math.MaxUint { // Can we fit this inside of an uint
 			return emptyValue, fmt.Errorf("%d overflows uint", i64)
 		}
 
-		return reflect.ValueOf(uint(i64)), nil
+		return reflect.ValueOf(uint(v)), nil
 	default:
 		return emptyValue, ValueDecoderError{
 			Name:     "UintDecodeValue",
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/byte_slice_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/byte_slice_codec_options.go
index b1256a4d..996bd171 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/byte_slice_codec_options.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/byte_slice_codec_options.go
@@ -7,22 +7,33 @@
 package bsonoptions
 
 // ByteSliceCodecOptions represents all possible options for byte slice encoding and decoding.
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 type ByteSliceCodecOptions struct {
 	EncodeNilAsEmpty *bool // Specifies if a nil byte slice should encode as an empty binary instead of null. Defaults to false.
 }
 
 // ByteSliceCodec creates a new *ByteSliceCodecOptions
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 func ByteSliceCodec() *ByteSliceCodecOptions {
 	return &ByteSliceCodecOptions{}
 }
 
 // SetEncodeNilAsEmpty specifies  if a nil byte slice should encode as an empty binary instead of null. Defaults to false.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilByteSliceAsEmpty] instead.
 func (bs *ByteSliceCodecOptions) SetEncodeNilAsEmpty(b bool) *ByteSliceCodecOptions {
 	bs.EncodeNilAsEmpty = &b
 	return bs
 }
 
 // MergeByteSliceCodecOptions combines the given *ByteSliceCodecOptions into a single *ByteSliceCodecOptions in a last one wins fashion.
+//
+// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
+// single options struct instead.
 func MergeByteSliceCodecOptions(opts ...*ByteSliceCodecOptions) *ByteSliceCodecOptions {
 	bs := ByteSliceCodec()
 	for _, opt := range opts {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/empty_interface_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/empty_interface_codec_options.go
index 6caaa000..f522c7e0 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/empty_interface_codec_options.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/empty_interface_codec_options.go
@@ -7,22 +7,33 @@
 package bsonoptions
 
 // EmptyInterfaceCodecOptions represents all possible options for interface{} encoding and decoding.
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 type EmptyInterfaceCodecOptions struct {
 	DecodeBinaryAsSlice *bool // Specifies if Old and Generic type binarys should default to []slice instead of primitive.Binary. Defaults to false.
 }
 
 // EmptyInterfaceCodec creates a new *EmptyInterfaceCodecOptions
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 func EmptyInterfaceCodec() *EmptyInterfaceCodecOptions {
 	return &EmptyInterfaceCodecOptions{}
 }
 
 // SetDecodeBinaryAsSlice specifies if Old and Generic type binarys should default to []slice instead of primitive.Binary. Defaults to false.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.BinaryAsSlice] instead.
 func (e *EmptyInterfaceCodecOptions) SetDecodeBinaryAsSlice(b bool) *EmptyInterfaceCodecOptions {
 	e.DecodeBinaryAsSlice = &b
 	return e
 }
 
 // MergeEmptyInterfaceCodecOptions combines the given *EmptyInterfaceCodecOptions into a single *EmptyInterfaceCodecOptions in a last one wins fashion.
+//
+// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
+// single options struct instead.
 func MergeEmptyInterfaceCodecOptions(opts ...*EmptyInterfaceCodecOptions) *EmptyInterfaceCodecOptions {
 	e := EmptyInterfaceCodec()
 	for _, opt := range opts {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/map_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/map_codec_options.go
index 7a6a880b..a7a7c1d9 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/map_codec_options.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/map_codec_options.go
@@ -7,6 +7,9 @@
 package bsonoptions
 
 // MapCodecOptions represents all possible options for map encoding and decoding.
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 type MapCodecOptions struct {
 	DecodeZerosMap   *bool // Specifies if the map should be zeroed before decoding into it. Defaults to false.
 	EncodeNilAsEmpty *bool // Specifies if a nil map should encode as an empty document instead of null. Defaults to false.
@@ -19,17 +22,24 @@ type MapCodecOptions struct {
 }
 
 // MapCodec creates a new *MapCodecOptions
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 func MapCodec() *MapCodecOptions {
 	return &MapCodecOptions{}
 }
 
 // SetDecodeZerosMap specifies if the map should be zeroed before decoding into it. Defaults to false.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.ZeroMaps] instead.
 func (t *MapCodecOptions) SetDecodeZerosMap(b bool) *MapCodecOptions {
 	t.DecodeZerosMap = &b
 	return t
 }
 
 // SetEncodeNilAsEmpty specifies if a nil map should encode as an empty document instead of null. Defaults to false.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilMapAsEmpty] instead.
 func (t *MapCodecOptions) SetEncodeNilAsEmpty(b bool) *MapCodecOptions {
 	t.EncodeNilAsEmpty = &b
 	return t
@@ -40,12 +50,17 @@ func (t *MapCodecOptions) SetEncodeNilAsEmpty(b bool) *MapCodecOptions {
 // type must either be a string, an integer type, or implement bsoncodec.KeyUnmarshaler. If true, keys are encoded with
 // fmt.Sprint() and the encoding key type must be a string, an integer type, or a float. If true, the use of Stringer
 // will override TextMarshaler/TextUnmarshaler. Defaults to false.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.StringifyMapKeysWithFmt] instead.
 func (t *MapCodecOptions) SetEncodeKeysWithStringer(b bool) *MapCodecOptions {
 	t.EncodeKeysWithStringer = &b
 	return t
 }
 
 // MergeMapCodecOptions combines the given *MapCodecOptions into a single *MapCodecOptions in a last one wins fashion.
+//
+// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
+// single options struct instead.
 func MergeMapCodecOptions(opts ...*MapCodecOptions) *MapCodecOptions {
 	s := MapCodec()
 	for _, opt := range opts {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/slice_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/slice_codec_options.go
index ef965e4b..3c1e4f35 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/slice_codec_options.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/slice_codec_options.go
@@ -7,22 +7,33 @@
 package bsonoptions
 
 // SliceCodecOptions represents all possible options for slice encoding and decoding.
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 type SliceCodecOptions struct {
 	EncodeNilAsEmpty *bool // Specifies if a nil slice should encode as an empty array instead of null. Defaults to false.
 }
 
 // SliceCodec creates a new *SliceCodecOptions
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 func SliceCodec() *SliceCodecOptions {
 	return &SliceCodecOptions{}
 }
 
 // SetEncodeNilAsEmpty specifies  if a nil slice should encode as an empty array instead of null. Defaults to false.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.NilSliceAsEmpty] instead.
 func (s *SliceCodecOptions) SetEncodeNilAsEmpty(b bool) *SliceCodecOptions {
 	s.EncodeNilAsEmpty = &b
 	return s
 }
 
 // MergeSliceCodecOptions combines the given *SliceCodecOptions into a single *SliceCodecOptions in a last one wins fashion.
+//
+// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
+// single options struct instead.
 func MergeSliceCodecOptions(opts ...*SliceCodecOptions) *SliceCodecOptions {
 	s := SliceCodec()
 	for _, opt := range opts {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/string_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/string_codec_options.go
index 65964f42..f8b76f99 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/string_codec_options.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/string_codec_options.go
@@ -9,23 +9,34 @@ package bsonoptions
 var defaultDecodeOIDAsHex = true
 
 // StringCodecOptions represents all possible options for string encoding and decoding.
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 type StringCodecOptions struct {
 	DecodeObjectIDAsHex *bool // Specifies if we should decode ObjectID as the hex value. Defaults to true.
 }
 
 // StringCodec creates a new *StringCodecOptions
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 func StringCodec() *StringCodecOptions {
 	return &StringCodecOptions{}
 }
 
 // SetDecodeObjectIDAsHex specifies if object IDs should be decoded as their hex representation. If false, a string made
 // from the raw object ID bytes will be used. Defaults to true.
+//
+// Deprecated: Decoding object IDs as raw bytes will not be supported in Go Driver 2.0.
 func (t *StringCodecOptions) SetDecodeObjectIDAsHex(b bool) *StringCodecOptions {
 	t.DecodeObjectIDAsHex = &b
 	return t
 }
 
 // MergeStringCodecOptions combines the given *StringCodecOptions into a single *StringCodecOptions in a last one wins fashion.
+//
+// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
+// single options struct instead.
 func MergeStringCodecOptions(opts ...*StringCodecOptions) *StringCodecOptions {
 	s := &StringCodecOptions{&defaultDecodeOIDAsHex}
 	for _, opt := range opts {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/struct_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/struct_codec_options.go
index 78d1dd86..1cbfa32e 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/struct_codec_options.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/struct_codec_options.go
@@ -9,6 +9,9 @@ package bsonoptions
 var defaultOverwriteDuplicatedInlinedFields = true
 
 // StructCodecOptions represents all possible options for struct encoding and decoding.
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 type StructCodecOptions struct {
 	DecodeZeroStruct                 *bool // Specifies if structs should be zeroed before decoding into them. Defaults to false.
 	DecodeDeepZeroInline             *bool // Specifies if structs should be recursively zeroed when a inline value is decoded. Defaults to false.
@@ -18,17 +21,24 @@ type StructCodecOptions struct {
 }
 
 // StructCodec creates a new *StructCodecOptions
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 func StructCodec() *StructCodecOptions {
 	return &StructCodecOptions{}
 }
 
 // SetDecodeZeroStruct specifies if structs should be zeroed before decoding into them. Defaults to false.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.ZeroStructs] instead.
 func (t *StructCodecOptions) SetDecodeZeroStruct(b bool) *StructCodecOptions {
 	t.DecodeZeroStruct = &b
 	return t
 }
 
 // SetDecodeDeepZeroInline specifies if structs should be zeroed before decoding into them. Defaults to false.
+//
+// Deprecated: DecodeDeepZeroInline will not be supported in Go Driver 2.0.
 func (t *StructCodecOptions) SetDecodeDeepZeroInline(b bool) *StructCodecOptions {
 	t.DecodeDeepZeroInline = &b
 	return t
@@ -36,6 +46,8 @@ func (t *StructCodecOptions) SetDecodeDeepZeroInline(b bool) *StructCodecOptions
 
 // SetEncodeOmitDefaultStruct specifies if default structs should be considered empty by omitempty. A default struct has all
 // its values set to their default value. Defaults to false.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.OmitZeroStruct] instead.
 func (t *StructCodecOptions) SetEncodeOmitDefaultStruct(b bool) *StructCodecOptions {
 	t.EncodeOmitDefaultStruct = &b
 	return t
@@ -45,18 +57,26 @@ func (t *StructCodecOptions) SetEncodeOmitDefaultStruct(b bool) *StructCodecOpti
 // same bson key. When true and decoding, values will be written to the outermost struct with a matching key, and when
 // encoding, keys will have the value of the top-most matching field. When false, decoding and encoding will error if
 // there are duplicate keys after the struct is inlined. Defaults to true.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.ErrorOnInlineDuplicates] instead.
 func (t *StructCodecOptions) SetOverwriteDuplicatedInlinedFields(b bool) *StructCodecOptions {
 	t.OverwriteDuplicatedInlinedFields = &b
 	return t
 }
 
 // SetAllowUnexportedFields specifies if unexported fields should be marshaled/unmarshaled. Defaults to false.
+//
+// Deprecated: AllowUnexportedFields does not work on recent versions of Go and will not be
+// supported in Go Driver 2.0.
 func (t *StructCodecOptions) SetAllowUnexportedFields(b bool) *StructCodecOptions {
 	t.AllowUnexportedFields = &b
 	return t
 }
 
 // MergeStructCodecOptions combines the given *StructCodecOptions into a single *StructCodecOptions in a last one wins fashion.
+//
+// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
+// single options struct instead.
 func MergeStructCodecOptions(opts ...*StructCodecOptions) *StructCodecOptions {
 	s := &StructCodecOptions{
 		OverwriteDuplicatedInlinedFields: &defaultOverwriteDuplicatedInlinedFields,
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/time_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/time_codec_options.go
index 13496d12..3f38433d 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/time_codec_options.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/time_codec_options.go
@@ -7,22 +7,33 @@
 package bsonoptions
 
 // TimeCodecOptions represents all possible options for time.Time encoding and decoding.
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 type TimeCodecOptions struct {
 	UseLocalTimeZone *bool // Specifies if we should decode into the local time zone. Defaults to false.
 }
 
 // TimeCodec creates a new *TimeCodecOptions
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 func TimeCodec() *TimeCodecOptions {
 	return &TimeCodecOptions{}
 }
 
 // SetUseLocalTimeZone specifies if we should decode into the local time zone. Defaults to false.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Decoder.UseLocalTimeZone] instead.
 func (t *TimeCodecOptions) SetUseLocalTimeZone(b bool) *TimeCodecOptions {
 	t.UseLocalTimeZone = &b
 	return t
 }
 
 // MergeTimeCodecOptions combines the given *TimeCodecOptions into a single *TimeCodecOptions in a last one wins fashion.
+//
+// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
+// single options struct instead.
 func MergeTimeCodecOptions(opts ...*TimeCodecOptions) *TimeCodecOptions {
 	t := TimeCodec()
 	for _, opt := range opts {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/uint_codec_options.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/uint_codec_options.go
index e08b7f19..5091e4d9 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/uint_codec_options.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonoptions/uint_codec_options.go
@@ -7,22 +7,33 @@
 package bsonoptions
 
 // UIntCodecOptions represents all possible options for uint encoding and decoding.
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 type UIntCodecOptions struct {
 	EncodeToMinSize *bool // Specifies if all uints except uint64 should be decoded to minimum size bsontype. Defaults to false.
 }
 
 // UIntCodec creates a new *UIntCodecOptions
+//
+// Deprecated: Use the bson.Encoder and bson.Decoder configuration methods to set the desired BSON marshal
+// and unmarshal behavior instead.
 func UIntCodec() *UIntCodecOptions {
 	return &UIntCodecOptions{}
 }
 
 // SetEncodeToMinSize specifies if all uints except uint64 should be decoded to minimum size bsontype. Defaults to false.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.Encoder.IntMinSize] instead.
 func (u *UIntCodecOptions) SetEncodeToMinSize(b bool) *UIntCodecOptions {
 	u.EncodeToMinSize = &b
 	return u
 }
 
 // MergeUIntCodecOptions combines the given *UIntCodecOptions into a single *UIntCodecOptions in a last one wins fashion.
+//
+// Deprecated: Merging options structs will not be supported in Go Driver 2.0. Users should create a
+// single options struct instead.
 func MergeUIntCodecOptions(opts ...*UIntCodecOptions) *UIntCodecOptions {
 	u := UIntCodec()
 	for _, opt := range opts {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/copier.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/copier.go
index 5cdf6460..1e25570b 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/copier.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/copier.go
@@ -7,6 +7,7 @@
 package bsonrw
 
 import (
+	"errors"
 	"fmt"
 	"io"
 
@@ -17,20 +18,32 @@ import (
 
 // Copier is a type that allows copying between ValueReaders, ValueWriters, and
 // []byte values.
+//
+// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
+// supported in Go Driver 2.0.
 type Copier struct{}
 
 // NewCopier creates a new copier with the given registry. If a nil registry is provided
 // a default registry is used.
+//
+// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
+// supported in Go Driver 2.0.
 func NewCopier() Copier {
 	return Copier{}
 }
 
 // CopyDocument handles copying a document from src to dst.
+//
+// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
+// supported in Go Driver 2.0.
 func CopyDocument(dst ValueWriter, src ValueReader) error {
 	return Copier{}.CopyDocument(dst, src)
 }
 
 // CopyDocument handles copying one document from the src to the dst.
+//
+// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
+// supported in Go Driver 2.0.
 func (c Copier) CopyDocument(dst ValueWriter, src ValueReader) error {
 	dr, err := src.ReadDocument()
 	if err != nil {
@@ -47,6 +60,9 @@ func (c Copier) CopyDocument(dst ValueWriter, src ValueReader) error {
 
 // CopyArrayFromBytes copies the values from a BSON array represented as a
 // []byte to a ValueWriter.
+//
+// Deprecated: Copying BSON arrays using the ValueWriter and ValueReader interfaces will not be
+// supported in Go Driver 2.0.
 func (c Copier) CopyArrayFromBytes(dst ValueWriter, src []byte) error {
 	aw, err := dst.WriteArray()
 	if err != nil {
@@ -63,6 +79,9 @@ func (c Copier) CopyArrayFromBytes(dst ValueWriter, src []byte) error {
 
 // CopyDocumentFromBytes copies the values from a BSON document represented as a
 // []byte to a ValueWriter.
+//
+// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
+// supported in Go Driver 2.0.
 func (c Copier) CopyDocumentFromBytes(dst ValueWriter, src []byte) error {
 	dw, err := dst.WriteDocument()
 	if err != nil {
@@ -81,6 +100,9 @@ type writeElementFn func(key string) (ValueWriter, error)
 
 // CopyBytesToArrayWriter copies the values from a BSON Array represented as a []byte to an
 // ArrayWriter.
+//
+// Deprecated: Copying BSON arrays using the ArrayWriter interface will not be supported in Go
+// Driver 2.0.
 func (c Copier) CopyBytesToArrayWriter(dst ArrayWriter, src []byte) error {
 	wef := func(_ string) (ValueWriter, error) {
 		return dst.WriteArrayElement()
@@ -91,6 +113,9 @@ func (c Copier) CopyBytesToArrayWriter(dst ArrayWriter, src []byte) error {
 
 // CopyBytesToDocumentWriter copies the values from a BSON document represented as a []byte to a
 // DocumentWriter.
+//
+// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
+// supported in Go Driver 2.0.
 func (c Copier) CopyBytesToDocumentWriter(dst DocumentWriter, src []byte) error {
 	wef := func(key string) (ValueWriter, error) {
 		return dst.WriteDocumentElement(key)
@@ -100,7 +125,7 @@ func (c Copier) CopyBytesToDocumentWriter(dst DocumentWriter, src []byte) error
 }
 
 func (c Copier) copyBytesToValueWriter(src []byte, wef writeElementFn) error {
-	// TODO(skriptble): Create errors types here. Anything thats a tag should be a property.
+	// TODO(skriptble): Create errors types here. Anything that is a tag should be a property.
 	length, rem, ok := bsoncore.ReadLength(src)
 	if !ok {
 		return fmt.Errorf("couldn't read length from src, not enough bytes. length=%d", len(src))
@@ -150,12 +175,18 @@ func (c Copier) copyBytesToValueWriter(src []byte, wef writeElementFn) error {
 
 // CopyDocumentToBytes copies an entire document from the ValueReader and
 // returns it as bytes.
+//
+// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
+// supported in Go Driver 2.0.
 func (c Copier) CopyDocumentToBytes(src ValueReader) ([]byte, error) {
 	return c.AppendDocumentBytes(nil, src)
 }
 
 // AppendDocumentBytes functions the same as CopyDocumentToBytes, but will
 // append the result to dst.
+//
+// Deprecated: Copying BSON documents using the ValueWriter and ValueReader interfaces will not be
+// supported in Go Driver 2.0.
 func (c Copier) AppendDocumentBytes(dst []byte, src ValueReader) ([]byte, error) {
 	if br, ok := src.(BytesReader); ok {
 		_, dst, err := br.ReadValueBytes(dst)
@@ -163,7 +194,7 @@ func (c Copier) AppendDocumentBytes(dst []byte, src ValueReader) ([]byte, error)
 	}
 
 	vw := vwPool.Get().(*valueWriter)
-	defer vwPool.Put(vw)
+	defer putValueWriter(vw)
 
 	vw.reset(dst)
 
@@ -173,6 +204,9 @@ func (c Copier) AppendDocumentBytes(dst []byte, src ValueReader) ([]byte, error)
 }
 
 // AppendArrayBytes copies an array from the ValueReader to dst.
+//
+// Deprecated: Copying BSON arrays using the ValueWriter and ValueReader interfaces will not be
+// supported in Go Driver 2.0.
 func (c Copier) AppendArrayBytes(dst []byte, src ValueReader) ([]byte, error) {
 	if br, ok := src.(BytesReader); ok {
 		_, dst, err := br.ReadValueBytes(dst)
@@ -180,7 +214,7 @@ func (c Copier) AppendArrayBytes(dst []byte, src ValueReader) ([]byte, error) {
 	}
 
 	vw := vwPool.Get().(*valueWriter)
-	defer vwPool.Put(vw)
+	defer putValueWriter(vw)
 
 	vw.reset(dst)
 
@@ -190,6 +224,8 @@ func (c Copier) AppendArrayBytes(dst []byte, src ValueReader) ([]byte, error) {
 }
 
 // CopyValueFromBytes will write the value represtend by t and src to dst.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.UnmarshalValue] instead.
 func (c Copier) CopyValueFromBytes(dst ValueWriter, t bsontype.Type, src []byte) error {
 	if wvb, ok := dst.(BytesWriter); ok {
 		return wvb.WriteValueBytes(t, src)
@@ -206,19 +242,24 @@ func (c Copier) CopyValueFromBytes(dst ValueWriter, t bsontype.Type, src []byte)
 
 // CopyValueToBytes copies a value from src and returns it as a bsontype.Type and a
 // []byte.
+//
+// Deprecated: Use [go.mongodb.org/mongo-driver/bson.MarshalValue] instead.
 func (c Copier) CopyValueToBytes(src ValueReader) (bsontype.Type, []byte, error) {
 	return c.AppendValueBytes(nil, src)
 }
 
 // AppendValueBytes functions the same as CopyValueToBytes, but will append the
 // result to dst.
+//
+// Deprecated: Appending individual BSON elements to an existing slice will not be supported in Go
+// Driver 2.0.
 func (c Copier) AppendValueBytes(dst []byte, src ValueReader) (bsontype.Type, []byte, error) {
 	if br, ok := src.(BytesReader); ok {
 		return br.ReadValueBytes(dst)
 	}
 
 	vw := vwPool.Get().(*valueWriter)
-	defer vwPool.Put(vw)
+	defer putValueWriter(vw)
 
 	start := len(dst)
 
@@ -234,6 +275,9 @@ func (c Copier) AppendValueBytes(dst []byte, src ValueReader) (bsontype.Type, []
 }
 
 // CopyValue will copy a single value from src to dst.
+//
+// Deprecated: Copying BSON values using the ValueWriter and ValueReader interfaces will not be
+// supported in Go Driver 2.0.
 func (c Copier) CopyValue(dst ValueWriter, src ValueReader) error {
 	var err error
 	switch src.Type() {
@@ -399,7 +443,7 @@ func (c Copier) copyArray(dst ValueWriter, src ValueReader) error {
 
 	for {
 		vr, err := ar.ReadValue()
-		if err == ErrEOA {
+		if errors.Is(err, ErrEOA) {
 			break
 		}
 		if err != nil {
@@ -423,7 +467,7 @@ func (c Copier) copyArray(dst ValueWriter, src ValueReader) error {
 func (c Copier) copyDocumentCore(dw DocumentWriter, dr DocumentReader) error {
 	for {
 		key, vr, err := dr.ReadElement()
-		if err == ErrEOD {
+		if errors.Is(err, ErrEOD) {
 			break
 		}
 		if err != nil {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go
index 54c76bf7..bb52a0ec 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go
@@ -313,7 +313,7 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) {
 				// convert hex to bytes
 				bytes, err := hex.DecodeString(uuidNoHyphens)
 				if err != nil {
-					return nil, fmt.Errorf("$uuid value does not follow RFC 4122 format regarding hex bytes: %v", err)
+					return nil, fmt.Errorf("$uuid value does not follow RFC 4122 format regarding hex bytes: %w", err)
 				}
 
 				ejp.advanceState()
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_reader.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_reader.go
index 35832d73..59ddfc44 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_reader.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_reader.go
@@ -7,6 +7,7 @@
 package bsonrw
 
 import (
+	"errors"
 	"fmt"
 	"io"
 	"sync"
@@ -16,11 +17,15 @@ import (
 )
 
 // ExtJSONValueReaderPool is a pool for ValueReaders that read ExtJSON.
+//
+// Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0.
 type ExtJSONValueReaderPool struct {
 	pool sync.Pool
 }
 
 // NewExtJSONValueReaderPool instantiates a new ExtJSONValueReaderPool.
+//
+// Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0.
 func NewExtJSONValueReaderPool() *ExtJSONValueReaderPool {
 	return &ExtJSONValueReaderPool{
 		pool: sync.Pool{
@@ -32,6 +37,8 @@ func NewExtJSONValueReaderPool() *ExtJSONValueReaderPool {
 }
 
 // Get retrieves a ValueReader from the pool and uses src as the underlying ExtJSON.
+//
+// Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0.
 func (bvrp *ExtJSONValueReaderPool) Get(r io.Reader, canonical bool) (ValueReader, error) {
 	vr := bvrp.pool.Get().(*extJSONValueReader)
 	return vr.reset(r, canonical)
@@ -39,6 +46,8 @@ func (bvrp *ExtJSONValueReaderPool) Get(r io.Reader, canonical bool) (ValueReade
 
 // Put inserts a ValueReader into the pool. If the ValueReader is not a ExtJSON ValueReader nothing
 // is inserted into the pool and ok will be false.
+//
+// Deprecated: ExtJSONValueReaderPool will not be supported in Go Driver 2.0.
 func (bvrp *ExtJSONValueReaderPool) Put(vr ValueReader) (ok bool) {
 	bvr, ok := vr.(*extJSONValueReader)
 	if !ok {
@@ -605,7 +614,7 @@ func (ejvr *extJSONValueReader) ReadElement() (string, ValueReader, error) {
 	name, t, err := ejvr.p.readKey()
 
 	if err != nil {
-		if err == ErrEOD {
+		if errors.Is(err, ErrEOD) {
 			if ejvr.stack[ejvr.frame].mode == mCodeWithScope {
 				_, err := ejvr.p.peekType()
 				if err != nil {
@@ -632,7 +641,7 @@ func (ejvr *extJSONValueReader) ReadValue() (ValueReader, error) {
 
 	t, err := ejvr.p.peekType()
 	if err != nil {
-		if err == ErrEOA {
+		if errors.Is(err, ErrEOA) {
 			ejvr.pop()
 		}
 
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_wrappers.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_wrappers.go
index 96957042..af6ae7b7 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_wrappers.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_wrappers.go
@@ -95,9 +95,9 @@ func (ejv *extJSONValue) parseBinary() (b []byte, subType byte, err error) {
 				return nil, 0, fmt.Errorf("$binary subType value should be string, but instead is %s", val.t)
 			}
 
-			i, err := strconv.ParseInt(val.v.(string), 16, 64)
+			i, err := strconv.ParseUint(val.v.(string), 16, 8)
 			if err != nil {
-				return nil, 0, fmt.Errorf("invalid $binary subType string: %s", val.v.(string))
+				return nil, 0, fmt.Errorf("invalid $binary subType string: %q: %w", val.v.(string), err)
 			}
 
 			subType = byte(i)
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_writer.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_writer.go
index 99ed524b..bb930316 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_writer.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_writer.go
@@ -23,11 +23,15 @@ import (
 )
 
 // ExtJSONValueWriterPool is a pool for ExtJSON ValueWriters.
+//
+// Deprecated: ExtJSONValueWriterPool will not be supported in Go Driver 2.0.
 type ExtJSONValueWriterPool struct {
 	pool sync.Pool
 }
 
 // NewExtJSONValueWriterPool creates a new pool for ValueWriter instances that write to ExtJSON.
+//
+// Deprecated: ExtJSONValueWriterPool will not be supported in Go Driver 2.0.
 func NewExtJSONValueWriterPool() *ExtJSONValueWriterPool {
 	return &ExtJSONValueWriterPool{
 		pool: sync.Pool{
@@ -39,6 +43,8 @@ func NewExtJSONValueWriterPool() *ExtJSONValueWriterPool {
 }
 
 // Get retrieves a ExtJSON ValueWriter from the pool and resets it to use w as the destination.
+//
+// Deprecated: ExtJSONValueWriterPool will not be supported in Go Driver 2.0.
 func (bvwp *ExtJSONValueWriterPool) Get(w io.Writer, canonical, escapeHTML bool) ValueWriter {
 	vw := bvwp.pool.Get().(*extJSONValueWriter)
 	if writer, ok := w.(*SliceWriter); ok {
@@ -53,6 +59,8 @@ func (bvwp *ExtJSONValueWriterPool) Get(w io.Writer, canonical, escapeHTML bool)
 
 // Put inserts a ValueWriter into the pool. If the ValueWriter is not a ExtJSON ValueWriter, nothing
 // happens and ok will be false.
+//
+// Deprecated: ExtJSONValueWriterPool will not be supported in Go Driver 2.0.
 func (bvwp *ExtJSONValueWriterPool) Put(vw ValueWriter) (ok bool) {
 	bvw, ok := vw.(*extJSONValueWriter)
 	if !ok {
@@ -80,6 +88,7 @@ type extJSONValueWriter struct {
 	frame      int64
 	canonical  bool
 	escapeHTML bool
+	newlines   bool
 }
 
 // NewExtJSONValueWriter creates a ValueWriter that writes Extended JSON to w.
@@ -88,10 +97,13 @@ func NewExtJSONValueWriter(w io.Writer, canonical, escapeHTML bool) (ValueWriter
 		return nil, errNilWriter
 	}
 
-	return newExtJSONWriter(w, canonical, escapeHTML), nil
+	// Enable newlines for all Extended JSON value writers created by NewExtJSONValueWriter. We
+	// expect these value writers to be used with an Encoder, which should add newlines after
+	// encoded Extended JSON documents.
+	return newExtJSONWriter(w, canonical, escapeHTML, true), nil
 }
 
-func newExtJSONWriter(w io.Writer, canonical, escapeHTML bool) *extJSONValueWriter {
+func newExtJSONWriter(w io.Writer, canonical, escapeHTML, newlines bool) *extJSONValueWriter {
 	stack := make([]ejvwState, 1, 5)
 	stack[0] = ejvwState{mode: mTopLevel}
 
@@ -101,6 +113,7 @@ func newExtJSONWriter(w io.Writer, canonical, escapeHTML bool) *extJSONValueWrit
 		stack:      stack,
 		canonical:  canonical,
 		escapeHTML: escapeHTML,
+		newlines:   newlines,
 	}
 }
 
@@ -564,6 +577,12 @@ func (ejvw *extJSONValueWriter) WriteDocumentEnd() error {
 	case mDocument:
 		ejvw.buf = append(ejvw.buf, ',')
 	case mTopLevel:
+		// If the value writer has newlines enabled, end top-level documents with a newline so that
+		// multiple documents encoded to the same writer are separated by newlines. That matches the
+		// Go json.Encoder behavior and also works with bsonrw.NewExtJSONValueReader.
+		if ejvw.newlines {
+			ejvw.buf = append(ejvw.buf, '\n')
+		}
 		if ejvw.w != nil {
 			if _, err := ejvw.w.Write(ejvw.buf); err != nil {
 				return err
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/json_scanner.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/json_scanner.go
index cd4843a3..43f3e4f3 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/json_scanner.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/json_scanner.go
@@ -58,7 +58,7 @@ func (js *jsonScanner) nextToken() (*jsonToken, error) {
 		c, err = js.readNextByte()
 	}
 
-	if err == io.EOF {
+	if errors.Is(err, io.EOF) {
 		return &jsonToken{t: jttEOF}, nil
 	} else if err != nil {
 		return nil, err
@@ -198,7 +198,7 @@ func (js *jsonScanner) scanString() (*jsonToken, error) {
 	for {
 		c, err = js.readNextByte()
 		if err != nil {
-			if err == io.EOF {
+			if errors.Is(err, io.EOF) {
 				return nil, errors.New("end of input in JSON string")
 			}
 			return nil, err
@@ -209,7 +209,7 @@ func (js *jsonScanner) scanString() (*jsonToken, error) {
 		case '\\':
 			c, err = js.readNextByte()
 			if err != nil {
-				if err == io.EOF {
+				if errors.Is(err, io.EOF) {
 					return nil, errors.New("end of input in JSON string")
 				}
 				return nil, err
@@ -248,7 +248,7 @@ func (js *jsonScanner) scanString() (*jsonToken, error) {
 				if utf16.IsSurrogate(rn) {
 					c, err = js.readNextByte()
 					if err != nil {
-						if err == io.EOF {
+						if errors.Is(err, io.EOF) {
 							return nil, errors.New("end of input in JSON string")
 						}
 						return nil, err
@@ -264,7 +264,7 @@ func (js *jsonScanner) scanString() (*jsonToken, error) {
 
 					c, err = js.readNextByte()
 					if err != nil {
-						if err == io.EOF {
+						if errors.Is(err, io.EOF) {
 							return nil, errors.New("end of input in JSON string")
 						}
 						return nil, err
@@ -325,17 +325,17 @@ func (js *jsonScanner) scanLiteral(first byte) (*jsonToken, error) {
 
 	c5, err := js.readNextByte()
 
-	if bytes.Equal([]byte("true"), lit) && (isValueTerminator(c5) || err == io.EOF) {
+	if bytes.Equal([]byte("true"), lit) && (isValueTerminator(c5) || errors.Is(err, io.EOF)) {
 		js.pos = int(math.Max(0, float64(js.pos-1)))
 		return &jsonToken{t: jttBool, v: true, p: p}, nil
-	} else if bytes.Equal([]byte("null"), lit) && (isValueTerminator(c5) || err == io.EOF) {
+	} else if bytes.Equal([]byte("null"), lit) && (isValueTerminator(c5) || errors.Is(err, io.EOF)) {
 		js.pos = int(math.Max(0, float64(js.pos-1)))
 		return &jsonToken{t: jttNull, v: nil, p: p}, nil
 	} else if bytes.Equal([]byte("fals"), lit) {
 		if c5 == 'e' {
 			c5, err = js.readNextByte()
 
-			if isValueTerminator(c5) || err == io.EOF {
+			if isValueTerminator(c5) || errors.Is(err, io.EOF) {
 				js.pos = int(math.Max(0, float64(js.pos-1)))
 				return &jsonToken{t: jttBool, v: false, p: p}, nil
 			}
@@ -384,7 +384,7 @@ func (js *jsonScanner) scanNumber(first byte) (*jsonToken, error) {
 	for {
 		c, err = js.readNextByte()
 
-		if err != nil && err != io.EOF {
+		if err != nil && !errors.Is(err, io.EOF) {
 			return nil, err
 		}
 
@@ -413,7 +413,7 @@ func (js *jsonScanner) scanNumber(first byte) (*jsonToken, error) {
 			case '}', ']', ',':
 				s = nssDone
 			default:
-				if isWhiteSpace(c) || err == io.EOF {
+				if isWhiteSpace(c) || errors.Is(err, io.EOF) {
 					s = nssDone
 				} else {
 					s = nssInvalid
@@ -430,7 +430,7 @@ func (js *jsonScanner) scanNumber(first byte) (*jsonToken, error) {
 			case '}', ']', ',':
 				s = nssDone
 			default:
-				if isWhiteSpace(c) || err == io.EOF {
+				if isWhiteSpace(c) || errors.Is(err, io.EOF) {
 					s = nssDone
 				} else if isDigit(c) {
 					s = nssSawIntegerDigits
@@ -455,7 +455,7 @@ func (js *jsonScanner) scanNumber(first byte) (*jsonToken, error) {
 			case '}', ']', ',':
 				s = nssDone
 			default:
-				if isWhiteSpace(c) || err == io.EOF {
+				if isWhiteSpace(c) || errors.Is(err, io.EOF) {
 					s = nssDone
 				} else if isDigit(c) {
 					s = nssSawFractionDigits
@@ -490,7 +490,7 @@ func (js *jsonScanner) scanNumber(first byte) (*jsonToken, error) {
 			case '}', ']', ',':
 				s = nssDone
 			default:
-				if isWhiteSpace(c) || err == io.EOF {
+				if isWhiteSpace(c) || errors.Is(err, io.EOF) {
 					s = nssDone
 				} else if isDigit(c) {
 					s = nssSawExponentDigits
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/reader.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/reader.go
index 0b8fa28d..324b10b6 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/reader.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/reader.go
@@ -58,6 +58,8 @@ type ValueReader interface {
 // types that implement ValueReader may also implement this interface.
 //
 // The bytes of the value will be appended to dst.
+//
+// Deprecated: BytesReader will not be supported in Go Driver 2.0.
 type BytesReader interface {
 	ReadValueBytes(dst []byte) (bsontype.Type, []byte, error)
 }
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_reader.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_reader.go
index ef5d837c..0e07d505 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_reader.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_reader.go
@@ -28,11 +28,15 @@ var vrPool = sync.Pool{
 }
 
 // BSONValueReaderPool is a pool for ValueReaders that read BSON.
+//
+// Deprecated: BSONValueReaderPool will not be supported in Go Driver 2.0.
 type BSONValueReaderPool struct {
 	pool sync.Pool
 }
 
 // NewBSONValueReaderPool instantiates a new BSONValueReaderPool.
+//
+// Deprecated: BSONValueReaderPool will not be supported in Go Driver 2.0.
 func NewBSONValueReaderPool() *BSONValueReaderPool {
 	return &BSONValueReaderPool{
 		pool: sync.Pool{
@@ -44,6 +48,8 @@ func NewBSONValueReaderPool() *BSONValueReaderPool {
 }
 
 // Get retrieves a ValueReader from the pool and uses src as the underlying BSON.
+//
+// Deprecated: BSONValueReaderPool will not be supported in Go Driver 2.0.
 func (bvrp *BSONValueReaderPool) Get(src []byte) ValueReader {
 	vr := bvrp.pool.Get().(*valueReader)
 	vr.reset(src)
@@ -52,6 +58,8 @@ func (bvrp *BSONValueReaderPool) Get(src []byte) ValueReader {
 
 // Put inserts a ValueReader into the pool. If the ValueReader is not a BSON ValueReader nothing
 // is inserted into the pool and ok will be false.
+//
+// Deprecated: BSONValueReaderPool will not be supported in Go Driver 2.0.
 func (bvrp *BSONValueReaderPool) Put(vr ValueReader) (ok bool) {
 	bvr, ok := vr.(*valueReader)
 	if !ok {
@@ -731,8 +739,7 @@ func (vr *valueReader) ReadValue() (ValueReader, error) {
 		return nil, ErrEOA
 	}
 
-	_, err = vr.readCString()
-	if err != nil {
+	if err := vr.skipCString(); err != nil {
 		return nil, err
 	}
 
@@ -786,6 +793,15 @@ func (vr *valueReader) readByte() (byte, error) {
 	return vr.d[vr.offset-1], nil
 }
 
+func (vr *valueReader) skipCString() error {
+	idx := bytes.IndexByte(vr.d[vr.offset:], 0x00)
+	if idx < 0 {
+		return io.EOF
+	}
+	vr.offset += int64(idx) + 1
+	return nil
+}
+
 func (vr *valueReader) readCString() (string, error) {
 	idx := bytes.IndexByte(vr.d[vr.offset:], 0x00)
 	if idx < 0 {
@@ -826,7 +842,7 @@ func (vr *valueReader) peekLength() (int32, error) {
 	}
 
 	idx := vr.offset
-	return (int32(vr.d[idx]) | int32(vr.d[idx+1])<<8 | int32(vr.d[idx+2])<<16 | int32(vr.d[idx+3])<<24), nil
+	return int32(binary.LittleEndian.Uint32(vr.d[idx:])), nil
 }
 
 func (vr *valueReader) readLength() (int32, error) { return vr.readi32() }
@@ -838,7 +854,7 @@ func (vr *valueReader) readi32() (int32, error) {
 
 	idx := vr.offset
 	vr.offset += 4
-	return (int32(vr.d[idx]) | int32(vr.d[idx+1])<<8 | int32(vr.d[idx+2])<<16 | int32(vr.d[idx+3])<<24), nil
+	return int32(binary.LittleEndian.Uint32(vr.d[idx:])), nil
 }
 
 func (vr *valueReader) readu32() (uint32, error) {
@@ -848,7 +864,7 @@ func (vr *valueReader) readu32() (uint32, error) {
 
 	idx := vr.offset
 	vr.offset += 4
-	return (uint32(vr.d[idx]) | uint32(vr.d[idx+1])<<8 | uint32(vr.d[idx+2])<<16 | uint32(vr.d[idx+3])<<24), nil
+	return binary.LittleEndian.Uint32(vr.d[idx:]), nil
 }
 
 func (vr *valueReader) readi64() (int64, error) {
@@ -858,8 +874,7 @@ func (vr *valueReader) readi64() (int64, error) {
 
 	idx := vr.offset
 	vr.offset += 8
-	return int64(vr.d[idx]) | int64(vr.d[idx+1])<<8 | int64(vr.d[idx+2])<<16 | int64(vr.d[idx+3])<<24 |
-		int64(vr.d[idx+4])<<32 | int64(vr.d[idx+5])<<40 | int64(vr.d[idx+6])<<48 | int64(vr.d[idx+7])<<56, nil
+	return int64(binary.LittleEndian.Uint64(vr.d[idx:])), nil
 }
 
 func (vr *valueReader) readu64() (uint64, error) {
@@ -869,6 +884,5 @@ func (vr *valueReader) readu64() (uint64, error) {
 
 	idx := vr.offset
 	vr.offset += 8
-	return uint64(vr.d[idx]) | uint64(vr.d[idx+1])<<8 | uint64(vr.d[idx+2])<<16 | uint64(vr.d[idx+3])<<24 |
-		uint64(vr.d[idx+4])<<32 | uint64(vr.d[idx+5])<<40 | uint64(vr.d[idx+6])<<48 | uint64(vr.d[idx+7])<<56, nil
+	return binary.LittleEndian.Uint64(vr.d[idx:]), nil
 }
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_writer.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_writer.go
index f95a08af..311518a8 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_writer.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_writer.go
@@ -28,12 +28,23 @@ var vwPool = sync.Pool{
 	},
 }
 
+func putValueWriter(vw *valueWriter) {
+	if vw != nil {
+		vw.w = nil // don't leak the writer
+		vwPool.Put(vw)
+	}
+}
+
 // BSONValueWriterPool is a pool for BSON ValueWriters.
+//
+// Deprecated: BSONValueWriterPool will not be supported in Go Driver 2.0.
 type BSONValueWriterPool struct {
 	pool sync.Pool
 }
 
 // NewBSONValueWriterPool creates a new pool for ValueWriter instances that write to BSON.
+//
+// Deprecated: BSONValueWriterPool will not be supported in Go Driver 2.0.
 func NewBSONValueWriterPool() *BSONValueWriterPool {
 	return &BSONValueWriterPool{
 		pool: sync.Pool{
@@ -45,6 +56,8 @@ func NewBSONValueWriterPool() *BSONValueWriterPool {
 }
 
 // Get retrieves a BSON ValueWriter from the pool and resets it to use w as the destination.
+//
+// Deprecated: BSONValueWriterPool will not be supported in Go Driver 2.0.
 func (bvwp *BSONValueWriterPool) Get(w io.Writer) ValueWriter {
 	vw := bvwp.pool.Get().(*valueWriter)
 
@@ -56,6 +69,8 @@ func (bvwp *BSONValueWriterPool) Get(w io.Writer) ValueWriter {
 }
 
 // GetAtModeElement retrieves a ValueWriterFlusher from the pool and resets it to use w as the destination.
+//
+// Deprecated: BSONValueWriterPool will not be supported in Go Driver 2.0.
 func (bvwp *BSONValueWriterPool) GetAtModeElement(w io.Writer) ValueWriterFlusher {
 	vw := bvwp.Get(w).(*valueWriter)
 	vw.push(mElement)
@@ -64,6 +79,8 @@ func (bvwp *BSONValueWriterPool) GetAtModeElement(w io.Writer) ValueWriterFlushe
 
 // Put inserts a ValueWriter into the pool. If the ValueWriter is not a BSON ValueWriter, nothing
 // happens and ok will be false.
+//
+// Deprecated: BSONValueWriterPool will not be supported in Go Driver 2.0.
 func (bvwp *BSONValueWriterPool) Put(vw ValueWriter) (ok bool) {
 	bvw, ok := vw.(*valueWriter)
 	if !ok {
@@ -139,32 +156,21 @@ type valueWriter struct {
 }
 
 func (vw *valueWriter) advanceFrame() {
-	if vw.frame+1 >= int64(len(vw.stack)) { // We need to grow the stack
-		length := len(vw.stack)
-		if length+1 >= cap(vw.stack) {
-			// double it
-			buf := make([]vwState, 2*cap(vw.stack)+1)
-			copy(buf, vw.stack)
-			vw.stack = buf
-		}
-		vw.stack = vw.stack[:length+1]
-	}
 	vw.frame++
+	if vw.frame >= int64(len(vw.stack)) {
+		vw.stack = append(vw.stack, vwState{})
+	}
 }
 
 func (vw *valueWriter) push(m mode) {
 	vw.advanceFrame()
 
 	// Clean the stack
-	vw.stack[vw.frame].mode = m
-	vw.stack[vw.frame].key = ""
-	vw.stack[vw.frame].arrkey = 0
-	vw.stack[vw.frame].start = 0
+	vw.stack[vw.frame] = vwState{mode: m}
 
-	vw.stack[vw.frame].mode = m
 	switch m {
 	case mDocument, mArray, mCodeWithScope:
-		vw.reserveLength()
+		vw.reserveLength() // WARN: this is not needed
 	}
 }
 
@@ -203,6 +209,7 @@ func newValueWriter(w io.Writer) *valueWriter {
 	return vw
 }
 
+// TODO: only used in tests
 func newValueWriterFromSlice(buf []byte) *valueWriter {
 	vw := new(valueWriter)
 	stack := make([]vwState, 1, 5)
@@ -239,17 +246,16 @@ func (vw *valueWriter) invalidTransitionError(destination mode, name string, mod
 }
 
 func (vw *valueWriter) writeElementHeader(t bsontype.Type, destination mode, callerName string, addmodes ...mode) error {
-	switch vw.stack[vw.frame].mode {
+	frame := &vw.stack[vw.frame]
+	switch frame.mode {
 	case mElement:
-		key := vw.stack[vw.frame].key
+		key := frame.key
 		if !isValidCString(key) {
 			return errors.New("BSON element key cannot contain null bytes")
 		}
-
-		vw.buf = bsoncore.AppendHeader(vw.buf, t, key)
+		vw.appendHeader(t, key)
 	case mValue:
-		// TODO: Do this with a cache of the first 1000 or so array keys.
-		vw.buf = bsoncore.AppendHeader(vw.buf, t, strconv.Itoa(vw.stack[vw.frame].arrkey))
+		vw.appendIntHeader(t, frame.arrkey)
 	default:
 		modes := []mode{mElement, mValue}
 		if addmodes != nil {
@@ -591,9 +597,11 @@ func (vw *valueWriter) writeLength() error {
 	if length > maxSize {
 		return errMaxDocumentSizeExceeded{size: int64(len(vw.buf))}
 	}
-	length = length - int(vw.stack[vw.frame].start)
-	start := vw.stack[vw.frame].start
+	frame := &vw.stack[vw.frame]
+	length = length - int(frame.start)
+	start := frame.start
 
+	_ = vw.buf[start+3] // BCE
 	vw.buf[start+0] = byte(length)
 	vw.buf[start+1] = byte(length >> 8)
 	vw.buf[start+2] = byte(length >> 16)
@@ -602,5 +610,31 @@ func (vw *valueWriter) writeLength() error {
 }
 
 func isValidCString(cs string) bool {
-	return !strings.ContainsRune(cs, '\x00')
+	// Disallow the zero byte in a cstring because the zero byte is used as the
+	// terminating character.
+	//
+	// It's safe to check bytes instead of runes because all multibyte UTF-8
+	// code points start with (binary) 11xxxxxx or 10xxxxxx, so 00000000 (i.e.
+	// 0) will never be part of a multibyte UTF-8 code point. This logic is the
+	// same as the "r < utf8.RuneSelf" case in strings.IndexRune but can be
+	// inlined.
+	//
+	// https://cs.opensource.google/go/go/+/refs/tags/go1.21.1:src/strings/strings.go;l=127
+	return strings.IndexByte(cs, 0) == -1
+}
+
+// appendHeader is the same as bsoncore.AppendHeader but does not check if the
+// key is a valid C string since the caller has already checked for that.
+//
+// The caller of this function must check if key is a valid C string.
+func (vw *valueWriter) appendHeader(t bsontype.Type, key string) {
+	vw.buf = bsoncore.AppendType(vw.buf, t)
+	vw.buf = append(vw.buf, key...)
+	vw.buf = append(vw.buf, 0x00)
+}
+
+func (vw *valueWriter) appendIntHeader(t bsontype.Type, key int) {
+	vw.buf = bsoncore.AppendType(vw.buf, t)
+	vw.buf = strconv.AppendInt(vw.buf, int64(key), 10)
+	vw.buf = append(vw.buf, 0x00)
 }
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/writer.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/writer.go
index dff65f87..628f4529 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/writer.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/writer.go
@@ -56,6 +56,8 @@ type ValueWriter interface {
 }
 
 // ValueWriterFlusher is a superset of ValueWriter that exposes functionality to flush to the underlying buffer.
+//
+// Deprecated: ValueWriterFlusher will not be supported in Go Driver 2.0.
 type ValueWriterFlusher interface {
 	ValueWriter
 	Flush() error
@@ -64,13 +66,20 @@ type ValueWriterFlusher interface {
 // BytesWriter is the interface used to write BSON bytes to a ValueWriter.
 // This interface is meant to be a superset of ValueWriter, so that types that
 // implement ValueWriter may also implement this interface.
+//
+// Deprecated: BytesWriter will not be supported in Go Driver 2.0.
 type BytesWriter interface {
 	WriteValueBytes(t bsontype.Type, b []byte) error
 }
 
 // SliceWriter allows a pointer to a slice of bytes to be used as an io.Writer.
+//
+// Deprecated: SliceWriter will not be supported in Go Driver 2.0.
 type SliceWriter []byte
 
+// Write writes the bytes to the underlying slice.
+//
+// Deprecated: SliceWriter will not be supported in Go Driver 2.0.
 func (sw *SliceWriter) Write(p []byte) (int, error) {
 	written := len(p)
 	*sw = append(*sw, p...)
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsontype/bsontype.go b/vendor/go.mongodb.org/mongo-driver/bson/bsontype/bsontype.go
index 7c91ae51..255d9909 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/bsontype/bsontype.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/bsontype/bsontype.go
@@ -8,7 +8,9 @@
 // a stringifier for the Type to enable easier debugging when working with BSON.
 package bsontype // import "go.mongodb.org/mongo-driver/bson/bsontype"
 
-// These constants uniquely refer to each BSON type.
+// BSON element types as described in https://bsonspec.org/spec.html.
+//
+// Deprecated: Use bson.Type* constants instead.
 const (
 	Double           Type = 0x01
 	String           Type = 0x02
@@ -31,7 +33,12 @@ const (
 	Decimal128       Type = 0x13
 	MinKey           Type = 0xFF
 	MaxKey           Type = 0x7F
+)
 
+// BSON binary element subtypes as described in https://bsonspec.org/spec.html.
+//
+// Deprecated: Use the bson.TypeBinary* constants instead.
+const (
 	BinaryGeneric     byte = 0x00
 	BinaryFunction    byte = 0x01
 	BinaryBinaryOld   byte = 0x02
@@ -40,6 +47,7 @@ const (
 	BinaryMD5         byte = 0x05
 	BinaryEncrypted   byte = 0x06
 	BinaryColumn      byte = 0x07
+	BinarySensitive   byte = 0x08
 	BinaryUserDefined byte = 0x80
 )
 
@@ -95,3 +103,14 @@ func (bt Type) String() string {
 		return "invalid"
 	}
 }
+
+// IsValid will return true if the Type is valid.
+func (bt Type) IsValid() bool {
+	switch bt {
+	case Double, String, EmbeddedDocument, Array, Binary, Undefined, ObjectID, Boolean, DateTime, Null, Regex,
+		DBPointer, JavaScript, Symbol, CodeWithScope, Int32, Timestamp, Int64, Decimal128, MinKey, MaxKey:
+		return true
+	default:
+		return false
+	}
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/decoder.go b/vendor/go.mongodb.org/mongo-driver/bson/decoder.go
index 6e189fa5..eac74cd3 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/decoder.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/decoder.go
@@ -38,6 +38,12 @@ type Decoder struct {
 	// (*Decoder).SetContext.
 	defaultDocumentM bool
 	defaultDocumentD bool
+
+	binaryAsSlice     bool
+	useJSONStructTags bool
+	useLocalTimeZone  bool
+	zeroMaps          bool
+	zeroStructs       bool
 }
 
 // NewDecoder returns a new decoder that uses the DefaultRegistry to read from vr.
@@ -53,6 +59,9 @@ func NewDecoder(vr bsonrw.ValueReader) (*Decoder, error) {
 }
 
 // NewDecoderWithContext returns a new decoder that uses DecodeContext dc to read from vr.
+//
+// Deprecated: Use [NewDecoder] and use the Decoder configuration methods set the desired unmarshal
+// behavior instead.
 func NewDecoderWithContext(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader) (*Decoder, error) {
 	if dc.Registry == nil {
 		dc.Registry = DefaultRegistry
@@ -70,8 +79,7 @@ func NewDecoderWithContext(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader) (*
 // Decode reads the next BSON document from the stream and decodes it into the
 // value pointed to by val.
 //
-// The documentation for Unmarshal contains details about of BSON into a Go
-// value.
+// See [Unmarshal] for details about BSON unmarshaling behavior.
 func (d *Decoder) Decode(val interface{}) error {
 	if unmarshaler, ok := val.(Unmarshaler); ok {
 		// TODO(skriptble): Reuse a []byte here and use the AppendDocumentBytes method.
@@ -100,42 +108,101 @@ func (d *Decoder) Decode(val interface{}) error {
 	if err != nil {
 		return err
 	}
+
 	if d.defaultDocumentM {
 		d.dc.DefaultDocumentM()
 	}
 	if d.defaultDocumentD {
 		d.dc.DefaultDocumentD()
 	}
+	if d.binaryAsSlice {
+		d.dc.BinaryAsSlice()
+	}
+	if d.useJSONStructTags {
+		d.dc.UseJSONStructTags()
+	}
+	if d.useLocalTimeZone {
+		d.dc.UseLocalTimeZone()
+	}
+	if d.zeroMaps {
+		d.dc.ZeroMaps()
+	}
+	if d.zeroStructs {
+		d.dc.ZeroStructs()
+	}
+
 	return decoder.DecodeValue(d.dc, d.vr, rval)
 }
 
 // Reset will reset the state of the decoder, using the same *DecodeContext used in
 // the original construction but using vr for reading.
 func (d *Decoder) Reset(vr bsonrw.ValueReader) error {
+	// TODO:(GODRIVER-2719): Remove error return value.
 	d.vr = vr
 	return nil
 }
 
 // SetRegistry replaces the current registry of the decoder with r.
 func (d *Decoder) SetRegistry(r *bsoncodec.Registry) error {
+	// TODO:(GODRIVER-2719): Remove error return value.
 	d.dc.Registry = r
 	return nil
 }
 
 // SetContext replaces the current registry of the decoder with dc.
+//
+// Deprecated: Use the Decoder configuration methods to set the desired unmarshal behavior instead.
 func (d *Decoder) SetContext(dc bsoncodec.DecodeContext) error {
+	// TODO:(GODRIVER-2719): Remove error return value.
 	d.dc = dc
 	return nil
 }
 
-// DefaultDocumentM will decode empty documents using the primitive.M type. This behavior is restricted to data typed as
-// "interface{}" or "map[string]interface{}".
+// DefaultDocumentM causes the Decoder to always unmarshal documents into the primitive.M type. This
+// behavior is restricted to data typed as "interface{}" or "map[string]interface{}".
 func (d *Decoder) DefaultDocumentM() {
 	d.defaultDocumentM = true
 }
 
-// DefaultDocumentD will decode empty documents using the primitive.D type. This behavior is restricted to data typed as
-// "interface{}" or "map[string]interface{}".
+// DefaultDocumentD causes the Decoder to always unmarshal documents into the primitive.D type. This
+// behavior is restricted to data typed as "interface{}" or "map[string]interface{}".
 func (d *Decoder) DefaultDocumentD() {
 	d.defaultDocumentD = true
 }
+
+// AllowTruncatingDoubles causes the Decoder to truncate the fractional part of BSON "double" values
+// when attempting to unmarshal them into a Go integer (int, int8, int16, int32, or int64) struct
+// field. The truncation logic does not apply to BSON "decimal128" values.
+func (d *Decoder) AllowTruncatingDoubles() {
+	d.dc.Truncate = true
+}
+
+// BinaryAsSlice causes the Decoder to unmarshal BSON binary field values that are the "Generic" or
+// "Old" BSON binary subtype as a Go byte slice instead of a primitive.Binary.
+func (d *Decoder) BinaryAsSlice() {
+	d.binaryAsSlice = true
+}
+
+// UseJSONStructTags causes the Decoder to fall back to using the "json" struct tag if a "bson"
+// struct tag is not specified.
+func (d *Decoder) UseJSONStructTags() {
+	d.useJSONStructTags = true
+}
+
+// UseLocalTimeZone causes the Decoder to unmarshal time.Time values in the local timezone instead
+// of the UTC timezone.
+func (d *Decoder) UseLocalTimeZone() {
+	d.useLocalTimeZone = true
+}
+
+// ZeroMaps causes the Decoder to delete any existing values from Go maps in the destination value
+// passed to Decode before unmarshaling BSON documents into them.
+func (d *Decoder) ZeroMaps() {
+	d.zeroMaps = true
+}
+
+// ZeroStructs causes the Decoder to delete any existing values from Go structs in the destination
+// value passed to Decode before unmarshaling BSON documents into them.
+func (d *Decoder) ZeroStructs() {
+	d.zeroStructs = true
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/doc.go b/vendor/go.mongodb.org/mongo-driver/bson/doc.go
index 0134006d..af609847 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/doc.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/doc.go
@@ -6,8 +6,9 @@
 
 // Package bson is a library for reading, writing, and manipulating BSON. BSON is a binary serialization format used to
 // store documents and make remote procedure calls in MongoDB. The BSON specification is located at https://bsonspec.org.
-// The BSON library handles marshalling and unmarshalling of values through a configurable codec system. For a description
-// of the codec system and examples of registering custom codecs, see the bsoncodec package.
+// The BSON library handles marshaling and unmarshaling of values through a configurable codec system. For a description
+// of the codec system and examples of registering custom codecs, see the bsoncodec package. For additional information
+// and usage examples, check out the [Work with BSON] page in the Go Driver docs site.
 //
 // # Raw BSON
 //
@@ -37,7 +38,7 @@
 //	bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
 //	bson.M{"foo": "bar", "hello": "world", "pi": 3.14159}
 //
-// When decoding BSON to a D or M, the following type mappings apply when unmarshalling:
+// When decoding BSON to a D or M, the following type mappings apply when unmarshaling:
 //
 //  1. BSON int32 unmarshals to an int32.
 //  2. BSON int64 unmarshals to an int64.
@@ -61,81 +62,78 @@
 //  20. BSON DBPointer unmarshals to a primitive.DBPointer.
 //  21. BSON symbol unmarshals to a primitive.Symbol.
 //
-// The above mappings also apply when marshalling a D or M to BSON. Some other useful marshalling mappings are:
+// The above mappings also apply when marshaling a D or M to BSON. Some other useful marshaling mappings are:
 //
 //  1. time.Time marshals to a BSON datetime.
 //  2. int8, int16, and int32 marshal to a BSON int32.
 //  3. int marshals to a BSON int32 if the value is between math.MinInt32 and math.MaxInt32, inclusive, and a BSON int64
 //     otherwise.
-//  4. int64 marshals to BSON int64.
+//  4. int64 marshals to BSON int64 (unless [Encoder.IntMinSize] is set).
 //  5. uint8 and uint16 marshal to a BSON int32.
-//  6. uint, uint32, and uint64 marshal to a BSON int32 if the value is between math.MinInt32 and math.MaxInt32,
-//     inclusive, and BSON int64 otherwise.
-//  7. BSON null and undefined values will unmarshal into the zero value of a field (e.g. unmarshalling a BSON null or
+//  6. uint, uint32, and uint64 marshal to a BSON int64 (unless [Encoder.IntMinSize] is set).
+//  7. BSON null and undefined values will unmarshal into the zero value of a field (e.g. unmarshaling a BSON null or
 //     undefined value into a string will yield the empty string.).
 //
 // # Structs
 //
-// Structs can be marshalled/unmarshalled to/from BSON or Extended JSON. When transforming structs to/from BSON or Extended
+// Structs can be marshaled/unmarshaled to/from BSON or Extended JSON. When transforming structs to/from BSON or Extended
 // JSON, the following rules apply:
 //
-//  1. Only exported fields in structs will be marshalled or unmarshalled.
+//  1. Only exported fields in structs will be marshaled or unmarshaled.
 //
-//  2. When marshalling a struct, each field will be lowercased to generate the key for the corresponding BSON element.
+//  2. When marshaling a struct, each field will be lowercased to generate the key for the corresponding BSON element.
 //     For example, a struct field named "Foo" will generate key "foo". This can be overridden via a struct tag (e.g.
 //     `bson:"fooField"` to generate key "fooField" instead).
 //
-//  3. An embedded struct field is marshalled as a subdocument. The key will be the lowercased name of the field's type.
+//  3. An embedded struct field is marshaled as a subdocument. The key will be the lowercased name of the field's type.
 //
-//  4. A pointer field is marshalled as the underlying type if the pointer is non-nil. If the pointer is nil, it is
-//     marshalled as a BSON null value.
+//  4. A pointer field is marshaled as the underlying type if the pointer is non-nil. If the pointer is nil, it is
+//     marshaled as a BSON null value.
 //
-//  5. When unmarshalling, a field of type interface{} will follow the D/M type mappings listed above. BSON documents
-//     unmarshalled into an interface{} field will be unmarshalled as a D.
+//  5. When unmarshaling, a field of type interface{} will follow the D/M type mappings listed above. BSON documents
+//     unmarshaled into an interface{} field will be unmarshaled as a D.
 //
 // The encoding of each struct field can be customized by the "bson" struct tag.
 //
 // This tag behavior is configurable, and different struct tag behavior can be configured by initializing a new
-// bsoncodec.StructCodec with the desired tag parser and registering that StructCodec onto the Registry. By default, JSON tags
-// are not honored, but that can be enabled by creating a StructCodec with JSONFallbackStructTagParser, like below:
+// bsoncodec.StructCodec with the desired tag parser and registering that StructCodec onto the Registry. By default, JSON
+// tags are not honored, but that can be enabled by creating a StructCodec with JSONFallbackStructTagParser, like below:
 //
 // Example:
 //
 //	structcodec, _ := bsoncodec.NewStructCodec(bsoncodec.JSONFallbackStructTagParser)
 //
 // The bson tag gives the name of the field, possibly followed by a comma-separated list of options.
-// The name may be empty in order to specify options without overriding the default field name. The following options can be used
-// to configure behavior:
-//
-//  1. omitempty: If the omitempty struct tag is specified on a field, the field will not be marshalled if it is set to
-//     the zero value. Fields with language primitive types such as integers, booleans, and strings are considered empty if
-//     their value is equal to the zero value for the type (i.e. 0 for integers, false for booleans, and "" for strings).
-//     Slices, maps, and arrays are considered empty if they are of length zero. Interfaces and pointers are considered
-//     empty if their value is nil. By default, structs are only considered empty if the struct type implements the
-//     bsoncodec.Zeroer interface and the IsZero method returns true. Struct fields whose types do not implement Zeroer are
-//     never considered empty and will be marshalled as embedded documents.
+// The name may be empty in order to specify options without overriding the default field name. The following options can
+// be used to configure behavior:
+//
+//  1. omitempty: If the omitempty struct tag is specified on a field, the field will be omitted from the marshaling if
+//     the field has an empty value, defined as false, 0, a nil pointer, a nil interface value, and any empty array,
+//     slice, map, or string.
 //     NOTE: It is recommended that this tag be used for all slice and map fields.
 //
 //  2. minsize: If the minsize struct tag is specified on a field of type int64, uint, uint32, or uint64 and the value of
-//     the field can fit in a signed int32, the field will be serialized as a BSON int32 rather than a BSON int64. For other
-//     types, this tag is ignored.
+//     the field can fit in a signed int32, the field will be serialized as a BSON int32 rather than a BSON int64. For
+//     other types, this tag is ignored.
 //
-//  3. truncate: If the truncate struct tag is specified on a field with a non-float numeric type, BSON doubles unmarshalled
-//     into that field will be truncated at the decimal point. For example, if 3.14 is unmarshalled into a field of type int,
-//     it will be unmarshalled as 3. If this tag is not specified, the decoder will throw an error if the value cannot be
-//     decoded without losing precision. For float64 or non-numeric types, this tag is ignored.
+//  3. truncate: If the truncate struct tag is specified on a field with a non-float numeric type, BSON doubles
+//     unmarshaled into that field will be truncated at the decimal point. For example, if 3.14 is unmarshaled into a
+//     field of type int, it will be unmarshaled as 3. If this tag is not specified, the decoder will throw an error if
+//     the value cannot be decoded without losing precision. For float64 or non-numeric types, this tag is ignored.
 //
 //  4. inline: If the inline struct tag is specified for a struct or map field, the field will be "flattened" when
-//     marshalling and "un-flattened" when unmarshalling. This means that all of the fields in that struct/map will be
-//     pulled up one level and will become top-level fields rather than being fields in a nested document. For example, if a
-//     map field named "Map" with value map[string]interface{}{"foo": "bar"} is inlined, the resulting document will be
-//     {"foo": "bar"} instead of {"map": {"foo": "bar"}}. There can only be one inlined map field in a struct. If there are
-//     duplicated fields in the resulting document when an inlined struct is marshalled, the inlined field will be overwritten.
-//     If there are duplicated fields in the resulting document when an inlined map is marshalled, an error will be returned.
-//     This tag can be used with fields that are pointers to structs. If an inlined pointer field is nil, it will not be
-//     marshalled. For fields that are not maps or structs, this tag is ignored.
-//
-// # Marshalling and Unmarshalling
-//
-// Manually marshalling and unmarshalling can be done with the Marshal and Unmarshal family of functions.
+//     marshaling and "un-flattened" when unmarshaling. This means that all of the fields in that struct/map will be
+//     pulled up one level and will become top-level fields rather than being fields in a nested document. For example,
+//     if a map field named "Map" with value map[string]interface{}{"foo": "bar"} is inlined, the resulting document will
+//     be {"foo": "bar"} instead of {"map": {"foo": "bar"}}. There can only be one inlined map field in a struct. If
+//     there are duplicated fields in the resulting document when an inlined struct is marshaled, the inlined field will
+//     be overwritten. If there are duplicated fields in the resulting document when an inlined map is marshaled, an
+//     error will be returned. This tag can be used with fields that are pointers to structs. If an inlined pointer field
+//     is nil, it will not be marshaled. For fields that are not maps or structs, this tag is ignored.
+//
+// # Marshaling and Unmarshaling
+//
+// Manually marshaling and unmarshaling can be done with the Marshal and Unmarshal family of functions.
+//
+// [Work with BSON]: https://www.mongodb.com/docs/drivers/go/current/fundamentals/bson/
 package bson
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/encoder.go b/vendor/go.mongodb.org/mongo-driver/bson/encoder.go
index fe5125d0..0be2a97f 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/encoder.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/encoder.go
@@ -29,10 +29,20 @@ var encPool = sync.Pool{
 type Encoder struct {
 	ec bsoncodec.EncodeContext
 	vw bsonrw.ValueWriter
+
+	errorOnInlineDuplicates bool
+	intMinSize              bool
+	stringifyMapKeysWithFmt bool
+	nilMapAsEmpty           bool
+	nilSliceAsEmpty         bool
+	nilByteSliceAsEmpty     bool
+	omitZeroStruct          bool
+	useJSONStructTags       bool
 }
 
 // NewEncoder returns a new encoder that uses the DefaultRegistry to write to vw.
 func NewEncoder(vw bsonrw.ValueWriter) (*Encoder, error) {
+	// TODO:(GODRIVER-2719): Remove error return value.
 	if vw == nil {
 		return nil, errors.New("cannot create a new Encoder with a nil ValueWriter")
 	}
@@ -44,6 +54,9 @@ func NewEncoder(vw bsonrw.ValueWriter) (*Encoder, error) {
 }
 
 // NewEncoderWithContext returns a new encoder that uses EncodeContext ec to write to vw.
+//
+// Deprecated: Use [NewEncoder] and use the Encoder configuration methods to set the desired marshal
+// behavior instead.
 func NewEncoderWithContext(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter) (*Encoder, error) {
 	if ec.Registry == nil {
 		ec = bsoncodec.EncodeContext{Registry: DefaultRegistry}
@@ -60,8 +73,7 @@ func NewEncoderWithContext(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter) (*
 
 // Encode writes the BSON encoding of val to the stream.
 //
-// The documentation for Marshal contains details about the conversion of Go
-// values to BSON.
+// See [Marshal] for details about BSON marshaling behavior.
 func (e *Encoder) Encode(val interface{}) error {
 	if marshaler, ok := val.(Marshaler); ok {
 		// TODO(skriptble): Should we have a MarshalAppender interface so that we can have []byte reuse?
@@ -76,24 +88,112 @@ func (e *Encoder) Encode(val interface{}) error {
 	if err != nil {
 		return err
 	}
+
+	// Copy the configurations applied to the Encoder over to the EncodeContext, which actually
+	// communicates those configurations to the default ValueEncoders.
+	if e.errorOnInlineDuplicates {
+		e.ec.ErrorOnInlineDuplicates()
+	}
+	if e.intMinSize {
+		e.ec.MinSize = true
+	}
+	if e.stringifyMapKeysWithFmt {
+		e.ec.StringifyMapKeysWithFmt()
+	}
+	if e.nilMapAsEmpty {
+		e.ec.NilMapAsEmpty()
+	}
+	if e.nilSliceAsEmpty {
+		e.ec.NilSliceAsEmpty()
+	}
+	if e.nilByteSliceAsEmpty {
+		e.ec.NilByteSliceAsEmpty()
+	}
+	if e.omitZeroStruct {
+		e.ec.OmitZeroStruct()
+	}
+	if e.useJSONStructTags {
+		e.ec.UseJSONStructTags()
+	}
+
 	return encoder.EncodeValue(e.ec, e.vw, reflect.ValueOf(val))
 }
 
-// Reset will reset the state of the encoder, using the same *EncodeContext used in
+// Reset will reset the state of the Encoder, using the same *EncodeContext used in
 // the original construction but using vw.
 func (e *Encoder) Reset(vw bsonrw.ValueWriter) error {
+	// TODO:(GODRIVER-2719): Remove error return value.
 	e.vw = vw
 	return nil
 }
 
-// SetRegistry replaces the current registry of the encoder with r.
+// SetRegistry replaces the current registry of the Encoder with r.
 func (e *Encoder) SetRegistry(r *bsoncodec.Registry) error {
+	// TODO:(GODRIVER-2719): Remove error return value.
 	e.ec.Registry = r
 	return nil
 }
 
-// SetContext replaces the current EncodeContext of the encoder with er.
+// SetContext replaces the current EncodeContext of the encoder with ec.
+//
+// Deprecated: Use the Encoder configuration methods set the desired marshal behavior instead.
 func (e *Encoder) SetContext(ec bsoncodec.EncodeContext) error {
+	// TODO:(GODRIVER-2719): Remove error return value.
 	e.ec = ec
 	return nil
 }
+
+// ErrorOnInlineDuplicates causes the Encoder to return an error if there is a duplicate field in
+// the marshaled BSON when the "inline" struct tag option is set.
+func (e *Encoder) ErrorOnInlineDuplicates() {
+	e.errorOnInlineDuplicates = true
+}
+
+// IntMinSize causes the Encoder to marshal Go integer values (int, int8, int16, int32, int64, uint,
+// uint8, uint16, uint32, or uint64) as the minimum BSON int size (either 32 or 64 bits) that can
+// represent the integer value.
+func (e *Encoder) IntMinSize() {
+	e.intMinSize = true
+}
+
+// StringifyMapKeysWithFmt causes the Encoder to convert Go map keys to BSON document field name
+// strings using fmt.Sprint instead of the default string conversion logic.
+func (e *Encoder) StringifyMapKeysWithFmt() {
+	e.stringifyMapKeysWithFmt = true
+}
+
+// NilMapAsEmpty causes the Encoder to marshal nil Go maps as empty BSON documents instead of BSON
+// null.
+func (e *Encoder) NilMapAsEmpty() {
+	e.nilMapAsEmpty = true
+}
+
+// NilSliceAsEmpty causes the Encoder to marshal nil Go slices as empty BSON arrays instead of BSON
+// null.
+func (e *Encoder) NilSliceAsEmpty() {
+	e.nilSliceAsEmpty = true
+}
+
+// NilByteSliceAsEmpty causes the Encoder to marshal nil Go byte slices as empty BSON binary values
+// instead of BSON null.
+func (e *Encoder) NilByteSliceAsEmpty() {
+	e.nilByteSliceAsEmpty = true
+}
+
+// TODO(GODRIVER-2820): Update the description to remove the note about only examining exported
+// TODO struct fields once the logic is updated to also inspect private struct fields.
+
+// OmitZeroStruct causes the Encoder to consider the zero value for a struct (e.g. MyStruct{})
+// as empty and omit it from the marshaled BSON when the "omitempty" struct tag option is set.
+//
+// Note that the Encoder only examines exported struct fields when determining if a struct is the
+// zero value. It considers pointers to a zero struct value (e.g. &MyStruct{}) not empty.
+func (e *Encoder) OmitZeroStruct() {
+	e.omitZeroStruct = true
+}
+
+// UseJSONStructTags causes the Encoder to fall back to using the "json" struct tag if a "bson"
+// struct tag is not specified.
+func (e *Encoder) UseJSONStructTags() {
+	e.useJSONStructTags = true
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/marshal.go b/vendor/go.mongodb.org/mongo-driver/bson/marshal.go
index db8d8ee9..17ce6697 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/marshal.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/marshal.go
@@ -9,6 +9,7 @@ package bson
 import (
 	"bytes"
 	"encoding/json"
+	"sync"
 
 	"go.mongodb.org/mongo-driver/bson/bsoncodec"
 	"go.mongodb.org/mongo-driver/bson/bsonrw"
@@ -20,17 +21,23 @@ const defaultDstCap = 256
 var bvwPool = bsonrw.NewBSONValueWriterPool()
 var extjPool = bsonrw.NewExtJSONValueWriterPool()
 
-// Marshaler is an interface implemented by types that can marshal themselves
-// into a BSON document represented as bytes. The bytes returned must be a valid
-// BSON document if the error is nil.
+// Marshaler is the interface implemented by types that can marshal themselves
+// into a valid BSON document.
+//
+// Implementations of Marshaler must return a full BSON document. To create
+// custom BSON marshaling behavior for individual values in a BSON document,
+// implement the ValueMarshaler interface instead.
 type Marshaler interface {
 	MarshalBSON() ([]byte, error)
 }
 
-// ValueMarshaler is an interface implemented by types that can marshal
-// themselves into a BSON value as bytes. The type must be the valid type for
-// the bytes returned. The bytes and byte type together must be valid if the
-// error is nil.
+// ValueMarshaler is the interface implemented by types that can marshal
+// themselves into a valid BSON value. The format of the returned bytes must
+// match the returned type.
+//
+// Implementations of ValueMarshaler must return an individual BSON value. To
+// create custom BSON marshaling behavior for an entire BSON document, implement
+// the Marshaler interface instead.
 type ValueMarshaler interface {
 	MarshalBSONValue() (bsontype.Type, []byte, error)
 }
@@ -48,12 +55,42 @@ func Marshal(val interface{}) ([]byte, error) {
 // MarshalAppend will encode val as a BSON document and append the bytes to dst. If dst is not large enough to hold the
 // bytes, it will be grown. If val is not a type that can be transformed into a document, MarshalValueAppend should be
 // used instead.
+//
+// Deprecated: Use [NewEncoder] and pass the dst byte slice (wrapped by a bytes.Buffer) into
+// [bsonrw.NewBSONValueWriter]:
+//
+//	buf := bytes.NewBuffer(dst)
+//	vw, err := bsonrw.NewBSONValueWriter(buf)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc, err := bson.NewEncoder(vw)
+//	if err != nil {
+//		panic(err)
+//	}
+//
+// See [Encoder] for more examples.
 func MarshalAppend(dst []byte, val interface{}) ([]byte, error) {
 	return MarshalAppendWithRegistry(DefaultRegistry, dst, val)
 }
 
 // MarshalWithRegistry returns the BSON encoding of val as a BSON document. If val is not a type that can be transformed
 // into a document, MarshalValueWithRegistry should be used instead.
+//
+// Deprecated: Use [NewEncoder] and specify the Registry by calling [Encoder.SetRegistry] instead:
+//
+//	buf := new(bytes.Buffer)
+//	vw, err := bsonrw.NewBSONValueWriter(buf)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc, err := bson.NewEncoder(vw)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc.SetRegistry(reg)
+//
+// See [Encoder] for more examples.
 func MarshalWithRegistry(r *bsoncodec.Registry, val interface{}) ([]byte, error) {
 	dst := make([]byte, 0)
 	return MarshalAppendWithRegistry(r, dst, val)
@@ -61,6 +98,22 @@ func MarshalWithRegistry(r *bsoncodec.Registry, val interface{}) ([]byte, error)
 
 // MarshalWithContext returns the BSON encoding of val as a BSON document using EncodeContext ec. If val is not a type
 // that can be transformed into a document, MarshalValueWithContext should be used instead.
+//
+// Deprecated: Use [NewEncoder] and use the Encoder configuration methods to set the desired marshal
+// behavior instead:
+//
+//	buf := bytes.NewBuffer(dst)
+//	vw, err := bsonrw.NewBSONValueWriter(buf)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc, err := bson.NewEncoder(vw)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc.IntMinSize()
+//
+// See [Encoder] for more examples.
 func MarshalWithContext(ec bsoncodec.EncodeContext, val interface{}) ([]byte, error) {
 	dst := make([]byte, 0)
 	return MarshalAppendWithContext(ec, dst, val)
@@ -69,16 +122,74 @@ func MarshalWithContext(ec bsoncodec.EncodeContext, val interface{}) ([]byte, er
 // MarshalAppendWithRegistry will encode val as a BSON document using Registry r and append the bytes to dst. If dst is
 // not large enough to hold the bytes, it will be grown. If val is not a type that can be transformed into a document,
 // MarshalValueAppendWithRegistry should be used instead.
+//
+// Deprecated: Use [NewEncoder], and pass the dst byte slice (wrapped by a bytes.Buffer) into
+// [bsonrw.NewBSONValueWriter], and specify the Registry by calling [Encoder.SetRegistry] instead:
+//
+//	buf := bytes.NewBuffer(dst)
+//	vw, err := bsonrw.NewBSONValueWriter(buf)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc, err := bson.NewEncoder(vw)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc.SetRegistry(reg)
+//
+// See [Encoder] for more examples.
 func MarshalAppendWithRegistry(r *bsoncodec.Registry, dst []byte, val interface{}) ([]byte, error) {
 	return MarshalAppendWithContext(bsoncodec.EncodeContext{Registry: r}, dst, val)
 }
 
+// Pool of buffers for marshalling BSON.
+var bufPool = sync.Pool{
+	New: func() interface{} {
+		return new(bytes.Buffer)
+	},
+}
+
 // MarshalAppendWithContext will encode val as a BSON document using Registry r and EncodeContext ec and append the
 // bytes to dst. If dst is not large enough to hold the bytes, it will be grown. If val is not a type that can be
 // transformed into a document, MarshalValueAppendWithContext should be used instead.
+//
+// Deprecated: Use [NewEncoder], pass the dst byte slice (wrapped by a bytes.Buffer) into
+// [bsonrw.NewBSONValueWriter], and use the Encoder configuration methods to set the desired marshal
+// behavior instead:
+//
+//	buf := bytes.NewBuffer(dst)
+//	vw, err := bsonrw.NewBSONValueWriter(buf)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc, err := bson.NewEncoder(vw)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc.IntMinSize()
+//
+// See [Encoder] for more examples.
 func MarshalAppendWithContext(ec bsoncodec.EncodeContext, dst []byte, val interface{}) ([]byte, error) {
-	sw := new(bsonrw.SliceWriter)
-	*sw = dst
+	sw := bufPool.Get().(*bytes.Buffer)
+	defer func() {
+		// Proper usage of a sync.Pool requires each entry to have approximately
+		// the same memory cost. To obtain this property when the stored type
+		// contains a variably-sized buffer, we add a hard limit on the maximum
+		// buffer to place back in the pool. We limit the size to 16MiB because
+		// that's the maximum wire message size supported by any current MongoDB
+		// server.
+		//
+		// Comment based on
+		// https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/fmt/print.go;l=147
+		//
+		// Recycle byte slices that are smaller than 16MiB and at least half
+		// occupied.
+		if sw.Cap() < 16*1024*1024 && sw.Cap()/2 < sw.Len() {
+			bufPool.Put(sw)
+		}
+	}()
+
+	sw.Reset()
 	vw := bvwPool.Get(sw)
 	defer bvwPool.Put(vw)
 
@@ -99,7 +210,7 @@ func MarshalAppendWithContext(ec bsoncodec.EncodeContext, dst []byte, val interf
 		return nil, err
 	}
 
-	return *sw, nil
+	return append(dst, sw.Bytes()...), nil
 }
 
 // MarshalValue returns the BSON encoding of val.
@@ -112,17 +223,26 @@ func MarshalValue(val interface{}) (bsontype.Type, []byte, error) {
 
 // MarshalValueAppend will append the BSON encoding of val to dst. If dst is not large enough to hold the BSON encoding
 // of val, dst will be grown.
+//
+// Deprecated: Appending individual BSON elements to an existing slice will not be supported in Go
+// Driver 2.0.
 func MarshalValueAppend(dst []byte, val interface{}) (bsontype.Type, []byte, error) {
 	return MarshalValueAppendWithRegistry(DefaultRegistry, dst, val)
 }
 
 // MarshalValueWithRegistry returns the BSON encoding of val using Registry r.
+//
+// Deprecated: Using a custom registry to marshal individual BSON values will not be supported in Go
+// Driver 2.0.
 func MarshalValueWithRegistry(r *bsoncodec.Registry, val interface{}) (bsontype.Type, []byte, error) {
 	dst := make([]byte, 0)
 	return MarshalValueAppendWithRegistry(r, dst, val)
 }
 
 // MarshalValueWithContext returns the BSON encoding of val using EncodeContext ec.
+//
+// Deprecated: Using a custom EncodeContext to marshal individual BSON elements will not be
+// supported in Go Driver 2.0.
 func MarshalValueWithContext(ec bsoncodec.EncodeContext, val interface{}) (bsontype.Type, []byte, error) {
 	dst := make([]byte, 0)
 	return MarshalValueAppendWithContext(ec, dst, val)
@@ -130,12 +250,18 @@ func MarshalValueWithContext(ec bsoncodec.EncodeContext, val interface{}) (bsont
 
 // MarshalValueAppendWithRegistry will append the BSON encoding of val to dst using Registry r. If dst is not large
 // enough to hold the BSON encoding of val, dst will be grown.
+//
+// Deprecated: Appending individual BSON elements to an existing slice will not be supported in Go
+// Driver 2.0.
 func MarshalValueAppendWithRegistry(r *bsoncodec.Registry, dst []byte, val interface{}) (bsontype.Type, []byte, error) {
 	return MarshalValueAppendWithContext(bsoncodec.EncodeContext{Registry: r}, dst, val)
 }
 
 // MarshalValueAppendWithContext will append the BSON encoding of val to dst using EncodeContext ec. If dst is not large
 // enough to hold the BSON encoding of val, dst will be grown.
+//
+// Deprecated: Appending individual BSON elements to an existing slice will not be supported in Go
+// Driver 2.0.
 func MarshalValueAppendWithContext(ec bsoncodec.EncodeContext, dst []byte, val interface{}) (bsontype.Type, []byte, error) {
 	// get a ValueWriter configured to write to dst
 	sw := new(bsonrw.SliceWriter)
@@ -173,17 +299,63 @@ func MarshalExtJSON(val interface{}, canonical, escapeHTML bool) ([]byte, error)
 // MarshalExtJSONAppend will append the extended JSON encoding of val to dst.
 // If dst is not large enough to hold the extended JSON encoding of val, dst
 // will be grown.
+//
+// Deprecated: Use [NewEncoder] and pass the dst byte slice (wrapped by a bytes.Buffer) into
+// [bsonrw.NewExtJSONValueWriter] instead:
+//
+//	buf := bytes.NewBuffer(dst)
+//	vw, err := bsonrw.NewExtJSONValueWriter(buf, true, false)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc, err := bson.NewEncoder(vw)
+//	if err != nil {
+//		panic(err)
+//	}
+//
+// See [Encoder] for more examples.
 func MarshalExtJSONAppend(dst []byte, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
 	return MarshalExtJSONAppendWithRegistry(DefaultRegistry, dst, val, canonical, escapeHTML)
 }
 
 // MarshalExtJSONWithRegistry returns the extended JSON encoding of val using Registry r.
+//
+// Deprecated: Use [NewEncoder] and specify the Registry by calling [Encoder.SetRegistry] instead:
+//
+//	buf := new(bytes.Buffer)
+//	vw, err := bsonrw.NewBSONValueWriter(buf)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc, err := bson.NewEncoder(vw)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc.SetRegistry(reg)
+//
+// See [Encoder] for more examples.
 func MarshalExtJSONWithRegistry(r *bsoncodec.Registry, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
 	dst := make([]byte, 0, defaultDstCap)
 	return MarshalExtJSONAppendWithContext(bsoncodec.EncodeContext{Registry: r}, dst, val, canonical, escapeHTML)
 }
 
 // MarshalExtJSONWithContext returns the extended JSON encoding of val using Registry r.
+//
+// Deprecated: Use [NewEncoder] and use the Encoder configuration methods to set the desired marshal
+// behavior instead:
+//
+//	buf := new(bytes.Buffer)
+//	vw, err := bsonrw.NewBSONValueWriter(buf)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc, err := bson.NewEncoder(vw)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc.IntMinSize()
+//
+// See [Encoder] for more examples.
 func MarshalExtJSONWithContext(ec bsoncodec.EncodeContext, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
 	dst := make([]byte, 0, defaultDstCap)
 	return MarshalExtJSONAppendWithContext(ec, dst, val, canonical, escapeHTML)
@@ -192,6 +364,22 @@ func MarshalExtJSONWithContext(ec bsoncodec.EncodeContext, val interface{}, cano
 // MarshalExtJSONAppendWithRegistry will append the extended JSON encoding of
 // val to dst using Registry r. If dst is not large enough to hold the BSON
 // encoding of val, dst will be grown.
+//
+// Deprecated: Use [NewEncoder], pass the dst byte slice (wrapped by a bytes.Buffer) into
+// [bsonrw.NewExtJSONValueWriter], and specify the Registry by calling [Encoder.SetRegistry]
+// instead:
+//
+//	buf := bytes.NewBuffer(dst)
+//	vw, err := bsonrw.NewExtJSONValueWriter(buf, true, false)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc, err := bson.NewEncoder(vw)
+//	if err != nil {
+//		panic(err)
+//	}
+//
+// See [Encoder] for more examples.
 func MarshalExtJSONAppendWithRegistry(r *bsoncodec.Registry, dst []byte, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
 	return MarshalExtJSONAppendWithContext(bsoncodec.EncodeContext{Registry: r}, dst, val, canonical, escapeHTML)
 }
@@ -199,6 +387,23 @@ func MarshalExtJSONAppendWithRegistry(r *bsoncodec.Registry, dst []byte, val int
 // MarshalExtJSONAppendWithContext will append the extended JSON encoding of
 // val to dst using Registry r. If dst is not large enough to hold the BSON
 // encoding of val, dst will be grown.
+//
+// Deprecated: Use [NewEncoder], pass the dst byte slice (wrapped by a bytes.Buffer) into
+// [bsonrw.NewExtJSONValueWriter], and use the Encoder configuration methods to set the desired marshal
+// behavior instead:
+//
+//	buf := bytes.NewBuffer(dst)
+//	vw, err := bsonrw.NewExtJSONValueWriter(buf, true, false)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc, err := bson.NewEncoder(vw)
+//	if err != nil {
+//		panic(err)
+//	}
+//	enc.IntMinSize()
+//
+// See [Encoder] for more examples.
 func MarshalExtJSONAppendWithContext(ec bsoncodec.EncodeContext, dst []byte, val interface{}, canonical, escapeHTML bool) ([]byte, error) {
 	sw := new(bsonrw.SliceWriter)
 	*sw = dst
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go b/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go
index ba7c9112..08c39514 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/primitive/decimal.go
@@ -164,9 +164,6 @@ func (d Decimal128) BigInt() (*big.Int, int, error) {
 
 	// Would be handled by the logic below, but that's trivial and common.
 	if high == 0 && low == 0 && exp == 0 {
-		if posSign {
-			return new(big.Int), 0, nil
-		}
 		return new(big.Int), 0, nil
 	}
 
@@ -328,6 +325,7 @@ func ParseDecimal128(s string) (Decimal128, error) {
 		return dErr(s)
 	}
 
+	// Parse the significand (i.e. the non-exponent part) as a big.Int.
 	bi, ok := new(big.Int).SetString(intPart+decPart, 10)
 	if !ok {
 		return dErr(s)
@@ -360,6 +358,19 @@ func ParseDecimal128FromBigInt(bi *big.Int, exp int) (Decimal128, bool) {
 	q := new(big.Int)
 	r := new(big.Int)
 
+	// If the significand is zero, the logical value will always be zero, independent of the
+	// exponent. However, the loops for handling out-of-range exponent values below may be extremely
+	// slow for zero values because the significand never changes. Limit the exponent value to the
+	// supported range here to prevent entering the loops below.
+	if bi.Cmp(zero) == 0 {
+		if exp > MaxDecimal128Exp {
+			exp = MaxDecimal128Exp
+		}
+		if exp < MinDecimal128Exp {
+			exp = MinDecimal128Exp
+		}
+	}
+
 	for bigIntCmpAbs(bi, maxS) == 1 {
 		bi, _ = q.QuoRem(bi, ten, r)
 		if r.Cmp(zero) != 0 {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go b/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go
index ded36731..c130e3ff 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/primitive/objectid.go
@@ -82,18 +82,18 @@ func ObjectIDFromHex(s string) (ObjectID, error) {
 		return NilObjectID, ErrInvalidHex
 	}
 
-	b, err := hex.DecodeString(s)
+	var oid [12]byte
+	_, err := hex.Decode(oid[:], []byte(s))
 	if err != nil {
 		return NilObjectID, err
 	}
 
-	var oid [12]byte
-	copy(oid[:], b)
-
 	return oid, nil
 }
 
 // IsValidObjectID returns true if the provided hex string represents a valid ObjectID and false if not.
+//
+// Deprecated: Use ObjectIDFromHex and check the error instead.
 func IsValidObjectID(s string) bool {
 	_, err := ObjectIDFromHex(s)
 	return err == nil
@@ -183,7 +183,7 @@ func processUniqueBytes() [5]byte {
 	var b [5]byte
 	_, err := io.ReadFull(rand.Reader, b[:])
 	if err != nil {
-		panic(fmt.Errorf("cannot initialize objectid package with crypto.rand.Reader: %v", err))
+		panic(fmt.Errorf("cannot initialize objectid package with crypto.rand.Reader: %w", err))
 	}
 
 	return b
@@ -193,7 +193,7 @@ func readRandomUint32() uint32 {
 	var b [4]byte
 	_, err := io.ReadFull(rand.Reader, b[:])
 	if err != nil {
-		panic(fmt.Errorf("cannot initialize objectid package with crypto.rand.Reader: %v", err))
+		panic(fmt.Errorf("cannot initialize objectid package with crypto.rand.Reader: %w", err))
 	}
 
 	return (uint32(b[0]) << 0) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24)
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go b/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go
index c72ccc1c..65f4fbb9 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/primitive/primitive.go
@@ -45,7 +45,7 @@ var _ json.Unmarshaler = (*DateTime)(nil)
 
 // MarshalJSON marshal to time type.
 func (d DateTime) MarshalJSON() ([]byte, error) {
-	return json.Marshal(d.Time())
+	return json.Marshal(d.Time().UTC())
 }
 
 // UnmarshalJSON creates a primitive.DateTime from a JSON string.
@@ -141,6 +141,16 @@ type Timestamp struct {
 	I uint32
 }
 
+// After reports whether the time instant tp is after tp2.
+func (tp Timestamp) After(tp2 Timestamp) bool {
+	return tp.T > tp2.T || (tp.T == tp2.T && tp.I > tp2.I)
+}
+
+// Before reports whether the time instant tp is before tp2.
+func (tp Timestamp) Before(tp2 Timestamp) bool {
+	return tp.T < tp2.T || (tp.T == tp2.T && tp.I < tp2.I)
+}
+
 // Equal compares tp to tp2 and returns true if they are equal.
 func (tp Timestamp) Equal(tp2 Timestamp) bool {
 	return tp.T == tp2.T && tp.I == tp2.I
@@ -151,24 +161,25 @@ func (tp Timestamp) IsZero() bool {
 	return tp.T == 0 && tp.I == 0
 }
 
-// CompareTimestamp returns an integer comparing two Timestamps, where T is compared first, followed by I.
-// Returns 0 if tp = tp2, 1 if tp > tp2, -1 if tp < tp2.
-func CompareTimestamp(tp, tp2 Timestamp) int {
-	if tp.Equal(tp2) {
+// Compare compares the time instant tp with tp2. If tp is before tp2, it returns -1; if tp is after
+// tp2, it returns +1; if they're the same, it returns 0.
+func (tp Timestamp) Compare(tp2 Timestamp) int {
+	switch {
+	case tp.Equal(tp2):
 		return 0
-	}
-
-	if tp.T > tp2.T {
-		return 1
-	}
-	if tp.T < tp2.T {
+	case tp.Before(tp2):
 		return -1
+	default:
+		return +1
 	}
-	// Compare I values because T values are equal
-	if tp.I > tp2.I {
-		return 1
-	}
-	return -1
+}
+
+// CompareTimestamp compares the time instant tp with tp2. If tp is before tp2, it returns -1; if tp is after
+// tp2, it returns +1; if they're the same, it returns 0.
+//
+// Deprecated: Use Timestamp.Compare instead.
+func CompareTimestamp(tp, tp2 Timestamp) int {
+	return tp.Compare(tp2)
 }
 
 // MinKey represents the BSON minkey value.
@@ -186,6 +197,9 @@ type MaxKey struct{}
 type D []E
 
 // Map creates a map from the elements of the D.
+//
+// Deprecated: Converting directly from a D to an M will not be supported in Go Driver 2.0. Instead,
+// users should marshal the D to BSON using bson.Marshal and unmarshal it to M using bson.Unmarshal.
 func (d D) Map() M {
 	m := make(M, len(d))
 	for _, e := range d {
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/primitive_codecs.go b/vendor/go.mongodb.org/mongo-driver/bson/primitive_codecs.go
index 1cbe3884..ff32a87a 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/primitive_codecs.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/primitive_codecs.go
@@ -8,6 +8,7 @@ package bson
 
 import (
 	"errors"
+	"fmt"
 	"reflect"
 
 	"go.mongodb.org/mongo-driver/bson/bsoncodec"
@@ -21,10 +22,16 @@ var primitiveCodecs PrimitiveCodecs
 
 // PrimitiveCodecs is a namespace for all of the default bsoncodec.Codecs for the primitive types
 // defined in this package.
+//
+// Deprecated: Use bson.NewRegistry to get a registry with all primitive encoders and decoders
+// registered.
 type PrimitiveCodecs struct{}
 
 // RegisterPrimitiveCodecs will register the encode and decode methods attached to PrimitiveCodecs
 // with the provided RegistryBuilder. if rb is nil, a new empty RegistryBuilder will be created.
+//
+// Deprecated: Use bson.NewRegistry to get a registry with all primitive encoders and decoders
+// registered.
 func (pc PrimitiveCodecs) RegisterPrimitiveCodecs(rb *bsoncodec.RegistryBuilder) {
 	if rb == nil {
 		panic(errors.New("argument to RegisterPrimitiveCodecs must not be nil"))
@@ -38,18 +45,35 @@ func (pc PrimitiveCodecs) RegisterPrimitiveCodecs(rb *bsoncodec.RegistryBuilder)
 }
 
 // RawValueEncodeValue is the ValueEncoderFunc for RawValue.
-func (PrimitiveCodecs) RawValueEncodeValue(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// If the RawValue's Type is "invalid" and the RawValue's Value is not empty or
+// nil, then this method will return an error.
+//
+// Deprecated: Use bson.NewRegistry to get a registry with all primitive
+// encoders and decoders registered.
+func (PrimitiveCodecs) RawValueEncodeValue(_ bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tRawValue {
-		return bsoncodec.ValueEncoderError{Name: "RawValueEncodeValue", Types: []reflect.Type{tRawValue}, Received: val}
+		return bsoncodec.ValueEncoderError{
+			Name:     "RawValueEncodeValue",
+			Types:    []reflect.Type{tRawValue},
+			Received: val,
+		}
 	}
 
 	rawvalue := val.Interface().(RawValue)
 
+	if !rawvalue.Type.IsValid() {
+		return fmt.Errorf("the RawValue Type specifies an invalid BSON type: %#x", byte(rawvalue.Type))
+	}
+
 	return bsonrw.Copier{}.CopyValueFromBytes(vw, rawvalue.Type, rawvalue.Value)
 }
 
 // RawValueDecodeValue is the ValueDecoderFunc for RawValue.
-func (PrimitiveCodecs) RawValueDecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+//
+// Deprecated: Use bson.NewRegistry to get a registry with all primitive encoders and decoders
+// registered.
+func (PrimitiveCodecs) RawValueDecodeValue(_ bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tRawValue {
 		return bsoncodec.ValueDecoderError{Name: "RawValueDecodeValue", Types: []reflect.Type{tRawValue}, Received: val}
 	}
@@ -64,7 +88,10 @@ func (PrimitiveCodecs) RawValueDecodeValue(dc bsoncodec.DecodeContext, vr bsonrw
 }
 
 // RawEncodeValue is the ValueEncoderFunc for Reader.
-func (PrimitiveCodecs) RawEncodeValue(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
+//
+// Deprecated: Use bson.NewRegistry to get a registry with all primitive encoders and decoders
+// registered.
+func (PrimitiveCodecs) RawEncodeValue(_ bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
 	if !val.IsValid() || val.Type() != tRaw {
 		return bsoncodec.ValueEncoderError{Name: "RawEncodeValue", Types: []reflect.Type{tRaw}, Received: val}
 	}
@@ -75,7 +102,10 @@ func (PrimitiveCodecs) RawEncodeValue(ec bsoncodec.EncodeContext, vw bsonrw.Valu
 }
 
 // RawDecodeValue is the ValueDecoderFunc for Reader.
-func (PrimitiveCodecs) RawDecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
+//
+// Deprecated: Use bson.NewRegistry to get a registry with all primitive encoders and decoders
+// registered.
+func (PrimitiveCodecs) RawDecodeValue(_ bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
 	if !val.CanSet() || val.Type() != tRaw {
 		return bsoncodec.ValueDecoderError{Name: "RawDecodeValue", Types: []reflect.Type{tRaw}, Received: val}
 	}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/raw.go b/vendor/go.mongodb.org/mongo-driver/bson/raw.go
index efd705da..130da61b 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/raw.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/raw.go
@@ -16,18 +16,27 @@ import (
 // ErrNilReader indicates that an operation was attempted on a nil bson.Reader.
 var ErrNilReader = errors.New("nil reader")
 
-// Raw is a wrapper around a byte slice. It will interpret the slice as a
-// BSON document. This type is a wrapper around a bsoncore.Document. Errors returned from the
-// methods on this type and associated types come from the bsoncore package.
+// Raw is a raw encoded BSON document. It can be used to delay BSON document decoding or precompute
+// a BSON encoded document.
+//
+// A Raw must be a full BSON document. Use the RawValue type for individual BSON values.
 type Raw []byte
 
-// NewFromIOReader reads in a document from the given io.Reader and constructs a Raw from
-// it.
-func NewFromIOReader(r io.Reader) (Raw, error) {
+// ReadDocument reads a BSON document from the io.Reader and returns it as a bson.Raw. If the
+// reader contains multiple BSON documents, only the first document is read.
+func ReadDocument(r io.Reader) (Raw, error) {
 	doc, err := bsoncore.NewDocumentFromReader(r)
 	return Raw(doc), err
 }
 
+// NewFromIOReader reads a BSON document from the io.Reader and returns it as a bson.Raw. If the
+// reader contains multiple BSON documents, only the first document is read.
+//
+// Deprecated: Use ReadDocument instead.
+func NewFromIOReader(r io.Reader) (Raw, error) {
+	return ReadDocument(r)
+}
+
 // Validate validates the document. This method only validates the first document in
 // the slice, to validate other documents, the slice must be resliced.
 func (r Raw) Validate() (err error) { return bsoncore.Document(r).Validate() }
@@ -51,12 +60,19 @@ func (r Raw) LookupErr(key ...string) (RawValue, error) {
 // elements. If the document is not valid, the elements up to the invalid point will be returned
 // along with an error.
 func (r Raw) Elements() ([]RawElement, error) {
-	elems, err := bsoncore.Document(r).Elements()
+	doc := bsoncore.Document(r)
+	if len(doc) == 0 {
+		return nil, nil
+	}
+	elems, err := doc.Elements()
+	if err != nil {
+		return nil, err
+	}
 	relems := make([]RawElement, 0, len(elems))
 	for _, elem := range elems {
 		relems = append(relems, RawElement(elem))
 	}
-	return relems, err
+	return relems, nil
 }
 
 // Values returns this document as a slice of values. The returned slice will contain valid values.
@@ -81,5 +97,5 @@ func (r Raw) IndexErr(index uint) (RawElement, error) {
 	return RawElement(elem), err
 }
 
-// String implements the fmt.Stringer interface.
+// String returns the BSON document encoded as Extended JSON.
 func (r Raw) String() string { return bsoncore.Document(r).String() }
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/raw_element.go b/vendor/go.mongodb.org/mongo-driver/bson/raw_element.go
index 006f503a..8ce13c2c 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/raw_element.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/raw_element.go
@@ -10,10 +10,7 @@ import (
 	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
 )
 
-// RawElement represents a BSON element in byte form. This type provides a simple way to
-// transform a slice of bytes into a BSON element and extract information from it.
-//
-// RawElement is a thin wrapper around a bsoncore.Element.
+// RawElement is a raw encoded BSON document or array element.
 type RawElement []byte
 
 // Key returns the key for this element. If the element is not valid, this method returns an empty
@@ -36,7 +33,7 @@ func (re RawElement) ValueErr() (RawValue, error) {
 // Validate ensures re is a valid BSON element.
 func (re RawElement) Validate() error { return bsoncore.Element(re).Validate() }
 
-// String implements the fmt.Stringer interface. The output will be in extended JSON format.
+// String returns the BSON element encoded as Extended JSON.
 func (re RawElement) String() string {
 	doc := bsoncore.BuildDocument(nil, re)
 	j, err := MarshalExtJSON(Raw(doc), true, false)
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/raw_value.go b/vendor/go.mongodb.org/mongo-driver/bson/raw_value.go
index 75297f30..a8088e1e 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/raw_value.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/raw_value.go
@@ -26,11 +26,10 @@ var ErrNilContext = errors.New("DecodeContext cannot be nil")
 // ErrNilRegistry is returned when the provided registry is nil.
 var ErrNilRegistry = errors.New("Registry cannot be nil")
 
-// RawValue represents a BSON value in byte form. It can be used to hold unprocessed BSON or to
-// defer processing of BSON. Type is the BSON type of the value and Value are the raw bytes that
-// represent the element.
+// RawValue is a raw encoded BSON value. It can be used to delay BSON value decoding or precompute
+// BSON encoded value. Type is the BSON type of the value and Value is the raw encoded BSON value.
 //
-// This type wraps bsoncore.Value for most of it's functionality.
+// A RawValue must be an individual BSON value. Use the Raw type for full BSON documents.
 type RawValue struct {
 	Type  bsontype.Type
 	Value []byte
@@ -38,6 +37,12 @@ type RawValue struct {
 	r *bsoncodec.Registry
 }
 
+// IsZero reports whether the RawValue is zero, i.e. no data is present on
+// the RawValue. It returns true if Type is 0 and Value is empty or nil.
+func (rv RawValue) IsZero() bool {
+	return rv.Type == 0x00 && len(rv.Value) == 0
+}
+
 // Unmarshal deserializes BSON into the provided val. If RawValue cannot be unmarshaled into val, an
 // error is returned. This method will use the registry used to create the RawValue, if the RawValue
 // was created from partial BSON processing, or it will use the default registry. Users wishing to
@@ -83,8 +88,12 @@ func (rv RawValue) UnmarshalWithRegistry(r *bsoncodec.Registry, val interface{})
 	return dec.DecodeValue(bsoncodec.DecodeContext{Registry: r}, vr, rval)
 }
 
-// UnmarshalWithContext performs the same unmarshalling as Unmarshal but uses the provided DecodeContext
-// instead of the one attached or the default registry.
+// UnmarshalWithContext performs the same unmarshalling as Unmarshal but uses
+// the provided DecodeContext instead of the one attached or the default
+// registry.
+//
+// Deprecated: Use [RawValue.UnmarshalWithRegistry] with a custom registry to customize
+// unmarshal behavior instead.
 func (rv RawValue) UnmarshalWithContext(dc *bsoncodec.DecodeContext, val interface{}) error {
 	if dc == nil {
 		return ErrNilContext
@@ -268,10 +277,16 @@ func (rv RawValue) Int32OK() (int32, bool) { return convertToCoreValue(rv).Int32
 
 // AsInt32 returns a BSON number as an int32. If the BSON type is not a numeric one, this method
 // will panic.
+//
+// Deprecated: Use AsInt64 instead. If an int32 is required, convert the returned value to an int32
+// and perform any required overflow/underflow checking.
 func (rv RawValue) AsInt32() int32 { return convertToCoreValue(rv).AsInt32() }
 
 // AsInt32OK is the same as AsInt32, except that it returns a boolean instead of
 // panicking.
+//
+// Deprecated: Use AsInt64OK instead. If an int32 is required, convert the returned value to an
+// int32 and perform any required overflow/underflow checking.
 func (rv RawValue) AsInt32OK() (int32, bool) { return convertToCoreValue(rv).AsInt32OK() }
 
 // Timestamp returns the BSON timestamp value the Value represents. It panics if the value is a
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/registry.go b/vendor/go.mongodb.org/mongo-driver/bson/registry.go
index 16d7573e..d6afb285 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/registry.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/registry.go
@@ -6,15 +6,31 @@
 
 package bson
 
-import "go.mongodb.org/mongo-driver/bson/bsoncodec"
+import (
+	"go.mongodb.org/mongo-driver/bson/bsoncodec"
+)
 
-// DefaultRegistry is the default bsoncodec.Registry. It contains the default codecs and the
-// primitive codecs.
-var DefaultRegistry = NewRegistryBuilder().Build()
+// DefaultRegistry is the default bsoncodec.Registry. It contains the default
+// codecs and the primitive codecs.
+//
+// Deprecated: Use [NewRegistry] to construct a new default registry. To use a
+// custom registry when marshaling or unmarshaling, use the "SetRegistry" method
+// on an [Encoder] or [Decoder] instead:
+//
+//	dec, err := bson.NewDecoder(bsonrw.NewBSONDocumentReader(data))
+//	if err != nil {
+//	    panic(err)
+//	}
+//	dec.SetRegistry(reg)
+//
+// See [Encoder] and [Decoder] for more examples.
+var DefaultRegistry = NewRegistry()
 
 // NewRegistryBuilder creates a new RegistryBuilder configured with the default encoders and
 // decoders from the bsoncodec.DefaultValueEncoders and bsoncodec.DefaultValueDecoders types and the
 // PrimitiveCodecs type in this package.
+//
+// Deprecated: Use [NewRegistry] instead.
 func NewRegistryBuilder() *bsoncodec.RegistryBuilder {
 	rb := bsoncodec.NewRegistryBuilder()
 	bsoncodec.DefaultValueEncoders{}.RegisterDefaultEncoders(rb)
@@ -22,3 +38,10 @@ func NewRegistryBuilder() *bsoncodec.RegistryBuilder {
 	primitiveCodecs.RegisterPrimitiveCodecs(rb)
 	return rb
 }
+
+// NewRegistry creates a new Registry configured with the default encoders and decoders from the
+// bsoncodec.DefaultValueEncoders and bsoncodec.DefaultValueDecoders types and the PrimitiveCodecs
+// type in this package.
+func NewRegistry() *bsoncodec.Registry {
+	return NewRegistryBuilder().Build()
+}
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/types.go b/vendor/go.mongodb.org/mongo-driver/bson/types.go
index 13a1c35c..ef398124 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/types.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/types.go
@@ -10,7 +10,7 @@ import (
 	"go.mongodb.org/mongo-driver/bson/bsontype"
 )
 
-// These constants uniquely refer to each BSON type.
+// BSON element types as described in https://bsonspec.org/spec.html.
 const (
 	TypeDouble           = bsontype.Double
 	TypeString           = bsontype.String
@@ -34,3 +34,17 @@ const (
 	TypeMinKey           = bsontype.MinKey
 	TypeMaxKey           = bsontype.MaxKey
 )
+
+// BSON binary element subtypes as described in https://bsonspec.org/spec.html.
+const (
+	TypeBinaryGeneric     = bsontype.BinaryGeneric
+	TypeBinaryFunction    = bsontype.BinaryFunction
+	TypeBinaryBinaryOld   = bsontype.BinaryBinaryOld
+	TypeBinaryUUIDOld     = bsontype.BinaryUUIDOld
+	TypeBinaryUUID        = bsontype.BinaryUUID
+	TypeBinaryMD5         = bsontype.BinaryMD5
+	TypeBinaryEncrypted   = bsontype.BinaryEncrypted
+	TypeBinaryColumn      = bsontype.BinaryColumn
+	TypeBinarySensitive   = bsontype.BinarySensitive
+	TypeBinaryUserDefined = bsontype.BinaryUserDefined
+)
diff --git a/vendor/go.mongodb.org/mongo-driver/bson/unmarshal.go b/vendor/go.mongodb.org/mongo-driver/bson/unmarshal.go
index f936ba18..66da17ee 100644
--- a/vendor/go.mongodb.org/mongo-driver/bson/unmarshal.go
+++ b/vendor/go.mongodb.org/mongo-driver/bson/unmarshal.go
@@ -14,18 +14,26 @@ import (
 	"go.mongodb.org/mongo-driver/bson/bsontype"
 )
 
-// Unmarshaler is an interface implemented by types that can unmarshal a BSON
-// document representation of themselves. The BSON bytes can be assumed to be
-// valid. UnmarshalBSON must copy the BSON bytes if it wishes to retain the data
-// after returning.
+// Unmarshaler is the interface implemented by types that can unmarshal a BSON
+// document representation of themselves. The input can be assumed to be a valid
+// encoding of a BSON document. UnmarshalBSON must copy the JSON data if it
+// wishes to retain the data after returning.
+//
+// Unmarshaler is only used to unmarshal full BSON documents. To create custom
+// BSON unmarshaling behavior for individual values in a BSON document,
+// implement the ValueUnmarshaler interface instead.
 type Unmarshaler interface {
 	UnmarshalBSON([]byte) error
 }
 
-// ValueUnmarshaler is an interface implemented by types that can unmarshal a
-// BSON value representation of themselves. The BSON bytes and type can be
-// assumed to be valid. UnmarshalBSONValue must copy the BSON value bytes if it
-// wishes to retain the data after returning.
+// ValueUnmarshaler is the interface implemented by types that can unmarshal a
+// BSON value representation of themselves. The input can be assumed to be a
+// valid encoding of a BSON value. UnmarshalBSONValue must copy the BSON value
+// bytes if it wishes to retain the data after returning.
+//
+// ValueUnmarshaler is only used to unmarshal individual values in a BSON
+// document. To create custom BSON unmarshaling behavior for an entire BSON
+// document, implement the Unmarshaler interface instead.
 type ValueUnmarshaler interface {
 	UnmarshalBSONValue(bsontype.Type, []byte) error
 }
@@ -40,6 +48,16 @@ func Unmarshal(data []byte, val interface{}) error {
 // UnmarshalWithRegistry parses the BSON-encoded data using Registry r and
 // stores the result in the value pointed to by val. If val is nil or not
 // a pointer, UnmarshalWithRegistry returns InvalidUnmarshalError.
+//
+// Deprecated: Use [NewDecoder] and specify the Registry by calling [Decoder.SetRegistry] instead:
+//
+//	dec, err := bson.NewDecoder(bsonrw.NewBSONDocumentReader(data))
+//	if err != nil {
+//		panic(err)
+//	}
+//	dec.SetRegistry(reg)
+//
+// See [Decoder] for more examples.
 func UnmarshalWithRegistry(r *bsoncodec.Registry, data []byte, val interface{}) error {
 	vr := bsonrw.NewBSONDocumentReader(data)
 	return unmarshalFromReader(bsoncodec.DecodeContext{Registry: r}, vr, val)
@@ -48,11 +66,40 @@ func UnmarshalWithRegistry(r *bsoncodec.Registry, data []byte, val interface{})
 // UnmarshalWithContext parses the BSON-encoded data using DecodeContext dc and
 // stores the result in the value pointed to by val. If val is nil or not
 // a pointer, UnmarshalWithRegistry returns InvalidUnmarshalError.
+//
+// Deprecated: Use [NewDecoder] and use the Decoder configuration methods to set the desired unmarshal
+// behavior instead:
+//
+//	dec, err := bson.NewDecoder(bsonrw.NewBSONDocumentReader(data))
+//	if err != nil {
+//		panic(err)
+//	}
+//	dec.DefaultDocumentM()
+//
+// See [Decoder] for more examples.
 func UnmarshalWithContext(dc bsoncodec.DecodeContext, data []byte, val interface{}) error {
 	vr := bsonrw.NewBSONDocumentReader(data)
 	return unmarshalFromReader(dc, vr, val)
 }
 
+// UnmarshalValue parses the BSON value of type t with bson.DefaultRegistry and
+// stores the result in the value pointed to by val. If val is nil or not a pointer,
+// UnmarshalValue returns an error.
+func UnmarshalValue(t bsontype.Type, data []byte, val interface{}) error {
+	return UnmarshalValueWithRegistry(DefaultRegistry, t, data, val)
+}
+
+// UnmarshalValueWithRegistry parses the BSON value of type t with registry r and
+// stores the result in the value pointed to by val. If val is nil or not a pointer,
+// UnmarshalValue returns an error.
+//
+// Deprecated: Using a custom registry to unmarshal individual BSON values will not be supported in
+// Go Driver 2.0.
+func UnmarshalValueWithRegistry(r *bsoncodec.Registry, t bsontype.Type, data []byte, val interface{}) error {
+	vr := bsonrw.NewBSONValueReader(t, data)
+	return unmarshalFromReader(bsoncodec.DecodeContext{Registry: r}, vr, val)
+}
+
 // UnmarshalExtJSON parses the extended JSON-encoded data and stores the result
 // in the value pointed to by val. If val is nil or not a pointer, Unmarshal
 // returns InvalidUnmarshalError.
@@ -63,6 +110,20 @@ func UnmarshalExtJSON(data []byte, canonical bool, val interface{}) error {
 // UnmarshalExtJSONWithRegistry parses the extended JSON-encoded data using
 // Registry r and stores the result in the value pointed to by val. If val is
 // nil or not a pointer, UnmarshalWithRegistry returns InvalidUnmarshalError.
+//
+// Deprecated: Use [NewDecoder] and specify the Registry by calling [Decoder.SetRegistry] instead:
+//
+//	vr, err := bsonrw.NewExtJSONValueReader(bytes.NewReader(data), true)
+//	if err != nil {
+//		panic(err)
+//	}
+//	dec, err := bson.NewDecoder(vr)
+//	if err != nil {
+//		panic(err)
+//	}
+//	dec.SetRegistry(reg)
+//
+// See [Decoder] for more examples.
 func UnmarshalExtJSONWithRegistry(r *bsoncodec.Registry, data []byte, canonical bool, val interface{}) error {
 	ejvr, err := bsonrw.NewExtJSONValueReader(bytes.NewReader(data), canonical)
 	if err != nil {
@@ -75,6 +136,21 @@ func UnmarshalExtJSONWithRegistry(r *bsoncodec.Registry, data []byte, canonical
 // UnmarshalExtJSONWithContext parses the extended JSON-encoded data using
 // DecodeContext dc and stores the result in the value pointed to by val. If val is
 // nil or not a pointer, UnmarshalWithRegistry returns InvalidUnmarshalError.
+//
+// Deprecated: Use [NewDecoder] and use the Decoder configuration methods to set the desired unmarshal
+// behavior instead:
+//
+//	vr, err := bsonrw.NewExtJSONValueReader(bytes.NewReader(data), true)
+//	if err != nil {
+//		panic(err)
+//	}
+//	dec, err := bson.NewDecoder(vr)
+//	if err != nil {
+//		panic(err)
+//	}
+//	dec.DefaultDocumentM()
+//
+// See [Decoder] for more examples.
 func UnmarshalExtJSONWithContext(dc bsoncodec.DecodeContext, data []byte, canonical bool, val interface{}) error {
 	ejvr, err := bsonrw.NewExtJSONValueReader(bytes.NewReader(data), canonical)
 	if err != nil {
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/array.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/array.go
index 8ea60ba3..6bc0afa7 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/array.go
+++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/array.go
@@ -7,10 +7,10 @@
 package bsoncore
 
 import (
-	"bytes"
 	"fmt"
 	"io"
 	"strconv"
+	"strings"
 )
 
 // NewArrayLengthError creates and returns an error for when the length of an array exceeds the
@@ -53,7 +53,7 @@ func (a Array) DebugString() string {
 	if len(a) < 5 {
 		return "<malformed>"
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	buf.WriteString("Array")
 	length, rem, _ := ReadLength(a) // We know we have enough bytes to read the length
 	buf.WriteByte('(')
@@ -69,7 +69,7 @@ func (a Array) DebugString() string {
 			buf.WriteString(fmt.Sprintf("<malformed (%d)>", length))
 			break
 		}
-		fmt.Fprintf(&buf, "%s", elem.Value().DebugString())
+		buf.WriteString(elem.Value().DebugString())
 		if length != 1 {
 			buf.WriteByte(',')
 		}
@@ -85,7 +85,7 @@ func (a Array) String() string {
 	if len(a) < 5 {
 		return ""
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	buf.WriteByte('[')
 
 	length, rem, _ := ReadLength(a) // We know we have enough bytes to read the length
@@ -100,7 +100,7 @@ func (a Array) String() string {
 		if !ok {
 			return ""
 		}
-		fmt.Fprintf(&buf, "%s", elem.Value().String())
+		buf.WriteString(elem.Value().String())
 		if length > 1 {
 			buf.WriteByte(',')
 		}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go
index 17aad6d7..03925d7a 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go
+++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go
@@ -4,29 +4,11 @@
 // 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
 
-// Package bsoncore contains functions that can be used to encode and decode BSON
-// elements and values to or from a slice of bytes. These functions are aimed at
-// allowing low level manipulation of BSON and can be used to build a higher
-// level BSON library.
-//
-// The Read* functions within this package return the values of the element and
-// a boolean indicating if the values are valid. A boolean was used instead of
-// an error because any error that would be returned would be the same: not
-// enough bytes. This library attempts to do no validation, it will only return
-// false if there are not enough bytes for an item to be read. For example, the
-// ReadDocument function checks the length, if that length is larger than the
-// number of bytes available, it will return false, if there are enough bytes, it
-// will return those bytes and true. It is the consumers responsibility to
-// validate those bytes.
-//
-// The Append* functions within this package will append the type value to the
-// given dst slice. If the slice has enough capacity, it will not grow the
-// slice. The Append*Element functions within this package operate in the same
-// way, but additionally append the BSON type and the key before the value.
 package bsoncore // import "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
 
 import (
 	"bytes"
+	"encoding/binary"
 	"fmt"
 	"math"
 	"strconv"
@@ -254,7 +236,7 @@ func BuildDocumentValue(elems ...[]byte) Value {
 	return Value{Type: bsontype.EmbeddedDocument, Data: BuildDocument(nil, elems...)}
 }
 
-// BuildDocumentElement will append a BSON embedded document elemnt using key and the provided
+// BuildDocumentElement will append a BSON embedded document element using key and the provided
 // elements and return the extended buffer.
 func BuildDocumentElement(dst []byte, key string, elems ...[]byte) []byte {
 	return BuildDocument(AppendHeader(dst, bsontype.EmbeddedDocument, key), elems...)
@@ -725,17 +707,16 @@ func ReserveLength(dst []byte) (int32, []byte) {
 
 // UpdateLength updates the length at index with length and returns the []byte.
 func UpdateLength(dst []byte, index, length int32) []byte {
-	dst[index] = byte(length)
-	dst[index+1] = byte(length >> 8)
-	dst[index+2] = byte(length >> 16)
-	dst[index+3] = byte(length >> 24)
+	binary.LittleEndian.PutUint32(dst[index:], uint32(length))
 	return dst
 }
 
 func appendLength(dst []byte, l int32) []byte { return appendi32(dst, l) }
 
 func appendi32(dst []byte, i32 int32) []byte {
-	return append(dst, byte(i32), byte(i32>>8), byte(i32>>16), byte(i32>>24))
+	b := []byte{0, 0, 0, 0}
+	binary.LittleEndian.PutUint32(b, uint32(i32))
+	return append(dst, b...)
 }
 
 // ReadLength reads an int32 length from src and returns the length and the remaining bytes. If
@@ -753,27 +734,26 @@ func readi32(src []byte) (int32, []byte, bool) {
 	if len(src) < 4 {
 		return 0, src, false
 	}
-	return (int32(src[0]) | int32(src[1])<<8 | int32(src[2])<<16 | int32(src[3])<<24), src[4:], true
+	return int32(binary.LittleEndian.Uint32(src)), src[4:], true
 }
 
 func appendi64(dst []byte, i64 int64) []byte {
-	return append(dst,
-		byte(i64), byte(i64>>8), byte(i64>>16), byte(i64>>24),
-		byte(i64>>32), byte(i64>>40), byte(i64>>48), byte(i64>>56),
-	)
+	b := []byte{0, 0, 0, 0, 0, 0, 0, 0}
+	binary.LittleEndian.PutUint64(b, uint64(i64))
+	return append(dst, b...)
 }
 
 func readi64(src []byte) (int64, []byte, bool) {
 	if len(src) < 8 {
 		return 0, src, false
 	}
-	i64 := (int64(src[0]) | int64(src[1])<<8 | int64(src[2])<<16 | int64(src[3])<<24 |
-		int64(src[4])<<32 | int64(src[5])<<40 | int64(src[6])<<48 | int64(src[7])<<56)
-	return i64, src[8:], true
+	return int64(binary.LittleEndian.Uint64(src)), src[8:], true
 }
 
 func appendu32(dst []byte, u32 uint32) []byte {
-	return append(dst, byte(u32), byte(u32>>8), byte(u32>>16), byte(u32>>24))
+	b := []byte{0, 0, 0, 0}
+	binary.LittleEndian.PutUint32(b, u32)
+	return append(dst, b...)
 }
 
 func readu32(src []byte) (uint32, []byte, bool) {
@@ -781,23 +761,20 @@ func readu32(src []byte) (uint32, []byte, bool) {
 		return 0, src, false
 	}
 
-	return (uint32(src[0]) | uint32(src[1])<<8 | uint32(src[2])<<16 | uint32(src[3])<<24), src[4:], true
+	return binary.LittleEndian.Uint32(src), src[4:], true
 }
 
 func appendu64(dst []byte, u64 uint64) []byte {
-	return append(dst,
-		byte(u64), byte(u64>>8), byte(u64>>16), byte(u64>>24),
-		byte(u64>>32), byte(u64>>40), byte(u64>>48), byte(u64>>56),
-	)
+	b := []byte{0, 0, 0, 0, 0, 0, 0, 0}
+	binary.LittleEndian.PutUint64(b, u64)
+	return append(dst, b...)
 }
 
 func readu64(src []byte) (uint64, []byte, bool) {
 	if len(src) < 8 {
 		return 0, src, false
 	}
-	u64 := (uint64(src[0]) | uint64(src[1])<<8 | uint64(src[2])<<16 | uint64(src[3])<<24 |
-		uint64(src[4])<<32 | uint64(src[5])<<40 | uint64(src[6])<<48 | uint64(src[7])<<56)
-	return u64, src[8:], true
+	return binary.LittleEndian.Uint64(src), src[8:], true
 }
 
 // keep in sync with readcstringbytes
@@ -844,6 +821,9 @@ func readLengthBytes(src []byte) ([]byte, []byte, bool) {
 	if !ok {
 		return nil, src, false
 	}
+	if l < 4 {
+		return nil, src, false
+	}
 	if len(src) < int(l) {
 		return nil, src, false
 	}
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/doc.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/doc.go
new file mode 100644
index 00000000..f68e1da1
--- /dev/null
+++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/doc.go
@@ -0,0 +1,34 @@
+// Copyright (C) MongoDB, Inc. 2022-present.
+//
+// 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
+
+// Package bsoncore is intended for internal use only. It is made available to
+// facilitate use cases that require access to internal MongoDB driver
+// functionality and state. The API of this package is not stable and there is
+// no backward compatibility guarantee.
+//
+// WARNING: THIS PACKAGE IS EXPERIMENTAL AND MAY BE MODIFIED OR REMOVED WITHOUT
+// NOTICE! USE WITH EXTREME CAUTION!
+//
+// Package bsoncore contains functions that can be used to encode and decode
+// BSON elements and values to or from a slice of bytes. These functions are
+// aimed at allowing low level manipulation of BSON and can be used to build a
+// higher level BSON library.
+//
+// The Read* functions within this package return the values of the element and
+// a boolean indicating if the values are valid. A boolean was used instead of
+// an error because any error that would be returned would be the same: not
+// enough bytes. This library attempts to do no validation, it will only return
+// false if there are not enough bytes for an item to be read. For example, the
+// ReadDocument function checks the length, if that length is larger than the
+// number of bytes available, it will return false, if there are enough bytes,
+// it will return those bytes and true. It is the consumers responsibility to
+// validate those bytes.
+//
+// The Append* functions within this package will append the type value to the
+// given dst slice. If the slice has enough capacity, it will not grow the
+// slice. The Append*Element functions within this package operate in the same
+// way, but additionally append the BSON type and the key before the value.
+package bsoncore
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document.go
index d6e4bb06..3f360f1a 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document.go
+++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/document.go
@@ -7,11 +7,11 @@
 package bsoncore
 
 import (
-	"bytes"
 	"errors"
 	"fmt"
 	"io"
 	"strconv"
+	"strings"
 
 	"go.mongodb.org/mongo-driver/bson/bsontype"
 )
@@ -237,7 +237,7 @@ func (d Document) DebugString() string {
 	if len(d) < 5 {
 		return "<malformed>"
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	buf.WriteString("Document")
 	length, rem, _ := ReadLength(d) // We know we have enough bytes to read the length
 	buf.WriteByte('(')
@@ -253,7 +253,7 @@ func (d Document) DebugString() string {
 			buf.WriteString(fmt.Sprintf("<malformed (%d)>", length))
 			break
 		}
-		fmt.Fprintf(&buf, "%s ", elem.DebugString())
+		buf.WriteString(elem.DebugString())
 	}
 	buf.WriteByte('}')
 
@@ -266,7 +266,7 @@ func (d Document) String() string {
 	if len(d) < 5 {
 		return ""
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	buf.WriteByte('{')
 
 	length, rem, _ := ReadLength(d) // We know we have enough bytes to read the length
@@ -285,7 +285,7 @@ func (d Document) String() string {
 		if !ok {
 			return ""
 		}
-		fmt.Fprintf(&buf, "%s", elem.String())
+		buf.WriteString(elem.String())
 		first = false
 	}
 	buf.WriteByte('}')
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/element.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/element.go
index 3acb4222..1fe0897c 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/element.go
+++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/element.go
@@ -129,7 +129,7 @@ func (e Element) String() string {
 	if !valid {
 		return ""
 	}
-	return fmt.Sprintf(`"%s": %v`, key, val)
+	return "\"" + string(key) + "\": " + val.String()
 }
 
 // DebugString outputs a human readable version of RawElement. It will attempt to stringify the
diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go
index 789d2b98..69c1f9ed 100644
--- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go
+++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/value.go
@@ -59,8 +59,6 @@ func (v Value) IsNumber() bool {
 
 // AsInt32 returns a BSON number as an int32. If the BSON type is not a numeric one, this method
 // will panic.
-//
-// TODO(skriptble): Add support for Decimal128.
 func (v Value) AsInt32() int32 {
 	if !v.IsNumber() {
 		panic(ElementTypeError{"bsoncore.Value.AsInt32", v.Type})
@@ -93,8 +91,6 @@ func (v Value) AsInt32() int32 {
 
 // AsInt32OK functions the same as AsInt32 but returns a boolean instead of panicking. False
 // indicates an error.
-//
-// TODO(skriptble): Add support for Decimal128.
 func (v Value) AsInt32OK() (int32, bool) {
 	if !v.IsNumber() {
 		return 0, false
@@ -127,8 +123,6 @@ func (v Value) AsInt32OK() (int32, bool) {
 
 // AsInt64 returns a BSON number as an int64. If the BSON type is not a numeric one, this method
 // will panic.
-//
-// TODO(skriptble): Add support for Decimal128.
 func (v Value) AsInt64() int64 {
 	if !v.IsNumber() {
 		panic(ElementTypeError{"bsoncore.Value.AsInt64", v.Type})
@@ -162,8 +156,6 @@ func (v Value) AsInt64() int64 {
 
 // AsInt64OK functions the same as AsInt64 but returns a boolean instead of panicking. False
 // indicates an error.
-//
-// TODO(skriptble): Add support for Decimal128.
 func (v Value) AsInt64OK() (int64, bool) {
 	if !v.IsNumber() {
 		return 0, false
@@ -198,21 +190,14 @@ func (v Value) AsInt64OK() (int64, bool) {
 // AsFloat64 returns a BSON number as an float64. If the BSON type is not a numeric one, this method
 // will panic.
 //
-// TODO(skriptble): Add support for Decimal128.
-func (v Value) AsFloat64() float64 { return 0 }
+// TODO(GODRIVER-2751): Implement AsFloat64.
+// func (v Value) AsFloat64() float64
 
 // AsFloat64OK functions the same as AsFloat64 but returns a boolean instead of panicking. False
 // indicates an error.
 //
-// TODO(skriptble): Add support for Decimal128.
-func (v Value) AsFloat64OK() (float64, bool) { return 0, false }
-
-// Add will add this value to another. This is currently only implemented for strings and numbers.
-// If either value is a string, the other type is coerced into a string and added to the other.
-//
-// This method will alter v and will attempt to reuse the []byte of v. If the []byte is too small,
-// it will be expanded.
-func (v *Value) Add(v2 Value) error { return nil }
+// TODO(GODRIVER-2751): Implement AsFloat64OK.
+// func (v Value) AsFloat64OK() (float64, bool)
 
 // Equal compaes v to v2 and returns true if they are equal.
 func (v Value) Equal(v2 Value) bool {
diff --git a/vendor/go.opentelemetry.io/otel/.codespellignore b/vendor/go.opentelemetry.io/otel/.codespellignore
new file mode 100644
index 00000000..6bf3abc4
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/.codespellignore
@@ -0,0 +1,9 @@
+ot
+fo
+te
+collison
+consequentially
+ans
+nam
+valu
+thirdparty
diff --git a/vendor/go.opentelemetry.io/otel/.codespellrc b/vendor/go.opentelemetry.io/otel/.codespellrc
new file mode 100644
index 00000000..e2cb3ea9
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/.codespellrc
@@ -0,0 +1,10 @@
+# https://github.com/codespell-project/codespell
+[codespell]
+builtin = clear,rare,informal
+check-filenames =
+check-hidden =
+ignore-words = .codespellignore
+interactive = 1
+skip = .git,go.mod,go.sum,go.work,go.work.sum,semconv,venv,.tools
+uri-ignore-words-list = *
+write =
diff --git a/vendor/go.opentelemetry.io/otel/.gitignore b/vendor/go.opentelemetry.io/otel/.gitignore
index 0b605b3d..895c7664 100644
--- a/vendor/go.opentelemetry.io/otel/.gitignore
+++ b/vendor/go.opentelemetry.io/otel/.gitignore
@@ -2,20 +2,21 @@
 Thumbs.db
 
 .tools/
+venv/
 .idea/
 .vscode/
 *.iml
 *.so
 coverage.*
+go.work
+go.work.sum
 
 gen/
 
-/example/fib/fib
-/example/fib/traces.txt
-/example/jaeger/jaeger
+/example/dice/dice
 /example/namedtracer/namedtracer
+/example/otel-collector/otel-collector
 /example/opencensus/opencensus
 /example/passthrough/passthrough
 /example/prometheus/prometheus
 /example/zipkin/zipkin
-/example/otel-collector/otel-collector
diff --git a/vendor/go.opentelemetry.io/otel/.gitmodules b/vendor/go.opentelemetry.io/otel/.gitmodules
deleted file mode 100644
index 38a1f569..00000000
--- a/vendor/go.opentelemetry.io/otel/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "opentelemetry-proto"]
-	path = exporters/otlp/internal/opentelemetry-proto
-	url = https://github.com/open-telemetry/opentelemetry-proto
diff --git a/vendor/go.opentelemetry.io/otel/.golangci.yml b/vendor/go.opentelemetry.io/otel/.golangci.yml
index 0f099f57..6d9c8b64 100644
--- a/vendor/go.opentelemetry.io/otel/.golangci.yml
+++ b/vendor/go.opentelemetry.io/otel/.golangci.yml
@@ -11,17 +11,22 @@ linters:
   enable:
     - depguard
     - errcheck
+    - errorlint
     - godot
-    - gofmt
+    - gofumpt
     - goimports
+    - gosec
     - gosimple
     - govet
     - ineffassign
     - misspell
     - revive
     - staticcheck
+    - tenv
     - typecheck
+    - unconvert
     - unused
+    - unparam
 
 issues:
   # Maximum issues count per one linter.
@@ -53,6 +58,20 @@ issues:
       text: "calls to (.+) only in main[(][)] or init[(][)] functions"
       linters:
         - revive
+    # It's okay to not run gosec in a test.
+    - path: _test\.go
+      linters:
+        - gosec
+    # Igonoring gosec G404: Use of weak random number generator (math/rand instead of crypto/rand)
+    # as we commonly use it in tests and examples.
+    - text: "G404:"
+      linters:
+        - gosec
+    # Igonoring gosec G402: TLS MinVersion too low
+    # as the https://pkg.go.dev/crypto/tls#Config handles MinVersion default well.
+    - text: "G402: TLS MinVersion too low."
+      linters:
+        - gosec
   include:
     # revive exported should have comment or be unexported.
     - EXC0012
@@ -61,30 +80,69 @@ issues:
 
 linters-settings:
   depguard:
-    # Check the list against standard lib.
-    # Default: false
-    include-go-root: true
-    # A list of packages for the list type specified.
-    # Default: []
-    packages:
-      - "crypto/md5"
-      - "crypto/sha1"
-      - "crypto/**/pkix"
-    ignore-file-rules:
-      - "**/*_test.go"
-    additional-guards:
-      # Do not allow testing packages in non-test files.
-      - list-type: denylist
-        include-go-root: true
-        packages:
-          - testing
-          - github.com/stretchr/testify
-        ignore-file-rules:
-          - "**/*_test.go"
-          - "**/*test/*.go"
-          - "**/internal/matchers/*.go"
+    rules:
+      non-tests:
+        files:
+          - "!$test"
+          - "!**/*test/*.go"
+          - "!**/internal/matchers/*.go"
+        deny:
+          - pkg: "testing"
+          - pkg: "github.com/stretchr/testify"
+          - pkg: "crypto/md5"
+          - pkg: "crypto/sha1"
+          - pkg: "crypto/**/pkix"
+      otlp-internal:
+        files:
+          - "!**/exporters/otlp/internal/**/*.go"
+        deny:
+          - pkg: "go.opentelemetry.io/otel/exporters/otlp/internal"
+            desc: Do not use cross-module internal packages.
+      otlptrace-internal:
+        files:
+          - "!**/exporters/otlp/otlptrace/*.go"
+          - "!**/exporters/otlp/otlptrace/internal/**.go"
+        deny:
+          - pkg: "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal"
+            desc: Do not use cross-module internal packages.
+      otlpmetric-internal:
+        files:
+          - "!**/exporters/otlp/otlpmetric/internal/*.go"
+          - "!**/exporters/otlp/otlpmetric/internal/**/*.go"
+        deny:
+          - pkg: "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal"
+            desc: Do not use cross-module internal packages.
+      otel-internal:
+        files:
+          - "**/sdk/*.go"
+          - "**/sdk/**/*.go"
+          - "**/exporters/*.go"
+          - "**/exporters/**/*.go"
+          - "**/schema/*.go"
+          - "**/schema/**/*.go"
+          - "**/metric/*.go"
+          - "**/metric/**/*.go"
+          - "**/bridge/*.go"
+          - "**/bridge/**/*.go"
+          - "**/example/*.go"
+          - "**/example/**/*.go"
+          - "**/trace/*.go"
+          - "**/trace/**/*.go"
+          - "**/log/*.go"
+          - "**/log/**/*.go"
+        deny:
+          - pkg: "go.opentelemetry.io/otel/internal$"
+            desc: Do not use cross-module internal packages.
+          - pkg: "go.opentelemetry.io/otel/internal/attribute"
+            desc: Do not use cross-module internal packages.
+          - pkg: "go.opentelemetry.io/otel/internal/internaltest"
+            desc: Do not use cross-module internal packages.
+          - pkg: "go.opentelemetry.io/otel/internal/matchers"
+            desc: Do not use cross-module internal packages.
   godot:
     exclude:
+      # Exclude links.
+      - '^ *\[[^]]+\]:'
       # Exclude sentence fragments for lists.
       - '^[ ]*[-•]'
       # Exclude sentences prefixing a list.
@@ -111,7 +169,7 @@ linters-settings:
       - name: constant-logical-expr
         disabled: false
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-as-argument
-      # TODO (#3372) reenable linter when it is compatible. https://github.com/golangci/golangci-lint/issues/3280
+      # TODO (#3372) re-enable linter when it is compatible. https://github.com/golangci/golangci-lint/issues/3280
       - name: context-as-argument
         disabled: true
         arguments:
diff --git a/vendor/go.opentelemetry.io/otel/CHANGELOG.md b/vendor/go.opentelemetry.io/otel/CHANGELOG.md
index 1d9726f6..c01e6998 100644
--- a/vendor/go.opentelemetry.io/otel/CHANGELOG.md
+++ b/vendor/go.opentelemetry.io/otel/CHANGELOG.md
@@ -8,6 +8,707 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
 
 ## [Unreleased]
 
+## [1.28.0/0.50.0/0.4.0] 2024-07-02
+
+### Added
+
+- The `IsEmpty` method is added to the `Instrument` type in `go.opentelemetry.io/otel/sdk/metric`.
+  This method is used to check if an `Instrument` instance is a zero-value. (#5431)
+- Store and provide the emitted `context.Context` in `ScopeRecords` of `go.opentelemetry.io/otel/sdk/log/logtest`. (#5468)
+- The `go.opentelemetry.io/otel/semconv/v1.26.0` package.
+  The package contains semantic conventions from the `v1.26.0` version of the OpenTelemetry Semantic Conventions. (#5476)
+- The `AssertRecordEqual` method to `go.opentelemetry.io/otel/log/logtest` to allow comparison of two log records in tests. (#5499)
+- The `WithHeaders` option to `go.opentelemetry.io/otel/exporters/zipkin` to allow configuring custom http headers while exporting spans. (#5530)
+
+### Changed
+
+- `Tracer.Start` in `go.opentelemetry.io/otel/trace/noop` no longer allocates a span for empty span context. (#5457)
+- Upgrade `go.opentelemetry.io/otel/semconv/v1.25.0` to `go.opentelemetry.io/otel/semconv/v1.26.0` in `go.opentelemetry.io/otel/example/otel-collector`. (#5490)
+- Upgrade `go.opentelemetry.io/otel/semconv/v1.25.0` to `go.opentelemetry.io/otel/semconv/v1.26.0` in `go.opentelemetry.io/otel/example/zipkin`. (#5490)
+- Upgrade `go.opentelemetry.io/otel/semconv/v1.25.0` to `go.opentelemetry.io/otel/semconv/v1.26.0` in `go.opentelemetry.io/otel/exporters/zipkin`. (#5490)
+  - The exporter no longer exports the deprecated "otel.library.name" or "otel.library.version" attributes.
+- Upgrade `go.opentelemetry.io/otel/semconv/v1.25.0` to `go.opentelemetry.io/otel/semconv/v1.26.0` in `go.opentelemetry.io/otel/sdk/resource`. (#5490)
+- Upgrade `go.opentelemetry.io/otel/semconv/v1.25.0` to `go.opentelemetry.io/otel/semconv/v1.26.0` in `go.opentelemetry.io/otel/sdk/trace`. (#5490)
+- `SimpleProcessor.OnEmit` in `go.opentelemetry.io/otel/sdk/log` no longer allocates a slice which makes it possible to have a zero-allocation log processing using `SimpleProcessor`. (#5493)
+- Use non-generic functions in the `Start` method of `"go.opentelemetry.io/otel/sdk/trace".Trace` to reduce memory allocation. (#5497)
+- `service.instance.id` is populated for a `Resource` created with `"go.opentelemetry.io/otel/sdk/resource".Default` with a default value when `OTEL_GO_X_RESOURCE` is set. (#5520)
+- Improve performance of metric instruments in `go.opentelemetry.io/otel/sdk/metric` by removing unnecessary calls to `time.Now`. (#5545)
+
+### Fixed
+
+- Log a warning to the OpenTelemetry internal logger when a `Record` in `go.opentelemetry.io/otel/sdk/log` drops an attribute due to a limit being reached. (#5376)
+- Identify the `Tracer` returned from the global `TracerProvider` in `go.opentelemetry.io/otel/global` with its schema URL. (#5426)
+- Identify the `Meter` returned from the global `MeterProvider` in `go.opentelemetry.io/otel/global` with its schema URL. (#5426)
+- Log a warning to the OpenTelemetry internal logger when a `Span` in `go.opentelemetry.io/otel/sdk/trace` drops an attribute, event, or link due to a limit being reached. (#5434)
+- Document instrument name requirements in `go.opentelemetry.io/otel/metric`. (#5435)
+- Prevent random number generation data-race for experimental rand exemplars in `go.opentelemetry.io/otel/sdk/metric`. (#5456)
+- Fix counting number of dropped attributes of `Record` in `go.opentelemetry.io/otel/sdk/log`. (#5464)
+- Fix panic in baggage creation when a member contains `0x80` char in key or value. (#5494)
+- Correct comments for the priority of the `WithEndpoint` and `WithEndpointURL` options and their corresponding environment variables in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#5508)
+- Retry trace and span ID generation if it generated an invalid one in `go.opentelemetry.io/otel/sdk/trace`. (#5514)
+- Fix stale timestamps reported by the last-value aggregation. (#5517)
+- Indicate the `Exporter` in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` must be created by the `New` method. (#5521)
+- Improved performance in all `{Bool,Int64,Float64,String}SliceValue` functions of `go.opentelemetry.io/attributes` by reducing the number of allocations. (#5549)
+
+## [1.27.0/0.49.0/0.3.0] 2024-05-21
+
+### Added
+
+- Add example for `go.opentelemetry.io/otel/exporters/stdout/stdoutlog`. (#5242)
+- Add `RecordFactory` in `go.opentelemetry.io/otel/sdk/log/logtest` to facilitate testing exporter and processor implementations. (#5258)
+- Add `RecordFactory` in `go.opentelemetry.io/otel/log/logtest` to facilitate testing bridge implementations. (#5263)
+- The count of dropped records from the `BatchProcessor` in `go.opentelemetry.io/otel/sdk/log` is logged. (#5276)
+- Add metrics in the `otel-collector` example. (#5283)
+- Add the synchronous gauge instrument to `go.opentelemetry.io/otel/metric`. (#5304)
+  - An `int64` or `float64` synchronous gauge instrument can now be created from a `Meter`.
+  - All implementations of the API (`go.opentelemetry.io/otel/metric/noop`, `go.opentelemetry.io/otel/sdk/metric`) are updated to support this instrument.
+- Add logs to `go.opentelemetry.io/otel/example/dice`. (#5349)
+
+### Changed
+
+- The `Shutdown` method of `Exporter` in `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` ignores the context cancellation and always returns `nil`. (#5189)
+- The `ForceFlush` and `Shutdown` methods of the exporter returned by `New` in `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` ignore the context cancellation and always return `nil`. (#5189)
+- Apply the value length limits to `Record` attributes in `go.opentelemetry.io/otel/sdk/log`. (#5230)
+- De-duplicate map attributes added to a `Record` in `go.opentelemetry.io/otel/sdk/log`. (#5230)
+- `go.opentelemetry.io/otel/exporters/stdout/stdoutlog` won't print timestamps when `WithoutTimestamps` option is set. (#5241)
+- The `go.opentelemetry.io/otel/exporters/stdout/stdoutlog` exporter won't print `AttributeValueLengthLimit` and `AttributeCountLimit` fields now, instead it prints the `DroppedAttributes` field. (#5272)
+- Improved performance in the `Stringer` implementation of `go.opentelemetry.io/otel/baggage.Member` by reducing the number of allocations. (#5286)
+- Set the start time for last-value aggregates in `go.opentelemetry.io/otel/sdk/metric`. (#5305)
+- The `Span` in `go.opentelemetry.io/otel/sdk/trace` will record links without span context if either non-empty `TraceState` or attributes are provided. (#5315)
+- Upgrade all dependencies of `go.opentelemetry.io/otel/semconv/v1.24.0` to `go.opentelemetry.io/otel/semconv/v1.25.0`. (#5374)
+
+### Fixed
+
+- Comparison of unordered maps for `go.opentelemetry.io/otel/log.KeyValue` and `go.opentelemetry.io/otel/log.Value`. (#5306)
+- Fix the empty output of `go.opentelemetry.io/otel/log.Value` in `go.opentelemetry.io/otel/exporters/stdout/stdoutlog`. (#5311)
+- Split the behavior of `Recorder` in `go.opentelemetry.io/otel/log/logtest` so it behaves as a `LoggerProvider` only. (#5365)
+- Fix wrong package name of the error message when parsing endpoint URL in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#5371)
+- Identify the `Logger` returned from the global `LoggerProvider` in `go.opentelemetry.io/otel/log/global` with its schema URL. (#5375)
+
+## [1.26.0/0.48.0/0.2.0-alpha] 2024-04-24
+
+### Added
+
+- Add `Recorder` in `go.opentelemetry.io/otel/log/logtest` to facilitate testing the log bridge implementations. (#5134)
+- Add span flags to OTLP spans and links exported by `go.opentelemetry.io/otel/exporters/otlp/otlptrace`. (#5194)
+- Make the initial alpha release of `go.opentelemetry.io/otel/sdk/log`.
+  This new module contains the Go implementation of the OpenTelemetry Logs SDK.
+  This module is unstable and breaking changes may be introduced.
+  See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. (#5240)
+- Make the initial alpha release of `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`.
+  This new module contains an OTLP exporter that transmits log telemetry using HTTP.
+  This module is unstable and breaking changes may be introduced.
+  See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. (#5240)
+- Make the initial alpha release of `go.opentelemetry.io/otel/exporters/stdout/stdoutlog`.
+  This new module contains an exporter prints log records to STDOUT.
+  This module is unstable and breaking changes may be introduced.
+  See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. (#5240)
+- The `go.opentelemetry.io/otel/semconv/v1.25.0` package.
+  The package contains semantic conventions from the `v1.25.0` version of the OpenTelemetry Semantic Conventions. (#5254)
+
+### Changed
+
+- Update `go.opentelemetry.io/proto/otlp` from v1.1.0 to v1.2.0. (#5177)
+- Improve performance of baggage member character validation in `go.opentelemetry.io/otel/baggage`. (#5214)
+- The `otel-collector` example now uses docker compose to bring up services instead of kubernetes. (#5244)
+
+### Fixed
+
+- Slice attribute values in `go.opentelemetry.io/otel/attribute` are now emitted as their JSON representation. (#5159)
+
+## [1.25.0/0.47.0/0.0.8/0.1.0-alpha] 2024-04-05
+
+### Added
+
+- Add `WithProxy` option in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4906)
+- Add `WithProxy` option in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlptracehttp`. (#4906)
+- Add `AddLink` method to the `Span` interface in `go.opentelemetry.io/otel/trace`. (#5032)
+- The `Enabled` method is added to the `Logger` interface in `go.opentelemetry.io/otel/log`.
+  This method is used to notify users if a log record will be emitted or not. (#5071)
+- Add `SeverityUndefined` `const` to `go.opentelemetry.io/otel/log`.
+  This value represents an unset severity level. (#5072)
+- Add `Empty` function in `go.opentelemetry.io/otel/log` to return a `KeyValue` for an empty value. (#5076)
+- Add `go.opentelemetry.io/otel/log/global` to manage the global `LoggerProvider`.
+  This package is provided with the anticipation that all functionality will be migrate to `go.opentelemetry.io/otel` when `go.opentelemetry.io/otel/log` stabilizes.
+  At which point, users will be required to migrage their code, and this package will be deprecated then removed. (#5085)
+- Add support for `Summary` metrics in the `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` exporters. (#5100)
+- Add `otel.scope.name` and `otel.scope.version` tags to spans exported by `go.opentelemetry.io/otel/exporters/zipkin`. (#5108)
+- Add support for `AddLink` to `go.opentelemetry.io/otel/bridge/opencensus`. (#5116)
+- Add `String` method to `Value` and `KeyValue` in `go.opentelemetry.io/otel/log`. (#5117)
+- Add Exemplar support to `go.opentelemetry.io/otel/exporters/prometheus`. (#5111)
+- Add metric semantic conventions to `go.opentelemetry.io/otel/semconv/v1.24.0`. Future `semconv` packages will include metric semantic conventions as well. (#4528)
+
+### Changed
+
+- `SpanFromContext` and `SpanContextFromContext` in `go.opentelemetry.io/otel/trace` no longer make a heap allocation when the passed context has no span. (#5049)
+- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` now create a gRPC client in idle mode and with "dns" as the default resolver using [`grpc.NewClient`](https://pkg.go.dev/google.golang.org/grpc#NewClient). (#5151)
+  Because of that `WithDialOption` ignores [`grpc.WithBlock`](https://pkg.go.dev/google.golang.org/grpc#WithBlock), [`grpc.WithTimeout`](https://pkg.go.dev/google.golang.org/grpc#WithTimeout), and [`grpc.WithReturnConnectionError`](https://pkg.go.dev/google.golang.org/grpc#WithReturnConnectionError).
+  Notice that [`grpc.DialContext`](https://pkg.go.dev/google.golang.org/grpc#DialContext) which was used before is now deprecated.
+
+### Fixed
+
+- Clarify the documentation about equivalence guarantees for the `Set` and `Distinct` types in `go.opentelemetry.io/otel/attribute`. (#5027)
+- Prevent default `ErrorHandler` self-delegation. (#5137)
+- Update all dependencies to address [GO-2024-2687]. (#5139)
+
+### Removed
+
+- Drop support for [Go 1.20]. (#4967)
+
+### Deprecated
+
+- Deprecate `go.opentelemetry.io/otel/attribute.Sortable` type. (#4734)
+- Deprecate `go.opentelemetry.io/otel/attribute.NewSetWithSortable` function. (#4734)
+- Deprecate `go.opentelemetry.io/otel/attribute.NewSetWithSortableFiltered` function. (#4734)
+
+## [1.24.0/0.46.0/0.0.1-alpha] 2024-02-23
+
+This release is the last to support [Go 1.20].
+The next release will require at least [Go 1.21].
+
+### Added
+
+- Support [Go 1.22]. (#4890)
+- Add exemplar support to `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4900)
+- Add exemplar support to `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4900)
+- The `go.opentelemetry.io/otel/log` module is added.
+  This module includes OpenTelemetry Go's implementation of the Logs Bridge API.
+  This module is in an alpha state, it is subject to breaking changes.
+  See our [versioning policy](./VERSIONING.md) for more info. (#4961)
+- ARM64 platform to the compatibility testing suite. (#4994)
+
+### Fixed
+
+- Fix registration of multiple callbacks when using the global meter provider from `go.opentelemetry.io/otel`. (#4945)
+- Fix negative buckets in output of exponential histograms. (#4956)
+
+## [1.23.1] 2024-02-07
+
+### Fixed
+
+- Register all callbacks passed during observable instrument creation instead of just the last one multiple times in `go.opentelemetry.io/otel/sdk/metric`. (#4888)
+
+## [1.23.0] 2024-02-06
+
+This release contains the first stable, `v1`, release of the following modules:
+
+- `go.opentelemetry.io/otel/bridge/opencensus`
+- `go.opentelemetry.io/otel/bridge/opencensus/test`
+- `go.opentelemetry.io/otel/example/opencensus`
+- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`
+- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`
+- `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric`
+
+See our [versioning policy](VERSIONING.md) for more information about these stability guarantees.
+
+### Added
+
+- Add `WithEndpointURL` option to the `exporters/otlp/otlpmetric/otlpmetricgrpc`, `exporters/otlp/otlpmetric/otlpmetrichttp`, `exporters/otlp/otlptrace/otlptracegrpc` and `exporters/otlp/otlptrace/otlptracehttp` packages. (#4808)
+- Experimental exemplar exporting is added to the metric SDK.
+  See [metric documentation](./sdk/metric/internal/x/README.md#exemplars) for more information about this feature and how to enable it. (#4871)
+- `ErrSchemaURLConflict` is added to `go.opentelemetry.io/otel/sdk/resource`.
+  This error is returned when a merge of two `Resource`s with different (non-empty) schema URL is attempted. (#4876)
+
+### Changed
+
+- The `Merge` and `New` functions in `go.opentelemetry.io/otel/sdk/resource` now returns a partial result if there is a schema URL merge conflict.
+  Instead of returning `nil` when two `Resource`s with different (non-empty) schema URLs are merged the merged `Resource`, along with the new `ErrSchemaURLConflict` error, is returned.
+  It is up to the user to decide if they want to use the returned `Resource` or not.
+  It may have desired attributes overwritten or include stale semantic conventions. (#4876)
+
+### Fixed
+
+- Fix `ContainerID` resource detection on systemd when cgroup path has a colon. (#4449)
+- Fix `go.opentelemetry.io/otel/sdk/metric` to cache instruments to avoid leaking memory when the same instrument is created multiple times. (#4820)
+- Fix missing `Mix` and `Max` values for `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` by introducing `MarshalText` and `MarshalJSON` for the `Extrema` type in `go.opentelemetry.io/sdk/metric/metricdata`. (#4827)
+
+## [1.23.0-rc.1] 2024-01-18
+
+This is a release candidate for the v1.23.0 release.
+That release is expected to include the `v1` release of the following modules:
+
+- `go.opentelemetry.io/otel/bridge/opencensus`
+- `go.opentelemetry.io/otel/bridge/opencensus/test`
+- `go.opentelemetry.io/otel/example/opencensus`
+- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`
+- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`
+- `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric`
+
+See our [versioning policy](VERSIONING.md) for more information about these stability guarantees.
+
+## [1.22.0/0.45.0] 2024-01-17
+
+### Added
+
+- The `go.opentelemetry.io/otel/semconv/v1.22.0` package.
+  The package contains semantic conventions from the `v1.22.0` version of the OpenTelemetry Semantic Conventions. (#4735)
+- The `go.opentelemetry.io/otel/semconv/v1.23.0` package.
+  The package contains semantic conventions from the `v1.23.0` version of the OpenTelemetry Semantic Conventions. (#4746)
+- The `go.opentelemetry.io/otel/semconv/v1.23.1` package.
+  The package contains semantic conventions from the `v1.23.1` version of the OpenTelemetry Semantic Conventions. (#4749)
+- The `go.opentelemetry.io/otel/semconv/v1.24.0` package.
+  The package contains semantic conventions from the `v1.24.0` version of the OpenTelemetry Semantic Conventions. (#4770)
+- Add `WithResourceAsConstantLabels` option to apply resource attributes for every metric emitted by the Prometheus exporter. (#4733)
+- Experimental cardinality limiting is added to the metric SDK.
+  See [metric documentation](./sdk/metric/internal/x/README.md#cardinality-limit) for more information about this feature and how to enable it. (#4457)
+- Add `NewMemberRaw` and `NewKeyValuePropertyRaw` in `go.opentelemetry.io/otel/baggage`. (#4804)
+
+### Changed
+
+- Upgrade all use of `go.opentelemetry.io/otel/semconv` to use `v1.24.0`. (#4754)
+- Update transformations in `go.opentelemetry.io/otel/exporters/zipkin` to follow `v1.24.0` version of the OpenTelemetry specification. (#4754)
+- Record synchronous measurements when the passed context is canceled instead of dropping in `go.opentelemetry.io/otel/sdk/metric`.
+  If you do not want to make a measurement when the context is cancelled, you need to handle it yourself (e.g  `if ctx.Err() != nil`). (#4671)
+- Improve `go.opentelemetry.io/otel/trace.TraceState`'s performance. (#4722)
+- Improve `go.opentelemetry.io/otel/propagation.TraceContext`'s performance. (#4721)
+- Improve `go.opentelemetry.io/otel/baggage` performance. (#4743)
+- Improve performance of the `(*Set).Filter` method in `go.opentelemetry.io/otel/attribute` when the passed filter does not filter out any attributes from the set. (#4774)
+- `Member.String` in `go.opentelemetry.io/otel/baggage` percent-encodes only when necessary. (#4775)
+- Improve `go.opentelemetry.io/otel/trace.Span`'s performance when adding multiple attributes. (#4818)
+- `Property.Value` in `go.opentelemetry.io/otel/baggage` now returns a raw string instead of a percent-encoded value. (#4804)
+
+### Fixed
+
+- Fix `Parse` in `go.opentelemetry.io/otel/baggage` to validate member value before percent-decoding. (#4755)
+- Fix whitespace encoding of `Member.String` in `go.opentelemetry.io/otel/baggage`. (#4756)
+- Fix observable not registered error when the asynchronous instrument has a drop aggregation in `go.opentelemetry.io/otel/sdk/metric`. (#4772)
+- Fix baggage item key so that it is not canonicalized in `go.opentelemetry.io/otel/bridge/opentracing`. (#4776)
+- Fix `go.opentelemetry.io/otel/bridge/opentracing` to properly handle baggage values that requires escaping during propagation. (#4804)
+- Fix a bug where using multiple readers resulted in incorrect asynchronous counter values in `go.opentelemetry.io/otel/sdk/metric`. (#4742)
+
+## [1.21.0/0.44.0] 2023-11-16
+
+### Removed
+
+- Remove the deprecated `go.opentelemetry.io/otel/bridge/opencensus.NewTracer`. (#4706)
+- Remove the deprecated `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` module. (#4707)
+- Remove the deprecated `go.opentelemetry.io/otel/example/view` module. (#4708)
+- Remove the deprecated `go.opentelemetry.io/otel/example/fib` module. (#4723)
+
+### Fixed
+
+- Do not parse non-protobuf responses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4719)
+- Do not parse non-protobuf responses in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4719)
+
+## [1.20.0/0.43.0] 2023-11-10
+
+This release brings a breaking change for custom trace API implementations. Some interfaces (`TracerProvider`, `Tracer`, `Span`) now embed the `go.opentelemetry.io/otel/trace/embedded` types. Implementers need to update their implementations based on what they want the default behavior to be. See the "API Implementations" section of the [trace API] package documentation for more information about how to accomplish this.
+
+### Added
+
+- Add `go.opentelemetry.io/otel/bridge/opencensus.InstallTraceBridge`, which installs the OpenCensus trace bridge, and replaces `opencensus.NewTracer`. (#4567)
+- Add scope version to trace and metric bridges in `go.opentelemetry.io/otel/bridge/opencensus`. (#4584)
+- Add the `go.opentelemetry.io/otel/trace/embedded` package to be embedded in the exported trace API interfaces. (#4620)
+- Add the `go.opentelemetry.io/otel/trace/noop` package as a default no-op implementation of the trace API. (#4620)
+- Add context propagation in `go.opentelemetry.io/otel/example/dice`. (#4644)
+- Add view configuration to `go.opentelemetry.io/otel/example/prometheus`. (#4649)
+- Add `go.opentelemetry.io/otel/metric.WithExplicitBucketBoundaries`, which allows defining default explicit bucket boundaries when creating histogram instruments. (#4603)
+- Add `Version` function in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4660)
+- Add `Version` function in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4660)
+- Add Summary, SummaryDataPoint, and QuantileValue to `go.opentelemetry.io/sdk/metric/metricdata`. (#4622)
+- `go.opentelemetry.io/otel/bridge/opencensus.NewMetricProducer` now supports exemplars from OpenCensus. (#4585)
+- Add support for `WithExplicitBucketBoundaries` in `go.opentelemetry.io/otel/sdk/metric`. (#4605)
+- Add support for Summary metrics in `go.opentelemetry.io/otel/bridge/opencensus`. (#4668)
+
+### Deprecated
+
+- Deprecate `go.opentelemetry.io/otel/bridge/opencensus.NewTracer` in favor of `opencensus.InstallTraceBridge`. (#4567)
+- Deprecate `go.opentelemetry.io/otel/example/fib` package is in favor of `go.opentelemetry.io/otel/example/dice`. (#4618)
+- Deprecate `go.opentelemetry.io/otel/trace.NewNoopTracerProvider`.
+  Use the added `NewTracerProvider` function in `go.opentelemetry.io/otel/trace/noop` instead. (#4620)
+- Deprecate `go.opentelemetry.io/otel/example/view` package in favor of `go.opentelemetry.io/otel/example/prometheus`. (#4649)
+- Deprecate `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#4693)
+
+### Changed
+
+- `go.opentelemetry.io/otel/bridge/opencensus.NewMetricProducer` returns a `*MetricProducer` struct instead of the metric.Producer interface. (#4583)
+- The `TracerProvider` in `go.opentelemetry.io/otel/trace` now embeds the `go.opentelemetry.io/otel/trace/embedded.TracerProvider` type.
+  This extends the `TracerProvider` interface and is is a breaking change for any existing implementation.
+  Implementers need to update their implementations based on what they want the default behavior of the interface to be.
+  See the "API Implementations" section of the `go.opentelemetry.io/otel/trace` package documentation for more information about how to accomplish this. (#4620)
+- The `Tracer` in `go.opentelemetry.io/otel/trace` now embeds the `go.opentelemetry.io/otel/trace/embedded.Tracer` type.
+  This extends the `Tracer` interface and is is a breaking change for any existing implementation.
+  Implementers need to update their implementations based on what they want the default behavior of the interface to be.
+  See the "API Implementations" section of the `go.opentelemetry.io/otel/trace` package documentation for more information about how to accomplish this. (#4620)
+- The `Span` in `go.opentelemetry.io/otel/trace` now embeds the `go.opentelemetry.io/otel/trace/embedded.Span` type.
+  This extends the `Span` interface and is is a breaking change for any existing implementation.
+  Implementers need to update their implementations based on what they want the default behavior of the interface to be.
+  See the "API Implementations" section of the `go.opentelemetry.io/otel/trace` package documentation for more information about how to accomplish this. (#4620)
+- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` does no longer depend on `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#4660)
+- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` does no longer depend on `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#4660)
+- Retry for `502 Bad Gateway` and `504 Gateway Timeout` HTTP statuses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4670)
+- Retry for `502 Bad Gateway` and `504 Gateway Timeout` HTTP statuses in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4670)
+- Retry for `RESOURCE_EXHAUSTED` only if RetryInfo is returned in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4669)
+- Retry for `RESOURCE_EXHAUSTED` only if RetryInfo is returned in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#4669)
+- Retry temporary HTTP request failures in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4679)
+- Retry temporary HTTP request failures in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4679)
+
+### Fixed
+
+- Fix improper parsing of characters such us `+`, `/` by `Parse` in `go.opentelemetry.io/otel/baggage` as they were rendered as a whitespace. (#4667)
+- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_RESOURCE_ATTRIBUTES` in `go.opentelemetry.io/otel/sdk/resource` as they were rendered as a whitespace. (#4699)
+- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_METRICS_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` as they were rendered as a whitespace. (#4699)
+- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_METRICS_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` as they were rendered as a whitespace. (#4699)
+- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_TRACES_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlptracegrpc` as they were rendered as a whitespace. (#4699)
+- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_TRACES_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlptracehttp` as they were rendered as a whitespace. (#4699)
+- In `go.opentelemetry.op/otel/exporters/prometheus`, the exporter no longer `Collect`s metrics after `Shutdown` is invoked. (#4648)
+- Fix documentation for `WithCompressor` in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#4695)
+- Fix documentation for `WithCompressor` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4695)
+
+## [1.19.0/0.42.0/0.0.7] 2023-09-28
+
+This release contains the first stable release of the OpenTelemetry Go [metric SDK].
+Our project stability guarantees now apply to the `go.opentelemetry.io/otel/sdk/metric` package.
+See our [versioning policy](VERSIONING.md) for more information about these stability guarantees.
+
+### Added
+
+- Add the "Roll the dice" getting started application example in `go.opentelemetry.io/otel/example/dice`. (#4539)
+- The `WithWriter` and `WithPrettyPrint` options to `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` to set a custom `io.Writer`, and allow displaying the output in human-readable JSON. (#4507)
+
+### Changed
+
+- Allow '/' characters in metric instrument names. (#4501)
+- The exporter in `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` does not prettify its output by default anymore. (#4507)
+- Upgrade `gopkg.io/yaml` from `v2` to `v3` in `go.opentelemetry.io/otel/schema`. (#4535)
+
+### Fixed
+
+- In `go.opentelemetry.op/otel/exporters/prometheus`, don't try to create the Prometheus metric on every `Collect` if we know the scope is invalid. (#4499)
+
+### Removed
+
+- Remove `"go.opentelemetry.io/otel/bridge/opencensus".NewMetricExporter`, which is replaced by `NewMetricProducer`. (#4566)
+
+## [1.19.0-rc.1/0.42.0-rc.1] 2023-09-14
+
+This is a release candidate for the v1.19.0/v0.42.0 release.
+That release is expected to include the `v1` release of the OpenTelemetry Go metric SDK and will provide stability guarantees of that SDK.
+See our [versioning policy](VERSIONING.md) for more information about these stability guarantees.
+
+### Changed
+
+- Allow '/' characters in metric instrument names. (#4501)
+
+### Fixed
+
+- In `go.opentelemetry.op/otel/exporters/prometheus`, don't try to create the prometheus metric on every `Collect` if we know the scope is invalid. (#4499)
+
+## [1.18.0/0.41.0/0.0.6] 2023-09-12
+
+This release drops the compatibility guarantee of [Go 1.19].
+
+### Added
+
+- Add `WithProducer` option in `go.opentelemetry.op/otel/exporters/prometheus` to restore the ability to register producers on the prometheus exporter's manual reader. (#4473)
+- Add `IgnoreValue` option in `go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest` to allow ignoring values when comparing metrics. (#4447)
+
+### Changed
+
+- Use a `TestingT` interface instead of `*testing.T` struct in `go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest`. (#4483)
+
+### Deprecated
+
+- The `NewMetricExporter` in `go.opentelemetry.io/otel/bridge/opencensus` was deprecated in `v0.35.0` (#3541).
+  The deprecation notice format for the function has been corrected to trigger Go documentation and build tooling. (#4470)
+
+### Removed
+
+- Removed the deprecated `go.opentelemetry.io/otel/exporters/jaeger` package. (#4467)
+- Removed the deprecated `go.opentelemetry.io/otel/example/jaeger` package. (#4467)
+- Removed the deprecated `go.opentelemetry.io/otel/sdk/metric/aggregation` package. (#4468)
+- Removed the deprecated internal packages in `go.opentelemetry.io/otel/exporters/otlp` and its sub-packages. (#4469)
+- Dropped guaranteed support for versions of Go less than 1.20. (#4481)
+
+## [1.17.0/0.40.0/0.0.5] 2023-08-28
+
+### Added
+
+- Export the `ManualReader` struct in `go.opentelemetry.io/otel/sdk/metric`. (#4244)
+- Export the `PeriodicReader` struct in `go.opentelemetry.io/otel/sdk/metric`. (#4244)
+- Add support for exponential histogram aggregations.
+  A histogram can be configured as an exponential histogram using a view with `"go.opentelemetry.io/otel/sdk/metric".ExponentialHistogram` as the aggregation. (#4245)
+- Export the `Exporter` struct in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4272)
+- Export the `Exporter` struct in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4272)
+- The exporters in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` now support the `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` environment variable. (#4287)
+- Add `WithoutCounterSuffixes` option in `go.opentelemetry.io/otel/exporters/prometheus` to disable addition of `_total` suffixes. (#4306)
+- Add info and debug logging to the metric SDK in `go.opentelemetry.io/otel/sdk/metric`. (#4315)
+- The `go.opentelemetry.io/otel/semconv/v1.21.0` package.
+  The package contains semantic conventions from the `v1.21.0` version of the OpenTelemetry Semantic Conventions. (#4362)
+- Accept 201 to 299 HTTP status as success in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4365)
+- Document the `Temporality` and `Aggregation` methods of the `"go.opentelemetry.io/otel/sdk/metric".Exporter"` need to be concurrent safe. (#4381)
+- Expand the set of units supported by the Prometheus exporter, and don't add unit suffixes if they are already present in `go.opentelemetry.op/otel/exporters/prometheus` (#4374)
+- Move the `Aggregation` interface and its implementations from `go.opentelemetry.io/otel/sdk/metric/aggregation` to `go.opentelemetry.io/otel/sdk/metric`. (#4435)
+- The exporters in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` now support the `OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION` environment variable. (#4437)
+- Add the `NewAllowKeysFilter` and `NewDenyKeysFilter` functions to `go.opentelemetry.io/otel/attribute` to allow convenient creation of allow-keys and deny-keys filters. (#4444)
+- Support Go 1.21. (#4463)
+
+### Changed
+
+- Starting from `v1.21.0` of semantic conventions, `go.opentelemetry.io/otel/semconv/{version}/httpconv` and `go.opentelemetry.io/otel/semconv/{version}/netconv` packages will no longer be published. (#4145)
+- Log duplicate instrument conflict at a warning level instead of info in `go.opentelemetry.io/otel/sdk/metric`. (#4202)
+- Return an error on the creation of new instruments in `go.opentelemetry.io/otel/sdk/metric` if their name doesn't pass regexp validation. (#4210)
+- `NewManualReader` in `go.opentelemetry.io/otel/sdk/metric` returns `*ManualReader` instead of `Reader`. (#4244)
+- `NewPeriodicReader` in `go.opentelemetry.io/otel/sdk/metric` returns `*PeriodicReader` instead of `Reader`. (#4244)
+- Count the Collect time in the `PeriodicReader` timeout in `go.opentelemetry.io/otel/sdk/metric`. (#4221)
+- The function `New` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` returns `*Exporter` instead of `"go.opentelemetry.io/otel/sdk/metric".Exporter`. (#4272)
+- The function `New` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` returns `*Exporter` instead of `"go.opentelemetry.io/otel/sdk/metric".Exporter`. (#4272)
+- If an attribute set is omitted from an async callback, the previous value will no longer be exported in `go.opentelemetry.io/otel/sdk/metric`. (#4290)
+- If an attribute set is observed multiple times in an async callback in `go.opentelemetry.io/otel/sdk/metric`, the values will be summed instead of the last observation winning. (#4289)
+- Allow the explicit bucket histogram aggregation to be used for the up-down counter, observable counter, observable up-down counter, and observable gauge in the `go.opentelemetry.io/otel/sdk/metric` package. (#4332)
+- Restrict `Meter`s in `go.opentelemetry.io/otel/sdk/metric` to only register and collect instruments it created. (#4333)
+- `PeriodicReader.Shutdown` and `PeriodicReader.ForceFlush` in `go.opentelemetry.io/otel/sdk/metric` now apply the periodic reader's timeout to the operation if the user provided context does not contain a deadline. (#4356, #4377)
+- Upgrade all use of `go.opentelemetry.io/otel/semconv` to use `v1.21.0`. (#4408)
+- Increase instrument name maximum length from 63 to 255 characters in `go.opentelemetry.io/otel/sdk/metric`. (#4434)
+- Add `go.opentelemetry.op/otel/sdk/metric.WithProducer` as an `Option` for `"go.opentelemetry.io/otel/sdk/metric".NewManualReader` and `"go.opentelemetry.io/otel/sdk/metric".NewPeriodicReader`. (#4346)
+
+### Removed
+
+- Remove `Reader.RegisterProducer` in `go.opentelemetry.io/otel/metric`.
+  Use the added `WithProducer` option instead. (#4346)
+- Remove `Reader.ForceFlush` in `go.opentelemetry.io/otel/metric`.
+  Notice that `PeriodicReader.ForceFlush` is still available. (#4375)
+
+### Fixed
+
+- Correctly format log messages from the `go.opentelemetry.io/otel/exporters/zipkin` exporter. (#4143)
+- Log an error for calls to `NewView` in `go.opentelemetry.io/otel/sdk/metric` that have empty criteria. (#4307)
+- Fix `"go.opentelemetry.io/otel/sdk/resource".WithHostID()` to not set an empty `host.id`. (#4317)
+- Use the instrument identifying fields to cache aggregators and determine duplicate instrument registrations in `go.opentelemetry.io/otel/sdk/metric`. (#4337)
+- Detect duplicate instruments for case-insensitive names in `go.opentelemetry.io/otel/sdk/metric`. (#4338)
+- The `ManualReader` will not panic if `AggregationSelector` returns `nil` in `go.opentelemetry.io/otel/sdk/metric`. (#4350)
+- If a `Reader`'s `AggregationSelector` returns `nil` or `DefaultAggregation` the pipeline will use the default aggregation. (#4350)
+- Log a suggested view that fixes instrument conflicts in `go.opentelemetry.io/otel/sdk/metric`. (#4349)
+- Fix possible panic, deadlock and race condition in batch span processor in `go.opentelemetry.io/otel/sdk/trace`. (#4353)
+- Improve context cancellation handling in batch span processor's `ForceFlush` in  `go.opentelemetry.io/otel/sdk/trace`. (#4369)
+- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` using gotmpl. (#4397, #3846)
+- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` using gotmpl. (#4404, #3846)
+- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` using gotmpl. (#4407, #3846)
+- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` using gotmpl. (#4400, #3846)
+- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` using gotmpl. (#4401, #3846)
+- Do not block the metric SDK when OTLP metric exports are blocked in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#3925, #4395)
+- Do not append `_total` if the counter already has that suffix for the Prometheus exproter in `go.opentelemetry.io/otel/exporter/prometheus`. (#4373)
+- Fix resource detection data race in `go.opentelemetry.io/otel/sdk/resource`. (#4409)
+- Use the first-seen instrument name during instrument name conflicts in `go.opentelemetry.io/otel/sdk/metric`. (#4428)
+
+### Deprecated
+
+- The `go.opentelemetry.io/otel/exporters/jaeger` package is deprecated.
+  OpenTelemetry dropped support for Jaeger exporter in July 2023.
+  Use `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`
+  or `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` instead. (#4423)
+- The `go.opentelemetry.io/otel/example/jaeger` package is deprecated. (#4423)
+- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` package is deprecated. (#4420)
+- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/oconf` package is deprecated. (#4420)
+- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/otest` package is deprecated. (#4420)
+- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/transform` package is deprecated. (#4420)
+- The `go.opentelemetry.io/otel/exporters/otlp/internal` package is deprecated. (#4421)
+- The `go.opentelemetry.io/otel/exporters/otlp/internal/envconfig` package is deprecated. (#4421)
+- The `go.opentelemetry.io/otel/exporters/otlp/internal/retry` package is deprecated. (#4421)
+- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` package is deprecated. (#4425)
+- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/envconfig` package is deprecated. (#4425)
+- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig` package is deprecated. (#4425)
+- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlptracetest` package is deprecated. (#4425)
+- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/retry` package is deprecated. (#4425)
+- The `go.opentelemetry.io/otel/sdk/metric/aggregation` package is deprecated.
+  Use the aggregation types added to `go.opentelemetry.io/otel/sdk/metric` instead. (#4435)
+
+## [1.16.0/0.39.0] 2023-05-18
+
+This release contains the first stable release of the OpenTelemetry Go [metric API].
+Our project stability guarantees now apply to the `go.opentelemetry.io/otel/metric` package.
+See our [versioning policy](VERSIONING.md) for more information about these stability guarantees.
+
+### Added
+
+- The `go.opentelemetry.io/otel/semconv/v1.19.0` package.
+  The package contains semantic conventions from the `v1.19.0` version of the OpenTelemetry specification. (#3848)
+- The `go.opentelemetry.io/otel/semconv/v1.20.0` package.
+  The package contains semantic conventions from the `v1.20.0` version of the OpenTelemetry specification. (#4078)
+- The Exponential Histogram data types in `go.opentelemetry.io/otel/sdk/metric/metricdata`. (#4165)
+- OTLP metrics exporter now supports the Exponential Histogram Data Type. (#4222)
+- Fix serialization of `time.Time` zero values in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` packages. (#4271)
+
+### Changed
+
+- Use `strings.Cut()` instead of `string.SplitN()` for better readability and memory use. (#4049)
+- `MeterProvider` returns noop meters once it has been shutdown. (#4154)
+
+### Removed
+
+- The deprecated `go.opentelemetry.io/otel/metric/instrument` package is removed.
+  Use `go.opentelemetry.io/otel/metric` instead. (#4055)
+
+### Fixed
+
+- Fix build for BSD based systems in `go.opentelemetry.io/otel/sdk/resource`. (#4077)
+
+## [1.16.0-rc.1/0.39.0-rc.1] 2023-05-03
+
+This is a release candidate for the v1.16.0/v0.39.0 release.
+That release is expected to include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API.
+See our [versioning policy](VERSIONING.md) for more information about these stability guarantees.
+
+### Added
+
+- Support global `MeterProvider` in `go.opentelemetry.io/otel`. (#4039)
+  - Use `Meter` for a `metric.Meter` from the global `metric.MeterProvider`.
+  - Use `GetMeterProivder` for a global `metric.MeterProvider`.
+  - Use `SetMeterProivder` to set the global `metric.MeterProvider`.
+
+### Changed
+
+- Move the `go.opentelemetry.io/otel/metric` module to the `stable-v1` module set.
+  This stages the metric API to be released as a stable module. (#4038)
+
+### Removed
+
+- The `go.opentelemetry.io/otel/metric/global` package is removed.
+  Use `go.opentelemetry.io/otel` instead. (#4039)
+
+## [1.15.1/0.38.1] 2023-05-02
+
+### Fixed
+
+- Remove unused imports from `sdk/resource/host_id_bsd.go` which caused build failures. (#4040, #4041)
+
+## [1.15.0/0.38.0] 2023-04-27
+
+### Added
+
+- The `go.opentelemetry.io/otel/metric/embedded` package. (#3916)
+- The `Version` function to `go.opentelemetry.io/otel/sdk` to return the SDK version. (#3949)
+- Add a `WithNamespace` option to `go.opentelemetry.io/otel/exporters/prometheus` to allow users to prefix metrics with a namespace. (#3970)
+- The following configuration types were added to `go.opentelemetry.io/otel/metric/instrument` to be used in the configuration of measurement methods. (#3971)
+  - The `AddConfig` used to hold configuration for addition measurements
+    - `NewAddConfig` used to create a new `AddConfig`
+    - `AddOption` used to configure an `AddConfig`
+  - The `RecordConfig` used to hold configuration for recorded measurements
+    - `NewRecordConfig` used to create a new `RecordConfig`
+    - `RecordOption` used to configure a `RecordConfig`
+  - The `ObserveConfig` used to hold configuration for observed measurements
+    - `NewObserveConfig` used to create a new `ObserveConfig`
+    - `ObserveOption` used to configure an `ObserveConfig`
+- `WithAttributeSet` and `WithAttributes` are added to `go.opentelemetry.io/otel/metric/instrument`.
+  They return an option used during a measurement that defines the attribute Set associated with the measurement. (#3971)
+- The `Version` function to `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` to return the OTLP metrics client version. (#3956)
+- The `Version` function to `go.opentelemetry.io/otel/exporters/otlp/otlptrace` to return the OTLP trace client version. (#3956)
+
+### Changed
+
+- The `Extrema` in `go.opentelemetry.io/otel/sdk/metric/metricdata` is redefined with a generic argument of `[N int64 | float64]`. (#3870)
+- Update all exported interfaces from `go.opentelemetry.io/otel/metric` to embed their corresponding interface from `go.opentelemetry.io/otel/metric/embedded`.
+  This adds an implementation requirement to set the interface default behavior for unimplemented methods. (#3916)
+- Move No-Op implementation from `go.opentelemetry.io/otel/metric` into its own package `go.opentelemetry.io/otel/metric/noop`. (#3941)
+  - `metric.NewNoopMeterProvider` is replaced with `noop.NewMeterProvider`
+- Add all the methods from `"go.opentelemetry.io/otel/trace".SpanContext` to `bridgeSpanContext` by embedding `otel.SpanContext` in `bridgeSpanContext`. (#3966)
+- Wrap `UploadMetrics` error in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/` to improve error message when encountering generic grpc errors. (#3974)
+- The measurement methods for all instruments in `go.opentelemetry.io/otel/metric/instrument` accept an option instead of the variadic `"go.opentelemetry.io/otel/attribute".KeyValue`. (#3971)
+  - The `Int64Counter.Add` method now accepts `...AddOption`
+  - The `Float64Counter.Add` method now accepts `...AddOption`
+  - The `Int64UpDownCounter.Add` method now accepts `...AddOption`
+  - The `Float64UpDownCounter.Add` method now accepts `...AddOption`
+  - The `Int64Histogram.Record` method now accepts `...RecordOption`
+  - The `Float64Histogram.Record` method now accepts `...RecordOption`
+  - The `Int64Observer.Observe` method now accepts `...ObserveOption`
+  - The `Float64Observer.Observe` method now accepts `...ObserveOption`
+- The `Observer` methods in `go.opentelemetry.io/otel/metric` accept an option instead of the variadic `"go.opentelemetry.io/otel/attribute".KeyValue`. (#3971)
+  - The `Observer.ObserveInt64` method now accepts `...ObserveOption`
+  - The `Observer.ObserveFloat64` method now accepts `...ObserveOption`
+- Move global metric back to `go.opentelemetry.io/otel/metric/global` from `go.opentelemetry.io/otel`. (#3986)
+
+### Fixed
+
+- `TracerProvider` allows calling `Tracer()` while it's shutting down.
+  It used to deadlock. (#3924)
+- Use the SDK version for the Telemetry SDK resource detector in `go.opentelemetry.io/otel/sdk/resource`. (#3949)
+- Fix a data race in `SpanProcessor` returned by `NewSimpleSpanProcessor` in `go.opentelemetry.io/otel/sdk/trace`. (#3951)
+- Automatically figure out the default aggregation with `aggregation.Default`. (#3967)
+
+### Deprecated
+
+- The `go.opentelemetry.io/otel/metric/instrument` package is deprecated.
+  Use the equivalent types added to `go.opentelemetry.io/otel/metric` instead. (#4018)
+
+## [1.15.0-rc.2/0.38.0-rc.2] 2023-03-23
+
+This is a release candidate for the v1.15.0/v0.38.0 release.
+That release will include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API.
+See our [versioning policy](VERSIONING.md) for more information about these stability guarantees.
+
+### Added
+
+- The `WithHostID` option to `go.opentelemetry.io/otel/sdk/resource`. (#3812)
+- The `WithoutTimestamps` option to `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` to sets all timestamps to zero. (#3828)
+- The new `Exemplar` type is added to `go.opentelemetry.io/otel/sdk/metric/metricdata`.
+  Both the `DataPoint` and `HistogramDataPoint` types from that package have a new field of `Exemplars` containing the sampled exemplars for their timeseries. (#3849)
+- Configuration for each metric instrument in `go.opentelemetry.io/otel/sdk/metric/instrument`. (#3895)
+- The internal logging introduces a warning level verbosity equal to `V(1)`. (#3900)
+- Added a log message warning about usage of `SimpleSpanProcessor` in production environments. (#3854)
+
+### Changed
+
+- Optimize memory allocation when creation a new `Set` using `NewSet` or `NewSetWithFiltered` in `go.opentelemetry.io/otel/attribute`. (#3832)
+- Optimize memory allocation when creation new metric instruments in `go.opentelemetry.io/otel/sdk/metric`. (#3832)
+- Avoid creating new objects on all calls to `WithDeferredSetup` and `SkipContextSetup` in OpenTracing bridge. (#3833)
+- The `New` and `Detect` functions from `go.opentelemetry.io/otel/sdk/resource` return errors that wrap underlying errors instead of just containing the underlying error strings. (#3844)
+- Both the `Histogram` and `HistogramDataPoint` are redefined with a generic argument of `[N int64 | float64]` in `go.opentelemetry.io/otel/sdk/metric/metricdata`. (#3849)
+- The metric `Export` interface from `go.opentelemetry.io/otel/sdk/metric` accepts a `*ResourceMetrics` instead of `ResourceMetrics`. (#3853)
+- Rename `Asynchronous` to `Observable` in `go.opentelemetry.io/otel/metric/instrument`. (#3892)
+- Rename `Int64ObserverOption` to `Int64ObservableOption` in `go.opentelemetry.io/otel/metric/instrument`. (#3895)
+- Rename `Float64ObserverOption` to `Float64ObservableOption` in `go.opentelemetry.io/otel/metric/instrument`. (#3895)
+- The internal logging changes the verbosity level of info to `V(4)`, the verbosity level of debug to `V(8)`. (#3900)
+
+### Fixed
+
+- `TracerProvider` consistently doesn't allow to register a `SpanProcessor` after shutdown. (#3845)
+
+### Removed
+
+- The deprecated `go.opentelemetry.io/otel/metric/global` package is removed. (#3829)
+- The unneeded `Synchronous` interface in `go.opentelemetry.io/otel/metric/instrument` was removed. (#3892)
+- The `Float64ObserverConfig` and `NewFloat64ObserverConfig` in `go.opentelemetry.io/otel/sdk/metric/instrument`.
+  Use the added `float64` instrument configuration instead. (#3895)
+- The `Int64ObserverConfig` and `NewInt64ObserverConfig` in `go.opentelemetry.io/otel/sdk/metric/instrument`.
+  Use the added `int64` instrument configuration instead. (#3895)
+- The `NewNoopMeter` function in `go.opentelemetry.io/otel/metric`, use `NewMeterProvider().Meter("")` instead. (#3893)
+
+## [1.15.0-rc.1/0.38.0-rc.1] 2023-03-01
+
+This is a release candidate for the v1.15.0/v0.38.0 release.
+That release will include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API.
+See our [versioning policy](VERSIONING.md) for more information about these stability guarantees.
+
+This release drops the compatibility guarantee of [Go 1.18].
+
+### Added
+
+- Support global `MeterProvider` in `go.opentelemetry.io/otel`. (#3818)
+  - Use `Meter` for a `metric.Meter` from the global `metric.MeterProvider`.
+  - Use `GetMeterProivder` for a global `metric.MeterProvider`.
+  - Use `SetMeterProivder` to set the global `metric.MeterProvider`.
+
+### Changed
+
+- Dropped compatibility testing for [Go 1.18].
+  The project no longer guarantees support for this version of Go. (#3813)
+
+### Fixed
+
+- Handle empty environment variable as it they were not set. (#3764)
+- Clarify the `httpconv` and `netconv` packages in `go.opentelemetry.io/otel/semconv/*` provide tracing semantic conventions. (#3823)
+- Fix race conditions in `go.opentelemetry.io/otel/exporters/metric/prometheus` that could cause a panic. (#3899)
+- Fix sending nil `scopeInfo` to metrics channel in `go.opentelemetry.io/otel/exporters/metric/prometheus` that could cause a panic in `github.com/prometheus/client_golang/prometheus`. (#3899)
+
+### Deprecated
+
+- The `go.opentelemetry.io/otel/metric/global` package is deprecated.
+  Use `go.opentelemetry.io/otel` instead. (#3818)
+
+### Removed
+
+- The deprecated `go.opentelemetry.io/otel/metric/unit` package is removed. (#3814)
+
 ## [1.14.0/0.37.0/0.0.4] 2023-02-27
 
 This release is the last to support [Go 1.18].
@@ -121,7 +822,7 @@ The next release will require at least [Go 1.19].
 - The `go.opentelemetry.io/otel/semconv/v1.16.0` package.
   The package contains semantic conventions from the `v1.16.0` version of the OpenTelemetry specification. (#3579)
 - Metric instruments to `go.opentelemetry.io/otel/metric/instrument`.
-  These instruments are use as replacements of the depreacted `go.opentelemetry.io/otel/metric/instrument/{asyncfloat64,asyncint64,syncfloat64,syncint64}` packages.(#3575, #3586)
+  These instruments are use as replacements of the deprecated `go.opentelemetry.io/otel/metric/instrument/{asyncfloat64,asyncint64,syncfloat64,syncint64}` packages.(#3575, #3586)
   - `Float64ObservableCounter` replaces the `asyncfloat64.Counter`
   - `Float64ObservableUpDownCounter` replaces the `asyncfloat64.UpDownCounter`
   - `Float64ObservableGauge` replaces the `asyncfloat64.Gauge`
@@ -144,7 +845,7 @@ The next release will require at least [Go 1.19].
 ### Changed
 
 - Jaeger and Zipkin exporter use `github.com/go-logr/logr` as the logging interface, and add the `WithLogr` option. (#3497, #3500)
-- Instrument configuration in `go.opentelemetry.io/otel/metric/instrument` is split into specific options and confguration based on the instrument type. (#3507)
+- Instrument configuration in `go.opentelemetry.io/otel/metric/instrument` is split into specific options and configuration based on the instrument type. (#3507)
   - Use the added `Int64Option` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/syncint64`.
   - Use the added `Float64Option` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/syncfloat64`.
   - Use the added `Int64ObserverOption` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/asyncint64`.
@@ -157,7 +858,7 @@ The next release will require at least [Go 1.19].
 - The `Shutdown` method of the `"go.opentelemetry.io/otel/sdk/trace".TracerProvider` releases all computational resources when called the first time. (#3551)
 - The `Sampler` returned from `TraceIDRatioBased` `go.opentelemetry.io/otel/sdk/trace` now uses the rightmost bits for sampling decisions.
   This fixes random sampling when using ID generators like `xray.IDGenerator` and increasing parity with other language implementations. (#3557)
-- Errors from `go.opentelemetry.io/otel/exporters/otlp/otlptrace` exporters are wrapped in erros identifying their signal name.
+- Errors from `go.opentelemetry.io/otel/exporters/otlp/otlptrace` exporters are wrapped in errors identifying their signal name.
   Existing users of the exporters attempting to identify specific errors will need to use `errors.Unwrap()` to get the underlying error. (#3516)
 - Exporters from `go.opentelemetry.io/otel/exporters/otlp` will print the final retryable error message when attempts to retry time out. (#3514)
 - The instrument kind names in `go.opentelemetry.io/otel/sdk/metric` are updated to match the API. (#3562)
@@ -266,8 +967,8 @@ The next release will require at least [Go 1.19].
 - Asynchronous counters (`Counter` and `UpDownCounter`) from the metric SDK now produce delta sums when configured with delta temporality. (#3398)
 - Exported `Status` codes in the `go.opentelemetry.io/otel/exporters/zipkin` exporter are now exported as all upper case values. (#3340)
 - `Aggregation`s from `go.opentelemetry.io/otel/sdk/metric` with no data are not exported. (#3394, #3436)
-- Reenabled Attribute Filters in the Metric SDK. (#3396)
-- Asynchronous callbacks are only called if they are registered with at least one instrument that does not use drop aggragation. (#3408)
+- Re-enabled Attribute Filters in the Metric SDK. (#3396)
+- Asynchronous callbacks are only called if they are registered with at least one instrument that does not use drop aggregation. (#3408)
 - Do not report empty partial-success responses in the `go.opentelemetry.io/otel/exporters/otlp` exporters. (#3438, #3432)
 - Handle partial success responses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` exporters. (#3162, #3440)
 - Prevent duplicate Prometheus description, unit, and type. (#3469)
@@ -847,7 +1548,7 @@ This release includes an API and SDK for the tracing signal that will comply wit
 - Setting the global `ErrorHandler` with `"go.opentelemetry.io/otel".SetErrorHandler` multiple times is now supported. (#2160, #2140)
 - The `"go.opentelemetry.io/otel/attribute".Any` function now supports `int32` values. (#2169)
 - Multiple calls to `"go.opentelemetry.io/otel/sdk/metric/controller/basic".WithResource()` are handled correctly, and when no resources are provided `"go.opentelemetry.io/otel/sdk/resource".Default()` is used. (#2120)
-- The `WithoutTimestamps` option for the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` exporter causes the exporter to correctly ommit timestamps. (#2195)
+- The `WithoutTimestamps` option for the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` exporter causes the exporter to correctly omit timestamps. (#2195)
 - Fixed typos in resources.go. (#2201)
 
 ## [1.0.0-RC2] - 2021-07-26
@@ -1293,7 +1994,7 @@ with major version 0.
 - `NewGRPCDriver` function returns a `ProtocolDriver` that maintains a single gRPC connection to the collector. (#1369)
 - Added documentation about the project's versioning policy. (#1388)
 - Added `NewSplitDriver` for OTLP exporter that allows sending traces and metrics to different endpoints. (#1418)
-- Added codeql worfklow to GitHub Actions (#1428)
+- Added codeql workflow to GitHub Actions (#1428)
 - Added Gosec workflow to GitHub Actions (#1429)
 - Add new HTTP driver for OTLP exporter in `exporters/otlp/otlphttp`. Currently it only supports the binary protobuf payloads. (#1420)
 - Add an OpenCensus exporter bridge. (#1444)
@@ -1312,7 +2013,7 @@ with major version 0.
 - `NewExporter` from `exporters/otlp` now takes a `ProtocolDriver` as a parameter. (#1369)
 - Many OTLP Exporter options became gRPC ProtocolDriver options. (#1369)
 - Unify endpoint API that related to OTel exporter. (#1401)
-- Optimize metric histogram aggregator to re-use its slice of buckets. (#1435)
+- Optimize metric histogram aggregator to reuse its slice of buckets. (#1435)
 - Metric aggregator Count() and histogram Bucket.Counts are consistently `uint64`. (1430)
 - Histogram aggregator accepts functional options, uses default boundaries if none given. (#1434)
 - `SamplingResult` now passed a `Tracestate` from the parent `SpanContext` (#1432)
@@ -2136,7 +2837,7 @@ There is still a possibility of breaking changes.
 
 ### Fixed
 
-- Use stateful batcher on Prometheus exporter fixing regresion introduced in #395. (#428)
+- Use stateful batcher on Prometheus exporter fixing regression introduced in #395. (#428)
 
 ## [0.2.1] - 2020-01-08
 
@@ -2302,7 +3003,28 @@ It contains api and sdk for trace and meter.
 - CircleCI build CI manifest files.
 - CODEOWNERS file to track owners of this project.
 
-[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.14.0...HEAD
+[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.28.0...HEAD
+[1.28.0/0.50.0/0.4.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.28.0
+[1.27.0/0.49.0/0.3.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.27.0
+[1.26.0/0.48.0/0.2.0-alpha]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.26.0
+[1.25.0/0.47.0/0.0.8/0.1.0-alpha]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.25.0
+[1.24.0/0.46.0/0.0.1-alpha]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.24.0
+[1.23.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.23.1
+[1.23.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.23.0
+[1.23.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.23.0-rc.1
+[1.22.0/0.45.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.22.0
+[1.21.0/0.44.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.21.0
+[1.20.0/0.43.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.20.0
+[1.19.0/0.42.0/0.0.7]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.19.0
+[1.19.0-rc.1/0.42.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.19.0-rc.1
+[1.18.0/0.41.0/0.0.6]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.18.0
+[1.17.0/0.40.0/0.0.5]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.17.0
+[1.16.0/0.39.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.16.0
+[1.16.0-rc.1/0.39.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.16.0-rc.1
+[1.15.1/0.38.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.1
+[1.15.0/0.38.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0
+[1.15.0-rc.2/0.38.0-rc.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0-rc.2
+[1.15.0-rc.1/0.38.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0-rc.1
 [1.14.0/0.37.0/0.0.4]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.14.0
 [1.13.0/0.36.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.13.0
 [1.12.0/0.35.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.12.0
@@ -2364,6 +3086,14 @@ It contains api and sdk for trace and meter.
 [0.1.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.1.1
 [0.1.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.1.0
 
+[Go 1.22]: https://go.dev/doc/go1.22
+[Go 1.21]: https://go.dev/doc/go1.21
 [Go 1.20]: https://go.dev/doc/go1.20
 [Go 1.19]: https://go.dev/doc/go1.19
 [Go 1.18]: https://go.dev/doc/go1.18
+
+[metric API]:https://pkg.go.dev/go.opentelemetry.io/otel/metric
+[metric SDK]:https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric
+[trace API]:https://pkg.go.dev/go.opentelemetry.io/otel/trace
+
+[GO-2024-2687]: https://pkg.go.dev/vuln/GO-2024-2687
diff --git a/vendor/go.opentelemetry.io/otel/CODEOWNERS b/vendor/go.opentelemetry.io/otel/CODEOWNERS
index c4012ed6..20255493 100644
--- a/vendor/go.opentelemetry.io/otel/CODEOWNERS
+++ b/vendor/go.opentelemetry.io/otel/CODEOWNERS
@@ -12,6 +12,6 @@
 #  https://help.github.com/en/articles/about-code-owners
 #
 
-* @jmacd @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @MadVikingGod @pellared @hanyuancheung @dmathieu
+* @MrAlias @XSAM @dashpole @MadVikingGod @pellared @hanyuancheung @dmathieu
 
-CODEOWNERS @MrAlias @Aneurysm9 @MadVikingGod
+CODEOWNERS @MrAlias @MadVikingGod @pellared @dashpole @XSAM @dmathieu
diff --git a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
index a6928bfd..b86572f5 100644
--- a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
+++ b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
@@ -6,7 +6,7 @@ OpenTelemetry
 repo for information on this and other language SIGs.
 
 See the [public meeting
-notes](https://docs.google.com/document/d/1A63zSWX0x2CyCK_LoNhmQC4rqhLpYXJzXbEPDUQ2n6w/edit#heading=h.9tngw7jdwd6b)
+notes](https://docs.google.com/document/d/1E5e7Ld0NuU1iVvf-42tOBpu2VBBLYnh73GJuITGJTTU/edit)
 for a summary description of past meetings. To request edit access,
 join the meeting or get in touch on
 [Slack](https://cloud-native.slack.com/archives/C01NPAXACKT).
@@ -28,6 +28,11 @@ precommit` - the `precommit` target is the default).
 The `precommit` target also fixes the formatting of the code and
 checks the status of the go module files.
 
+Additionally, there is a `codespell` target that checks for common
+typos in the code. It is not run by default, but you can run it
+manually with `make codespell`. It will set up a virtual environment
+in `venv` and install `codespell` there.
+
 If after running `make precommit` the output of `git status` contains
 `nothing to commit, working tree clean` then it means that everything
 is up-to-date and properly formatted.
@@ -85,6 +90,10 @@ git push <YOUR_FORK> <YOUR_BRANCH_NAME>
 Open a pull request against the main `opentelemetry-go` repo. Be sure to add the pull
 request ID to the entry you added to `CHANGELOG.md`.
 
+Avoid rebasing and force-pushing to your branch to facilitate reviewing the pull request.
+Rewriting Git history makes it difficult to keep track of iterations during code review.
+All pull requests are squashed to a single commit upon merge to `main`.
+
 ### How to Receive Comments
 
 * If the PR is not ready for review, please put `[WIP]` in the title,
@@ -94,38 +103,66 @@ request ID to the entry you added to `CHANGELOG.md`.
 
 ### How to Get PRs Merged
 
-A PR is considered to be **ready to merge** when:
-
-* It has received two approvals from Collaborators/Maintainers (at
-  different companies). This is not enforced through technical means
-  and a PR may be **ready to merge** with a single approval if the change
-  and its approach have been discussed and consensus reached.
-* Feedback has been addressed.
-* Any substantive changes to your PR will require that you clear any prior
-  Approval reviews, this includes changes resulting from other feedback. Unless
-  the approver explicitly stated that their approval will persist across
-  changes it should be assumed that the PR needs their review again. Other
-  project members (e.g. approvers, maintainers) can help with this if there are
-  any questions or if you forget to clear reviews.
-* It has been open for review for at least one working day. This gives
-  people reasonable time to review.
-* Trivial changes (typo, cosmetic, doc, etc.) do not have to wait for
-  one day and may be merged with a single Maintainer's approval.
-* `CHANGELOG.md` has been updated to reflect what has been
-  added, changed, removed, or fixed.
-* `README.md` has been updated if necessary.
-* Urgent fix can take exception as long as it has been actively
-  communicated.
-
-Any Maintainer can merge the PR once it is **ready to merge**.
+A PR is considered **ready to merge** when:
+
+* It has received two qualified approvals[^1].
+
+  This is not enforced through automation, but needs to be validated by the
+  maintainer merging.
+  * The qualified approvals need to be from [Approver]s/[Maintainer]s
+    affiliated with different companies. Two qualified approvals from
+    [Approver]s or [Maintainer]s affiliated with the same company counts as a
+    single qualified approval.
+  * PRs introducing changes that have already been discussed and consensus
+    reached only need one qualified approval. The discussion and resolution
+    needs to be linked to the PR.
+  * Trivial changes[^2] only need one qualified approval.
+
+* All feedback has been addressed.
+  * All PR comments and suggestions are resolved.
+  * All GitHub Pull Request reviews with a status of "Request changes" have
+    been addressed. Another review by the objecting reviewer with a different
+    status can be submitted to clear the original review, or the review can be
+    dismissed by a [Maintainer] when the issues from the original review have
+    been addressed.
+  * Any comments or reviews that cannot be resolved between the PR author and
+    reviewers can be submitted to the community [Approver]s and [Maintainer]s
+    during the weekly SIG meeting. If consensus is reached among the
+    [Approver]s and [Maintainer]s during the SIG meeting the objections to the
+    PR may be dismissed or resolved or the PR closed by a [Maintainer].
+  * Any substantive changes to the PR require existing Approval reviews be
+    cleared unless the approver explicitly states that their approval persists
+    across changes. This includes changes resulting from other feedback.
+    [Approver]s and [Maintainer]s can help in clearing reviews and they should
+    be consulted if there are any questions.
+
+* The PR branch is up to date with the base branch it is merging into.
+  * To ensure this does not block the PR, it should be configured to allow
+    maintainers to update it.
+
+* It has been open for review for at least one working day. This gives people
+  reasonable time to review.
+  * Trivial changes[^2] do not have to wait for one day and may be merged with
+    a single [Maintainer]'s approval.
+
+* All required GitHub workflows have succeeded.
+* Urgent fix can take exception as long as it has been actively communicated
+  among [Maintainer]s.
+
+Any [Maintainer] can merge the PR once the above criteria have been met.
+
+[^1]: A qualified approval is a GitHub Pull Request review with "Approve"
+  status from an OpenTelemetry Go [Approver] or [Maintainer].
+[^2]: Trivial changes include: typo corrections, cosmetic non-substantive
+  changes, documentation corrections or updates, dependency updates, etc.
 
 ## Design Choices
 
 As with other OpenTelemetry clients, opentelemetry-go follows the
-[opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification).
+[OpenTelemetry Specification](https://opentelemetry.io/docs/specs/otel).
 
 It's especially valuable to read through the [library
-guidelines](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/library-guidelines.md).
+guidelines](https://opentelemetry.io/docs/specs/otel/library-guidelines).
 
 ### Focus on Capabilities, Not Structure Compliance
 
@@ -146,23 +183,33 @@ For a deeper discussion, see
 
 ## Documentation
 
-Each non-example Go Module should have its own `README.md` containing:
+Each (non-internal, non-test) package must be documented using
+[Go Doc Comments](https://go.dev/doc/comment),
+preferably in a `doc.go` file.
+
+Prefer using [Examples](https://pkg.go.dev/testing#hdr-Examples)
+instead of putting code snippets in Go doc comments.
+In some cases, you can even create [Testable Examples](https://go.dev/blog/examples).
+
+You can install and run a "local Go Doc site" in the following way:
+
+  ```sh
+  go install golang.org/x/pkgsite/cmd/pkgsite@latest
+  pkgsite
+  ```
+
+[`go.opentelemetry.io/otel/metric`](https://pkg.go.dev/go.opentelemetry.io/otel/metric)
+is an example of a very well-documented package.
 
-- A pkg.go.dev badge which can be generated [here](https://pkg.go.dev/badge/).
-- Brief description.
-- Installation instructions (and requirements if applicable).
-- Hyperlink to an example. Depending on the component the example can be:
-  - An `example_test.go` like [here](exporters/stdout/stdouttrace/example_test.go).
-  - A sample Go application with its own `README.md`, like [here](example/zipkin).
-- Additional documentation sections such us:
-  - Configuration,
-  - Contributing,
-  - References.
+### README files
 
-[Here](exporters/jaeger/README.md) is an example of a concise `README.md`.
+Each (non-internal, non-test, non-documentation) package must contain a
+`README.md` file containing at least a title, and a `pkg.go.dev` badge.
 
-Moreover, it should be possible to navigate to any `README.md` from the
-root `README.md`.
+The README should not be a repetition of Go doc comments.
+
+You can verify the presence of all README files with the `make verify-readmes`
+command.
 
 ## Style Guide
 
@@ -216,7 +263,7 @@ Meaning a `config` from one package should not be directly used by another. The
 one exception is the API packages.  The configs from the base API, eg.
 `go.opentelemetry.io/otel/trace.TracerConfig` and
 `go.opentelemetry.io/otel/metric.InstrumentConfig`, are intended to be consumed
-by the SDK therefor it is expected that these are exported.
+by the SDK therefore it is expected that these are exported.
 
 When a config is exported we want to maintain forward and backward
 compatibility, to achieve this no fields should be exported but should
@@ -234,12 +281,12 @@ func newConfig(options ...Option) config {
 	for _, option := range options {
 		config = option.apply(config)
 	}
-	// Preform any validation here.
+	// Perform any validation here.
 	return config
 }
 ```
 
-If validation of the `config` options is also preformed this can return an
+If validation of the `config` options is also performed this can return an
 error as well that is expected to be handled by the instantiation function
 or propagated to the user.
 
@@ -438,12 +485,37 @@ their parameters appropriately named.
 #### Interface Stability
 
 All exported stable interfaces that include the following warning in their
-doumentation are allowed to be extended with additional methods.
+documentation are allowed to be extended with additional methods.
 
 > Warning: methods may be added to this interface in minor releases.
 
+These interfaces are defined by the OpenTelemetry specification and will be
+updated as the specification evolves.
+
 Otherwise, stable interfaces MUST NOT be modified.
 
+#### How to Change Specification Interfaces
+
+When an API change must be made, we will update the SDK with the new method one
+release before the API change. This will allow the SDK one version before the
+API change to work seamlessly with the new API.
+
+If an incompatible version of the SDK is used with the new API the application
+will fail to compile.
+
+#### How Not to Change Specification Interfaces
+
+We have explored using a v2 of the API to change interfaces and found that there
+was no way to introduce a v2 and have it work seamlessly with the v1 of the API.
+Problems happened with libraries that upgraded to v2 when an application did not,
+and would not produce any telemetry.
+
+More detail of the approaches considered and their limitations can be found in
+the [Use a V2 API to evolve interfaces](https://github.com/open-telemetry/opentelemetry-go/issues/3920)
+issue.
+
+#### How to Change Other Interfaces
+
 If new functionality is needed for an interface that cannot be changed it MUST
 be added by including an additional interface. That added interface can be a
 simple interface for the specific functionality that you want to add or it can
@@ -498,29 +570,89 @@ functionality should be added, each one will need their own super-set
 interfaces and will duplicate the pattern. For this reason, the simple targeted
 interface that defines the specific functionality should be preferred.
 
+See also:
+[Keeping Your Modules Compatible: Working with interfaces](https://go.dev/blog/module-compatibility#working-with-interfaces).
+
+### Testing
+
+The tests should never leak goroutines.
+
+Use the term `ConcurrentSafe` in the test name when it aims to verify the
+absence of race conditions.
+
+### Internal packages
+
+The use of internal packages should be scoped to a single module. A sub-module
+should never import from a parent internal package. This creates a coupling
+between the two modules where a user can upgrade the parent without the child
+and if the internal package API has changed it will fail to upgrade[^3].
+
+There are two known exceptions to this rule:
+
+- `go.opentelemetry.io/otel/internal/global`
+  - This package manages global state for all of opentelemetry-go. It needs to
+  be a single package in order to ensure the uniqueness of the global state.
+- `go.opentelemetry.io/otel/internal/baggage`
+  - This package provides values in a `context.Context` that need to be
+  recognized by `go.opentelemetry.io/otel/baggage` and
+  `go.opentelemetry.io/otel/bridge/opentracing` but remain private.
+
+If you have duplicate code in multiple modules, make that code into a Go
+template stored in `go.opentelemetry.io/otel/internal/shared` and use [gotmpl]
+to render the templates in the desired locations. See [#4404] for an example of
+this.
+
+[^3]: https://github.com/open-telemetry/opentelemetry-go/issues/3548
+
+### Ignoring context cancellation
+
+OpenTelemetry API implementations need to ignore the cancellation of the context that are
+passed when recording a value (e.g. starting a span, recording a measurement, emitting a log).
+Recording methods should not return an error describing the cancellation state of the context
+when they complete, nor should they abort any work.
+
+This rule may not apply if the OpenTelemetry specification defines a timeout mechanism for
+the method. In that case the context cancellation can be used for the timeout with the
+restriction that this behavior is documented for the method. Otherwise, timeouts
+are expected to be handled by the user calling the API, not the implementation.
+
+Stoppage of the telemetry pipeline is handled by calling the appropriate `Shutdown` method
+of a provider. It is assumed the context passed from a user is not used for this purpose.
+
+Outside of the direct recording of telemetry from the API (e.g. exporting telemetry,
+force flushing telemetry, shutting down a signal provider) the context cancellation
+should be honored. This means all work done on behalf of the user provided context
+should be canceled.
+
 ## Approvers and Maintainers
 
-Approvers:
+### Approvers
 
-- [Evan Torrie](https://github.com/evantorrie), Verizon Media
-- [Josh MacDonald](https://github.com/jmacd), LightStep
-- [Sam Xie](https://github.com/XSAM), Cisco/AppDynamics
-- [David Ashpole](https://github.com/dashpole), Google
-- [Robert Pająk](https://github.com/pellared), Splunk
 - [Chester Cheung](https://github.com/hanyuancheung), Tencent
-- [Damien Mathieu](https://github.com/dmathieu), Elastic
 
-Maintainers:
+### Maintainers
 
 - [Aaron Clawson](https://github.com/MadVikingGod), LightStep
-- [Anthony Mirabella](https://github.com/Aneurysm9), AWS
+- [Damien Mathieu](https://github.com/dmathieu), Elastic
+- [David Ashpole](https://github.com/dashpole), Google
+- [Robert Pająk](https://github.com/pellared), Splunk
+- [Sam Xie](https://github.com/XSAM), Cisco/AppDynamics
 - [Tyler Yahn](https://github.com/MrAlias), Splunk
 
-Emeritus:
+### Emeritus
 
+- [Liz Fong-Jones](https://github.com/lizthegrey), Honeycomb
 - [Gustavo Silva Paiva](https://github.com/paivagustavo), LightStep
+- [Josh MacDonald](https://github.com/jmacd), LightStep
+- [Anthony Mirabella](https://github.com/Aneurysm9), AWS
+- [Evan Torrie](https://github.com/evantorrie), Yahoo
 
 ### Become an Approver or a Maintainer
 
 See the [community membership document in OpenTelemetry community
 repo](https://github.com/open-telemetry/community/blob/main/community-membership.md).
+
+[Approver]: #approvers
+[Maintainer]: #maintainers
+[gotmpl]: https://pkg.go.dev/go.opentelemetry.io/build-tools/gotmpl
+[#4404]: https://github.com/open-telemetry/opentelemetry-go/pull/4404
diff --git a/vendor/go.opentelemetry.io/otel/Makefile b/vendor/go.opentelemetry.io/otel/Makefile
index 0e6ffa28..f33619f7 100644
--- a/vendor/go.opentelemetry.io/otel/Makefile
+++ b/vendor/go.opentelemetry.io/otel/Makefile
@@ -1,16 +1,5 @@
 # Copyright The OpenTelemetry 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.
+# SPDX-License-Identifier: Apache-2.0
 
 TOOLS_MOD_DIR := ./internal/tools
 
@@ -25,8 +14,8 @@ TIMEOUT = 60
 .DEFAULT_GOAL := precommit
 
 .PHONY: precommit ci
-precommit: dependabot-generate license-check vanity-import-fix misspell go-mod-tidy golangci-lint-fix test-default
-ci: dependabot-check license-check lint vanity-import-check build test-default check-clean-work-tree test-coverage
+precommit: generate license-check misspell go-mod-tidy golangci-lint-fix verify-readmes verify-mods test-default
+ci: generate license-check lint vanity-import-check verify-readmes verify-mods build test-default check-clean-work-tree test-coverage
 
 # Tools
 
@@ -34,7 +23,7 @@ TOOLS = $(CURDIR)/.tools
 
 $(TOOLS):
 	@mkdir -p $@
-$(TOOLS)/%: | $(TOOLS)
+$(TOOLS)/%: $(TOOLS_MOD_DIR)/go.mod | $(TOOLS)
 	cd $(TOOLS_MOD_DIR) && \
 	$(GO) build -o $@ $(PACKAGE)
 
@@ -50,9 +39,6 @@ $(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/build-tools/crosslink
 SEMCONVKIT = $(TOOLS)/semconvkit
 $(TOOLS)/semconvkit: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/semconvkit
 
-DBOTCONF = $(TOOLS)/dbotconf
-$(TOOLS)/dbotconf: PACKAGE=go.opentelemetry.io/build-tools/dbotconf
-
 GOLANGCI_LINT = $(TOOLS)/golangci-lint
 $(TOOLS)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-lint
 
@@ -71,21 +57,78 @@ $(TOOLS)/porto: PACKAGE=github.com/jcchavezs/porto/cmd/porto
 GOJQ = $(TOOLS)/gojq
 $(TOOLS)/gojq: PACKAGE=github.com/itchyny/gojq/cmd/gojq
 
+GOTMPL = $(TOOLS)/gotmpl
+$(GOTMPL): PACKAGE=go.opentelemetry.io/build-tools/gotmpl
+
+GORELEASE = $(TOOLS)/gorelease
+$(GORELEASE): PACKAGE=golang.org/x/exp/cmd/gorelease
+
+GOVULNCHECK = $(TOOLS)/govulncheck
+$(TOOLS)/govulncheck: PACKAGE=golang.org/x/vuln/cmd/govulncheck
+
 .PHONY: tools
-tools: $(CROSSLINK) $(DBOTCONF) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(GOJQ) $(SEMCONVGEN) $(MULTIMOD) $(SEMCONVKIT)
+tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(GOJQ) $(SEMCONVGEN) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE)
 
-# Build
+# Virtualized python tools via docker
+
+# The directory where the virtual environment is created.
+VENVDIR := venv
+
+# The directory where the python tools are installed.
+PYTOOLS := $(VENVDIR)/bin
+
+# The pip executable in the virtual environment.
+PIP := $(PYTOOLS)/pip
+
+# The directory in the docker image where the current directory is mounted.
+WORKDIR := /workdir
 
-.PHONY: generate build
+# The python image to use for the virtual environment.
+PYTHONIMAGE := python:3.11.3-slim-bullseye
 
-generate: $(OTEL_GO_MOD_DIRS:%=generate/%)
-generate/%: DIR=$*
-generate/%: | $(STRINGER) $(PORTO)
+# Run the python image with the current directory mounted.
+DOCKERPY := docker run --rm -v "$(CURDIR):$(WORKDIR)" -w $(WORKDIR) $(PYTHONIMAGE)
+
+# Create a virtual environment for Python tools.
+$(PYTOOLS):
+# The `--upgrade` flag is needed to ensure that the virtual environment is
+# created with the latest pip version.
+	@$(DOCKERPY) bash -c "python3 -m venv $(VENVDIR) && $(PIP) install --upgrade pip"
+
+# Install python packages into the virtual environment.
+$(PYTOOLS)/%: $(PYTOOLS)
+	@$(DOCKERPY) $(PIP) install -r requirements.txt
+
+CODESPELL = $(PYTOOLS)/codespell
+$(CODESPELL): PACKAGE=codespell
+
+# Generate
+
+.PHONY: generate
+generate: go-generate vanity-import-fix
+
+.PHONY: go-generate
+go-generate: $(OTEL_GO_MOD_DIRS:%=go-generate/%)
+go-generate/%: DIR=$*
+go-generate/%: $(STRINGER) $(GOTMPL)
 	@echo "$(GO) generate $(DIR)/..." \
 		&& cd $(DIR) \
-		&& PATH="$(TOOLS):$${PATH}" $(GO) generate ./... && $(PORTO) -w .
+		&& PATH="$(TOOLS):$${PATH}" $(GO) generate ./...
+
+.PHONY: vanity-import-fix
+vanity-import-fix: $(PORTO)
+	@$(PORTO) --include-internal -w .
 
-build: generate $(OTEL_GO_MOD_DIRS:%=build/%) $(OTEL_GO_MOD_DIRS:%=build-tests/%)
+# Generate go.work file for local development.
+.PHONY: go-work
+go-work: $(CROSSLINK)
+	$(CROSSLINK) work --root=$(shell pwd)
+
+# Build
+
+.PHONY: build
+
+build: $(OTEL_GO_MOD_DIRS:%=build/%) $(OTEL_GO_MOD_DIRS:%=build-tests/%)
 build/%: DIR=$*
 build/%:
 	@echo "$(GO) build $(DIR)/..." \
@@ -121,7 +164,7 @@ test/%:
 COVERAGE_MODE    = atomic
 COVERAGE_PROFILE = coverage.out
 .PHONY: test-coverage
-test-coverage: | $(GOCOVMERGE)
+test-coverage: $(GOCOVMERGE)
 	@set -e; \
 	printf "" > coverage.txt; \
 	for dir in $(ALL_COVERAGE_MOD_DIRS); do \
@@ -135,66 +178,77 @@ test-coverage: | $(GOCOVMERGE)
 	done; \
 	$(GOCOVMERGE) $$(find . -name coverage.out) > coverage.txt
 
+# Adding a directory will include all benchmarks in that directory if a filter is not specified.
+BENCHMARK_TARGETS := sdk/trace
+.PHONY: benchmark
+benchmark: $(BENCHMARK_TARGETS:%=benchmark/%)
+BENCHMARK_FILTER = .
+# You can override the filter for a particular directory by adding a rule here.
+benchmark/sdk/trace: BENCHMARK_FILTER = SpanWithAttributes_8/AlwaysSample
+benchmark/%:
+	@echo "$(GO) test -timeout $(TIMEOUT)s -run=xxxxxMatchNothingxxxxx -bench=$(BENCHMARK_FILTER) $*..." \
+		&& cd $* \
+		$(foreach filter, $(BENCHMARK_FILTER), && $(GO) test -timeout $(TIMEOUT)s -run=xxxxxMatchNothingxxxxx -bench=$(filter))
+
 .PHONY: golangci-lint golangci-lint-fix
 golangci-lint-fix: ARGS=--fix
 golangci-lint-fix: golangci-lint
 golangci-lint: $(OTEL_GO_MOD_DIRS:%=golangci-lint/%)
 golangci-lint/%: DIR=$*
-golangci-lint/%: | $(GOLANGCI_LINT)
+golangci-lint/%: $(GOLANGCI_LINT)
 	@echo 'golangci-lint $(if $(ARGS),$(ARGS) ,)$(DIR)' \
 		&& cd $(DIR) \
 		&& $(GOLANGCI_LINT) run --allow-serial-runners $(ARGS)
 
 .PHONY: crosslink
-crosslink: | $(CROSSLINK)
+crosslink: $(CROSSLINK)
 	@echo "Updating intra-repository dependencies in all go modules" \
 		&& $(CROSSLINK) --root=$(shell pwd) --prune
 
 .PHONY: go-mod-tidy
 go-mod-tidy: $(ALL_GO_MOD_DIRS:%=go-mod-tidy/%)
 go-mod-tidy/%: DIR=$*
-go-mod-tidy/%: | crosslink
+go-mod-tidy/%: crosslink
 	@echo "$(GO) mod tidy in $(DIR)" \
 		&& cd $(DIR) \
-		&& $(GO) mod tidy -compat=1.18
+		&& $(GO) mod tidy -compat=1.21
 
 .PHONY: lint-modules
 lint-modules: go-mod-tidy
 
 .PHONY: lint
-lint: misspell lint-modules golangci-lint
+lint: misspell lint-modules golangci-lint govulncheck
 
 .PHONY: vanity-import-check
-vanity-import-check: | $(PORTO)
-	@$(PORTO) --include-internal -l . || echo "(run: make vanity-import-fix)"
-
-.PHONY: vanity-import-fix
-vanity-import-fix: | $(PORTO)
-	@$(PORTO) --include-internal -w .
+vanity-import-check: $(PORTO)
+	@$(PORTO) --include-internal -l . || ( echo "(run: make vanity-import-fix)"; exit 1 )
 
 .PHONY: misspell
-misspell: | $(MISSPELL)
+misspell: $(MISSPELL)
 	@$(MISSPELL) -w $(ALL_DOCS)
 
+.PHONY: govulncheck
+govulncheck: $(OTEL_GO_MOD_DIRS:%=govulncheck/%)
+govulncheck/%: DIR=$*
+govulncheck/%: $(GOVULNCHECK)
+	@echo "govulncheck ./... in $(DIR)" \
+		&& cd $(DIR) \
+		&& $(GOVULNCHECK) ./...
+
+.PHONY: codespell
+codespell: $(CODESPELL)
+	@$(DOCKERPY) $(CODESPELL)
+
 .PHONY: license-check
 license-check:
 	@licRes=$$(for f in $$(find . -type f \( -iname '*.go' -o -iname '*.sh' \) ! -path '**/third_party/*' ! -path './.git/*' ) ; do \
-	           awk '/Copyright The OpenTelemetry Authors|generated|GENERATED/ && NR<=3 { found=1; next } END { if (!found) print FILENAME }' $$f; \
+	           awk '/Copyright The OpenTelemetry Authors|generated|GENERATED/ && NR<=4 { found=1; next } END { if (!found) print FILENAME }' $$f; \
 	   done); \
 	   if [ -n "$${licRes}" ]; then \
 	           echo "license header checking failed:"; echo "$${licRes}"; \
 	           exit 1; \
 	   fi
 
-DEPENDABOT_CONFIG = .github/dependabot.yml
-.PHONY: dependabot-check
-dependabot-check: | $(DBOTCONF)
-	@$(DBOTCONF) verify $(DEPENDABOT_CONFIG) || echo "(run: make dependabot-generate)"
-
-.PHONY: dependabot-generate
-dependabot-generate: | $(DBOTCONF)
-	@$(DBOTCONF) generate > $(DEPENDABOT_CONFIG)
-
 .PHONY: check-clean-work-tree
 check-clean-work-tree:
 	@if ! git diff --quiet; then \
@@ -207,21 +261,41 @@ check-clean-work-tree:
 
 SEMCONVPKG ?= "semconv/"
 .PHONY: semconv-generate
-semconv-generate: | $(SEMCONVGEN) $(SEMCONVKIT)
-	[ "$(TAG)" ] || ( echo "TAG unset: missing opentelemetry specification tag"; exit 1 )
-	[ "$(OTEL_SPEC_REPO)" ] || ( echo "OTEL_SPEC_REPO unset: missing path to opentelemetry specification repo"; exit 1 )
-	$(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/." --only=span -p conventionType=trace -f trace.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)"
-	$(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/." --only=event -p conventionType=event -f event.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)"
-	$(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/." --only=resource -p conventionType=resource -f resource.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)"
+semconv-generate: $(SEMCONVGEN) $(SEMCONVKIT)
+	[ "$(TAG)" ] || ( echo "TAG unset: missing opentelemetry semantic-conventions tag"; exit 1 )
+	[ "$(OTEL_SEMCONV_REPO)" ] || ( echo "OTEL_SEMCONV_REPO unset: missing path to opentelemetry semantic-conventions repo"; exit 1 )
+	$(SEMCONVGEN) -i "$(OTEL_SEMCONV_REPO)/model/." --only=attribute_group -p conventionType=trace -f attribute_group.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)"
+	$(SEMCONVGEN) -i "$(OTEL_SEMCONV_REPO)/model/." --only=metric  -f metric.go -t "$(SEMCONVPKG)/metric_template.j2" -s "$(TAG)"
 	$(SEMCONVKIT) -output "$(SEMCONVPKG)/$(TAG)" -tag "$(TAG)"
 
+.PHONY: gorelease
+gorelease: $(OTEL_GO_MOD_DIRS:%=gorelease/%)
+gorelease/%: DIR=$*
+gorelease/%:| $(GORELEASE)
+	@echo "gorelease in $(DIR):" \
+		&& cd $(DIR) \
+		&& $(GORELEASE) \
+		|| echo ""
+
+.PHONY: verify-mods
+verify-mods: $(MULTIMOD)
+	$(MULTIMOD) verify
+
 .PHONY: prerelease
-prerelease: | $(MULTIMOD)
+prerelease: verify-mods
 	@[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 )
-	$(MULTIMOD) verify && $(MULTIMOD) prerelease -m ${MODSET}
+	$(MULTIMOD) prerelease -m ${MODSET}
 
 COMMIT ?= "HEAD"
 .PHONY: add-tags
-add-tags: | $(MULTIMOD)
+add-tags: verify-mods
 	@[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 )
-	$(MULTIMOD) verify && $(MULTIMOD) tag -m ${MODSET} -c ${COMMIT}
+	$(MULTIMOD) tag -m ${MODSET} -c ${COMMIT}
+
+.PHONY: lint-markdown
+lint-markdown:
+	docker run -v "$(CURDIR):$(WORKDIR)" avtodev/markdown-lint:v1 -c $(WORKDIR)/.markdownlint.yaml $(WORKDIR)/**/*.md
+
+.PHONY: verify-readmes
+verify-readmes:
+	./verify_readmes.sh
diff --git a/vendor/go.opentelemetry.io/otel/README.md b/vendor/go.opentelemetry.io/otel/README.md
index 878d87e5..5a890931 100644
--- a/vendor/go.opentelemetry.io/otel/README.md
+++ b/vendor/go.opentelemetry.io/otel/README.md
@@ -11,22 +11,21 @@ It provides a set of APIs to directly measure performance and behavior of your s
 
 ## Project Status
 
-| Signal  | Status     | Project |
-| ------- | ---------- | ------- |
-| Traces  | Stable     | N/A     |
-| Metrics | Alpha      | N/A     |
-| Logs    | Frozen [1] | N/A     |
+| Signal  | Status             |
+|---------|--------------------|
+| Traces  | Stable             |
+| Metrics | Stable             |
+| Logs    | Beta[^1]           |
 
-- [1]: The Logs signal development is halted for this project while we develop both Traces and Metrics.
-   No Logs Pull Requests are currently being accepted.
-
-Progress and status specific to this repository is tracked in our local
+Progress and status specific to this repository is tracked in our
 [project boards](https://github.com/open-telemetry/opentelemetry-go/projects)
 and
 [milestones](https://github.com/open-telemetry/opentelemetry-go/milestones).
 
 Project versioning information and stability guarantees can be found in the
-[versioning documentation](./VERSIONING.md).
+[versioning documentation](VERSIONING.md).
+
+[^1]: https://github.com/orgs/open-telemetry/projects/43
 
 ### Compatibility
 
@@ -49,29 +48,26 @@ stop ensuring compatibility with these versions in the following manner:
 Currently, this project supports the following environments.
 
 | OS      | Go Version | Architecture |
-| ------- | ---------- | ------------ |
-| Ubuntu  | 1.20       | amd64        |
-| Ubuntu  | 1.19       | amd64        |
-| Ubuntu  | 1.18       | amd64        |
-| Ubuntu  | 1.20       | 386          |
-| Ubuntu  | 1.19       | 386          |
-| Ubuntu  | 1.18       | 386          |
-| MacOS   | 1.20       | amd64        |
-| MacOS   | 1.19       | amd64        |
-| MacOS   | 1.18       | amd64        |
-| Windows | 1.20       | amd64        |
-| Windows | 1.19       | amd64        |
-| Windows | 1.18       | amd64        |
-| Windows | 1.20       | 386          |
-| Windows | 1.19       | 386          |
-| Windows | 1.18       | 386          |
+|---------|------------|--------------|
+| Ubuntu  | 1.22       | amd64        |
+| Ubuntu  | 1.21       | amd64        |
+| Ubuntu  | 1.22       | 386          |
+| Ubuntu  | 1.21       | 386          |
+| Linux   | 1.22       | arm64        |
+| Linux   | 1.21       | arm64        |
+| MacOS   | 1.22       | amd64        |
+| MacOS   | 1.21       | amd64        |
+| Windows | 1.22       | amd64        |
+| Windows | 1.21       | amd64        |
+| Windows | 1.22       | 386          |
+| Windows | 1.21       | 386          |
 
 While this project should work for other systems, no compatibility guarantees
 are made for those systems currently.
 
 ## Getting Started
 
-You can find a getting started guide on [opentelemetry.io](https://opentelemetry.io/docs/go/getting-started/).
+You can find a getting started guide on [opentelemetry.io](https://opentelemetry.io/docs/languages/go/getting-started/).
 
 OpenTelemetry's goal is to provide a single set of APIs to capture distributed
 traces and metrics from your application and send them to an observability
@@ -101,13 +97,12 @@ export pipeline to send that telemetry to an observability platform.
 
 All officially supported exporters for the OpenTelemetry project are contained in the [exporters directory](./exporters).
 
-| Exporter                              | Metrics | Traces |
-| :-----------------------------------: | :-----: | :----: |
-| [Jaeger](./exporters/jaeger/)         |         | ✓      |
-| [OTLP](./exporters/otlp/)             | ✓       | ✓      |
-| [Prometheus](./exporters/prometheus/) | ✓       |        |
-| [stdout](./exporters/stdout/)         | ✓       | ✓      |
-| [Zipkin](./exporters/zipkin/)         |         | ✓      |
+| Exporter                              | Logs | Metrics | Traces |
+|---------------------------------------|:----:|:-------:|:------:|
+| [OTLP](./exporters/otlp/)             |  ✓   |    ✓    |   ✓    |
+| [Prometheus](./exporters/prometheus/) |      |    ✓    |        |
+| [stdout](./exporters/stdout/)         |  ✓   |    ✓    |   ✓    |
+| [Zipkin](./exporters/zipkin/)         |      |         |   ✓    |
 
 ## Contributing
 
diff --git a/vendor/go.opentelemetry.io/otel/RELEASING.md b/vendor/go.opentelemetry.io/otel/RELEASING.md
index 77d56c93..940f57f3 100644
--- a/vendor/go.opentelemetry.io/otel/RELEASING.md
+++ b/vendor/go.opentelemetry.io/otel/RELEASING.md
@@ -2,28 +2,36 @@
 
 ## Semantic Convention Generation
 
-New versions of the [OpenTelemetry specification] mean new versions of the `semconv` package need to be generated.
+New versions of the [OpenTelemetry Semantic Conventions] mean new versions of the `semconv` package need to be generated.
 The `semconv-generate` make target is used for this.
 
-1. Checkout a local copy of the [OpenTelemetry specification] to the desired release tag.
+1. Checkout a local copy of the [OpenTelemetry Semantic Conventions] to the desired release tag.
 2. Pull the latest `otel/semconvgen` image: `docker pull otel/semconvgen:latest`
 3. Run the `make semconv-generate ...` target from this repository.
 
 For example,
 
 ```sh
-export TAG="v1.13.0" # Change to the release version you are generating.
-export OTEL_SPEC_REPO="/absolute/path/to/opentelemetry-specification"
-git -C "$OTEL_SPEC_REPO" checkout "tags/$TAG" -b "$TAG"
+export TAG="v1.21.0" # Change to the release version you are generating.
+export OTEL_SEMCONV_REPO="/absolute/path/to/opentelemetry/semantic-conventions"
 docker pull otel/semconvgen:latest
-make semconv-generate # Uses the exported TAG and OTEL_SPEC_REPO.
+make semconv-generate # Uses the exported TAG and OTEL_SEMCONV_REPO.
 ```
 
 This should create a new sub-package of [`semconv`](./semconv).
 Ensure things look correct before submitting a pull request to include the addition.
 
-**Note**, the generation code was changed to generate versions >= 1.13.
-To generate versions prior to this, checkout the old release of this repository (i.e. [2fe8861](https://github.com/open-telemetry/opentelemetry-go/commit/2fe8861a24e20088c065b116089862caf9e3cd8b)).
+## Breaking changes validation
+
+You can run `make gorelease` that runs [gorelease](https://pkg.go.dev/golang.org/x/exp/cmd/gorelease) to ensure that there are no unwanted changes done in the public API.
+
+You can check/report problems with `gorelease` [here](https://golang.org/issues/26420).
+
+## Verify changes for contrib repository
+
+If the changes in the main repository are going to affect the contrib repository, it is important to verify that the changes are compatible with the contrib repository.
+
+Follow [the steps](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/RELEASING.md#verify-otel-changes) in the contrib repository to verify OTel changes.
 
 ## Pre-Release
 
@@ -121,7 +129,17 @@ Once verified be sure to [make a release for the `contrib` repository](https://g
 
 ### Website Documentation
 
-Update [the documentation](./website_docs) for [the OpenTelemetry website](https://opentelemetry.io/docs/go/).
+Update the [Go instrumentation documentation] in the OpenTelemetry website under [content/en/docs/languages/go].
 Importantly, bump any package versions referenced to be the latest one you just released and ensure all code examples still compile and are accurate.
 
-[OpenTelemetry specification]: https://github.com/open-telemetry/opentelemetry-specification
+[OpenTelemetry Semantic Conventions]: https://github.com/open-telemetry/semantic-conventions
+[Go instrumentation documentation]: https://opentelemetry.io/docs/languages/go/
+[content/en/docs/languages/go]: https://github.com/open-telemetry/opentelemetry.io/tree/main/content/en/docs/languages/go
+
+### Demo Repository
+
+Bump the dependencies in the following Go services:
+
+- [`accountingservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/accountingservice)
+- [`checkoutservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/checkoutservice)
+- [`productcatalogservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/productcatalogservice)
diff --git a/vendor/go.opentelemetry.io/otel/attribute/README.md b/vendor/go.opentelemetry.io/otel/attribute/README.md
new file mode 100644
index 00000000..5b3da8f1
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/attribute/README.md
@@ -0,0 +1,3 @@
+# Attribute
+
+[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/attribute)](https://pkg.go.dev/go.opentelemetry.io/otel/attribute)
diff --git a/vendor/go.opentelemetry.io/otel/attribute/doc.go b/vendor/go.opentelemetry.io/otel/attribute/doc.go
index dafe7424..eef51ebc 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/doc.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/doc.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 // Package attribute provides key and value attributes.
 package attribute // import "go.opentelemetry.io/otel/attribute"
diff --git a/vendor/go.opentelemetry.io/otel/attribute/encoder.go b/vendor/go.opentelemetry.io/otel/attribute/encoder.go
index fe2bc576..318e42fc 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/encoder.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/encoder.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package attribute // import "go.opentelemetry.io/otel/attribute"
 
diff --git a/vendor/go.opentelemetry.io/otel/attribute/filter.go b/vendor/go.opentelemetry.io/otel/attribute/filter.go
new file mode 100644
index 00000000..be9cd922
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/attribute/filter.go
@@ -0,0 +1,49 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package attribute // import "go.opentelemetry.io/otel/attribute"
+
+// Filter supports removing certain attributes from attribute sets. When
+// the filter returns true, the attribute will be kept in the filtered
+// attribute set. When the filter returns false, the attribute is excluded
+// from the filtered attribute set, and the attribute instead appears in
+// the removed list of excluded attributes.
+type Filter func(KeyValue) bool
+
+// NewAllowKeysFilter returns a Filter that only allows attributes with one of
+// the provided keys.
+//
+// If keys is empty a deny-all filter is returned.
+func NewAllowKeysFilter(keys ...Key) Filter {
+	if len(keys) <= 0 {
+		return func(kv KeyValue) bool { return false }
+	}
+
+	allowed := make(map[Key]struct{})
+	for _, k := range keys {
+		allowed[k] = struct{}{}
+	}
+	return func(kv KeyValue) bool {
+		_, ok := allowed[kv.Key]
+		return ok
+	}
+}
+
+// NewDenyKeysFilter returns a Filter that only allows attributes
+// that do not have one of the provided keys.
+//
+// If keys is empty an allow-all filter is returned.
+func NewDenyKeysFilter(keys ...Key) Filter {
+	if len(keys) <= 0 {
+		return func(kv KeyValue) bool { return true }
+	}
+
+	forbid := make(map[Key]struct{})
+	for _, k := range keys {
+		forbid[k] = struct{}{}
+	}
+	return func(kv KeyValue) bool {
+		_, ok := forbid[kv.Key]
+		return !ok
+	}
+}
diff --git a/vendor/go.opentelemetry.io/otel/attribute/iterator.go b/vendor/go.opentelemetry.io/otel/attribute/iterator.go
index 841b271f..f2ba89ce 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/iterator.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/iterator.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package attribute // import "go.opentelemetry.io/otel/attribute"
 
diff --git a/vendor/go.opentelemetry.io/otel/attribute/key.go b/vendor/go.opentelemetry.io/otel/attribute/key.go
index 0656a04e..d9a22c65 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/key.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/key.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package attribute // import "go.opentelemetry.io/otel/attribute"
 
diff --git a/vendor/go.opentelemetry.io/otel/attribute/kv.go b/vendor/go.opentelemetry.io/otel/attribute/kv.go
index 1ddf3ce0..3028f9a4 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/kv.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/kv.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package attribute // import "go.opentelemetry.io/otel/attribute"
 
diff --git a/vendor/go.opentelemetry.io/otel/attribute/set.go b/vendor/go.opentelemetry.io/otel/attribute/set.go
index 26be5983..bff9c7fd 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/set.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/set.go
@@ -1,22 +1,13 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package attribute // import "go.opentelemetry.io/otel/attribute"
 
 import (
+	"cmp"
 	"encoding/json"
 	"reflect"
+	"slices"
 	"sort"
 )
 
@@ -25,30 +16,33 @@ type (
 	// immutable set of attributes, with an internal cache for storing
 	// attribute encodings.
 	//
-	// This type supports the Equivalent method of comparison using values of
-	// type Distinct.
+	// This type will remain comparable for backwards compatibility. The
+	// equivalence of Sets across versions is not guaranteed to be stable.
+	// Prior versions may find two Sets to be equal or not when compared
+	// directly (i.e. ==), but subsequent versions may not. Users should use
+	// the Equals method to ensure stable equivalence checking.
+	//
+	// Users should also use the Distinct returned from Equivalent as a map key
+	// instead of a Set directly. In addition to that type providing guarantees
+	// on stable equivalence, it may also provide performance improvements.
 	Set struct {
 		equivalent Distinct
 	}
 
-	// Distinct wraps a variable-size array of KeyValue, constructed with keys
-	// in sorted order. This can be used as a map key or for equality checking
-	// between Sets.
+	// Distinct is a unique identifier of a Set.
+	//
+	// Distinct is designed to be ensures equivalence stability: comparisons
+	// will return the save value across versions. For this reason, Distinct
+	// should always be used as a map key instead of a Set.
 	Distinct struct {
 		iface interface{}
 	}
 
-	// Filter supports removing certain attributes from attribute sets. When
-	// the filter returns true, the attribute will be kept in the filtered
-	// attribute set. When the filter returns false, the attribute is excluded
-	// from the filtered attribute set, and the attribute instead appears in
-	// the removed list of excluded attributes.
-	Filter func(KeyValue) bool
-
-	// Sortable implements sort.Interface, used for sorting KeyValue. This is
-	// an exported type to support a memory optimization. A pointer to one of
-	// these is needed for the call to sort.Stable(), which the caller may
-	// provide in order to avoid an allocation. See NewSetWithSortable().
+	// Sortable implements sort.Interface, used for sorting KeyValue.
+	//
+	// Deprecated: This type is no longer used. It was added as a performance
+	// optimization for Go < 1.21 that is no longer needed (Go < 1.21 is no
+	// longer supported by the module).
 	Sortable []KeyValue
 )
 
@@ -91,7 +85,7 @@ func (l *Set) Len() int {
 
 // Get returns the KeyValue at ordered position idx in this set.
 func (l *Set) Get(idx int) (KeyValue, bool) {
-	if l == nil {
+	if l == nil || !l.equivalent.Valid() {
 		return KeyValue{}, false
 	}
 	value := l.equivalent.reflectValue()
@@ -107,7 +101,7 @@ func (l *Set) Get(idx int) (KeyValue, bool) {
 
 // Value returns the value of a specified key in this set.
 func (l *Set) Value(k Key) (Value, bool) {
-	if l == nil {
+	if l == nil || !l.equivalent.Valid() {
 		return Value{}, false
 	}
 	rValue := l.equivalent.reflectValue()
@@ -187,11 +181,7 @@ func empty() Set {
 // Except for empty sets, this method adds an additional allocation compared
 // with calls that include a Sortable.
 func NewSet(kvs ...KeyValue) Set {
-	// Check for empty set.
-	if len(kvs) == 0 {
-		return empty()
-	}
-	s, _ := NewSetWithSortableFiltered(kvs, new(Sortable), nil)
+	s, _ := NewSetWithFiltered(kvs, nil)
 	return s
 }
 
@@ -199,12 +189,10 @@ func NewSet(kvs ...KeyValue) Set {
 // NewSetWithSortableFiltered for more details.
 //
 // This call includes a Sortable option as a memory optimization.
-func NewSetWithSortable(kvs []KeyValue, tmp *Sortable) Set {
-	// Check for empty set.
-	if len(kvs) == 0 {
-		return empty()
-	}
-	s, _ := NewSetWithSortableFiltered(kvs, tmp, nil)
+//
+// Deprecated: Use [NewSet] instead.
+func NewSetWithSortable(kvs []KeyValue, _ *Sortable) Set {
+	s, _ := NewSetWithFiltered(kvs, nil)
 	return s
 }
 
@@ -218,7 +206,37 @@ func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
 	if len(kvs) == 0 {
 		return empty(), nil
 	}
-	return NewSetWithSortableFiltered(kvs, new(Sortable), filter)
+
+	// Stable sort so the following de-duplication can implement
+	// last-value-wins semantics.
+	slices.SortStableFunc(kvs, func(a, b KeyValue) int {
+		return cmp.Compare(a.Key, b.Key)
+	})
+
+	position := len(kvs) - 1
+	offset := position - 1
+
+	// The requirements stated above require that the stable
+	// result be placed in the end of the input slice, while
+	// overwritten values are swapped to the beginning.
+	//
+	// De-duplicate with last-value-wins semantics.  Preserve
+	// duplicate values at the beginning of the input slice.
+	for ; offset >= 0; offset-- {
+		if kvs[offset].Key == kvs[position].Key {
+			continue
+		}
+		position--
+		kvs[offset], kvs[position] = kvs[position], kvs[offset]
+	}
+	kvs = kvs[position:]
+
+	if filter != nil {
+		if div := filteredToFront(kvs, filter); div != 0 {
+			return Set{equivalent: computeDistinct(kvs[div:])}, kvs[:div]
+		}
+	}
+	return Set{equivalent: computeDistinct(kvs)}, nil
 }
 
 // NewSetWithSortableFiltered returns a new Set.
@@ -244,82 +262,71 @@ func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
 //
 // The second []KeyValue return value is a list of attributes that were
 // excluded by the Filter (if non-nil).
-func NewSetWithSortableFiltered(kvs []KeyValue, tmp *Sortable, filter Filter) (Set, []KeyValue) {
-	// Check for empty set.
-	if len(kvs) == 0 {
-		return empty(), nil
-	}
-
-	*tmp = kvs
-
-	// Stable sort so the following de-duplication can implement
-	// last-value-wins semantics.
-	sort.Stable(tmp)
-
-	*tmp = nil
-
-	position := len(kvs) - 1
-	offset := position - 1
-
-	// The requirements stated above require that the stable
-	// result be placed in the end of the input slice, while
-	// overwritten values are swapped to the beginning.
-	//
-	// De-duplicate with last-value-wins semantics.  Preserve
-	// duplicate values at the beginning of the input slice.
-	for ; offset >= 0; offset-- {
-		if kvs[offset].Key == kvs[position].Key {
-			continue
-		}
-		position--
-		kvs[offset], kvs[position] = kvs[position], kvs[offset]
-	}
-	if filter != nil {
-		return filterSet(kvs[position:], filter)
-	}
-	return Set{
-		equivalent: computeDistinct(kvs[position:]),
-	}, nil
+//
+// Deprecated: Use [NewSetWithFiltered] instead.
+func NewSetWithSortableFiltered(kvs []KeyValue, _ *Sortable, filter Filter) (Set, []KeyValue) {
+	return NewSetWithFiltered(kvs, filter)
 }
 
-// filterSet reorders kvs so that included keys are contiguous at the end of
-// the slice, while excluded keys precede the included keys.
-func filterSet(kvs []KeyValue, filter Filter) (Set, []KeyValue) {
-	var excluded []KeyValue
-
-	// Move attributes that do not match the filter so they're adjacent before
-	// calling computeDistinct().
-	distinctPosition := len(kvs)
-
-	// Swap indistinct keys forward and distinct keys toward the
-	// end of the slice.
-	offset := len(kvs) - 1
-	for ; offset >= 0; offset-- {
-		if filter(kvs[offset]) {
-			distinctPosition--
-			kvs[offset], kvs[distinctPosition] = kvs[distinctPosition], kvs[offset]
-			continue
+// filteredToFront filters slice in-place using keep function. All KeyValues that need to
+// be removed are moved to the front. All KeyValues that need to be kept are
+// moved (in-order) to the back. The index for the first KeyValue to be kept is
+// returned.
+func filteredToFront(slice []KeyValue, keep Filter) int {
+	n := len(slice)
+	j := n
+	for i := n - 1; i >= 0; i-- {
+		if keep(slice[i]) {
+			j--
+			slice[i], slice[j] = slice[j], slice[i]
 		}
 	}
-	excluded = kvs[:distinctPosition]
-
-	return Set{
-		equivalent: computeDistinct(kvs[distinctPosition:]),
-	}, excluded
+	return j
 }
 
 // Filter returns a filtered copy of this Set. See the documentation for
 // NewSetWithSortableFiltered for more details.
 func (l *Set) Filter(re Filter) (Set, []KeyValue) {
 	if re == nil {
-		return Set{
-			equivalent: l.equivalent,
-		}, nil
+		return *l, nil
+	}
+
+	// Iterate in reverse to the first attribute that will be filtered out.
+	n := l.Len()
+	first := n - 1
+	for ; first >= 0; first-- {
+		kv, _ := l.Get(first)
+		if !re(kv) {
+			break
+		}
+	}
+
+	// No attributes will be dropped, return the immutable Set l and nil.
+	if first < 0 {
+		return *l, nil
 	}
 
-	// Note: This could be refactored to avoid the temporary slice
-	// allocation, if it proves to be expensive.
-	return filterSet(l.ToSlice(), re)
+	// Copy now that we know we need to return a modified set.
+	//
+	// Do not do this in-place on the underlying storage of *Set l. Sets are
+	// immutable and filtering should not change this.
+	slice := l.ToSlice()
+
+	// Don't re-iterate the slice if only slice[0] is filtered.
+	if first == 0 {
+		// It is safe to assume len(slice) >= 1 given we found at least one
+		// attribute above that needs to be filtered out.
+		return Set{equivalent: computeDistinct(slice[1:])}, slice[:1]
+	}
+
+	// Move the filtered slice[first] to the front (preserving order).
+	kv := slice[first]
+	copy(slice[1:first+1], slice[:first])
+	slice[0] = kv
+
+	// Do not re-evaluate re(slice[first+1:]).
+	div := filteredToFront(slice[1:first+1], re) + 1
+	return Set{equivalent: computeDistinct(slice[div:])}, slice[:div]
 }
 
 // computeDistinct returns a Distinct using either the fixed- or
@@ -399,7 +406,7 @@ func (l *Set) MarshalJSON() ([]byte, error) {
 	return json.Marshal(l.equivalent.iface)
 }
 
-// MarshalLog is the marshaling function used by the logging system to represent this exporter.
+// MarshalLog is the marshaling function used by the logging system to represent this Set.
 func (l Set) MarshalLog() interface{} {
 	kvs := make(map[string]string)
 	for _, kv := range l.ToSlice() {
diff --git a/vendor/go.opentelemetry.io/otel/attribute/value.go b/vendor/go.opentelemetry.io/otel/attribute/value.go
index cb21dd5c..9ea0ecbb 100644
--- a/vendor/go.opentelemetry.io/otel/attribute/value.go
+++ b/vendor/go.opentelemetry.io/otel/attribute/value.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package attribute // import "go.opentelemetry.io/otel/attribute"
 
@@ -242,15 +231,27 @@ func (v Value) Emit() string {
 	case BOOL:
 		return strconv.FormatBool(v.AsBool())
 	case INT64SLICE:
-		return fmt.Sprint(v.asInt64Slice())
+		j, err := json.Marshal(v.asInt64Slice())
+		if err != nil {
+			return fmt.Sprintf("invalid: %v", v.asInt64Slice())
+		}
+		return string(j)
 	case INT64:
 		return strconv.FormatInt(v.AsInt64(), 10)
 	case FLOAT64SLICE:
-		return fmt.Sprint(v.asFloat64Slice())
+		j, err := json.Marshal(v.asFloat64Slice())
+		if err != nil {
+			return fmt.Sprintf("invalid: %v", v.asFloat64Slice())
+		}
+		return string(j)
 	case FLOAT64:
 		return fmt.Sprint(v.AsFloat64())
 	case STRINGSLICE:
-		return fmt.Sprint(v.asStringSlice())
+		j, err := json.Marshal(v.asStringSlice())
+		if err != nil {
+			return fmt.Sprintf("invalid: %v", v.asStringSlice())
+		}
+		return string(j)
 	case STRING:
 		return v.stringly
 	default:
diff --git a/vendor/go.opentelemetry.io/otel/baggage/README.md b/vendor/go.opentelemetry.io/otel/baggage/README.md
new file mode 100644
index 00000000..7d798435
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/baggage/README.md
@@ -0,0 +1,3 @@
+# Baggage
+
+[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/baggage)](https://pkg.go.dev/go.opentelemetry.io/otel/baggage)
diff --git a/vendor/go.opentelemetry.io/otel/baggage/baggage.go b/vendor/go.opentelemetry.io/otel/baggage/baggage.go
index a36db8f8..c40c896c 100644
--- a/vendor/go.opentelemetry.io/otel/baggage/baggage.go
+++ b/vendor/go.opentelemetry.io/otel/baggage/baggage.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package baggage // import "go.opentelemetry.io/otel/baggage"
 
@@ -18,8 +7,8 @@ import (
 	"errors"
 	"fmt"
 	"net/url"
-	"regexp"
 	"strings"
+	"unicode/utf8"
 
 	"go.opentelemetry.io/otel/internal/baggage"
 )
@@ -32,16 +21,6 @@ const (
 	listDelimiter     = ","
 	keyValueDelimiter = "="
 	propertyDelimiter = ";"
-
-	keyDef      = `([\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5a\x5e-\x7a\x7c\x7e]+)`
-	valueDef    = `([\x21\x23-\x2b\x2d-\x3a\x3c-\x5B\x5D-\x7e]*)`
-	keyValueDef = `\s*` + keyDef + `\s*` + keyValueDelimiter + `\s*` + valueDef + `\s*`
-)
-
-var (
-	keyRe      = regexp.MustCompile(`^` + keyDef + `$`)
-	valueRe    = regexp.MustCompile(`^` + valueDef + `$`)
-	propertyRe = regexp.MustCompile(`^(?:\s*` + keyDef + `\s*|` + keyValueDef + `)$`)
 )
 
 var (
@@ -61,41 +40,50 @@ type Property struct {
 	// hasValue indicates if a zero-value value means the property does not
 	// have a value or if it was the zero-value.
 	hasValue bool
-
-	// hasData indicates whether the created property contains data or not.
-	// Properties that do not contain data are invalid with no other check
-	// required.
-	hasData bool
 }
 
 // NewKeyProperty returns a new Property for key.
 //
 // If key is invalid, an error will be returned.
 func NewKeyProperty(key string) (Property, error) {
-	if !keyRe.MatchString(key) {
+	if !validateKey(key) {
 		return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidKey, key)
 	}
 
-	p := Property{key: key, hasData: true}
+	p := Property{key: key}
 	return p, nil
 }
 
 // NewKeyValueProperty returns a new Property for key with value.
 //
-// If key or value are invalid, an error will be returned.
+// The passed key must be compliant with W3C Baggage specification.
+// The passed value must be percent-encoded as defined in W3C Baggage specification.
+//
+// Notice: Consider using [NewKeyValuePropertyRaw] instead
+// that does not require percent-encoding of the value.
 func NewKeyValueProperty(key, value string) (Property, error) {
-	if !keyRe.MatchString(key) {
-		return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidKey, key)
+	if !validateValue(value) {
+		return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidValue, value)
 	}
-	if !valueRe.MatchString(value) {
+	decodedValue, err := url.PathUnescape(value)
+	if err != nil {
 		return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidValue, value)
 	}
+	return NewKeyValuePropertyRaw(key, decodedValue)
+}
+
+// NewKeyValuePropertyRaw returns a new Property for key with value.
+//
+// The passed key must be compliant with W3C Baggage specification.
+func NewKeyValuePropertyRaw(key, value string) (Property, error) {
+	if !validateKey(key) {
+		return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidKey, key)
+	}
 
 	p := Property{
 		key:      key,
 		value:    value,
 		hasValue: true,
-		hasData:  true,
 	}
 	return p, nil
 }
@@ -112,20 +100,11 @@ func parseProperty(property string) (Property, error) {
 		return newInvalidProperty(), nil
 	}
 
-	match := propertyRe.FindStringSubmatch(property)
-	if len(match) != 4 {
+	p, ok := parsePropertyInternal(property)
+	if !ok {
 		return newInvalidProperty(), fmt.Errorf("%w: %q", errInvalidProperty, property)
 	}
 
-	p := Property{hasData: true}
-	if match[1] != "" {
-		p.key = match[1]
-	} else {
-		p.key = match[2]
-		p.value = match[3]
-		p.hasValue = true
-	}
-
 	return p, nil
 }
 
@@ -136,16 +115,9 @@ func (p Property) validate() error {
 		return fmt.Errorf("invalid property: %w", err)
 	}
 
-	if !p.hasData {
-		return errFunc(fmt.Errorf("%w: %q", errInvalidProperty, p))
-	}
-
-	if !keyRe.MatchString(p.key) {
+	if !validateKey(p.key) {
 		return errFunc(fmt.Errorf("%w: %q", errInvalidKey, p.key))
 	}
-	if p.hasValue && !valueRe.MatchString(p.value) {
-		return errFunc(fmt.Errorf("%w: %q", errInvalidValue, p.value))
-	}
 	if !p.hasValue && p.value != "" {
 		return errFunc(errors.New("inconsistent value"))
 	}
@@ -164,11 +136,11 @@ func (p Property) Value() (string, bool) {
 	return p.value, p.hasValue
 }
 
-// String encodes Property into a string compliant with the W3C Baggage
+// String encodes Property into a header string compliant with the W3C Baggage
 // specification.
 func (p Property) String() string {
 	if p.hasValue {
-		return fmt.Sprintf("%s%s%v", p.key, keyValueDelimiter, p.value)
+		return fmt.Sprintf("%s%s%v", p.key, keyValueDelimiter, valueEscape(p.value))
 	}
 	return p.key
 }
@@ -228,7 +200,7 @@ func (p properties) validate() error {
 	return nil
 }
 
-// String encodes properties into a string compliant with the W3C Baggage
+// String encodes properties into a header string compliant with the W3C Baggage
 // specification.
 func (p properties) String() string {
 	props := make([]string, len(p))
@@ -250,11 +222,28 @@ type Member struct {
 	hasData bool
 }
 
-// NewMember returns a new Member from the passed arguments. The key will be
-// used directly while the value will be url decoded after validation. An error
-// is returned if the created Member would be invalid according to the W3C
-// Baggage specification.
+// NewMember returns a new Member from the passed arguments.
+//
+// The passed key must be compliant with W3C Baggage specification.
+// The passed value must be percent-encoded as defined in W3C Baggage specification.
+//
+// Notice: Consider using [NewMemberRaw] instead
+// that does not require percent-encoding of the value.
 func NewMember(key, value string, props ...Property) (Member, error) {
+	if !validateValue(value) {
+		return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value)
+	}
+	decodedValue, err := url.PathUnescape(value)
+	if err != nil {
+		return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value)
+	}
+	return NewMemberRaw(key, decodedValue, props...)
+}
+
+// NewMemberRaw returns a new Member from the passed arguments.
+//
+// The passed key must be compliant with W3C Baggage specification.
+func NewMemberRaw(key, value string, props ...Property) (Member, error) {
 	m := Member{
 		key:        key,
 		value:      value,
@@ -264,11 +253,6 @@ func NewMember(key, value string, props ...Property) (Member, error) {
 	if err := m.validate(); err != nil {
 		return newInvalidMember(), err
 	}
-	decodedValue, err := url.QueryUnescape(value)
-	if err != nil {
-		return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value)
-	}
-	m.value = decodedValue
 	return m, nil
 }
 
@@ -284,69 +268,55 @@ func parseMember(member string) (Member, error) {
 		return newInvalidMember(), fmt.Errorf("%w: %d", errMemberBytes, n)
 	}
 
-	var (
-		key, value string
-		props      properties
-	)
-
-	parts := strings.SplitN(member, propertyDelimiter, 2)
-	switch len(parts) {
-	case 2:
+	var props properties
+	keyValue, properties, found := strings.Cut(member, propertyDelimiter)
+	if found {
 		// Parse the member properties.
-		for _, pStr := range strings.Split(parts[1], propertyDelimiter) {
+		for _, pStr := range strings.Split(properties, propertyDelimiter) {
 			p, err := parseProperty(pStr)
 			if err != nil {
 				return newInvalidMember(), err
 			}
 			props = append(props, p)
 		}
-		fallthrough
-	case 1:
-		// Parse the member key/value pair.
-
-		// Take into account a value can contain equal signs (=).
-		kv := strings.SplitN(parts[0], keyValueDelimiter, 2)
-		if len(kv) != 2 {
-			return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidMember, member)
-		}
-		// "Leading and trailing whitespaces are allowed but MUST be trimmed
-		// when converting the header into a data structure."
-		key = strings.TrimSpace(kv[0])
-		var err error
-		value, err = url.QueryUnescape(strings.TrimSpace(kv[1]))
-		if err != nil {
-			return newInvalidMember(), fmt.Errorf("%w: %q", err, value)
-		}
-		if !keyRe.MatchString(key) {
-			return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidKey, key)
-		}
-		if !valueRe.MatchString(value) {
-			return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value)
-		}
-	default:
-		// This should never happen unless a developer has changed the string
-		// splitting somehow. Panic instead of failing silently and allowing
-		// the bug to slip past the CI checks.
-		panic("failed to parse baggage member")
+	}
+	// Parse the member key/value pair.
+
+	// Take into account a value can contain equal signs (=).
+	k, v, found := strings.Cut(keyValue, keyValueDelimiter)
+	if !found {
+		return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidMember, member)
+	}
+	// "Leading and trailing whitespaces are allowed but MUST be trimmed
+	// when converting the header into a data structure."
+	key := strings.TrimSpace(k)
+	if !validateKey(key) {
+		return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidKey, key)
+	}
+
+	val := strings.TrimSpace(v)
+	if !validateValue(val) {
+		return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, v)
 	}
 
+	// Decode a percent-encoded value.
+	value, err := url.PathUnescape(val)
+	if err != nil {
+		return newInvalidMember(), fmt.Errorf("%w: %w", errInvalidValue, err)
+	}
 	return Member{key: key, value: value, properties: props, hasData: true}, nil
 }
 
 // validate ensures m conforms to the W3C Baggage specification.
-// A key is just an ASCII string, but a value must be URL encoded UTF-8,
-// returning an error otherwise.
+// A key must be an ASCII string, returning an error otherwise.
 func (m Member) validate() error {
 	if !m.hasData {
 		return fmt.Errorf("%w: %q", errInvalidMember, m)
 	}
 
-	if !keyRe.MatchString(m.key) {
+	if !validateKey(m.key) {
 		return fmt.Errorf("%w: %q", errInvalidKey, m.key)
 	}
-	if !valueRe.MatchString(m.value) {
-		return fmt.Errorf("%w: %q", errInvalidValue, m.value)
-	}
 	return m.properties.validate()
 }
 
@@ -359,13 +329,15 @@ func (m Member) Value() string { return m.value }
 // Properties returns a copy of the Member properties.
 func (m Member) Properties() []Property { return m.properties.Copy() }
 
-// String encodes Member into a string compliant with the W3C Baggage
+// String encodes Member into a header string compliant with the W3C Baggage
 // specification.
 func (m Member) String() string {
-	// A key is just an ASCII string, but a value is URL encoded UTF-8.
-	s := fmt.Sprintf("%s%s%s", m.key, keyValueDelimiter, url.QueryEscape(m.value))
+	// A key is just an ASCII string. A value is restricted to be
+	// US-ASCII characters excluding CTLs, whitespace,
+	// DQUOTE, comma, semicolon, and backslash.
+	s := m.key + keyValueDelimiter + valueEscape(m.value)
 	if len(m.properties) > 0 {
-		s = fmt.Sprintf("%s%s%s", s, propertyDelimiter, m.properties.String())
+		s += propertyDelimiter + m.properties.String()
 	}
 	return s
 }
@@ -554,9 +526,8 @@ func (b Baggage) Len() int {
 	return len(b.list)
 }
 
-// String encodes Baggage into a string compliant with the W3C Baggage
-// specification. The returned string will be invalid if the Baggage contains
-// any invalid list-members.
+// String encodes Baggage into a header string compliant with the W3C Baggage
+// specification.
 func (b Baggage) String() string {
 	members := make([]string, 0, len(b.list))
 	for k, v := range b.list {
@@ -568,3 +539,372 @@ func (b Baggage) String() string {
 	}
 	return strings.Join(members, listDelimiter)
 }
+
+// parsePropertyInternal attempts to decode a Property from the passed string.
+// It follows the spec at https://www.w3.org/TR/baggage/#definition.
+func parsePropertyInternal(s string) (p Property, ok bool) {
+	// For the entire function we will use "   key    =    value  " as an example.
+	// Attempting to parse the key.
+	// First skip spaces at the beginning "<   >key    =    value  " (they could be empty).
+	index := skipSpace(s, 0)
+
+	// Parse the key: "   <key>    =    value  ".
+	keyStart := index
+	keyEnd := index
+	for _, c := range s[keyStart:] {
+		if !validateKeyChar(c) {
+			break
+		}
+		keyEnd++
+	}
+
+	// If we couldn't find any valid key character,
+	// it means the key is either empty or invalid.
+	if keyStart == keyEnd {
+		return
+	}
+
+	// Skip spaces after the key: "   key<    >=    value  ".
+	index = skipSpace(s, keyEnd)
+
+	if index == len(s) {
+		// A key can have no value, like: "   key    ".
+		ok = true
+		p.key = s[keyStart:keyEnd]
+		return
+	}
+
+	// If we have not reached the end and we can't find the '=' delimiter,
+	// it means the property is invalid.
+	if s[index] != keyValueDelimiter[0] {
+		return
+	}
+
+	// Attempting to parse the value.
+	// Match: "   key    =<    >value  ".
+	index = skipSpace(s, index+1)
+
+	// Match the value string: "   key    =    <value>  ".
+	// A valid property can be: "   key    =".
+	// Therefore, we don't have to check if the value is empty.
+	valueStart := index
+	valueEnd := index
+	for _, c := range s[valueStart:] {
+		if !validateValueChar(c) {
+			break
+		}
+		valueEnd++
+	}
+
+	// Skip all trailing whitespaces: "   key    =    value<  >".
+	index = skipSpace(s, valueEnd)
+
+	// If after looking for the value and skipping whitespaces
+	// we have not reached the end, it means the property is
+	// invalid, something like: "   key    =    value  value1".
+	if index != len(s) {
+		return
+	}
+
+	// Decode a percent-encoded value.
+	value, err := url.PathUnescape(s[valueStart:valueEnd])
+	if err != nil {
+		return
+	}
+
+	ok = true
+	p.key = s[keyStart:keyEnd]
+	p.hasValue = true
+
+	p.value = value
+	return
+}
+
+func skipSpace(s string, offset int) int {
+	i := offset
+	for ; i < len(s); i++ {
+		c := s[i]
+		if c != ' ' && c != '\t' {
+			break
+		}
+	}
+	return i
+}
+
+var safeKeyCharset = [utf8.RuneSelf]bool{
+	// 0x23 to 0x27
+	'#':  true,
+	'$':  true,
+	'%':  true,
+	'&':  true,
+	'\'': true,
+
+	// 0x30 to 0x39
+	'0': true,
+	'1': true,
+	'2': true,
+	'3': true,
+	'4': true,
+	'5': true,
+	'6': true,
+	'7': true,
+	'8': true,
+	'9': true,
+
+	// 0x41 to 0x5a
+	'A': true,
+	'B': true,
+	'C': true,
+	'D': true,
+	'E': true,
+	'F': true,
+	'G': true,
+	'H': true,
+	'I': true,
+	'J': true,
+	'K': true,
+	'L': true,
+	'M': true,
+	'N': true,
+	'O': true,
+	'P': true,
+	'Q': true,
+	'R': true,
+	'S': true,
+	'T': true,
+	'U': true,
+	'V': true,
+	'W': true,
+	'X': true,
+	'Y': true,
+	'Z': true,
+
+	// 0x5e to 0x7a
+	'^': true,
+	'_': true,
+	'`': true,
+	'a': true,
+	'b': true,
+	'c': true,
+	'd': true,
+	'e': true,
+	'f': true,
+	'g': true,
+	'h': true,
+	'i': true,
+	'j': true,
+	'k': true,
+	'l': true,
+	'm': true,
+	'n': true,
+	'o': true,
+	'p': true,
+	'q': true,
+	'r': true,
+	's': true,
+	't': true,
+	'u': true,
+	'v': true,
+	'w': true,
+	'x': true,
+	'y': true,
+	'z': true,
+
+	// remainder
+	'!': true,
+	'*': true,
+	'+': true,
+	'-': true,
+	'.': true,
+	'|': true,
+	'~': true,
+}
+
+func validateKey(s string) bool {
+	if len(s) == 0 {
+		return false
+	}
+
+	for _, c := range s {
+		if !validateKeyChar(c) {
+			return false
+		}
+	}
+
+	return true
+}
+
+func validateKeyChar(c int32) bool {
+	return c >= 0 && c < int32(utf8.RuneSelf) && safeKeyCharset[c]
+}
+
+func validateValue(s string) bool {
+	for _, c := range s {
+		if !validateValueChar(c) {
+			return false
+		}
+	}
+
+	return true
+}
+
+var safeValueCharset = [utf8.RuneSelf]bool{
+	'!': true, // 0x21
+
+	// 0x23 to 0x2b
+	'#':  true,
+	'$':  true,
+	'%':  true,
+	'&':  true,
+	'\'': true,
+	'(':  true,
+	')':  true,
+	'*':  true,
+	'+':  true,
+
+	// 0x2d to 0x3a
+	'-': true,
+	'.': true,
+	'/': true,
+	'0': true,
+	'1': true,
+	'2': true,
+	'3': true,
+	'4': true,
+	'5': true,
+	'6': true,
+	'7': true,
+	'8': true,
+	'9': true,
+	':': true,
+
+	// 0x3c to 0x5b
+	'<': true, // 0x3C
+	'=': true, // 0x3D
+	'>': true, // 0x3E
+	'?': true, // 0x3F
+	'@': true, // 0x40
+	'A': true, // 0x41
+	'B': true, // 0x42
+	'C': true, // 0x43
+	'D': true, // 0x44
+	'E': true, // 0x45
+	'F': true, // 0x46
+	'G': true, // 0x47
+	'H': true, // 0x48
+	'I': true, // 0x49
+	'J': true, // 0x4A
+	'K': true, // 0x4B
+	'L': true, // 0x4C
+	'M': true, // 0x4D
+	'N': true, // 0x4E
+	'O': true, // 0x4F
+	'P': true, // 0x50
+	'Q': true, // 0x51
+	'R': true, // 0x52
+	'S': true, // 0x53
+	'T': true, // 0x54
+	'U': true, // 0x55
+	'V': true, // 0x56
+	'W': true, // 0x57
+	'X': true, // 0x58
+	'Y': true, // 0x59
+	'Z': true, // 0x5A
+	'[': true, // 0x5B
+
+	// 0x5d to 0x7e
+	']': true, // 0x5D
+	'^': true, // 0x5E
+	'_': true, // 0x5F
+	'`': true, // 0x60
+	'a': true, // 0x61
+	'b': true, // 0x62
+	'c': true, // 0x63
+	'd': true, // 0x64
+	'e': true, // 0x65
+	'f': true, // 0x66
+	'g': true, // 0x67
+	'h': true, // 0x68
+	'i': true, // 0x69
+	'j': true, // 0x6A
+	'k': true, // 0x6B
+	'l': true, // 0x6C
+	'm': true, // 0x6D
+	'n': true, // 0x6E
+	'o': true, // 0x6F
+	'p': true, // 0x70
+	'q': true, // 0x71
+	'r': true, // 0x72
+	's': true, // 0x73
+	't': true, // 0x74
+	'u': true, // 0x75
+	'v': true, // 0x76
+	'w': true, // 0x77
+	'x': true, // 0x78
+	'y': true, // 0x79
+	'z': true, // 0x7A
+	'{': true, // 0x7B
+	'|': true, // 0x7C
+	'}': true, // 0x7D
+	'~': true, // 0x7E
+}
+
+func validateValueChar(c int32) bool {
+	return c >= 0 && c < int32(utf8.RuneSelf) && safeValueCharset[c]
+}
+
+// valueEscape escapes the string so it can be safely placed inside a baggage value,
+// replacing special characters with %XX sequences as needed.
+//
+// The implementation is based on:
+// https://github.com/golang/go/blob/f6509cf5cdbb5787061b784973782933c47f1782/src/net/url/url.go#L285.
+func valueEscape(s string) string {
+	hexCount := 0
+	for i := 0; i < len(s); i++ {
+		c := s[i]
+		if shouldEscape(c) {
+			hexCount++
+		}
+	}
+
+	if hexCount == 0 {
+		return s
+	}
+
+	var buf [64]byte
+	var t []byte
+
+	required := len(s) + 2*hexCount
+	if required <= len(buf) {
+		t = buf[:required]
+	} else {
+		t = make([]byte, required)
+	}
+
+	j := 0
+	for i := 0; i < len(s); i++ {
+		c := s[i]
+		if shouldEscape(s[i]) {
+			const upperhex = "0123456789ABCDEF"
+			t[j] = '%'
+			t[j+1] = upperhex[c>>4]
+			t[j+2] = upperhex[c&15]
+			j += 3
+		} else {
+			t[j] = c
+			j++
+		}
+	}
+
+	return string(t)
+}
+
+// shouldEscape returns true if the specified byte should be escaped when
+// appearing in a baggage value string.
+func shouldEscape(c byte) bool {
+	if c == '%' {
+		// The percent character must be encoded so that percent-encoding can work.
+		return true
+	}
+	return !validateValueChar(int32(c))
+}
diff --git a/vendor/go.opentelemetry.io/otel/baggage/context.go b/vendor/go.opentelemetry.io/otel/baggage/context.go
index 24b34b75..a572461a 100644
--- a/vendor/go.opentelemetry.io/otel/baggage/context.go
+++ b/vendor/go.opentelemetry.io/otel/baggage/context.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package baggage // import "go.opentelemetry.io/otel/baggage"
 
diff --git a/vendor/go.opentelemetry.io/otel/baggage/doc.go b/vendor/go.opentelemetry.io/otel/baggage/doc.go
index 4545100d..b51d87ca 100644
--- a/vendor/go.opentelemetry.io/otel/baggage/doc.go
+++ b/vendor/go.opentelemetry.io/otel/baggage/doc.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 /*
 Package baggage provides functionality for storing and retrieving
diff --git a/vendor/go.opentelemetry.io/otel/codes/README.md b/vendor/go.opentelemetry.io/otel/codes/README.md
new file mode 100644
index 00000000..24c52b38
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/codes/README.md
@@ -0,0 +1,3 @@
+# Codes
+
+[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/codes)](https://pkg.go.dev/go.opentelemetry.io/otel/codes)
diff --git a/vendor/go.opentelemetry.io/otel/codes/codes.go b/vendor/go.opentelemetry.io/otel/codes/codes.go
index 587ebae4..df29d96a 100644
--- a/vendor/go.opentelemetry.io/otel/codes/codes.go
+++ b/vendor/go.opentelemetry.io/otel/codes/codes.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package codes // import "go.opentelemetry.io/otel/codes"
 
diff --git a/vendor/go.opentelemetry.io/otel/codes/doc.go b/vendor/go.opentelemetry.io/otel/codes/doc.go
index df3e0f1b..ee8db448 100644
--- a/vendor/go.opentelemetry.io/otel/codes/doc.go
+++ b/vendor/go.opentelemetry.io/otel/codes/doc.go
@@ -1,21 +1,10 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 /*
 Package codes defines the canonical error codes used by OpenTelemetry.
 
 It conforms to [the OpenTelemetry
-specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#statuscanonicalcode).
+specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/api.md#set-status).
 */
 package codes // import "go.opentelemetry.io/otel/codes"
diff --git a/vendor/go.opentelemetry.io/otel/doc.go b/vendor/go.opentelemetry.io/otel/doc.go
index daa36c89..441c5950 100644
--- a/vendor/go.opentelemetry.io/otel/doc.go
+++ b/vendor/go.opentelemetry.io/otel/doc.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 /*
 Package otel provides global access to the OpenTelemetry API. The subpackages of
@@ -22,7 +11,7 @@ transmitted anywhere. An implementation of the OpenTelemetry SDK, like the
 default SDK implementation (go.opentelemetry.io/otel/sdk), and associated
 exporters are used to process and transport this data.
 
-To read the getting started guide, see https://opentelemetry.io/docs/go/getting-started/.
+To read the getting started guide, see https://opentelemetry.io/docs/languages/go/getting-started/.
 
 To read more about tracing, see go.opentelemetry.io/otel/trace.
 
diff --git a/vendor/go.opentelemetry.io/otel/error_handler.go b/vendor/go.opentelemetry.io/otel/error_handler.go
index 72fad854..67414c71 100644
--- a/vendor/go.opentelemetry.io/otel/error_handler.go
+++ b/vendor/go.opentelemetry.io/otel/error_handler.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package otel // import "go.opentelemetry.io/otel"
 
diff --git a/vendor/go.opentelemetry.io/otel/get_main_pkgs.sh b/vendor/go.opentelemetry.io/otel/get_main_pkgs.sh
index 9a58fb1d..93e80ea3 100644
--- a/vendor/go.opentelemetry.io/otel/get_main_pkgs.sh
+++ b/vendor/go.opentelemetry.io/otel/get_main_pkgs.sh
@@ -1,18 +1,7 @@
 #!/usr/bin/env bash
 
 # Copyright The OpenTelemetry 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.
+# SPDX-License-Identifier: Apache-2.0
 
 set -euo pipefail
 
diff --git a/vendor/go.opentelemetry.io/otel/handler.go b/vendor/go.opentelemetry.io/otel/handler.go
index ecd363ab..07623b67 100644
--- a/vendor/go.opentelemetry.io/otel/handler.go
+++ b/vendor/go.opentelemetry.io/otel/handler.go
@@ -1,71 +1,14 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package otel // import "go.opentelemetry.io/otel"
 
 import (
-	"log"
-	"os"
-	"sync/atomic"
-	"unsafe"
-)
-
-var (
-	// globalErrorHandler provides an ErrorHandler that can be used
-	// throughout an OpenTelemetry instrumented project. When a user
-	// specified ErrorHandler is registered (`SetErrorHandler`) all calls to
-	// `Handle` and will be delegated to the registered ErrorHandler.
-	globalErrorHandler = defaultErrorHandler()
-
-	// Compile-time check that delegator implements ErrorHandler.
-	_ ErrorHandler = (*delegator)(nil)
-	// Compile-time check that errLogger implements ErrorHandler.
-	_ ErrorHandler = (*errLogger)(nil)
+	"go.opentelemetry.io/otel/internal/global"
 )
 
-type delegator struct {
-	delegate unsafe.Pointer
-}
-
-func (d *delegator) Handle(err error) {
-	d.getDelegate().Handle(err)
-}
-
-func (d *delegator) getDelegate() ErrorHandler {
-	return *(*ErrorHandler)(atomic.LoadPointer(&d.delegate))
-}
-
-// setDelegate sets the ErrorHandler delegate.
-func (d *delegator) setDelegate(eh ErrorHandler) {
-	atomic.StorePointer(&d.delegate, unsafe.Pointer(&eh))
-}
-
-func defaultErrorHandler() *delegator {
-	d := &delegator{}
-	d.setDelegate(&errLogger{l: log.New(os.Stderr, "", log.LstdFlags)})
-	return d
-}
-
-// errLogger logs errors if no delegate is set, otherwise they are delegated.
-type errLogger struct {
-	l *log.Logger
-}
-
-// Handle logs err if no delegate is set, otherwise it is delegated.
-func (h *errLogger) Handle(err error) {
-	h.l.Print(err)
-}
+// Compile-time check global.ErrDelegator implements ErrorHandler.
+var _ ErrorHandler = (*global.ErrDelegator)(nil)
 
 // GetErrorHandler returns the global ErrorHandler instance.
 //
@@ -76,9 +19,7 @@ func (h *errLogger) Handle(err error) {
 //
 // Subsequent calls to SetErrorHandler after the first will not forward errors
 // to the new ErrorHandler for prior returned instances.
-func GetErrorHandler() ErrorHandler {
-	return globalErrorHandler
-}
+func GetErrorHandler() ErrorHandler { return global.GetErrorHandler() }
 
 // SetErrorHandler sets the global ErrorHandler to h.
 //
@@ -86,11 +27,7 @@ func GetErrorHandler() ErrorHandler {
 // GetErrorHandler will send errors to h instead of the default logging
 // ErrorHandler. Subsequent calls will set the global ErrorHandler, but not
 // delegate errors to h.
-func SetErrorHandler(h ErrorHandler) {
-	globalErrorHandler.setDelegate(h)
-}
+func SetErrorHandler(h ErrorHandler) { global.SetErrorHandler(h) }
 
-// Handle is a convenience function for ErrorHandler().Handle(err).
-func Handle(err error) {
-	GetErrorHandler().Handle(err)
-}
+// Handle is a convenience function for GetErrorHandler().Handle(err).
+func Handle(err error) { global.GetErrorHandler().Handle(err) }
diff --git a/vendor/go.opentelemetry.io/otel/internal/attribute/attribute.go b/vendor/go.opentelemetry.io/otel/internal/attribute/attribute.go
index 622c3ee3..822d8479 100644
--- a/vendor/go.opentelemetry.io/otel/internal/attribute/attribute.go
+++ b/vendor/go.opentelemetry.io/otel/internal/attribute/attribute.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 /*
 Package attribute provide several helper functions for some commonly used
@@ -25,33 +14,33 @@ import (
 // BoolSliceValue converts a bool slice into an array with same elements as slice.
 func BoolSliceValue(v []bool) interface{} {
 	var zero bool
-	cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero)))
-	copy(cp.Elem().Slice(0, len(v)).Interface().([]bool), v)
-	return cp.Elem().Interface()
+	cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero))).Elem()
+	reflect.Copy(cp, reflect.ValueOf(v))
+	return cp.Interface()
 }
 
 // Int64SliceValue converts an int64 slice into an array with same elements as slice.
 func Int64SliceValue(v []int64) interface{} {
 	var zero int64
-	cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero)))
-	copy(cp.Elem().Slice(0, len(v)).Interface().([]int64), v)
-	return cp.Elem().Interface()
+	cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero))).Elem()
+	reflect.Copy(cp, reflect.ValueOf(v))
+	return cp.Interface()
 }
 
 // Float64SliceValue converts a float64 slice into an array with same elements as slice.
 func Float64SliceValue(v []float64) interface{} {
 	var zero float64
-	cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero)))
-	copy(cp.Elem().Slice(0, len(v)).Interface().([]float64), v)
-	return cp.Elem().Interface()
+	cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero))).Elem()
+	reflect.Copy(cp, reflect.ValueOf(v))
+	return cp.Interface()
 }
 
 // StringSliceValue converts a string slice into an array with same elements as slice.
 func StringSliceValue(v []string) interface{} {
 	var zero string
-	cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero)))
-	copy(cp.Elem().Slice(0, len(v)).Interface().([]string), v)
-	return cp.Elem().Interface()
+	cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero))).Elem()
+	reflect.Copy(cp, reflect.ValueOf(v))
+	return cp.Interface()
 }
 
 // AsBoolSlice converts a bool array into a slice into with same elements as array.
diff --git a/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go b/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go
index b96e5408..b4f85f44 100644
--- a/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go
+++ b/vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 /*
 Package baggage provides base types and functionality to store and retrieve
diff --git a/vendor/go.opentelemetry.io/otel/internal/baggage/context.go b/vendor/go.opentelemetry.io/otel/internal/baggage/context.go
index 4469700d..3aea9c49 100644
--- a/vendor/go.opentelemetry.io/otel/internal/baggage/context.go
+++ b/vendor/go.opentelemetry.io/otel/internal/baggage/context.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package baggage // import "go.opentelemetry.io/otel/internal/baggage"
 
diff --git a/vendor/go.opentelemetry.io/otel/internal/gen.go b/vendor/go.opentelemetry.io/otel/internal/gen.go
new file mode 100644
index 00000000..4259f032
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/internal/gen.go
@@ -0,0 +1,18 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package internal // import "go.opentelemetry.io/otel/internal"
+
+//go:generate gotmpl --body=./shared/matchers/expectation.go.tmpl "--data={}" --out=matchers/expectation.go
+//go:generate gotmpl --body=./shared/matchers/expecter.go.tmpl "--data={}" --out=matchers/expecter.go
+//go:generate gotmpl --body=./shared/matchers/temporal_matcher.go.tmpl "--data={}" --out=matchers/temporal_matcher.go
+
+//go:generate gotmpl --body=./shared/internaltest/alignment.go.tmpl "--data={}" --out=internaltest/alignment.go
+//go:generate gotmpl --body=./shared/internaltest/env.go.tmpl "--data={}" --out=internaltest/env.go
+//go:generate gotmpl --body=./shared/internaltest/env_test.go.tmpl "--data={}" --out=internaltest/env_test.go
+//go:generate gotmpl --body=./shared/internaltest/errors.go.tmpl "--data={}" --out=internaltest/errors.go
+//go:generate gotmpl --body=./shared/internaltest/harness.go.tmpl "--data={\"matchersImportPath\": \"go.opentelemetry.io/otel/internal/matchers\"}" --out=internaltest/harness.go
+//go:generate gotmpl --body=./shared/internaltest/text_map_carrier.go.tmpl "--data={}" --out=internaltest/text_map_carrier.go
+//go:generate gotmpl --body=./shared/internaltest/text_map_carrier_test.go.tmpl "--data={}" --out=internaltest/text_map_carrier_test.go
+//go:generate gotmpl --body=./shared/internaltest/text_map_propagator.go.tmpl "--data={}" --out=internaltest/text_map_propagator.go
+//go:generate gotmpl --body=./shared/internaltest/text_map_propagator_test.go.tmpl "--data={}" --out=internaltest/text_map_propagator_test.go
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/handler.go b/vendor/go.opentelemetry.io/otel/internal/global/handler.go
new file mode 100644
index 00000000..c657ff8e
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/internal/global/handler.go
@@ -0,0 +1,36 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package global // import "go.opentelemetry.io/otel/internal/global"
+
+import (
+	"log"
+	"sync/atomic"
+)
+
+// ErrorHandler handles irremediable events.
+type ErrorHandler interface {
+	// Handle handles any error deemed irremediable by an OpenTelemetry
+	// component.
+	Handle(error)
+}
+
+type ErrDelegator struct {
+	delegate atomic.Pointer[ErrorHandler]
+}
+
+// Compile-time check that delegator implements ErrorHandler.
+var _ ErrorHandler = (*ErrDelegator)(nil)
+
+func (d *ErrDelegator) Handle(err error) {
+	if eh := d.delegate.Load(); eh != nil {
+		(*eh).Handle(err)
+		return
+	}
+	log.Print(err)
+}
+
+// setDelegate sets the ErrorHandler delegate.
+func (d *ErrDelegator) setDelegate(eh ErrorHandler) {
+	d.delegate.Store(&eh)
+}
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/instruments.go b/vendor/go.opentelemetry.io/otel/internal/global/instruments.go
new file mode 100644
index 00000000..3a0cc42f
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/internal/global/instruments.go
@@ -0,0 +1,412 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package global // import "go.opentelemetry.io/otel/internal/global"
+
+import (
+	"context"
+	"sync/atomic"
+
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/metric/embedded"
+)
+
+// unwrapper unwraps to return the underlying instrument implementation.
+type unwrapper interface {
+	Unwrap() metric.Observable
+}
+
+type afCounter struct {
+	embedded.Float64ObservableCounter
+	metric.Float64Observable
+
+	name string
+	opts []metric.Float64ObservableCounterOption
+
+	delegate atomic.Value // metric.Float64ObservableCounter
+}
+
+var (
+	_ unwrapper                       = (*afCounter)(nil)
+	_ metric.Float64ObservableCounter = (*afCounter)(nil)
+)
+
+func (i *afCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64ObservableCounter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *afCounter) Unwrap() metric.Observable {
+	if ctr := i.delegate.Load(); ctr != nil {
+		return ctr.(metric.Float64ObservableCounter)
+	}
+	return nil
+}
+
+type afUpDownCounter struct {
+	embedded.Float64ObservableUpDownCounter
+	metric.Float64Observable
+
+	name string
+	opts []metric.Float64ObservableUpDownCounterOption
+
+	delegate atomic.Value // metric.Float64ObservableUpDownCounter
+}
+
+var (
+	_ unwrapper                             = (*afUpDownCounter)(nil)
+	_ metric.Float64ObservableUpDownCounter = (*afUpDownCounter)(nil)
+)
+
+func (i *afUpDownCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64ObservableUpDownCounter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *afUpDownCounter) Unwrap() metric.Observable {
+	if ctr := i.delegate.Load(); ctr != nil {
+		return ctr.(metric.Float64ObservableUpDownCounter)
+	}
+	return nil
+}
+
+type afGauge struct {
+	embedded.Float64ObservableGauge
+	metric.Float64Observable
+
+	name string
+	opts []metric.Float64ObservableGaugeOption
+
+	delegate atomic.Value // metric.Float64ObservableGauge
+}
+
+var (
+	_ unwrapper                     = (*afGauge)(nil)
+	_ metric.Float64ObservableGauge = (*afGauge)(nil)
+)
+
+func (i *afGauge) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64ObservableGauge(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *afGauge) Unwrap() metric.Observable {
+	if ctr := i.delegate.Load(); ctr != nil {
+		return ctr.(metric.Float64ObservableGauge)
+	}
+	return nil
+}
+
+type aiCounter struct {
+	embedded.Int64ObservableCounter
+	metric.Int64Observable
+
+	name string
+	opts []metric.Int64ObservableCounterOption
+
+	delegate atomic.Value // metric.Int64ObservableCounter
+}
+
+var (
+	_ unwrapper                     = (*aiCounter)(nil)
+	_ metric.Int64ObservableCounter = (*aiCounter)(nil)
+)
+
+func (i *aiCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64ObservableCounter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *aiCounter) Unwrap() metric.Observable {
+	if ctr := i.delegate.Load(); ctr != nil {
+		return ctr.(metric.Int64ObservableCounter)
+	}
+	return nil
+}
+
+type aiUpDownCounter struct {
+	embedded.Int64ObservableUpDownCounter
+	metric.Int64Observable
+
+	name string
+	opts []metric.Int64ObservableUpDownCounterOption
+
+	delegate atomic.Value // metric.Int64ObservableUpDownCounter
+}
+
+var (
+	_ unwrapper                           = (*aiUpDownCounter)(nil)
+	_ metric.Int64ObservableUpDownCounter = (*aiUpDownCounter)(nil)
+)
+
+func (i *aiUpDownCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64ObservableUpDownCounter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *aiUpDownCounter) Unwrap() metric.Observable {
+	if ctr := i.delegate.Load(); ctr != nil {
+		return ctr.(metric.Int64ObservableUpDownCounter)
+	}
+	return nil
+}
+
+type aiGauge struct {
+	embedded.Int64ObservableGauge
+	metric.Int64Observable
+
+	name string
+	opts []metric.Int64ObservableGaugeOption
+
+	delegate atomic.Value // metric.Int64ObservableGauge
+}
+
+var (
+	_ unwrapper                   = (*aiGauge)(nil)
+	_ metric.Int64ObservableGauge = (*aiGauge)(nil)
+)
+
+func (i *aiGauge) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64ObservableGauge(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *aiGauge) Unwrap() metric.Observable {
+	if ctr := i.delegate.Load(); ctr != nil {
+		return ctr.(metric.Int64ObservableGauge)
+	}
+	return nil
+}
+
+// Sync Instruments.
+type sfCounter struct {
+	embedded.Float64Counter
+
+	name string
+	opts []metric.Float64CounterOption
+
+	delegate atomic.Value // metric.Float64Counter
+}
+
+var _ metric.Float64Counter = (*sfCounter)(nil)
+
+func (i *sfCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64Counter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *sfCounter) Add(ctx context.Context, incr float64, opts ...metric.AddOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Float64Counter).Add(ctx, incr, opts...)
+	}
+}
+
+type sfUpDownCounter struct {
+	embedded.Float64UpDownCounter
+
+	name string
+	opts []metric.Float64UpDownCounterOption
+
+	delegate atomic.Value // metric.Float64UpDownCounter
+}
+
+var _ metric.Float64UpDownCounter = (*sfUpDownCounter)(nil)
+
+func (i *sfUpDownCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64UpDownCounter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *sfUpDownCounter) Add(ctx context.Context, incr float64, opts ...metric.AddOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Float64UpDownCounter).Add(ctx, incr, opts...)
+	}
+}
+
+type sfHistogram struct {
+	embedded.Float64Histogram
+
+	name string
+	opts []metric.Float64HistogramOption
+
+	delegate atomic.Value // metric.Float64Histogram
+}
+
+var _ metric.Float64Histogram = (*sfHistogram)(nil)
+
+func (i *sfHistogram) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64Histogram(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *sfHistogram) Record(ctx context.Context, x float64, opts ...metric.RecordOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Float64Histogram).Record(ctx, x, opts...)
+	}
+}
+
+type sfGauge struct {
+	embedded.Float64Gauge
+
+	name string
+	opts []metric.Float64GaugeOption
+
+	delegate atomic.Value // metric.Float64Gauge
+}
+
+var _ metric.Float64Gauge = (*sfGauge)(nil)
+
+func (i *sfGauge) setDelegate(m metric.Meter) {
+	ctr, err := m.Float64Gauge(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *sfGauge) Record(ctx context.Context, x float64, opts ...metric.RecordOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Float64Gauge).Record(ctx, x, opts...)
+	}
+}
+
+type siCounter struct {
+	embedded.Int64Counter
+
+	name string
+	opts []metric.Int64CounterOption
+
+	delegate atomic.Value // metric.Int64Counter
+}
+
+var _ metric.Int64Counter = (*siCounter)(nil)
+
+func (i *siCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64Counter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *siCounter) Add(ctx context.Context, x int64, opts ...metric.AddOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Int64Counter).Add(ctx, x, opts...)
+	}
+}
+
+type siUpDownCounter struct {
+	embedded.Int64UpDownCounter
+
+	name string
+	opts []metric.Int64UpDownCounterOption
+
+	delegate atomic.Value // metric.Int64UpDownCounter
+}
+
+var _ metric.Int64UpDownCounter = (*siUpDownCounter)(nil)
+
+func (i *siUpDownCounter) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64UpDownCounter(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *siUpDownCounter) Add(ctx context.Context, x int64, opts ...metric.AddOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Int64UpDownCounter).Add(ctx, x, opts...)
+	}
+}
+
+type siHistogram struct {
+	embedded.Int64Histogram
+
+	name string
+	opts []metric.Int64HistogramOption
+
+	delegate atomic.Value // metric.Int64Histogram
+}
+
+var _ metric.Int64Histogram = (*siHistogram)(nil)
+
+func (i *siHistogram) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64Histogram(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *siHistogram) Record(ctx context.Context, x int64, opts ...metric.RecordOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Int64Histogram).Record(ctx, x, opts...)
+	}
+}
+
+type siGauge struct {
+	embedded.Int64Gauge
+
+	name string
+	opts []metric.Int64GaugeOption
+
+	delegate atomic.Value // metric.Int64Gauge
+}
+
+var _ metric.Int64Gauge = (*siGauge)(nil)
+
+func (i *siGauge) setDelegate(m metric.Meter) {
+	ctr, err := m.Int64Gauge(i.name, i.opts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+		return
+	}
+	i.delegate.Store(ctr)
+}
+
+func (i *siGauge) Record(ctx context.Context, x int64, opts ...metric.RecordOption) {
+	if ctr := i.delegate.Load(); ctr != nil {
+		ctr.(metric.Int64Gauge).Record(ctx, x, opts...)
+	}
+}
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go b/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go
index 293c0896..adbca7d3 100644
--- a/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go
+++ b/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package global // import "go.opentelemetry.io/otel/internal/global"
 
@@ -18,46 +7,56 @@ import (
 	"log"
 	"os"
 	"sync/atomic"
-	"unsafe"
 
 	"github.com/go-logr/logr"
 	"github.com/go-logr/stdr"
 )
 
-// globalLogger is the logging interface used within the otel api and sdk provide deatails of the internals.
+// globalLogger holds a reference to the [logr.Logger] used within
+// go.opentelemetry.io/otel.
 //
 // The default logger uses stdr which is backed by the standard `log.Logger`
 // interface. This logger will only show messages at the Error Level.
-var globalLogger unsafe.Pointer
+var globalLogger = func() *atomic.Pointer[logr.Logger] {
+	l := stdr.New(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile))
 
-func init() {
-	SetLogger(stdr.New(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile)))
-}
+	p := new(atomic.Pointer[logr.Logger])
+	p.Store(&l)
+	return p
+}()
 
-// SetLogger overrides the globalLogger with l.
+// SetLogger sets the global Logger to l.
 //
-// To see Info messages use a logger with `l.V(1).Enabled() == true`
-// To see Debug messages use a logger with `l.V(5).Enabled() == true`.
+// To see Warn messages use a logger with `l.V(1).Enabled() == true`
+// To see Info messages use a logger with `l.V(4).Enabled() == true`
+// To see Debug messages use a logger with `l.V(8).Enabled() == true`.
 func SetLogger(l logr.Logger) {
-	atomic.StorePointer(&globalLogger, unsafe.Pointer(&l))
+	globalLogger.Store(&l)
 }
 
-func getLogger() logr.Logger {
-	return *(*logr.Logger)(atomic.LoadPointer(&globalLogger))
+// GetLogger returns the global logger.
+func GetLogger() logr.Logger {
+	return *globalLogger.Load()
 }
 
 // Info prints messages about the general state of the API or SDK.
-// This should usually be less then 5 messages a minute.
+// This should usually be less than 5 messages a minute.
 func Info(msg string, keysAndValues ...interface{}) {
-	getLogger().V(1).Info(msg, keysAndValues...)
+	GetLogger().V(4).Info(msg, keysAndValues...)
 }
 
 // Error prints messages about exceptional states of the API or SDK.
 func Error(err error, msg string, keysAndValues ...interface{}) {
-	getLogger().Error(err, msg, keysAndValues...)
+	GetLogger().Error(err, msg, keysAndValues...)
 }
 
 // Debug prints messages about all internal changes in the API or SDK.
 func Debug(msg string, keysAndValues ...interface{}) {
-	getLogger().V(5).Info(msg, keysAndValues...)
+	GetLogger().V(8).Info(msg, keysAndValues...)
+}
+
+// Warn prints messages about warnings in the API or SDK.
+// Not an error but is likely more important than an informational event.
+func Warn(msg string, keysAndValues ...interface{}) {
+	GetLogger().V(1).Info(msg, keysAndValues...)
 }
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/meter.go b/vendor/go.opentelemetry.io/otel/internal/global/meter.go
new file mode 100644
index 00000000..cfd1df9b
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/internal/global/meter.go
@@ -0,0 +1,368 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package global // import "go.opentelemetry.io/otel/internal/global"
+
+import (
+	"container/list"
+	"sync"
+	"sync/atomic"
+
+	"go.opentelemetry.io/otel/metric"
+	"go.opentelemetry.io/otel/metric/embedded"
+)
+
+// meterProvider is a placeholder for a configured SDK MeterProvider.
+//
+// All MeterProvider functionality is forwarded to a delegate once
+// configured.
+type meterProvider struct {
+	embedded.MeterProvider
+
+	mtx    sync.Mutex
+	meters map[il]*meter
+
+	delegate metric.MeterProvider
+}
+
+// setDelegate configures p to delegate all MeterProvider functionality to
+// provider.
+//
+// All Meters provided prior to this function call are switched out to be
+// Meters provided by provider. All instruments and callbacks are recreated and
+// delegated.
+//
+// It is guaranteed by the caller that this happens only once.
+func (p *meterProvider) setDelegate(provider metric.MeterProvider) {
+	p.mtx.Lock()
+	defer p.mtx.Unlock()
+
+	p.delegate = provider
+
+	if len(p.meters) == 0 {
+		return
+	}
+
+	for _, meter := range p.meters {
+		meter.setDelegate(provider)
+	}
+
+	p.meters = nil
+}
+
+// Meter implements MeterProvider.
+func (p *meterProvider) Meter(name string, opts ...metric.MeterOption) metric.Meter {
+	p.mtx.Lock()
+	defer p.mtx.Unlock()
+
+	if p.delegate != nil {
+		return p.delegate.Meter(name, opts...)
+	}
+
+	// At this moment it is guaranteed that no sdk is installed, save the meter in the meters map.
+
+	c := metric.NewMeterConfig(opts...)
+	key := il{
+		name:    name,
+		version: c.InstrumentationVersion(),
+		schema:  c.SchemaURL(),
+	}
+
+	if p.meters == nil {
+		p.meters = make(map[il]*meter)
+	}
+
+	if val, ok := p.meters[key]; ok {
+		return val
+	}
+
+	t := &meter{name: name, opts: opts}
+	p.meters[key] = t
+	return t
+}
+
+// meter is a placeholder for a metric.Meter.
+//
+// All Meter functionality is forwarded to a delegate once configured.
+// Otherwise, all functionality is forwarded to a NoopMeter.
+type meter struct {
+	embedded.Meter
+
+	name string
+	opts []metric.MeterOption
+
+	mtx         sync.Mutex
+	instruments []delegatedInstrument
+
+	registry list.List
+
+	delegate atomic.Value // metric.Meter
+}
+
+type delegatedInstrument interface {
+	setDelegate(metric.Meter)
+}
+
+// setDelegate configures m to delegate all Meter functionality to Meters
+// created by provider.
+//
+// All subsequent calls to the Meter methods will be passed to the delegate.
+//
+// It is guaranteed by the caller that this happens only once.
+func (m *meter) setDelegate(provider metric.MeterProvider) {
+	meter := provider.Meter(m.name, m.opts...)
+	m.delegate.Store(meter)
+
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	for _, inst := range m.instruments {
+		inst.setDelegate(meter)
+	}
+
+	var n *list.Element
+	for e := m.registry.Front(); e != nil; e = n {
+		r := e.Value.(*registration)
+		r.setDelegate(meter)
+		n = e.Next()
+		m.registry.Remove(e)
+	}
+
+	m.instruments = nil
+	m.registry.Init()
+}
+
+func (m *meter) Int64Counter(name string, options ...metric.Int64CounterOption) (metric.Int64Counter, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Int64Counter(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &siCounter{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+func (m *meter) Int64UpDownCounter(name string, options ...metric.Int64UpDownCounterOption) (metric.Int64UpDownCounter, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Int64UpDownCounter(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &siUpDownCounter{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+func (m *meter) Int64Histogram(name string, options ...metric.Int64HistogramOption) (metric.Int64Histogram, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Int64Histogram(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &siHistogram{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+func (m *meter) Int64Gauge(name string, options ...metric.Int64GaugeOption) (metric.Int64Gauge, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Int64Gauge(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &siGauge{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+func (m *meter) Int64ObservableCounter(name string, options ...metric.Int64ObservableCounterOption) (metric.Int64ObservableCounter, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Int64ObservableCounter(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &aiCounter{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+func (m *meter) Int64ObservableUpDownCounter(name string, options ...metric.Int64ObservableUpDownCounterOption) (metric.Int64ObservableUpDownCounter, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Int64ObservableUpDownCounter(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &aiUpDownCounter{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+func (m *meter) Int64ObservableGauge(name string, options ...metric.Int64ObservableGaugeOption) (metric.Int64ObservableGauge, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Int64ObservableGauge(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &aiGauge{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+func (m *meter) Float64Counter(name string, options ...metric.Float64CounterOption) (metric.Float64Counter, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Float64Counter(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &sfCounter{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+func (m *meter) Float64UpDownCounter(name string, options ...metric.Float64UpDownCounterOption) (metric.Float64UpDownCounter, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Float64UpDownCounter(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &sfUpDownCounter{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+func (m *meter) Float64Histogram(name string, options ...metric.Float64HistogramOption) (metric.Float64Histogram, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Float64Histogram(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &sfHistogram{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+func (m *meter) Float64Gauge(name string, options ...metric.Float64GaugeOption) (metric.Float64Gauge, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Float64Gauge(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &sfGauge{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+func (m *meter) Float64ObservableCounter(name string, options ...metric.Float64ObservableCounterOption) (metric.Float64ObservableCounter, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Float64ObservableCounter(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &afCounter{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+func (m *meter) Float64ObservableUpDownCounter(name string, options ...metric.Float64ObservableUpDownCounterOption) (metric.Float64ObservableUpDownCounter, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Float64ObservableUpDownCounter(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &afUpDownCounter{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+func (m *meter) Float64ObservableGauge(name string, options ...metric.Float64ObservableGaugeOption) (metric.Float64ObservableGauge, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		return del.Float64ObservableGauge(name, options...)
+	}
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+	i := &afGauge{name: name, opts: options}
+	m.instruments = append(m.instruments, i)
+	return i, nil
+}
+
+// RegisterCallback captures the function that will be called during Collect.
+func (m *meter) RegisterCallback(f metric.Callback, insts ...metric.Observable) (metric.Registration, error) {
+	if del, ok := m.delegate.Load().(metric.Meter); ok {
+		insts = unwrapInstruments(insts)
+		return del.RegisterCallback(f, insts...)
+	}
+
+	m.mtx.Lock()
+	defer m.mtx.Unlock()
+
+	reg := &registration{instruments: insts, function: f}
+	e := m.registry.PushBack(reg)
+	reg.unreg = func() error {
+		m.mtx.Lock()
+		_ = m.registry.Remove(e)
+		m.mtx.Unlock()
+		return nil
+	}
+	return reg, nil
+}
+
+type wrapped interface {
+	unwrap() metric.Observable
+}
+
+func unwrapInstruments(instruments []metric.Observable) []metric.Observable {
+	out := make([]metric.Observable, 0, len(instruments))
+
+	for _, inst := range instruments {
+		if in, ok := inst.(wrapped); ok {
+			out = append(out, in.unwrap())
+		} else {
+			out = append(out, inst)
+		}
+	}
+
+	return out
+}
+
+type registration struct {
+	embedded.Registration
+
+	instruments []metric.Observable
+	function    metric.Callback
+
+	unreg   func() error
+	unregMu sync.Mutex
+}
+
+func (c *registration) setDelegate(m metric.Meter) {
+	insts := unwrapInstruments(c.instruments)
+
+	c.unregMu.Lock()
+	defer c.unregMu.Unlock()
+
+	if c.unreg == nil {
+		// Unregister already called.
+		return
+	}
+
+	reg, err := m.RegisterCallback(c.function, insts...)
+	if err != nil {
+		GetErrorHandler().Handle(err)
+	}
+
+	c.unreg = reg.Unregister
+}
+
+func (c *registration) Unregister() error {
+	c.unregMu.Lock()
+	defer c.unregMu.Unlock()
+	if c.unreg == nil {
+		// Unregister already called.
+		return nil
+	}
+
+	var err error
+	err, c.unreg = c.unreg(), nil
+	return err
+}
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/propagator.go b/vendor/go.opentelemetry.io/otel/internal/global/propagator.go
index 06bac35c..38560ff9 100644
--- a/vendor/go.opentelemetry.io/otel/internal/global/propagator.go
+++ b/vendor/go.opentelemetry.io/otel/internal/global/propagator.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package global // import "go.opentelemetry.io/otel/internal/global"
 
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/state.go b/vendor/go.opentelemetry.io/otel/internal/global/state.go
index 1ad38f82..204ea142 100644
--- a/vendor/go.opentelemetry.io/otel/internal/global/state.go
+++ b/vendor/go.opentelemetry.io/otel/internal/global/state.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package global // import "go.opentelemetry.io/otel/internal/global"
 
@@ -19,11 +8,16 @@ import (
 	"sync"
 	"sync/atomic"
 
+	"go.opentelemetry.io/otel/metric"
 	"go.opentelemetry.io/otel/propagation"
 	"go.opentelemetry.io/otel/trace"
 )
 
 type (
+	errorHandlerHolder struct {
+		eh ErrorHandler
+	}
+
 	tracerProviderHolder struct {
 		tp trace.TracerProvider
 	}
@@ -31,16 +25,66 @@ type (
 	propagatorsHolder struct {
 		tm propagation.TextMapPropagator
 	}
+
+	meterProviderHolder struct {
+		mp metric.MeterProvider
+	}
 )
 
 var (
-	globalTracer      = defaultTracerValue()
-	globalPropagators = defaultPropagatorsValue()
+	globalErrorHandler  = defaultErrorHandler()
+	globalTracer        = defaultTracerValue()
+	globalPropagators   = defaultPropagatorsValue()
+	globalMeterProvider = defaultMeterProvider()
 
+	delegateErrorHandlerOnce      sync.Once
 	delegateTraceOnce             sync.Once
 	delegateTextMapPropagatorOnce sync.Once
+	delegateMeterOnce             sync.Once
 )
 
+// GetErrorHandler returns the global ErrorHandler instance.
+//
+// The default ErrorHandler instance returned will log all errors to STDERR
+// until an override ErrorHandler is set with SetErrorHandler. All
+// ErrorHandler returned prior to this will automatically forward errors to
+// the set instance instead of logging.
+//
+// Subsequent calls to SetErrorHandler after the first will not forward errors
+// to the new ErrorHandler for prior returned instances.
+func GetErrorHandler() ErrorHandler {
+	return globalErrorHandler.Load().(errorHandlerHolder).eh
+}
+
+// SetErrorHandler sets the global ErrorHandler to h.
+//
+// The first time this is called all ErrorHandler previously returned from
+// GetErrorHandler will send errors to h instead of the default logging
+// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not
+// delegate errors to h.
+func SetErrorHandler(h ErrorHandler) {
+	current := GetErrorHandler()
+
+	if _, cOk := current.(*ErrDelegator); cOk {
+		if _, ehOk := h.(*ErrDelegator); ehOk && current == h {
+			// Do not assign to the delegate of the default ErrDelegator to be
+			// itself.
+			Error(
+				errors.New("no ErrorHandler delegate configured"),
+				"ErrorHandler remains its current value.",
+			)
+			return
+		}
+	}
+
+	delegateErrorHandlerOnce.Do(func() {
+		if def, ok := current.(*ErrDelegator); ok {
+			def.setDelegate(h)
+		}
+	})
+	globalErrorHandler.Store(errorHandlerHolder{eh: h})
+}
+
 // TracerProvider is the internal implementation for global.TracerProvider.
 func TracerProvider() trace.TracerProvider {
 	return globalTracer.Load().(tracerProviderHolder).tp
@@ -56,7 +100,7 @@ func SetTracerProvider(tp trace.TracerProvider) {
 			// to itself.
 			Error(
 				errors.New("no delegate configured in tracer provider"),
-				"Setting tracer provider to it's current value. No delegate will be configured",
+				"Setting tracer provider to its current value. No delegate will be configured",
 			)
 			return
 		}
@@ -85,7 +129,7 @@ func SetTextMapPropagator(p propagation.TextMapPropagator) {
 			// delegate to itself.
 			Error(
 				errors.New("no delegate configured in text map propagator"),
-				"Setting text map propagator to it's current value. No delegate will be configured",
+				"Setting text map propagator to its current value. No delegate will be configured",
 			)
 			return
 		}
@@ -102,6 +146,40 @@ func SetTextMapPropagator(p propagation.TextMapPropagator) {
 	globalPropagators.Store(propagatorsHolder{tm: p})
 }
 
+// MeterProvider is the internal implementation for global.MeterProvider.
+func MeterProvider() metric.MeterProvider {
+	return globalMeterProvider.Load().(meterProviderHolder).mp
+}
+
+// SetMeterProvider is the internal implementation for global.SetMeterProvider.
+func SetMeterProvider(mp metric.MeterProvider) {
+	current := MeterProvider()
+	if _, cOk := current.(*meterProvider); cOk {
+		if _, mpOk := mp.(*meterProvider); mpOk && current == mp {
+			// Do not assign the default delegating MeterProvider to delegate
+			// to itself.
+			Error(
+				errors.New("no delegate configured in meter provider"),
+				"Setting meter provider to its current value. No delegate will be configured",
+			)
+			return
+		}
+	}
+
+	delegateMeterOnce.Do(func() {
+		if def, ok := current.(*meterProvider); ok {
+			def.setDelegate(mp)
+		}
+	})
+	globalMeterProvider.Store(meterProviderHolder{mp: mp})
+}
+
+func defaultErrorHandler() *atomic.Value {
+	v := &atomic.Value{}
+	v.Store(errorHandlerHolder{eh: &ErrDelegator{}})
+	return v
+}
+
 func defaultTracerValue() *atomic.Value {
 	v := &atomic.Value{}
 	v.Store(tracerProviderHolder{tp: &tracerProvider{}})
@@ -113,3 +191,9 @@ func defaultPropagatorsValue() *atomic.Value {
 	v.Store(propagatorsHolder{tm: newTextMapPropagator()})
 	return v
 }
+
+func defaultMeterProvider() *atomic.Value {
+	v := &atomic.Value{}
+	v.Store(meterProviderHolder{mp: &meterProvider{}})
+	return v
+}
diff --git a/vendor/go.opentelemetry.io/otel/internal/global/trace.go b/vendor/go.opentelemetry.io/otel/internal/global/trace.go
index 5f008d09..e31f442b 100644
--- a/vendor/go.opentelemetry.io/otel/internal/global/trace.go
+++ b/vendor/go.opentelemetry.io/otel/internal/global/trace.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package global // import "go.opentelemetry.io/otel/internal/global"
 
@@ -39,6 +28,7 @@ import (
 	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/codes"
 	"go.opentelemetry.io/otel/trace"
+	"go.opentelemetry.io/otel/trace/embedded"
 )
 
 // tracerProvider is a placeholder for a configured SDK TracerProvider.
@@ -46,6 +36,8 @@ import (
 // All TracerProvider functionality is forwarded to a delegate once
 // configured.
 type tracerProvider struct {
+	embedded.TracerProvider
+
 	mtx      sync.Mutex
 	tracers  map[il]*tracer
 	delegate trace.TracerProvider
@@ -94,6 +86,7 @@ func (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
 	key := il{
 		name:    name,
 		version: c.InstrumentationVersion(),
+		schema:  c.SchemaURL(),
 	}
 
 	if p.tracers == nil {
@@ -109,16 +102,15 @@ func (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
 	return t
 }
 
-type il struct {
-	name    string
-	version string
-}
+type il struct{ name, version, schema string }
 
 // tracer is a placeholder for a trace.Tracer.
 //
 // All Tracer functionality is forwarded to a delegate once configured.
 // Otherwise, all functionality is forwarded to a NoopTracer.
 type tracer struct {
+	embedded.Tracer
+
 	name     string
 	opts     []trace.TracerOption
 	provider *tracerProvider
@@ -156,6 +148,8 @@ func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStart
 // SpanContext. It performs no operations other than to return the wrapped
 // SpanContext.
 type nonRecordingSpan struct {
+	embedded.Span
+
 	sc     trace.SpanContext
 	tracer *tracer
 }
@@ -186,6 +180,9 @@ func (nonRecordingSpan) RecordError(error, ...trace.EventOption) {}
 // AddEvent does nothing.
 func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}
 
+// AddLink does nothing.
+func (nonRecordingSpan) AddLink(trace.Link) {}
+
 // SetName does nothing.
 func (nonRecordingSpan) SetName(string) {}
 
diff --git a/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go b/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go
index e07e7940..3e7bb3b3 100644
--- a/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go
+++ b/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package internal // import "go.opentelemetry.io/otel/internal"
 
diff --git a/vendor/go.opentelemetry.io/otel/internal_logging.go b/vendor/go.opentelemetry.io/otel/internal_logging.go
index c4f8acd5..6de7f2e4 100644
--- a/vendor/go.opentelemetry.io/otel/internal_logging.go
+++ b/vendor/go.opentelemetry.io/otel/internal_logging.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package otel // import "go.opentelemetry.io/otel"
 
diff --git a/vendor/go.opentelemetry.io/otel/metric.go b/vendor/go.opentelemetry.io/otel/metric.go
new file mode 100644
index 00000000..1e6473b3
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/metric.go
@@ -0,0 +1,42 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package otel // import "go.opentelemetry.io/otel"
+
+import (
+	"go.opentelemetry.io/otel/internal/global"
+	"go.opentelemetry.io/otel/metric"
+)
+
+// Meter returns a Meter from the global MeterProvider. The name must be the
+// name of the library providing instrumentation. This name may be the same as
+// the instrumented code only if that code provides built-in instrumentation.
+// If the name is empty, then a implementation defined default name will be
+// used instead.
+//
+// If this is called before a global MeterProvider is registered the returned
+// Meter will be a No-op implementation of a Meter. When a global MeterProvider
+// is registered for the first time, the returned Meter, and all the
+// instruments it has created or will create, are recreated automatically from
+// the new MeterProvider.
+//
+// This is short for GetMeterProvider().Meter(name).
+func Meter(name string, opts ...metric.MeterOption) metric.Meter {
+	return GetMeterProvider().Meter(name, opts...)
+}
+
+// GetMeterProvider returns the registered global meter provider.
+//
+// If no global GetMeterProvider has been registered, a No-op GetMeterProvider
+// implementation is returned. When a global GetMeterProvider is registered for
+// the first time, the returned GetMeterProvider, and all the Meters it has
+// created or will create, are recreated automatically from the new
+// GetMeterProvider.
+func GetMeterProvider() metric.MeterProvider {
+	return global.MeterProvider()
+}
+
+// SetMeterProvider registers mp as the global MeterProvider.
+func SetMeterProvider(mp metric.MeterProvider) {
+	global.SetMeterProvider(mp)
+}
diff --git a/vendor/gopkg.in/yaml.v2/LICENSE b/vendor/go.opentelemetry.io/otel/metric/LICENSE
similarity index 99%
rename from vendor/gopkg.in/yaml.v2/LICENSE
rename to vendor/go.opentelemetry.io/otel/metric/LICENSE
index 8dada3ed..261eeb9e 100644
--- a/vendor/gopkg.in/yaml.v2/LICENSE
+++ b/vendor/go.opentelemetry.io/otel/metric/LICENSE
@@ -178,7 +178,7 @@
    APPENDIX: How to apply the Apache License to your work.
 
       To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "{}"
+      boilerplate notice, with the fields enclosed by brackets "[]"
       replaced with your own identifying information. (Don't include
       the brackets!)  The text should be enclosed in the appropriate
       comment syntax for the file format. We also recommend that a
@@ -186,7 +186,7 @@
       same "printed page" as the copyright notice for easier
       identification within third-party archives.
 
-   Copyright {yyyy} {name of copyright owner}
+   Copyright [yyyy] [name of copyright owner]
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
diff --git a/vendor/go.opentelemetry.io/otel/metric/README.md b/vendor/go.opentelemetry.io/otel/metric/README.md
new file mode 100644
index 00000000..0cf902e0
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/metric/README.md
@@ -0,0 +1,3 @@
+# Metric API
+
+[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/metric)](https://pkg.go.dev/go.opentelemetry.io/otel/metric)
diff --git a/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go b/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go
new file mode 100644
index 00000000..cf23db77
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go
@@ -0,0 +1,260 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package metric // import "go.opentelemetry.io/otel/metric"
+
+import (
+	"context"
+
+	"go.opentelemetry.io/otel/metric/embedded"
+)
+
+// Float64Observable describes a set of instruments used asynchronously to
+// record float64 measurements once per collection cycle. Observations of
+// these instruments are only made within a callback.
+//
+// Warning: Methods may be added to this interface in minor releases.
+type Float64Observable interface {
+	Observable
+
+	float64Observable()
+}
+
+// Float64ObservableCounter is an instrument used to asynchronously record
+// increasing float64 measurements once per collection cycle. Observations are
+// only made within a callback for this instrument. The value observed is
+// assumed the to be the cumulative sum of the count.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for
+// unimplemented methods.
+type Float64ObservableCounter interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Float64ObservableCounter
+
+	Float64Observable
+}
+
+// Float64ObservableCounterConfig contains options for asynchronous counter
+// instruments that record float64 values.
+type Float64ObservableCounterConfig struct {
+	description string
+	unit        string
+	callbacks   []Float64Callback
+}
+
+// NewFloat64ObservableCounterConfig returns a new
+// [Float64ObservableCounterConfig] with all opts applied.
+func NewFloat64ObservableCounterConfig(opts ...Float64ObservableCounterOption) Float64ObservableCounterConfig {
+	var config Float64ObservableCounterConfig
+	for _, o := range opts {
+		config = o.applyFloat64ObservableCounter(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Float64ObservableCounterConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Float64ObservableCounterConfig) Unit() string {
+	return c.unit
+}
+
+// Callbacks returns the configured callbacks.
+func (c Float64ObservableCounterConfig) Callbacks() []Float64Callback {
+	return c.callbacks
+}
+
+// Float64ObservableCounterOption applies options to a
+// [Float64ObservableCounterConfig]. See [Float64ObservableOption] and
+// [InstrumentOption] for other options that can be used as a
+// Float64ObservableCounterOption.
+type Float64ObservableCounterOption interface {
+	applyFloat64ObservableCounter(Float64ObservableCounterConfig) Float64ObservableCounterConfig
+}
+
+// Float64ObservableUpDownCounter is an instrument used to asynchronously
+// record float64 measurements once per collection cycle. Observations are only
+// made within a callback for this instrument. The value observed is assumed
+// the to be the cumulative sum of the count.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Float64ObservableUpDownCounter interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Float64ObservableUpDownCounter
+
+	Float64Observable
+}
+
+// Float64ObservableUpDownCounterConfig contains options for asynchronous
+// counter instruments that record float64 values.
+type Float64ObservableUpDownCounterConfig struct {
+	description string
+	unit        string
+	callbacks   []Float64Callback
+}
+
+// NewFloat64ObservableUpDownCounterConfig returns a new
+// [Float64ObservableUpDownCounterConfig] with all opts applied.
+func NewFloat64ObservableUpDownCounterConfig(opts ...Float64ObservableUpDownCounterOption) Float64ObservableUpDownCounterConfig {
+	var config Float64ObservableUpDownCounterConfig
+	for _, o := range opts {
+		config = o.applyFloat64ObservableUpDownCounter(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Float64ObservableUpDownCounterConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Float64ObservableUpDownCounterConfig) Unit() string {
+	return c.unit
+}
+
+// Callbacks returns the configured callbacks.
+func (c Float64ObservableUpDownCounterConfig) Callbacks() []Float64Callback {
+	return c.callbacks
+}
+
+// Float64ObservableUpDownCounterOption applies options to a
+// [Float64ObservableUpDownCounterConfig]. See [Float64ObservableOption] and
+// [InstrumentOption] for other options that can be used as a
+// Float64ObservableUpDownCounterOption.
+type Float64ObservableUpDownCounterOption interface {
+	applyFloat64ObservableUpDownCounter(Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig
+}
+
+// Float64ObservableGauge is an instrument used to asynchronously record
+// instantaneous float64 measurements once per collection cycle. Observations
+// are only made within a callback for this instrument.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Float64ObservableGauge interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Float64ObservableGauge
+
+	Float64Observable
+}
+
+// Float64ObservableGaugeConfig contains options for asynchronous counter
+// instruments that record float64 values.
+type Float64ObservableGaugeConfig struct {
+	description string
+	unit        string
+	callbacks   []Float64Callback
+}
+
+// NewFloat64ObservableGaugeConfig returns a new [Float64ObservableGaugeConfig]
+// with all opts applied.
+func NewFloat64ObservableGaugeConfig(opts ...Float64ObservableGaugeOption) Float64ObservableGaugeConfig {
+	var config Float64ObservableGaugeConfig
+	for _, o := range opts {
+		config = o.applyFloat64ObservableGauge(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Float64ObservableGaugeConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Float64ObservableGaugeConfig) Unit() string {
+	return c.unit
+}
+
+// Callbacks returns the configured callbacks.
+func (c Float64ObservableGaugeConfig) Callbacks() []Float64Callback {
+	return c.callbacks
+}
+
+// Float64ObservableGaugeOption applies options to a
+// [Float64ObservableGaugeConfig]. See [Float64ObservableOption] and
+// [InstrumentOption] for other options that can be used as a
+// Float64ObservableGaugeOption.
+type Float64ObservableGaugeOption interface {
+	applyFloat64ObservableGauge(Float64ObservableGaugeConfig) Float64ObservableGaugeConfig
+}
+
+// Float64Observer is a recorder of float64 measurements.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Float64Observer interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Float64Observer
+
+	// Observe records the float64 value.
+	//
+	// Use the WithAttributeSet (or, if performance is not a concern,
+	// the WithAttributes) option to include measurement attributes.
+	Observe(value float64, options ...ObserveOption)
+}
+
+// Float64Callback is a function registered with a Meter that makes
+// observations for a Float64Observerable instrument it is registered with.
+// Calls to the Float64Observer record measurement values for the
+// Float64Observable.
+//
+// The function needs to complete in a finite amount of time and the deadline
+// of the passed context is expected to be honored.
+//
+// The function needs to make unique observations across all registered
+// Float64Callbacks. Meaning, it should not report measurements with the same
+// attributes as another Float64Callbacks also registered for the same
+// instrument.
+//
+// The function needs to be concurrent safe.
+type Float64Callback func(context.Context, Float64Observer) error
+
+// Float64ObservableOption applies options to float64 Observer instruments.
+type Float64ObservableOption interface {
+	Float64ObservableCounterOption
+	Float64ObservableUpDownCounterOption
+	Float64ObservableGaugeOption
+}
+
+type float64CallbackOpt struct {
+	cback Float64Callback
+}
+
+func (o float64CallbackOpt) applyFloat64ObservableCounter(cfg Float64ObservableCounterConfig) Float64ObservableCounterConfig {
+	cfg.callbacks = append(cfg.callbacks, o.cback)
+	return cfg
+}
+
+func (o float64CallbackOpt) applyFloat64ObservableUpDownCounter(cfg Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig {
+	cfg.callbacks = append(cfg.callbacks, o.cback)
+	return cfg
+}
+
+func (o float64CallbackOpt) applyFloat64ObservableGauge(cfg Float64ObservableGaugeConfig) Float64ObservableGaugeConfig {
+	cfg.callbacks = append(cfg.callbacks, o.cback)
+	return cfg
+}
+
+// WithFloat64Callback adds callback to be called for an instrument.
+func WithFloat64Callback(callback Float64Callback) Float64ObservableOption {
+	return float64CallbackOpt{callback}
+}
diff --git a/vendor/go.opentelemetry.io/otel/metric/asyncint64.go b/vendor/go.opentelemetry.io/otel/metric/asyncint64.go
new file mode 100644
index 00000000..c82ba532
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/metric/asyncint64.go
@@ -0,0 +1,258 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package metric // import "go.opentelemetry.io/otel/metric"
+
+import (
+	"context"
+
+	"go.opentelemetry.io/otel/metric/embedded"
+)
+
+// Int64Observable describes a set of instruments used asynchronously to record
+// int64 measurements once per collection cycle. Observations of these
+// instruments are only made within a callback.
+//
+// Warning: Methods may be added to this interface in minor releases.
+type Int64Observable interface {
+	Observable
+
+	int64Observable()
+}
+
+// Int64ObservableCounter is an instrument used to asynchronously record
+// increasing int64 measurements once per collection cycle. Observations are
+// only made within a callback for this instrument. The value observed is
+// assumed the to be the cumulative sum of the count.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Int64ObservableCounter interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Int64ObservableCounter
+
+	Int64Observable
+}
+
+// Int64ObservableCounterConfig contains options for asynchronous counter
+// instruments that record int64 values.
+type Int64ObservableCounterConfig struct {
+	description string
+	unit        string
+	callbacks   []Int64Callback
+}
+
+// NewInt64ObservableCounterConfig returns a new [Int64ObservableCounterConfig]
+// with all opts applied.
+func NewInt64ObservableCounterConfig(opts ...Int64ObservableCounterOption) Int64ObservableCounterConfig {
+	var config Int64ObservableCounterConfig
+	for _, o := range opts {
+		config = o.applyInt64ObservableCounter(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Int64ObservableCounterConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Int64ObservableCounterConfig) Unit() string {
+	return c.unit
+}
+
+// Callbacks returns the configured callbacks.
+func (c Int64ObservableCounterConfig) Callbacks() []Int64Callback {
+	return c.callbacks
+}
+
+// Int64ObservableCounterOption applies options to a
+// [Int64ObservableCounterConfig]. See [Int64ObservableOption] and
+// [InstrumentOption] for other options that can be used as an
+// Int64ObservableCounterOption.
+type Int64ObservableCounterOption interface {
+	applyInt64ObservableCounter(Int64ObservableCounterConfig) Int64ObservableCounterConfig
+}
+
+// Int64ObservableUpDownCounter is an instrument used to asynchronously record
+// int64 measurements once per collection cycle. Observations are only made
+// within a callback for this instrument. The value observed is assumed the to
+// be the cumulative sum of the count.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Int64ObservableUpDownCounter interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Int64ObservableUpDownCounter
+
+	Int64Observable
+}
+
+// Int64ObservableUpDownCounterConfig contains options for asynchronous counter
+// instruments that record int64 values.
+type Int64ObservableUpDownCounterConfig struct {
+	description string
+	unit        string
+	callbacks   []Int64Callback
+}
+
+// NewInt64ObservableUpDownCounterConfig returns a new
+// [Int64ObservableUpDownCounterConfig] with all opts applied.
+func NewInt64ObservableUpDownCounterConfig(opts ...Int64ObservableUpDownCounterOption) Int64ObservableUpDownCounterConfig {
+	var config Int64ObservableUpDownCounterConfig
+	for _, o := range opts {
+		config = o.applyInt64ObservableUpDownCounter(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Int64ObservableUpDownCounterConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Int64ObservableUpDownCounterConfig) Unit() string {
+	return c.unit
+}
+
+// Callbacks returns the configured callbacks.
+func (c Int64ObservableUpDownCounterConfig) Callbacks() []Int64Callback {
+	return c.callbacks
+}
+
+// Int64ObservableUpDownCounterOption applies options to a
+// [Int64ObservableUpDownCounterConfig]. See [Int64ObservableOption] and
+// [InstrumentOption] for other options that can be used as an
+// Int64ObservableUpDownCounterOption.
+type Int64ObservableUpDownCounterOption interface {
+	applyInt64ObservableUpDownCounter(Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig
+}
+
+// Int64ObservableGauge is an instrument used to asynchronously record
+// instantaneous int64 measurements once per collection cycle. Observations are
+// only made within a callback for this instrument.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Int64ObservableGauge interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Int64ObservableGauge
+
+	Int64Observable
+}
+
+// Int64ObservableGaugeConfig contains options for asynchronous counter
+// instruments that record int64 values.
+type Int64ObservableGaugeConfig struct {
+	description string
+	unit        string
+	callbacks   []Int64Callback
+}
+
+// NewInt64ObservableGaugeConfig returns a new [Int64ObservableGaugeConfig]
+// with all opts applied.
+func NewInt64ObservableGaugeConfig(opts ...Int64ObservableGaugeOption) Int64ObservableGaugeConfig {
+	var config Int64ObservableGaugeConfig
+	for _, o := range opts {
+		config = o.applyInt64ObservableGauge(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Int64ObservableGaugeConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Int64ObservableGaugeConfig) Unit() string {
+	return c.unit
+}
+
+// Callbacks returns the configured callbacks.
+func (c Int64ObservableGaugeConfig) Callbacks() []Int64Callback {
+	return c.callbacks
+}
+
+// Int64ObservableGaugeOption applies options to a
+// [Int64ObservableGaugeConfig]. See [Int64ObservableOption] and
+// [InstrumentOption] for other options that can be used as an
+// Int64ObservableGaugeOption.
+type Int64ObservableGaugeOption interface {
+	applyInt64ObservableGauge(Int64ObservableGaugeConfig) Int64ObservableGaugeConfig
+}
+
+// Int64Observer is a recorder of int64 measurements.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Int64Observer interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Int64Observer
+
+	// Observe records the int64 value.
+	//
+	// Use the WithAttributeSet (or, if performance is not a concern,
+	// the WithAttributes) option to include measurement attributes.
+	Observe(value int64, options ...ObserveOption)
+}
+
+// Int64Callback is a function registered with a Meter that makes observations
+// for an Int64Observerable instrument it is registered with. Calls to the
+// Int64Observer record measurement values for the Int64Observable.
+//
+// The function needs to complete in a finite amount of time and the deadline
+// of the passed context is expected to be honored.
+//
+// The function needs to make unique observations across all registered
+// Int64Callbacks. Meaning, it should not report measurements with the same
+// attributes as another Int64Callbacks also registered for the same
+// instrument.
+//
+// The function needs to be concurrent safe.
+type Int64Callback func(context.Context, Int64Observer) error
+
+// Int64ObservableOption applies options to int64 Observer instruments.
+type Int64ObservableOption interface {
+	Int64ObservableCounterOption
+	Int64ObservableUpDownCounterOption
+	Int64ObservableGaugeOption
+}
+
+type int64CallbackOpt struct {
+	cback Int64Callback
+}
+
+func (o int64CallbackOpt) applyInt64ObservableCounter(cfg Int64ObservableCounterConfig) Int64ObservableCounterConfig {
+	cfg.callbacks = append(cfg.callbacks, o.cback)
+	return cfg
+}
+
+func (o int64CallbackOpt) applyInt64ObservableUpDownCounter(cfg Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig {
+	cfg.callbacks = append(cfg.callbacks, o.cback)
+	return cfg
+}
+
+func (o int64CallbackOpt) applyInt64ObservableGauge(cfg Int64ObservableGaugeConfig) Int64ObservableGaugeConfig {
+	cfg.callbacks = append(cfg.callbacks, o.cback)
+	return cfg
+}
+
+// WithInt64Callback adds callback to be called for an instrument.
+func WithInt64Callback(callback Int64Callback) Int64ObservableOption {
+	return int64CallbackOpt{callback}
+}
diff --git a/vendor/go.opentelemetry.io/otel/metric/config.go b/vendor/go.opentelemetry.io/otel/metric/config.go
new file mode 100644
index 00000000..d9e3b13e
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/metric/config.go
@@ -0,0 +1,81 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package metric // import "go.opentelemetry.io/otel/metric"
+
+import "go.opentelemetry.io/otel/attribute"
+
+// MeterConfig contains options for Meters.
+type MeterConfig struct {
+	instrumentationVersion string
+	schemaURL              string
+	attrs                  attribute.Set
+
+	// Ensure forward compatibility by explicitly making this not comparable.
+	noCmp [0]func() //nolint: unused  // This is indeed used.
+}
+
+// InstrumentationVersion returns the version of the library providing
+// instrumentation.
+func (cfg MeterConfig) InstrumentationVersion() string {
+	return cfg.instrumentationVersion
+}
+
+// InstrumentationAttributes returns the attributes associated with the library
+// providing instrumentation.
+func (cfg MeterConfig) InstrumentationAttributes() attribute.Set {
+	return cfg.attrs
+}
+
+// SchemaURL is the schema_url of the library providing instrumentation.
+func (cfg MeterConfig) SchemaURL() string {
+	return cfg.schemaURL
+}
+
+// MeterOption is an interface for applying Meter options.
+type MeterOption interface {
+	// applyMeter is used to set a MeterOption value of a MeterConfig.
+	applyMeter(MeterConfig) MeterConfig
+}
+
+// NewMeterConfig creates a new MeterConfig and applies
+// all the given options.
+func NewMeterConfig(opts ...MeterOption) MeterConfig {
+	var config MeterConfig
+	for _, o := range opts {
+		config = o.applyMeter(config)
+	}
+	return config
+}
+
+type meterOptionFunc func(MeterConfig) MeterConfig
+
+func (fn meterOptionFunc) applyMeter(cfg MeterConfig) MeterConfig {
+	return fn(cfg)
+}
+
+// WithInstrumentationVersion sets the instrumentation version.
+func WithInstrumentationVersion(version string) MeterOption {
+	return meterOptionFunc(func(config MeterConfig) MeterConfig {
+		config.instrumentationVersion = version
+		return config
+	})
+}
+
+// WithInstrumentationAttributes sets the instrumentation attributes.
+//
+// The passed attributes will be de-duplicated.
+func WithInstrumentationAttributes(attr ...attribute.KeyValue) MeterOption {
+	return meterOptionFunc(func(config MeterConfig) MeterConfig {
+		config.attrs = attribute.NewSet(attr...)
+		return config
+	})
+}
+
+// WithSchemaURL sets the schema URL.
+func WithSchemaURL(schemaURL string) MeterOption {
+	return meterOptionFunc(func(config MeterConfig) MeterConfig {
+		config.schemaURL = schemaURL
+		return config
+	})
+}
diff --git a/vendor/go.opentelemetry.io/otel/metric/doc.go b/vendor/go.opentelemetry.io/otel/metric/doc.go
new file mode 100644
index 00000000..f153745b
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/metric/doc.go
@@ -0,0 +1,177 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+/*
+Package metric provides the OpenTelemetry API used to measure metrics about
+source code operation.
+
+This API is separate from its implementation so the instrumentation built from
+it is reusable. See [go.opentelemetry.io/otel/sdk/metric] for the official
+OpenTelemetry implementation of this API.
+
+All measurements made with this package are made via instruments. These
+instruments are created by a [Meter] which itself is created by a
+[MeterProvider]. Applications need to accept a [MeterProvider] implementation
+as a starting point when instrumenting. This can be done directly, or by using
+the OpenTelemetry global MeterProvider via [GetMeterProvider]. Using an
+appropriately named [Meter] from the accepted [MeterProvider], instrumentation
+can then be built from the [Meter]'s instruments.
+
+# Instruments
+
+Each instrument is designed to make measurements of a particular type. Broadly,
+all instruments fall into two overlapping logical categories: asynchronous or
+synchronous, and int64 or float64.
+
+All synchronous instruments ([Int64Counter], [Int64UpDownCounter],
+[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and
+[Float64Histogram]) are used to measure the operation and performance of source
+code during the source code execution. These instruments only make measurements
+when the source code they instrument is run.
+
+All asynchronous instruments ([Int64ObservableCounter],
+[Int64ObservableUpDownCounter], [Int64ObservableGauge],
+[Float64ObservableCounter], [Float64ObservableUpDownCounter], and
+[Float64ObservableGauge]) are used to measure metrics outside of the execution
+of source code. They are said to make "observations" via a callback function
+called once every measurement collection cycle.
+
+Each instrument is also grouped by the value type it measures. Either int64 or
+float64. The value being measured will dictate which instrument in these
+categories to use.
+
+Outside of these two broad categories, instruments are described by the
+function they are designed to serve. All Counters ([Int64Counter],
+[Float64Counter], [Int64ObservableCounter], and [Float64ObservableCounter]) are
+designed to measure values that never decrease in value, but instead only
+incrementally increase in value. UpDownCounters ([Int64UpDownCounter],
+[Float64UpDownCounter], [Int64ObservableUpDownCounter], and
+[Float64ObservableUpDownCounter]) on the other hand, are designed to measure
+values that can increase and decrease. When more information needs to be
+conveyed about all the synchronous measurements made during a collection cycle,
+a Histogram ([Int64Histogram] and [Float64Histogram]) should be used. Finally,
+when just the most recent measurement needs to be conveyed about an
+asynchronous measurement, a Gauge ([Int64ObservableGauge] and
+[Float64ObservableGauge]) should be used.
+
+See the [OpenTelemetry documentation] for more information about instruments
+and their intended use.
+
+# Instrument Name
+
+OpenTelemetry defines an [instrument name syntax] that restricts what
+instrument names are allowed.
+
+Instrument names should ...
+
+  - Not be empty.
+  - Have an alphabetic character as their first letter.
+  - Have any letter after the first be an alphanumeric character, ‘_’, ‘.’,
+    ‘-’, or ‘/’.
+  - Have a maximum length of 255 letters.
+
+To ensure compatibility with observability platforms, all instruments created
+need to conform to this syntax. Not all implementations of the API will validate
+these names, it is the callers responsibility to ensure compliance.
+
+# Measurements
+
+Measurements are made by recording values and information about the values with
+an instrument. How these measurements are recorded depends on the instrument.
+
+Measurements for synchronous instruments ([Int64Counter], [Int64UpDownCounter],
+[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and
+[Float64Histogram]) are recorded using the instrument methods directly. All
+counter instruments have an Add method that is used to measure an increment
+value, and all histogram instruments have a Record method to measure a data
+point.
+
+Asynchronous instruments ([Int64ObservableCounter],
+[Int64ObservableUpDownCounter], [Int64ObservableGauge],
+[Float64ObservableCounter], [Float64ObservableUpDownCounter], and
+[Float64ObservableGauge]) record measurements within a callback function. The
+callback is registered with the Meter which ensures the callback is called once
+per collection cycle. A callback can be registered two ways: during the
+instrument's creation using an option, or later using the RegisterCallback
+method of the [Meter] that created the instrument.
+
+If the following criteria are met, an option ([WithInt64Callback] or
+[WithFloat64Callback]) can be used during the asynchronous instrument's
+creation to register a callback ([Int64Callback] or [Float64Callback],
+respectively):
+
+  - The measurement process is known when the instrument is created
+  - Only that instrument will make a measurement within the callback
+  - The callback never needs to be unregistered
+
+If the criteria are not met, use the RegisterCallback method of the [Meter] that
+created the instrument to register a [Callback].
+
+# API Implementations
+
+This package does not conform to the standard Go versioning policy, all of its
+interfaces may have methods added to them without a package major version bump.
+This non-standard API evolution could surprise an uninformed implementation
+author. They could unknowingly build their implementation in a way that would
+result in a runtime panic for their users that update to the new API.
+
+The API is designed to help inform an instrumentation author about this
+non-standard API evolution. It requires them to choose a default behavior for
+unimplemented interface methods. There are three behavior choices they can
+make:
+
+  - Compilation failure
+  - Panic
+  - Default to another implementation
+
+All interfaces in this API embed a corresponding interface from
+[go.opentelemetry.io/otel/metric/embedded]. If an author wants the default
+behavior of their implementations to be a compilation failure, signaling to
+their users they need to update to the latest version of that implementation,
+they need to embed the corresponding interface from
+[go.opentelemetry.io/otel/metric/embedded] in their implementation. For
+example,
+
+	import "go.opentelemetry.io/otel/metric/embedded"
+
+	type MeterProvider struct {
+		embedded.MeterProvider
+		// ...
+	}
+
+If an author wants the default behavior of their implementations to a panic,
+they need to embed the API interface directly.
+
+	import "go.opentelemetry.io/otel/metric"
+
+	type MeterProvider struct {
+		metric.MeterProvider
+		// ...
+	}
+
+This is not a recommended behavior as it could lead to publishing packages that
+contain runtime panics when users update other package that use newer versions
+of [go.opentelemetry.io/otel/metric].
+
+Finally, an author can embed another implementation in theirs. The embedded
+implementation will be used for methods not defined by the author. For example,
+an author who wants to default to silently dropping the call can use
+[go.opentelemetry.io/otel/metric/noop]:
+
+	import "go.opentelemetry.io/otel/metric/noop"
+
+	type MeterProvider struct {
+		noop.MeterProvider
+		// ...
+	}
+
+It is strongly recommended that authors only embed
+[go.opentelemetry.io/otel/metric/noop] if they choose this default behavior.
+That implementation is the only one OpenTelemetry authors can guarantee will
+fully implement all the API interfaces when a user updates their API.
+
+[instrument name syntax]: https://opentelemetry.io/docs/specs/otel/metrics/api/#instrument-name-syntax
+[OpenTelemetry documentation]: https://opentelemetry.io/docs/concepts/signals/metrics/
+[GetMeterProvider]: https://pkg.go.dev/go.opentelemetry.io/otel#GetMeterProvider
+*/
+package metric // import "go.opentelemetry.io/otel/metric"
diff --git a/vendor/go.opentelemetry.io/otel/metric/embedded/README.md b/vendor/go.opentelemetry.io/otel/metric/embedded/README.md
new file mode 100644
index 00000000..1f6e0efa
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/metric/embedded/README.md
@@ -0,0 +1,3 @@
+# Metric Embedded
+
+[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/metric/embedded)](https://pkg.go.dev/go.opentelemetry.io/otel/metric/embedded)
diff --git a/vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go b/vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go
new file mode 100644
index 00000000..1a9dc680
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go
@@ -0,0 +1,243 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Package embedded provides interfaces embedded within the [OpenTelemetry
+// metric API].
+//
+// Implementers of the [OpenTelemetry metric API] can embed the relevant type
+// from this package into their implementation directly. Doing so will result
+// in a compilation error for users when the [OpenTelemetry metric API] is
+// extended (which is something that can happen without a major version bump of
+// the API package).
+//
+// [OpenTelemetry metric API]: https://pkg.go.dev/go.opentelemetry.io/otel/metric
+package embedded // import "go.opentelemetry.io/otel/metric/embedded"
+
+// MeterProvider is embedded in
+// [go.opentelemetry.io/otel/metric.MeterProvider].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.MeterProvider] if you want users to
+// experience a compilation error, signaling they need to update to your latest
+// implementation, when the [go.opentelemetry.io/otel/metric.MeterProvider]
+// interface is extended (which is something that can happen without a major
+// version bump of the API package).
+type MeterProvider interface{ meterProvider() }
+
+// Meter is embedded in [go.opentelemetry.io/otel/metric.Meter].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Meter] if you want users to experience a
+// compilation error, signaling they need to update to your latest
+// implementation, when the [go.opentelemetry.io/otel/metric.Meter] interface
+// is extended (which is something that can happen without a major version bump
+// of the API package).
+type Meter interface{ meter() }
+
+// Float64Observer is embedded in
+// [go.opentelemetry.io/otel/metric.Float64Observer].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Float64Observer] if you want
+// users to experience a compilation error, signaling they need to update to
+// your latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Float64Observer] interface is
+// extended (which is something that can happen without a major version bump of
+// the API package).
+type Float64Observer interface{ float64Observer() }
+
+// Int64Observer is embedded in
+// [go.opentelemetry.io/otel/metric.Int64Observer].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Int64Observer] if you want users
+// to experience a compilation error, signaling they need to update to your
+// latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Int64Observer] interface is
+// extended (which is something that can happen without a major version bump of
+// the API package).
+type Int64Observer interface{ int64Observer() }
+
+// Observer is embedded in [go.opentelemetry.io/otel/metric.Observer].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Observer] if you want users to experience a
+// compilation error, signaling they need to update to your latest
+// implementation, when the [go.opentelemetry.io/otel/metric.Observer]
+// interface is extended (which is something that can happen without a major
+// version bump of the API package).
+type Observer interface{ observer() }
+
+// Registration is embedded in [go.opentelemetry.io/otel/metric.Registration].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Registration] if you want users to
+// experience a compilation error, signaling they need to update to your latest
+// implementation, when the [go.opentelemetry.io/otel/metric.Registration]
+// interface is extended (which is something that can happen without a major
+// version bump of the API package).
+type Registration interface{ registration() }
+
+// Float64Counter is embedded in
+// [go.opentelemetry.io/otel/metric.Float64Counter].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Float64Counter] if you want
+// users to experience a compilation error, signaling they need to update to
+// your latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Float64Counter] interface is
+// extended (which is something that can happen without a major version bump of
+// the API package).
+type Float64Counter interface{ float64Counter() }
+
+// Float64Histogram is embedded in
+// [go.opentelemetry.io/otel/metric.Float64Histogram].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Float64Histogram] if you want
+// users to experience a compilation error, signaling they need to update to
+// your latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Float64Histogram] interface is
+// extended (which is something that can happen without a major version bump of
+// the API package).
+type Float64Histogram interface{ float64Histogram() }
+
+// Float64Gauge is embedded in [go.opentelemetry.io/otel/metric.Float64Gauge].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Float64Gauge] if you want users to
+// experience a compilation error, signaling they need to update to your latest
+// implementation, when the [go.opentelemetry.io/otel/metric.Float64Gauge]
+// interface is extended (which is something that can happen without a major
+// version bump of the API package).
+type Float64Gauge interface{ float64Gauge() }
+
+// Float64ObservableCounter is embedded in
+// [go.opentelemetry.io/otel/metric.Float64ObservableCounter].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Float64ObservableCounter] if you
+// want users to experience a compilation error, signaling they need to update
+// to your latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Float64ObservableCounter]
+// interface is extended (which is something that can happen without a major
+// version bump of the API package).
+type Float64ObservableCounter interface{ float64ObservableCounter() }
+
+// Float64ObservableGauge is embedded in
+// [go.opentelemetry.io/otel/metric.Float64ObservableGauge].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Float64ObservableGauge] if you
+// want users to experience a compilation error, signaling they need to update
+// to your latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Float64ObservableGauge]
+// interface is extended (which is something that can happen without a major
+// version bump of the API package).
+type Float64ObservableGauge interface{ float64ObservableGauge() }
+
+// Float64ObservableUpDownCounter is embedded in
+// [go.opentelemetry.io/otel/metric.Float64ObservableUpDownCounter].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Float64ObservableUpDownCounter]
+// if you want users to experience a compilation error, signaling they need to
+// update to your latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Float64ObservableUpDownCounter]
+// interface is extended (which is something that can happen without a major
+// version bump of the API package).
+type Float64ObservableUpDownCounter interface{ float64ObservableUpDownCounter() }
+
+// Float64UpDownCounter is embedded in
+// [go.opentelemetry.io/otel/metric.Float64UpDownCounter].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Float64UpDownCounter] if you
+// want users to experience a compilation error, signaling they need to update
+// to your latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Float64UpDownCounter] interface
+// is extended (which is something that can happen without a major version bump
+// of the API package).
+type Float64UpDownCounter interface{ float64UpDownCounter() }
+
+// Int64Counter is embedded in
+// [go.opentelemetry.io/otel/metric.Int64Counter].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Int64Counter] if you want users
+// to experience a compilation error, signaling they need to update to your
+// latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Int64Counter] interface is
+// extended (which is something that can happen without a major version bump of
+// the API package).
+type Int64Counter interface{ int64Counter() }
+
+// Int64Histogram is embedded in
+// [go.opentelemetry.io/otel/metric.Int64Histogram].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Int64Histogram] if you want
+// users to experience a compilation error, signaling they need to update to
+// your latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Int64Histogram] interface is
+// extended (which is something that can happen without a major version bump of
+// the API package).
+type Int64Histogram interface{ int64Histogram() }
+
+// Int64Gauge is embedded in [go.opentelemetry.io/otel/metric.Int64Gauge].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Int64Gauge] if you want users to experience
+// a compilation error, signaling they need to update to your latest
+// implementation, when the [go.opentelemetry.io/otel/metric.Int64Gauge]
+// interface is extended (which is something that can happen without a major
+// version bump of the API package).
+type Int64Gauge interface{ int64Gauge() }
+
+// Int64ObservableCounter is embedded in
+// [go.opentelemetry.io/otel/metric.Int64ObservableCounter].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Int64ObservableCounter] if you
+// want users to experience a compilation error, signaling they need to update
+// to your latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Int64ObservableCounter]
+// interface is extended (which is something that can happen without a major
+// version bump of the API package).
+type Int64ObservableCounter interface{ int64ObservableCounter() }
+
+// Int64ObservableGauge is embedded in
+// [go.opentelemetry.io/otel/metric.Int64ObservableGauge].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Int64ObservableGauge] if you
+// want users to experience a compilation error, signaling they need to update
+// to your latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Int64ObservableGauge] interface
+// is extended (which is something that can happen without a major version bump
+// of the API package).
+type Int64ObservableGauge interface{ int64ObservableGauge() }
+
+// Int64ObservableUpDownCounter is embedded in
+// [go.opentelemetry.io/otel/metric.Int64ObservableUpDownCounter].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Int64ObservableUpDownCounter] if
+// you want users to experience a compilation error, signaling they need to
+// update to your latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Int64ObservableUpDownCounter]
+// interface is extended (which is something that can happen without a major
+// version bump of the API package).
+type Int64ObservableUpDownCounter interface{ int64ObservableUpDownCounter() }
+
+// Int64UpDownCounter is embedded in
+// [go.opentelemetry.io/otel/metric.Int64UpDownCounter].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/metric.Int64UpDownCounter] if you want
+// users to experience a compilation error, signaling they need to update to
+// your latest implementation, when the
+// [go.opentelemetry.io/otel/metric.Int64UpDownCounter] interface is
+// extended (which is something that can happen without a major version bump of
+// the API package).
+type Int64UpDownCounter interface{ int64UpDownCounter() }
diff --git a/vendor/go.opentelemetry.io/otel/metric/instrument.go b/vendor/go.opentelemetry.io/otel/metric/instrument.go
new file mode 100644
index 00000000..ea52e402
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/metric/instrument.go
@@ -0,0 +1,368 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package metric // import "go.opentelemetry.io/otel/metric"
+
+import "go.opentelemetry.io/otel/attribute"
+
+// Observable is used as a grouping mechanism for all instruments that are
+// updated within a Callback.
+type Observable interface {
+	observable()
+}
+
+// InstrumentOption applies options to all instruments.
+type InstrumentOption interface {
+	Int64CounterOption
+	Int64UpDownCounterOption
+	Int64HistogramOption
+	Int64GaugeOption
+	Int64ObservableCounterOption
+	Int64ObservableUpDownCounterOption
+	Int64ObservableGaugeOption
+
+	Float64CounterOption
+	Float64UpDownCounterOption
+	Float64HistogramOption
+	Float64GaugeOption
+	Float64ObservableCounterOption
+	Float64ObservableUpDownCounterOption
+	Float64ObservableGaugeOption
+}
+
+// HistogramOption applies options to histogram instruments.
+type HistogramOption interface {
+	Int64HistogramOption
+	Float64HistogramOption
+}
+
+type descOpt string
+
+func (o descOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig {
+	c.description = string(o)
+	return c
+}
+
+func (o descOpt) applyFloat64UpDownCounter(c Float64UpDownCounterConfig) Float64UpDownCounterConfig {
+	c.description = string(o)
+	return c
+}
+
+func (o descOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig {
+	c.description = string(o)
+	return c
+}
+
+func (o descOpt) applyFloat64Gauge(c Float64GaugeConfig) Float64GaugeConfig {
+	c.description = string(o)
+	return c
+}
+
+func (o descOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig) Float64ObservableCounterConfig {
+	c.description = string(o)
+	return c
+}
+
+func (o descOpt) applyFloat64ObservableUpDownCounter(c Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig {
+	c.description = string(o)
+	return c
+}
+
+func (o descOpt) applyFloat64ObservableGauge(c Float64ObservableGaugeConfig) Float64ObservableGaugeConfig {
+	c.description = string(o)
+	return c
+}
+
+func (o descOpt) applyInt64Counter(c Int64CounterConfig) Int64CounterConfig {
+	c.description = string(o)
+	return c
+}
+
+func (o descOpt) applyInt64UpDownCounter(c Int64UpDownCounterConfig) Int64UpDownCounterConfig {
+	c.description = string(o)
+	return c
+}
+
+func (o descOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig {
+	c.description = string(o)
+	return c
+}
+
+func (o descOpt) applyInt64Gauge(c Int64GaugeConfig) Int64GaugeConfig {
+	c.description = string(o)
+	return c
+}
+
+func (o descOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig {
+	c.description = string(o)
+	return c
+}
+
+func (o descOpt) applyInt64ObservableUpDownCounter(c Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig {
+	c.description = string(o)
+	return c
+}
+
+func (o descOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig {
+	c.description = string(o)
+	return c
+}
+
+// WithDescription sets the instrument description.
+func WithDescription(desc string) InstrumentOption { return descOpt(desc) }
+
+type unitOpt string
+
+func (o unitOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig {
+	c.unit = string(o)
+	return c
+}
+
+func (o unitOpt) applyFloat64UpDownCounter(c Float64UpDownCounterConfig) Float64UpDownCounterConfig {
+	c.unit = string(o)
+	return c
+}
+
+func (o unitOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig {
+	c.unit = string(o)
+	return c
+}
+
+func (o unitOpt) applyFloat64Gauge(c Float64GaugeConfig) Float64GaugeConfig {
+	c.unit = string(o)
+	return c
+}
+
+func (o unitOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig) Float64ObservableCounterConfig {
+	c.unit = string(o)
+	return c
+}
+
+func (o unitOpt) applyFloat64ObservableUpDownCounter(c Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig {
+	c.unit = string(o)
+	return c
+}
+
+func (o unitOpt) applyFloat64ObservableGauge(c Float64ObservableGaugeConfig) Float64ObservableGaugeConfig {
+	c.unit = string(o)
+	return c
+}
+
+func (o unitOpt) applyInt64Counter(c Int64CounterConfig) Int64CounterConfig {
+	c.unit = string(o)
+	return c
+}
+
+func (o unitOpt) applyInt64UpDownCounter(c Int64UpDownCounterConfig) Int64UpDownCounterConfig {
+	c.unit = string(o)
+	return c
+}
+
+func (o unitOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig {
+	c.unit = string(o)
+	return c
+}
+
+func (o unitOpt) applyInt64Gauge(c Int64GaugeConfig) Int64GaugeConfig {
+	c.unit = string(o)
+	return c
+}
+
+func (o unitOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig {
+	c.unit = string(o)
+	return c
+}
+
+func (o unitOpt) applyInt64ObservableUpDownCounter(c Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig {
+	c.unit = string(o)
+	return c
+}
+
+func (o unitOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig {
+	c.unit = string(o)
+	return c
+}
+
+// WithUnit sets the instrument unit.
+//
+// The unit u should be defined using the appropriate [UCUM](https://ucum.org) case-sensitive code.
+func WithUnit(u string) InstrumentOption { return unitOpt(u) }
+
+// WithExplicitBucketBoundaries sets the instrument explicit bucket boundaries.
+//
+// This option is considered "advisory", and may be ignored by API implementations.
+func WithExplicitBucketBoundaries(bounds ...float64) HistogramOption { return bucketOpt(bounds) }
+
+type bucketOpt []float64
+
+func (o bucketOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig {
+	c.explicitBucketBoundaries = o
+	return c
+}
+
+func (o bucketOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig {
+	c.explicitBucketBoundaries = o
+	return c
+}
+
+// AddOption applies options to an addition measurement. See
+// [MeasurementOption] for other options that can be used as an AddOption.
+type AddOption interface {
+	applyAdd(AddConfig) AddConfig
+}
+
+// AddConfig contains options for an addition measurement.
+type AddConfig struct {
+	attrs attribute.Set
+}
+
+// NewAddConfig returns a new [AddConfig] with all opts applied.
+func NewAddConfig(opts []AddOption) AddConfig {
+	config := AddConfig{attrs: *attribute.EmptySet()}
+	for _, o := range opts {
+		config = o.applyAdd(config)
+	}
+	return config
+}
+
+// Attributes returns the configured attribute set.
+func (c AddConfig) Attributes() attribute.Set {
+	return c.attrs
+}
+
+// RecordOption applies options to an addition measurement. See
+// [MeasurementOption] for other options that can be used as a RecordOption.
+type RecordOption interface {
+	applyRecord(RecordConfig) RecordConfig
+}
+
+// RecordConfig contains options for a recorded measurement.
+type RecordConfig struct {
+	attrs attribute.Set
+}
+
+// NewRecordConfig returns a new [RecordConfig] with all opts applied.
+func NewRecordConfig(opts []RecordOption) RecordConfig {
+	config := RecordConfig{attrs: *attribute.EmptySet()}
+	for _, o := range opts {
+		config = o.applyRecord(config)
+	}
+	return config
+}
+
+// Attributes returns the configured attribute set.
+func (c RecordConfig) Attributes() attribute.Set {
+	return c.attrs
+}
+
+// ObserveOption applies options to an addition measurement. See
+// [MeasurementOption] for other options that can be used as a ObserveOption.
+type ObserveOption interface {
+	applyObserve(ObserveConfig) ObserveConfig
+}
+
+// ObserveConfig contains options for an observed measurement.
+type ObserveConfig struct {
+	attrs attribute.Set
+}
+
+// NewObserveConfig returns a new [ObserveConfig] with all opts applied.
+func NewObserveConfig(opts []ObserveOption) ObserveConfig {
+	config := ObserveConfig{attrs: *attribute.EmptySet()}
+	for _, o := range opts {
+		config = o.applyObserve(config)
+	}
+	return config
+}
+
+// Attributes returns the configured attribute set.
+func (c ObserveConfig) Attributes() attribute.Set {
+	return c.attrs
+}
+
+// MeasurementOption applies options to all instrument measurement.
+type MeasurementOption interface {
+	AddOption
+	RecordOption
+	ObserveOption
+}
+
+type attrOpt struct {
+	set attribute.Set
+}
+
+// mergeSets returns the union of keys between a and b. Any duplicate keys will
+// use the value associated with b.
+func mergeSets(a, b attribute.Set) attribute.Set {
+	// NewMergeIterator uses the first value for any duplicates.
+	iter := attribute.NewMergeIterator(&b, &a)
+	merged := make([]attribute.KeyValue, 0, a.Len()+b.Len())
+	for iter.Next() {
+		merged = append(merged, iter.Attribute())
+	}
+	return attribute.NewSet(merged...)
+}
+
+func (o attrOpt) applyAdd(c AddConfig) AddConfig {
+	switch {
+	case o.set.Len() == 0:
+	case c.attrs.Len() == 0:
+		c.attrs = o.set
+	default:
+		c.attrs = mergeSets(c.attrs, o.set)
+	}
+	return c
+}
+
+func (o attrOpt) applyRecord(c RecordConfig) RecordConfig {
+	switch {
+	case o.set.Len() == 0:
+	case c.attrs.Len() == 0:
+		c.attrs = o.set
+	default:
+		c.attrs = mergeSets(c.attrs, o.set)
+	}
+	return c
+}
+
+func (o attrOpt) applyObserve(c ObserveConfig) ObserveConfig {
+	switch {
+	case o.set.Len() == 0:
+	case c.attrs.Len() == 0:
+		c.attrs = o.set
+	default:
+		c.attrs = mergeSets(c.attrs, o.set)
+	}
+	return c
+}
+
+// WithAttributeSet sets the attribute Set associated with a measurement is
+// made with.
+//
+// If multiple WithAttributeSet or WithAttributes options are passed the
+// attributes will be merged together in the order they are passed. Attributes
+// with duplicate keys will use the last value passed.
+func WithAttributeSet(attributes attribute.Set) MeasurementOption {
+	return attrOpt{set: attributes}
+}
+
+// WithAttributes converts attributes into an attribute Set and sets the Set to
+// be associated with a measurement. This is shorthand for:
+//
+//	cp := make([]attribute.KeyValue, len(attributes))
+//	copy(cp, attributes)
+//	WithAttributes(attribute.NewSet(cp...))
+//
+// [attribute.NewSet] may modify the passed attributes so this will make a copy
+// of attributes before creating a set in order to ensure this function is
+// concurrent safe. This makes this option function less optimized in
+// comparison to [WithAttributeSet]. Therefore, [WithAttributeSet] should be
+// preferred for performance sensitive code.
+//
+// See [WithAttributeSet] for information about how multiple WithAttributes are
+// merged.
+func WithAttributes(attributes ...attribute.KeyValue) MeasurementOption {
+	cp := make([]attribute.KeyValue, len(attributes))
+	copy(cp, attributes)
+	return attrOpt{set: attribute.NewSet(cp...)}
+}
diff --git a/vendor/go.opentelemetry.io/otel/metric/meter.go b/vendor/go.opentelemetry.io/otel/metric/meter.go
new file mode 100644
index 00000000..6a7991e0
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/metric/meter.go
@@ -0,0 +1,265 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package metric // import "go.opentelemetry.io/otel/metric"
+
+import (
+	"context"
+
+	"go.opentelemetry.io/otel/metric/embedded"
+)
+
+// MeterProvider provides access to named Meter instances, for instrumenting
+// an application or package.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type MeterProvider interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.MeterProvider
+
+	// Meter returns a new Meter with the provided name and configuration.
+	//
+	// A Meter should be scoped at most to a single package. The name needs to
+	// be unique so it does not collide with other names used by
+	// an application, nor other applications. To achieve this, the import path
+	// of the instrumentation package is recommended to be used as name.
+	//
+	// If the name is empty, then an implementation defined default name will
+	// be used instead.
+	Meter(name string, opts ...MeterOption) Meter
+}
+
+// Meter provides access to instrument instances for recording metrics.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Meter interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Meter
+
+	// Int64Counter returns a new Int64Counter instrument identified by name
+	// and configured with options. The instrument is used to synchronously
+	// record increasing int64 measurements during a computational operation.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Int64Counter(name string, options ...Int64CounterOption) (Int64Counter, error)
+	// Int64UpDownCounter returns a new Int64UpDownCounter instrument
+	// identified by name and configured with options. The instrument is used
+	// to synchronously record int64 measurements during a computational
+	// operation.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Int64UpDownCounter(name string, options ...Int64UpDownCounterOption) (Int64UpDownCounter, error)
+	// Int64Histogram returns a new Int64Histogram instrument identified by
+	// name and configured with options. The instrument is used to
+	// synchronously record the distribution of int64 measurements during a
+	// computational operation.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Int64Histogram(name string, options ...Int64HistogramOption) (Int64Histogram, error)
+	// Int64Gauge returns a new Int64Gauge instrument identified by name and
+	// configured with options. The instrument is used to synchronously record
+	// instantaneous int64 measurements during a computational operation.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Int64Gauge(name string, options ...Int64GaugeOption) (Int64Gauge, error)
+	// Int64ObservableCounter returns a new Int64ObservableCounter identified
+	// by name and configured with options. The instrument is used to
+	// asynchronously record increasing int64 measurements once per a
+	// measurement collection cycle.
+	//
+	// Measurements for the returned instrument are made via a callback. Use
+	// the WithInt64Callback option to register the callback here, or use the
+	// RegisterCallback method of this Meter to register one later. See the
+	// Measurements section of the package documentation for more information.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Int64ObservableCounter(name string, options ...Int64ObservableCounterOption) (Int64ObservableCounter, error)
+	// Int64ObservableUpDownCounter returns a new Int64ObservableUpDownCounter
+	// instrument identified by name and configured with options. The
+	// instrument is used to asynchronously record int64 measurements once per
+	// a measurement collection cycle.
+	//
+	// Measurements for the returned instrument are made via a callback. Use
+	// the WithInt64Callback option to register the callback here, or use the
+	// RegisterCallback method of this Meter to register one later. See the
+	// Measurements section of the package documentation for more information.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Int64ObservableUpDownCounter(name string, options ...Int64ObservableUpDownCounterOption) (Int64ObservableUpDownCounter, error)
+	// Int64ObservableGauge returns a new Int64ObservableGauge instrument
+	// identified by name and configured with options. The instrument is used
+	// to asynchronously record instantaneous int64 measurements once per a
+	// measurement collection cycle.
+	//
+	// Measurements for the returned instrument are made via a callback. Use
+	// the WithInt64Callback option to register the callback here, or use the
+	// RegisterCallback method of this Meter to register one later. See the
+	// Measurements section of the package documentation for more information.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Int64ObservableGauge(name string, options ...Int64ObservableGaugeOption) (Int64ObservableGauge, error)
+
+	// Float64Counter returns a new Float64Counter instrument identified by
+	// name and configured with options. The instrument is used to
+	// synchronously record increasing float64 measurements during a
+	// computational operation.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Float64Counter(name string, options ...Float64CounterOption) (Float64Counter, error)
+	// Float64UpDownCounter returns a new Float64UpDownCounter instrument
+	// identified by name and configured with options. The instrument is used
+	// to synchronously record float64 measurements during a computational
+	// operation.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Float64UpDownCounter(name string, options ...Float64UpDownCounterOption) (Float64UpDownCounter, error)
+	// Float64Histogram returns a new Float64Histogram instrument identified by
+	// name and configured with options. The instrument is used to
+	// synchronously record the distribution of float64 measurements during a
+	// computational operation.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Float64Histogram(name string, options ...Float64HistogramOption) (Float64Histogram, error)
+	// Float64Gauge returns a new Float64Gauge instrument identified by name and
+	// configured with options. The instrument is used to synchronously record
+	// instantaneous float64 measurements during a computational operation.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Float64Gauge(name string, options ...Float64GaugeOption) (Float64Gauge, error)
+	// Float64ObservableCounter returns a new Float64ObservableCounter
+	// instrument identified by name and configured with options. The
+	// instrument is used to asynchronously record increasing float64
+	// measurements once per a measurement collection cycle.
+	//
+	// Measurements for the returned instrument are made via a callback. Use
+	// the WithFloat64Callback option to register the callback here, or use the
+	// RegisterCallback method of this Meter to register one later. See the
+	// Measurements section of the package documentation for more information.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Float64ObservableCounter(name string, options ...Float64ObservableCounterOption) (Float64ObservableCounter, error)
+	// Float64ObservableUpDownCounter returns a new
+	// Float64ObservableUpDownCounter instrument identified by name and
+	// configured with options. The instrument is used to asynchronously record
+	// float64 measurements once per a measurement collection cycle.
+	//
+	// Measurements for the returned instrument are made via a callback. Use
+	// the WithFloat64Callback option to register the callback here, or use the
+	// RegisterCallback method of this Meter to register one later. See the
+	// Measurements section of the package documentation for more information.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Float64ObservableUpDownCounter(name string, options ...Float64ObservableUpDownCounterOption) (Float64ObservableUpDownCounter, error)
+	// Float64ObservableGauge returns a new Float64ObservableGauge instrument
+	// identified by name and configured with options. The instrument is used
+	// to asynchronously record instantaneous float64 measurements once per a
+	// measurement collection cycle.
+	//
+	// Measurements for the returned instrument are made via a callback. Use
+	// the WithFloat64Callback option to register the callback here, or use the
+	// RegisterCallback method of this Meter to register one later. See the
+	// Measurements section of the package documentation for more information.
+	//
+	// The name needs to conform to the OpenTelemetry instrument name syntax.
+	// See the Instrument Name section of the package documentation for more
+	// information.
+	Float64ObservableGauge(name string, options ...Float64ObservableGaugeOption) (Float64ObservableGauge, error)
+
+	// RegisterCallback registers f to be called during the collection of a
+	// measurement cycle.
+	//
+	// If Unregister of the returned Registration is called, f needs to be
+	// unregistered and not called during collection.
+	//
+	// The instruments f is registered with are the only instruments that f may
+	// observe values for.
+	//
+	// If no instruments are passed, f should not be registered nor called
+	// during collection.
+	//
+	// The function f needs to be concurrent safe.
+	RegisterCallback(f Callback, instruments ...Observable) (Registration, error)
+}
+
+// Callback is a function registered with a Meter that makes observations for
+// the set of instruments it is registered with. The Observer parameter is used
+// to record measurement observations for these instruments.
+//
+// The function needs to complete in a finite amount of time and the deadline
+// of the passed context is expected to be honored.
+//
+// The function needs to make unique observations across all registered
+// Callbacks. Meaning, it should not report measurements for an instrument with
+// the same attributes as another Callback will report.
+//
+// The function needs to be concurrent safe.
+type Callback func(context.Context, Observer) error
+
+// Observer records measurements for multiple instruments in a Callback.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Observer interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Observer
+
+	// ObserveFloat64 records the float64 value for obsrv.
+	ObserveFloat64(obsrv Float64Observable, value float64, opts ...ObserveOption)
+	// ObserveInt64 records the int64 value for obsrv.
+	ObserveInt64(obsrv Int64Observable, value int64, opts ...ObserveOption)
+}
+
+// Registration is an token representing the unique registration of a callback
+// for a set of instruments with a Meter.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Registration interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Registration
+
+	// Unregister removes the callback registration from a Meter.
+	//
+	// This method needs to be idempotent and concurrent safe.
+	Unregister() error
+}
diff --git a/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go
new file mode 100644
index 00000000..8403a4ba
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/metric/syncfloat64.go
@@ -0,0 +1,226 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package metric // import "go.opentelemetry.io/otel/metric"
+
+import (
+	"context"
+
+	"go.opentelemetry.io/otel/metric/embedded"
+)
+
+// Float64Counter is an instrument that records increasing float64 values.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Float64Counter interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Float64Counter
+
+	// Add records a change to the counter.
+	//
+	// Use the WithAttributeSet (or, if performance is not a concern,
+	// the WithAttributes) option to include measurement attributes.
+	Add(ctx context.Context, incr float64, options ...AddOption)
+}
+
+// Float64CounterConfig contains options for synchronous counter instruments that
+// record float64 values.
+type Float64CounterConfig struct {
+	description string
+	unit        string
+}
+
+// NewFloat64CounterConfig returns a new [Float64CounterConfig] with all opts
+// applied.
+func NewFloat64CounterConfig(opts ...Float64CounterOption) Float64CounterConfig {
+	var config Float64CounterConfig
+	for _, o := range opts {
+		config = o.applyFloat64Counter(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Float64CounterConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Float64CounterConfig) Unit() string {
+	return c.unit
+}
+
+// Float64CounterOption applies options to a [Float64CounterConfig]. See
+// [InstrumentOption] for other options that can be used as a
+// Float64CounterOption.
+type Float64CounterOption interface {
+	applyFloat64Counter(Float64CounterConfig) Float64CounterConfig
+}
+
+// Float64UpDownCounter is an instrument that records increasing or decreasing
+// float64 values.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Float64UpDownCounter interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Float64UpDownCounter
+
+	// Add records a change to the counter.
+	//
+	// Use the WithAttributeSet (or, if performance is not a concern,
+	// the WithAttributes) option to include measurement attributes.
+	Add(ctx context.Context, incr float64, options ...AddOption)
+}
+
+// Float64UpDownCounterConfig contains options for synchronous counter
+// instruments that record float64 values.
+type Float64UpDownCounterConfig struct {
+	description string
+	unit        string
+}
+
+// NewFloat64UpDownCounterConfig returns a new [Float64UpDownCounterConfig]
+// with all opts applied.
+func NewFloat64UpDownCounterConfig(opts ...Float64UpDownCounterOption) Float64UpDownCounterConfig {
+	var config Float64UpDownCounterConfig
+	for _, o := range opts {
+		config = o.applyFloat64UpDownCounter(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Float64UpDownCounterConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Float64UpDownCounterConfig) Unit() string {
+	return c.unit
+}
+
+// Float64UpDownCounterOption applies options to a
+// [Float64UpDownCounterConfig]. See [InstrumentOption] for other options that
+// can be used as a Float64UpDownCounterOption.
+type Float64UpDownCounterOption interface {
+	applyFloat64UpDownCounter(Float64UpDownCounterConfig) Float64UpDownCounterConfig
+}
+
+// Float64Histogram is an instrument that records a distribution of float64
+// values.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Float64Histogram interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Float64Histogram
+
+	// Record adds an additional value to the distribution.
+	//
+	// Use the WithAttributeSet (or, if performance is not a concern,
+	// the WithAttributes) option to include measurement attributes.
+	Record(ctx context.Context, incr float64, options ...RecordOption)
+}
+
+// Float64HistogramConfig contains options for synchronous histogram
+// instruments that record float64 values.
+type Float64HistogramConfig struct {
+	description              string
+	unit                     string
+	explicitBucketBoundaries []float64
+}
+
+// NewFloat64HistogramConfig returns a new [Float64HistogramConfig] with all
+// opts applied.
+func NewFloat64HistogramConfig(opts ...Float64HistogramOption) Float64HistogramConfig {
+	var config Float64HistogramConfig
+	for _, o := range opts {
+		config = o.applyFloat64Histogram(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Float64HistogramConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Float64HistogramConfig) Unit() string {
+	return c.unit
+}
+
+// ExplicitBucketBoundaries returns the configured explicit bucket boundaries.
+func (c Float64HistogramConfig) ExplicitBucketBoundaries() []float64 {
+	return c.explicitBucketBoundaries
+}
+
+// Float64HistogramOption applies options to a [Float64HistogramConfig]. See
+// [InstrumentOption] for other options that can be used as a
+// Float64HistogramOption.
+type Float64HistogramOption interface {
+	applyFloat64Histogram(Float64HistogramConfig) Float64HistogramConfig
+}
+
+// Float64Gauge is an instrument that records instantaneous float64 values.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Float64Gauge interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Float64Gauge
+
+	// Record records the instantaneous value.
+	//
+	// Use the WithAttributeSet (or, if performance is not a concern,
+	// the WithAttributes) option to include measurement attributes.
+	Record(ctx context.Context, value float64, options ...RecordOption)
+}
+
+// Float64GaugeConfig contains options for synchronous gauge instruments that
+// record float64 values.
+type Float64GaugeConfig struct {
+	description string
+	unit        string
+}
+
+// NewFloat64GaugeConfig returns a new [Float64GaugeConfig] with all opts
+// applied.
+func NewFloat64GaugeConfig(opts ...Float64GaugeOption) Float64GaugeConfig {
+	var config Float64GaugeConfig
+	for _, o := range opts {
+		config = o.applyFloat64Gauge(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Float64GaugeConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Float64GaugeConfig) Unit() string {
+	return c.unit
+}
+
+// Float64GaugeOption applies options to a [Float64GaugeConfig]. See
+// [InstrumentOption] for other options that can be used as a
+// Float64GaugeOption.
+type Float64GaugeOption interface {
+	applyFloat64Gauge(Float64GaugeConfig) Float64GaugeConfig
+}
diff --git a/vendor/go.opentelemetry.io/otel/metric/syncint64.go b/vendor/go.opentelemetry.io/otel/metric/syncint64.go
new file mode 100644
index 00000000..783fdfba
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/metric/syncint64.go
@@ -0,0 +1,226 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package metric // import "go.opentelemetry.io/otel/metric"
+
+import (
+	"context"
+
+	"go.opentelemetry.io/otel/metric/embedded"
+)
+
+// Int64Counter is an instrument that records increasing int64 values.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Int64Counter interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Int64Counter
+
+	// Add records a change to the counter.
+	//
+	// Use the WithAttributeSet (or, if performance is not a concern,
+	// the WithAttributes) option to include measurement attributes.
+	Add(ctx context.Context, incr int64, options ...AddOption)
+}
+
+// Int64CounterConfig contains options for synchronous counter instruments that
+// record int64 values.
+type Int64CounterConfig struct {
+	description string
+	unit        string
+}
+
+// NewInt64CounterConfig returns a new [Int64CounterConfig] with all opts
+// applied.
+func NewInt64CounterConfig(opts ...Int64CounterOption) Int64CounterConfig {
+	var config Int64CounterConfig
+	for _, o := range opts {
+		config = o.applyInt64Counter(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Int64CounterConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Int64CounterConfig) Unit() string {
+	return c.unit
+}
+
+// Int64CounterOption applies options to a [Int64CounterConfig]. See
+// [InstrumentOption] for other options that can be used as an
+// Int64CounterOption.
+type Int64CounterOption interface {
+	applyInt64Counter(Int64CounterConfig) Int64CounterConfig
+}
+
+// Int64UpDownCounter is an instrument that records increasing or decreasing
+// int64 values.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Int64UpDownCounter interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Int64UpDownCounter
+
+	// Add records a change to the counter.
+	//
+	// Use the WithAttributeSet (or, if performance is not a concern,
+	// the WithAttributes) option to include measurement attributes.
+	Add(ctx context.Context, incr int64, options ...AddOption)
+}
+
+// Int64UpDownCounterConfig contains options for synchronous counter
+// instruments that record int64 values.
+type Int64UpDownCounterConfig struct {
+	description string
+	unit        string
+}
+
+// NewInt64UpDownCounterConfig returns a new [Int64UpDownCounterConfig] with
+// all opts applied.
+func NewInt64UpDownCounterConfig(opts ...Int64UpDownCounterOption) Int64UpDownCounterConfig {
+	var config Int64UpDownCounterConfig
+	for _, o := range opts {
+		config = o.applyInt64UpDownCounter(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Int64UpDownCounterConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Int64UpDownCounterConfig) Unit() string {
+	return c.unit
+}
+
+// Int64UpDownCounterOption applies options to a [Int64UpDownCounterConfig].
+// See [InstrumentOption] for other options that can be used as an
+// Int64UpDownCounterOption.
+type Int64UpDownCounterOption interface {
+	applyInt64UpDownCounter(Int64UpDownCounterConfig) Int64UpDownCounterConfig
+}
+
+// Int64Histogram is an instrument that records a distribution of int64
+// values.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Int64Histogram interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Int64Histogram
+
+	// Record adds an additional value to the distribution.
+	//
+	// Use the WithAttributeSet (or, if performance is not a concern,
+	// the WithAttributes) option to include measurement attributes.
+	Record(ctx context.Context, incr int64, options ...RecordOption)
+}
+
+// Int64HistogramConfig contains options for synchronous histogram instruments
+// that record int64 values.
+type Int64HistogramConfig struct {
+	description              string
+	unit                     string
+	explicitBucketBoundaries []float64
+}
+
+// NewInt64HistogramConfig returns a new [Int64HistogramConfig] with all opts
+// applied.
+func NewInt64HistogramConfig(opts ...Int64HistogramOption) Int64HistogramConfig {
+	var config Int64HistogramConfig
+	for _, o := range opts {
+		config = o.applyInt64Histogram(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Int64HistogramConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Int64HistogramConfig) Unit() string {
+	return c.unit
+}
+
+// ExplicitBucketBoundaries returns the configured explicit bucket boundaries.
+func (c Int64HistogramConfig) ExplicitBucketBoundaries() []float64 {
+	return c.explicitBucketBoundaries
+}
+
+// Int64HistogramOption applies options to a [Int64HistogramConfig]. See
+// [InstrumentOption] for other options that can be used as an
+// Int64HistogramOption.
+type Int64HistogramOption interface {
+	applyInt64Histogram(Int64HistogramConfig) Int64HistogramConfig
+}
+
+// Int64Gauge is an instrument that records instantaneous int64 values.
+//
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
+type Int64Gauge interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Int64Gauge
+
+	// Record records the instantaneous value.
+	//
+	// Use the WithAttributeSet (or, if performance is not a concern,
+	// the WithAttributes) option to include measurement attributes.
+	Record(ctx context.Context, value int64, options ...RecordOption)
+}
+
+// Int64GaugeConfig contains options for synchronous gauge instruments that
+// record int64 values.
+type Int64GaugeConfig struct {
+	description string
+	unit        string
+}
+
+// NewInt64GaugeConfig returns a new [Int64GaugeConfig] with all opts
+// applied.
+func NewInt64GaugeConfig(opts ...Int64GaugeOption) Int64GaugeConfig {
+	var config Int64GaugeConfig
+	for _, o := range opts {
+		config = o.applyInt64Gauge(config)
+	}
+	return config
+}
+
+// Description returns the configured description.
+func (c Int64GaugeConfig) Description() string {
+	return c.description
+}
+
+// Unit returns the configured unit.
+func (c Int64GaugeConfig) Unit() string {
+	return c.unit
+}
+
+// Int64GaugeOption applies options to a [Int64GaugeConfig]. See
+// [InstrumentOption] for other options that can be used as a
+// Int64GaugeOption.
+type Int64GaugeOption interface {
+	applyInt64Gauge(Int64GaugeConfig) Int64GaugeConfig
+}
diff --git a/vendor/go.opentelemetry.io/otel/propagation.go b/vendor/go.opentelemetry.io/otel/propagation.go
index d29aaa32..2fd94973 100644
--- a/vendor/go.opentelemetry.io/otel/propagation.go
+++ b/vendor/go.opentelemetry.io/otel/propagation.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package otel // import "go.opentelemetry.io/otel"
 
diff --git a/vendor/go.opentelemetry.io/otel/propagation/README.md b/vendor/go.opentelemetry.io/otel/propagation/README.md
new file mode 100644
index 00000000..e2959ac7
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/propagation/README.md
@@ -0,0 +1,3 @@
+# Propagation
+
+[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/propagation)](https://pkg.go.dev/go.opentelemetry.io/otel/propagation)
diff --git a/vendor/go.opentelemetry.io/otel/propagation/baggage.go b/vendor/go.opentelemetry.io/otel/propagation/baggage.go
index 303cdf1c..552263ba 100644
--- a/vendor/go.opentelemetry.io/otel/propagation/baggage.go
+++ b/vendor/go.opentelemetry.io/otel/propagation/baggage.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package propagation // import "go.opentelemetry.io/otel/propagation"
 
diff --git a/vendor/go.opentelemetry.io/otel/propagation/doc.go b/vendor/go.opentelemetry.io/otel/propagation/doc.go
index c119eb28..33a3baf1 100644
--- a/vendor/go.opentelemetry.io/otel/propagation/doc.go
+++ b/vendor/go.opentelemetry.io/otel/propagation/doc.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 /*
 Package propagation contains OpenTelemetry context propagators.
diff --git a/vendor/go.opentelemetry.io/otel/propagation/propagation.go b/vendor/go.opentelemetry.io/otel/propagation/propagation.go
index c94438f7..8c8286aa 100644
--- a/vendor/go.opentelemetry.io/otel/propagation/propagation.go
+++ b/vendor/go.opentelemetry.io/otel/propagation/propagation.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package propagation // import "go.opentelemetry.io/otel/propagation"
 
diff --git a/vendor/go.opentelemetry.io/otel/propagation/trace_context.go b/vendor/go.opentelemetry.io/otel/propagation/trace_context.go
index 902692da..6870e316 100644
--- a/vendor/go.opentelemetry.io/otel/propagation/trace_context.go
+++ b/vendor/go.opentelemetry.io/otel/propagation/trace_context.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package propagation // import "go.opentelemetry.io/otel/propagation"
 
@@ -18,7 +7,7 @@ import (
 	"context"
 	"encoding/hex"
 	"fmt"
-	"regexp"
+	"strings"
 
 	"go.opentelemetry.io/otel/trace"
 )
@@ -28,6 +17,7 @@ const (
 	maxVersion        = 254
 	traceparentHeader = "traceparent"
 	tracestateHeader  = "tracestate"
+	delimiter         = "-"
 )
 
 // TraceContext is a propagator that supports the W3C Trace Context format
@@ -40,10 +30,12 @@ const (
 // their proprietary information.
 type TraceContext struct{}
 
-var _ TextMapPropagator = TraceContext{}
-var traceCtxRegExp = regexp.MustCompile("^(?P<version>[0-9a-f]{2})-(?P<traceID>[a-f0-9]{32})-(?P<spanID>[a-f0-9]{16})-(?P<traceFlags>[a-f0-9]{2})(?:-.*)?$")
+var (
+	_           TextMapPropagator = TraceContext{}
+	versionPart                   = fmt.Sprintf("%.2X", supportedVersion)
+)
 
-// Inject set tracecontext from the Context into the carrier.
+// Inject injects the trace context from ctx into carrier.
 func (tc TraceContext) Inject(ctx context.Context, carrier TextMapCarrier) {
 	sc := trace.SpanContextFromContext(ctx)
 	if !sc.IsValid() {
@@ -57,12 +49,19 @@ func (tc TraceContext) Inject(ctx context.Context, carrier TextMapCarrier) {
 	// Clear all flags other than the trace-context supported sampling bit.
 	flags := sc.TraceFlags() & trace.FlagsSampled
 
-	h := fmt.Sprintf("%.2x-%s-%s-%s",
-		supportedVersion,
-		sc.TraceID(),
-		sc.SpanID(),
-		flags)
-	carrier.Set(traceparentHeader, h)
+	var sb strings.Builder
+	sb.Grow(2 + 32 + 16 + 2 + 3)
+	_, _ = sb.WriteString(versionPart)
+	traceID := sc.TraceID()
+	spanID := sc.SpanID()
+	flagByte := [1]byte{byte(flags)}
+	var buf [32]byte
+	for _, src := range [][]byte{traceID[:], spanID[:], flagByte[:]} {
+		_ = sb.WriteByte(delimiter[0])
+		n := hex.Encode(buf[:], src)
+		_, _ = sb.Write(buf[:n])
+	}
+	carrier.Set(traceparentHeader, sb.String())
 }
 
 // Extract reads tracecontext from the carrier into a returned Context.
@@ -84,21 +83,8 @@ func (tc TraceContext) extract(carrier TextMapCarrier) trace.SpanContext {
 		return trace.SpanContext{}
 	}
 
-	matches := traceCtxRegExp.FindStringSubmatch(h)
-
-	if len(matches) == 0 {
-		return trace.SpanContext{}
-	}
-
-	if len(matches) < 5 { // four subgroups plus the overall match
-		return trace.SpanContext{}
-	}
-
-	if len(matches[1]) != 2 {
-		return trace.SpanContext{}
-	}
-	ver, err := hex.DecodeString(matches[1])
-	if err != nil {
+	var ver [1]byte
+	if !extractPart(ver[:], &h, 2) {
 		return trace.SpanContext{}
 	}
 	version := int(ver[0])
@@ -106,36 +92,24 @@ func (tc TraceContext) extract(carrier TextMapCarrier) trace.SpanContext {
 		return trace.SpanContext{}
 	}
 
-	if version == 0 && len(matches) != 5 { // four subgroups plus the overall match
-		return trace.SpanContext{}
-	}
-
-	if len(matches[2]) != 32 {
-		return trace.SpanContext{}
-	}
-
 	var scc trace.SpanContextConfig
-
-	scc.TraceID, err = trace.TraceIDFromHex(matches[2][:32])
-	if err != nil {
+	if !extractPart(scc.TraceID[:], &h, 32) {
 		return trace.SpanContext{}
 	}
-
-	if len(matches[3]) != 16 {
-		return trace.SpanContext{}
-	}
-	scc.SpanID, err = trace.SpanIDFromHex(matches[3])
-	if err != nil {
+	if !extractPart(scc.SpanID[:], &h, 16) {
 		return trace.SpanContext{}
 	}
 
-	if len(matches[4]) != 2 {
+	var opts [1]byte
+	if !extractPart(opts[:], &h, 2) {
 		return trace.SpanContext{}
 	}
-	opts, err := hex.DecodeString(matches[4])
-	if err != nil || len(opts) < 1 || (version == 0 && opts[0] > 2) {
+	if version == 0 && (h != "" || opts[0] > 2) {
+		// version 0 not allow extra
+		// version 0 not allow other flag
 		return trace.SpanContext{}
 	}
+
 	// Clear all flags other than the trace-context supported sampling bit.
 	scc.TraceFlags = trace.TraceFlags(opts[0]) & trace.FlagsSampled
 
@@ -153,6 +127,29 @@ func (tc TraceContext) extract(carrier TextMapCarrier) trace.SpanContext {
 	return sc
 }
 
+// upperHex detect hex is upper case Unicode characters.
+func upperHex(v string) bool {
+	for _, c := range v {
+		if c >= 'A' && c <= 'F' {
+			return true
+		}
+	}
+	return false
+}
+
+func extractPart(dst []byte, h *string, n int) bool {
+	part, left, _ := strings.Cut(*h, delimiter)
+	*h = left
+	// hex.Decode decodes unsupported upper-case characters, so exclude explicitly.
+	if len(part) != n || upperHex(part) {
+		return false
+	}
+	if p, err := hex.Decode(dst, []byte(part)); err != nil || p != n/2 {
+		return false
+	}
+	return true
+}
+
 // Fields returns the keys who's values are set with Inject.
 func (tc TraceContext) Fields() []string {
 	return []string{traceparentHeader, tracestateHeader}
diff --git a/vendor/go.opentelemetry.io/otel/renovate.json b/vendor/go.opentelemetry.io/otel/renovate.json
new file mode 100644
index 00000000..8c5ac55c
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/renovate.json
@@ -0,0 +1,24 @@
+{
+  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+  "extends": [
+    "config:recommended"
+  ],
+  "ignorePaths": [],
+  "labels": ["Skip Changelog", "dependencies"],
+  "postUpdateOptions" : [
+    "gomodTidy"
+  ],
+  "packageRules": [
+    {
+      "matchManagers": ["gomod"],
+      "matchDepTypes": ["indirect"],
+      "enabled": true
+    },
+    {
+      "matchFileNames": ["internal/tools/**"],
+      "matchManagers": ["gomod"],
+      "matchDepTypes": ["indirect"],
+      "enabled": false
+    }
+  ]
+}
diff --git a/vendor/go.opentelemetry.io/otel/requirements.txt b/vendor/go.opentelemetry.io/otel/requirements.txt
new file mode 100644
index 00000000..ab09daf9
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/requirements.txt
@@ -0,0 +1 @@
+codespell==2.3.0
diff --git a/vendor/go.opentelemetry.io/otel/semconv/internal/http.go b/vendor/go.opentelemetry.io/otel/semconv/internal/http.go
deleted file mode 100644
index b580eede..00000000
--- a/vendor/go.opentelemetry.io/otel/semconv/internal/http.go
+++ /dev/null
@@ -1,336 +0,0 @@
-// Copyright The OpenTelemetry 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 "go.opentelemetry.io/otel/semconv/internal"
-
-import (
-	"fmt"
-	"net"
-	"net/http"
-	"strconv"
-	"strings"
-
-	"go.opentelemetry.io/otel/attribute"
-	"go.opentelemetry.io/otel/codes"
-	"go.opentelemetry.io/otel/trace"
-)
-
-// SemanticConventions are the semantic convention values defined for a
-// version of the OpenTelemetry specification.
-type SemanticConventions struct {
-	EnduserIDKey                attribute.Key
-	HTTPClientIPKey             attribute.Key
-	HTTPFlavorKey               attribute.Key
-	HTTPHostKey                 attribute.Key
-	HTTPMethodKey               attribute.Key
-	HTTPRequestContentLengthKey attribute.Key
-	HTTPRouteKey                attribute.Key
-	HTTPSchemeHTTP              attribute.KeyValue
-	HTTPSchemeHTTPS             attribute.KeyValue
-	HTTPServerNameKey           attribute.Key
-	HTTPStatusCodeKey           attribute.Key
-	HTTPTargetKey               attribute.Key
-	HTTPURLKey                  attribute.Key
-	HTTPUserAgentKey            attribute.Key
-	NetHostIPKey                attribute.Key
-	NetHostNameKey              attribute.Key
-	NetHostPortKey              attribute.Key
-	NetPeerIPKey                attribute.Key
-	NetPeerNameKey              attribute.Key
-	NetPeerPortKey              attribute.Key
-	NetTransportIP              attribute.KeyValue
-	NetTransportOther           attribute.KeyValue
-	NetTransportTCP             attribute.KeyValue
-	NetTransportUDP             attribute.KeyValue
-	NetTransportUnix            attribute.KeyValue
-}
-
-// NetAttributesFromHTTPRequest generates attributes of the net
-// namespace as specified by the OpenTelemetry specification for a
-// span.  The network parameter is a string that net.Dial function
-// from standard library can understand.
-func (sc *SemanticConventions) NetAttributesFromHTTPRequest(network string, request *http.Request) []attribute.KeyValue {
-	attrs := []attribute.KeyValue{}
-
-	switch network {
-	case "tcp", "tcp4", "tcp6":
-		attrs = append(attrs, sc.NetTransportTCP)
-	case "udp", "udp4", "udp6":
-		attrs = append(attrs, sc.NetTransportUDP)
-	case "ip", "ip4", "ip6":
-		attrs = append(attrs, sc.NetTransportIP)
-	case "unix", "unixgram", "unixpacket":
-		attrs = append(attrs, sc.NetTransportUnix)
-	default:
-		attrs = append(attrs, sc.NetTransportOther)
-	}
-
-	peerIP, peerName, peerPort := hostIPNamePort(request.RemoteAddr)
-	if peerIP != "" {
-		attrs = append(attrs, sc.NetPeerIPKey.String(peerIP))
-	}
-	if peerName != "" {
-		attrs = append(attrs, sc.NetPeerNameKey.String(peerName))
-	}
-	if peerPort != 0 {
-		attrs = append(attrs, sc.NetPeerPortKey.Int(peerPort))
-	}
-
-	hostIP, hostName, hostPort := "", "", 0
-	for _, someHost := range []string{request.Host, request.Header.Get("Host"), request.URL.Host} {
-		hostIP, hostName, hostPort = hostIPNamePort(someHost)
-		if hostIP != "" || hostName != "" || hostPort != 0 {
-			break
-		}
-	}
-	if hostIP != "" {
-		attrs = append(attrs, sc.NetHostIPKey.String(hostIP))
-	}
-	if hostName != "" {
-		attrs = append(attrs, sc.NetHostNameKey.String(hostName))
-	}
-	if hostPort != 0 {
-		attrs = append(attrs, sc.NetHostPortKey.Int(hostPort))
-	}
-
-	return attrs
-}
-
-// hostIPNamePort extracts the IP address, name and (optional) port from hostWithPort.
-// It handles both IPv4 and IPv6 addresses. If the host portion is not recognized
-// as a valid IPv4 or IPv6 address, the `ip` result will be empty and the
-// host portion will instead be returned in `name`.
-func hostIPNamePort(hostWithPort string) (ip string, name string, port int) {
-	var (
-		hostPart, portPart string
-		parsedPort         uint64
-		err                error
-	)
-	if hostPart, portPart, err = net.SplitHostPort(hostWithPort); err != nil {
-		hostPart, portPart = hostWithPort, ""
-	}
-	if parsedIP := net.ParseIP(hostPart); parsedIP != nil {
-		ip = parsedIP.String()
-	} else {
-		name = hostPart
-	}
-	if parsedPort, err = strconv.ParseUint(portPart, 10, 16); err == nil {
-		port = int(parsedPort)
-	}
-	return
-}
-
-// EndUserAttributesFromHTTPRequest generates attributes of the
-// enduser namespace as specified by the OpenTelemetry specification
-// for a span.
-func (sc *SemanticConventions) EndUserAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
-	if username, _, ok := request.BasicAuth(); ok {
-		return []attribute.KeyValue{sc.EnduserIDKey.String(username)}
-	}
-	return nil
-}
-
-// HTTPClientAttributesFromHTTPRequest generates attributes of the
-// http namespace as specified by the OpenTelemetry specification for
-// a span on the client side.
-func (sc *SemanticConventions) HTTPClientAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
-	attrs := []attribute.KeyValue{}
-
-	// remove any username/password info that may be in the URL
-	// before adding it to the attributes
-	userinfo := request.URL.User
-	request.URL.User = nil
-
-	attrs = append(attrs, sc.HTTPURLKey.String(request.URL.String()))
-
-	// restore any username/password info that was removed
-	request.URL.User = userinfo
-
-	return append(attrs, sc.httpCommonAttributesFromHTTPRequest(request)...)
-}
-
-func (sc *SemanticConventions) httpCommonAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
-	attrs := []attribute.KeyValue{}
-	if ua := request.UserAgent(); ua != "" {
-		attrs = append(attrs, sc.HTTPUserAgentKey.String(ua))
-	}
-	if request.ContentLength > 0 {
-		attrs = append(attrs, sc.HTTPRequestContentLengthKey.Int64(request.ContentLength))
-	}
-
-	return append(attrs, sc.httpBasicAttributesFromHTTPRequest(request)...)
-}
-
-func (sc *SemanticConventions) httpBasicAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
-	// as these attributes are used by HTTPServerMetricAttributesFromHTTPRequest, they should be low-cardinality
-	attrs := []attribute.KeyValue{}
-
-	if request.TLS != nil {
-		attrs = append(attrs, sc.HTTPSchemeHTTPS)
-	} else {
-		attrs = append(attrs, sc.HTTPSchemeHTTP)
-	}
-
-	if request.Host != "" {
-		attrs = append(attrs, sc.HTTPHostKey.String(request.Host))
-	} else if request.URL != nil && request.URL.Host != "" {
-		attrs = append(attrs, sc.HTTPHostKey.String(request.URL.Host))
-	}
-
-	flavor := ""
-	if request.ProtoMajor == 1 {
-		flavor = fmt.Sprintf("1.%d", request.ProtoMinor)
-	} else if request.ProtoMajor == 2 {
-		flavor = "2"
-	}
-	if flavor != "" {
-		attrs = append(attrs, sc.HTTPFlavorKey.String(flavor))
-	}
-
-	if request.Method != "" {
-		attrs = append(attrs, sc.HTTPMethodKey.String(request.Method))
-	} else {
-		attrs = append(attrs, sc.HTTPMethodKey.String(http.MethodGet))
-	}
-
-	return attrs
-}
-
-// HTTPServerMetricAttributesFromHTTPRequest generates low-cardinality attributes
-// to be used with server-side HTTP metrics.
-func (sc *SemanticConventions) HTTPServerMetricAttributesFromHTTPRequest(serverName string, request *http.Request) []attribute.KeyValue {
-	attrs := []attribute.KeyValue{}
-	if serverName != "" {
-		attrs = append(attrs, sc.HTTPServerNameKey.String(serverName))
-	}
-	return append(attrs, sc.httpBasicAttributesFromHTTPRequest(request)...)
-}
-
-// HTTPServerAttributesFromHTTPRequest generates attributes of the
-// http namespace as specified by the OpenTelemetry specification for
-// a span on the server side. Currently, only basic authentication is
-// supported.
-func (sc *SemanticConventions) HTTPServerAttributesFromHTTPRequest(serverName, route string, request *http.Request) []attribute.KeyValue {
-	attrs := []attribute.KeyValue{
-		sc.HTTPTargetKey.String(request.RequestURI),
-	}
-
-	if serverName != "" {
-		attrs = append(attrs, sc.HTTPServerNameKey.String(serverName))
-	}
-	if route != "" {
-		attrs = append(attrs, sc.HTTPRouteKey.String(route))
-	}
-	if values, ok := request.Header["X-Forwarded-For"]; ok && len(values) > 0 {
-		if addresses := strings.SplitN(values[0], ",", 2); len(addresses) > 0 {
-			attrs = append(attrs, sc.HTTPClientIPKey.String(addresses[0]))
-		}
-	}
-
-	return append(attrs, sc.httpCommonAttributesFromHTTPRequest(request)...)
-}
-
-// HTTPAttributesFromHTTPStatusCode generates attributes of the http
-// namespace as specified by the OpenTelemetry specification for a
-// span.
-func (sc *SemanticConventions) HTTPAttributesFromHTTPStatusCode(code int) []attribute.KeyValue {
-	attrs := []attribute.KeyValue{
-		sc.HTTPStatusCodeKey.Int(code),
-	}
-	return attrs
-}
-
-type codeRange struct {
-	fromInclusive int
-	toInclusive   int
-}
-
-func (r codeRange) contains(code int) bool {
-	return r.fromInclusive <= code && code <= r.toInclusive
-}
-
-var validRangesPerCategory = map[int][]codeRange{
-	1: {
-		{http.StatusContinue, http.StatusEarlyHints},
-	},
-	2: {
-		{http.StatusOK, http.StatusAlreadyReported},
-		{http.StatusIMUsed, http.StatusIMUsed},
-	},
-	3: {
-		{http.StatusMultipleChoices, http.StatusUseProxy},
-		{http.StatusTemporaryRedirect, http.StatusPermanentRedirect},
-	},
-	4: {
-		{http.StatusBadRequest, http.StatusTeapot}, // yes, teapot is so useful…
-		{http.StatusMisdirectedRequest, http.StatusUpgradeRequired},
-		{http.StatusPreconditionRequired, http.StatusTooManyRequests},
-		{http.StatusRequestHeaderFieldsTooLarge, http.StatusRequestHeaderFieldsTooLarge},
-		{http.StatusUnavailableForLegalReasons, http.StatusUnavailableForLegalReasons},
-	},
-	5: {
-		{http.StatusInternalServerError, http.StatusLoopDetected},
-		{http.StatusNotExtended, http.StatusNetworkAuthenticationRequired},
-	},
-}
-
-// SpanStatusFromHTTPStatusCode generates a status code and a message
-// as specified by the OpenTelemetry specification for a span.
-func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
-	spanCode, valid := validateHTTPStatusCode(code)
-	if !valid {
-		return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
-	}
-	return spanCode, ""
-}
-
-// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
-// as specified by the OpenTelemetry specification for a span.
-// Exclude 4xx for SERVER to set the appropriate status.
-func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
-	spanCode, valid := validateHTTPStatusCode(code)
-	if !valid {
-		return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
-	}
-	category := code / 100
-	if spanKind == trace.SpanKindServer && category == 4 {
-		return codes.Unset, ""
-	}
-	return spanCode, ""
-}
-
-// validateHTTPStatusCode validates the HTTP status code and returns
-// corresponding span status code. If the `code` is not a valid HTTP status
-// code, returns span status Error and false.
-func validateHTTPStatusCode(code int) (codes.Code, bool) {
-	category := code / 100
-	ranges, ok := validRangesPerCategory[category]
-	if !ok {
-		return codes.Error, false
-	}
-	ok = false
-	for _, crange := range ranges {
-		ok = crange.contains(code)
-		if ok {
-			break
-		}
-	}
-	if !ok {
-		return codes.Error, false
-	}
-	if category > 0 && category < 4 {
-		return codes.Unset, true
-	}
-	return codes.Error, true
-}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/internal/v2/http.go b/vendor/go.opentelemetry.io/otel/semconv/internal/v2/http.go
new file mode 100644
index 00000000..09e094de
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/internal/v2/http.go
@@ -0,0 +1,393 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package internal // import "go.opentelemetry.io/otel/semconv/internal/v2"
+
+import (
+	"fmt"
+	"net/http"
+	"strings"
+
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+)
+
+// HTTPConv are the HTTP semantic convention attributes defined for a version
+// of the OpenTelemetry specification.
+type HTTPConv struct {
+	NetConv *NetConv
+
+	EnduserIDKey                 attribute.Key
+	HTTPClientIPKey              attribute.Key
+	HTTPFlavorKey                attribute.Key
+	HTTPMethodKey                attribute.Key
+	HTTPRequestContentLengthKey  attribute.Key
+	HTTPResponseContentLengthKey attribute.Key
+	HTTPRouteKey                 attribute.Key
+	HTTPSchemeHTTP               attribute.KeyValue
+	HTTPSchemeHTTPS              attribute.KeyValue
+	HTTPStatusCodeKey            attribute.Key
+	HTTPTargetKey                attribute.Key
+	HTTPURLKey                   attribute.Key
+	HTTPUserAgentKey             attribute.Key
+}
+
+// ClientResponse returns attributes for an HTTP response received by a client
+// from a server. The following attributes are returned if the related values
+// are defined in resp: "http.status.code", "http.response_content_length".
+//
+// This does not add all OpenTelemetry required attributes for an HTTP event,
+// it assumes ClientRequest was used to create the span with a complete set of
+// attributes. If a complete set of attributes can be generated using the
+// request contained in resp. For example:
+//
+//	append(ClientResponse(resp), ClientRequest(resp.Request)...)
+func (c *HTTPConv) ClientResponse(resp *http.Response) []attribute.KeyValue {
+	var n int
+	if resp.StatusCode > 0 {
+		n++
+	}
+	if resp.ContentLength > 0 {
+		n++
+	}
+
+	attrs := make([]attribute.KeyValue, 0, n)
+	if resp.StatusCode > 0 {
+		attrs = append(attrs, c.HTTPStatusCodeKey.Int(resp.StatusCode))
+	}
+	if resp.ContentLength > 0 {
+		attrs = append(attrs, c.HTTPResponseContentLengthKey.Int(int(resp.ContentLength)))
+	}
+	return attrs
+}
+
+// ClientRequest returns attributes for an HTTP request made by a client. The
+// following attributes are always returned: "http.url", "http.flavor",
+// "http.method", "net.peer.name". The following attributes are returned if the
+// related values are defined in req: "net.peer.port", "http.user_agent",
+// "http.request_content_length", "enduser.id".
+func (c *HTTPConv) ClientRequest(req *http.Request) []attribute.KeyValue {
+	n := 3 // URL, peer name, proto, and method.
+	var h string
+	if req.URL != nil {
+		h = req.URL.Host
+	}
+	peer, p := firstHostPort(h, req.Header.Get("Host"))
+	port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", p)
+	if port > 0 {
+		n++
+	}
+	useragent := req.UserAgent()
+	if useragent != "" {
+		n++
+	}
+	if req.ContentLength > 0 {
+		n++
+	}
+	userID, _, hasUserID := req.BasicAuth()
+	if hasUserID {
+		n++
+	}
+	attrs := make([]attribute.KeyValue, 0, n)
+
+	attrs = append(attrs, c.method(req.Method))
+	attrs = append(attrs, c.proto(req.Proto))
+
+	var u string
+	if req.URL != nil {
+		// Remove any username/password info that may be in the URL.
+		userinfo := req.URL.User
+		req.URL.User = nil
+		u = req.URL.String()
+		// Restore any username/password info that was removed.
+		req.URL.User = userinfo
+	}
+	attrs = append(attrs, c.HTTPURLKey.String(u))
+
+	attrs = append(attrs, c.NetConv.PeerName(peer))
+	if port > 0 {
+		attrs = append(attrs, c.NetConv.PeerPort(port))
+	}
+
+	if useragent != "" {
+		attrs = append(attrs, c.HTTPUserAgentKey.String(useragent))
+	}
+
+	if l := req.ContentLength; l > 0 {
+		attrs = append(attrs, c.HTTPRequestContentLengthKey.Int64(l))
+	}
+
+	if hasUserID {
+		attrs = append(attrs, c.EnduserIDKey.String(userID))
+	}
+
+	return attrs
+}
+
+// ServerRequest returns attributes for an HTTP request received by a server.
+//
+// The server must be the primary server name if it is known. For example this
+// would be the ServerName directive
+// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache
+// server, and the server_name directive
+// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an
+// nginx server. More generically, the primary server name would be the host
+// header value that matches the default virtual host of an HTTP server. It
+// should include the host identifier and if a port is used to route to the
+// server that port identifier should be included as an appropriate port
+// suffix.
+//
+// If the primary server name is not known, server should be an empty string.
+// The req Host will be used to determine the server instead.
+//
+// The following attributes are always returned: "http.method", "http.scheme",
+// "http.flavor", "http.target", "net.host.name". The following attributes are
+// returned if they related values are defined in req: "net.host.port",
+// "net.sock.peer.addr", "net.sock.peer.port", "http.user_agent", "enduser.id",
+// "http.client_ip".
+func (c *HTTPConv) ServerRequest(server string, req *http.Request) []attribute.KeyValue {
+	// TODO: This currently does not add the specification required
+	// `http.target` attribute. It has too high of a cardinality to safely be
+	// added. An alternate should be added, or this comment removed, when it is
+	// addressed by the specification. If it is ultimately decided to continue
+	// not including the attribute, the HTTPTargetKey field of the HTTPConv
+	// should be removed as well.
+
+	n := 4 // Method, scheme, proto, and host name.
+	var host string
+	var p int
+	if server == "" {
+		host, p = splitHostPort(req.Host)
+	} else {
+		// Prioritize the primary server name.
+		host, p = splitHostPort(server)
+		if p < 0 {
+			_, p = splitHostPort(req.Host)
+		}
+	}
+	hostPort := requiredHTTPPort(req.TLS != nil, p)
+	if hostPort > 0 {
+		n++
+	}
+	peer, peerPort := splitHostPort(req.RemoteAddr)
+	if peer != "" {
+		n++
+		if peerPort > 0 {
+			n++
+		}
+	}
+	useragent := req.UserAgent()
+	if useragent != "" {
+		n++
+	}
+	userID, _, hasUserID := req.BasicAuth()
+	if hasUserID {
+		n++
+	}
+	clientIP := serverClientIP(req.Header.Get("X-Forwarded-For"))
+	if clientIP != "" {
+		n++
+	}
+	attrs := make([]attribute.KeyValue, 0, n)
+
+	attrs = append(attrs, c.method(req.Method))
+	attrs = append(attrs, c.scheme(req.TLS != nil))
+	attrs = append(attrs, c.proto(req.Proto))
+	attrs = append(attrs, c.NetConv.HostName(host))
+
+	if hostPort > 0 {
+		attrs = append(attrs, c.NetConv.HostPort(hostPort))
+	}
+
+	if peer != "" {
+		// The Go HTTP server sets RemoteAddr to "IP:port", this will not be a
+		// file-path that would be interpreted with a sock family.
+		attrs = append(attrs, c.NetConv.SockPeerAddr(peer))
+		if peerPort > 0 {
+			attrs = append(attrs, c.NetConv.SockPeerPort(peerPort))
+		}
+	}
+
+	if useragent != "" {
+		attrs = append(attrs, c.HTTPUserAgentKey.String(useragent))
+	}
+
+	if hasUserID {
+		attrs = append(attrs, c.EnduserIDKey.String(userID))
+	}
+
+	if clientIP != "" {
+		attrs = append(attrs, c.HTTPClientIPKey.String(clientIP))
+	}
+
+	return attrs
+}
+
+func (c *HTTPConv) method(method string) attribute.KeyValue {
+	if method == "" {
+		return c.HTTPMethodKey.String(http.MethodGet)
+	}
+	return c.HTTPMethodKey.String(method)
+}
+
+func (c *HTTPConv) scheme(https bool) attribute.KeyValue { // nolint:revive
+	if https {
+		return c.HTTPSchemeHTTPS
+	}
+	return c.HTTPSchemeHTTP
+}
+
+func (c *HTTPConv) proto(proto string) attribute.KeyValue {
+	switch proto {
+	case "HTTP/1.0":
+		return c.HTTPFlavorKey.String("1.0")
+	case "HTTP/1.1":
+		return c.HTTPFlavorKey.String("1.1")
+	case "HTTP/2":
+		return c.HTTPFlavorKey.String("2.0")
+	case "HTTP/3":
+		return c.HTTPFlavorKey.String("3.0")
+	default:
+		return c.HTTPFlavorKey.String(proto)
+	}
+}
+
+func serverClientIP(xForwardedFor string) string {
+	if idx := strings.Index(xForwardedFor, ","); idx >= 0 {
+		xForwardedFor = xForwardedFor[:idx]
+	}
+	return xForwardedFor
+}
+
+func requiredHTTPPort(https bool, port int) int { // nolint:revive
+	if https {
+		if port > 0 && port != 443 {
+			return port
+		}
+	} else {
+		if port > 0 && port != 80 {
+			return port
+		}
+	}
+	return -1
+}
+
+// Return the request host and port from the first non-empty source.
+func firstHostPort(source ...string) (host string, port int) {
+	for _, hostport := range source {
+		host, port = splitHostPort(hostport)
+		if host != "" || port > 0 {
+			break
+		}
+	}
+	return
+}
+
+// RequestHeader returns the contents of h as OpenTelemetry attributes.
+func (c *HTTPConv) RequestHeader(h http.Header) []attribute.KeyValue {
+	return c.header("http.request.header", h)
+}
+
+// ResponseHeader returns the contents of h as OpenTelemetry attributes.
+func (c *HTTPConv) ResponseHeader(h http.Header) []attribute.KeyValue {
+	return c.header("http.response.header", h)
+}
+
+func (c *HTTPConv) header(prefix string, h http.Header) []attribute.KeyValue {
+	key := func(k string) attribute.Key {
+		k = strings.ToLower(k)
+		k = strings.ReplaceAll(k, "-", "_")
+		k = fmt.Sprintf("%s.%s", prefix, k)
+		return attribute.Key(k)
+	}
+
+	attrs := make([]attribute.KeyValue, 0, len(h))
+	for k, v := range h {
+		attrs = append(attrs, key(k).StringSlice(v))
+	}
+	return attrs
+}
+
+// ClientStatus returns a span status code and message for an HTTP status code
+// value received by a client.
+func (c *HTTPConv) ClientStatus(code int) (codes.Code, string) {
+	stat, valid := validateHTTPStatusCode(code)
+	if !valid {
+		return stat, fmt.Sprintf("Invalid HTTP status code %d", code)
+	}
+	return stat, ""
+}
+
+// ServerStatus returns a span status code and message for an HTTP status code
+// value returned by a server. Status codes in the 400-499 range are not
+// returned as errors.
+func (c *HTTPConv) ServerStatus(code int) (codes.Code, string) {
+	stat, valid := validateHTTPStatusCode(code)
+	if !valid {
+		return stat, fmt.Sprintf("Invalid HTTP status code %d", code)
+	}
+
+	if code/100 == 4 {
+		return codes.Unset, ""
+	}
+	return stat, ""
+}
+
+type codeRange struct {
+	fromInclusive int
+	toInclusive   int
+}
+
+func (r codeRange) contains(code int) bool {
+	return r.fromInclusive <= code && code <= r.toInclusive
+}
+
+var validRangesPerCategory = map[int][]codeRange{
+	1: {
+		{http.StatusContinue, http.StatusEarlyHints},
+	},
+	2: {
+		{http.StatusOK, http.StatusAlreadyReported},
+		{http.StatusIMUsed, http.StatusIMUsed},
+	},
+	3: {
+		{http.StatusMultipleChoices, http.StatusUseProxy},
+		{http.StatusTemporaryRedirect, http.StatusPermanentRedirect},
+	},
+	4: {
+		{http.StatusBadRequest, http.StatusTeapot}, // yes, teapot is so useful…
+		{http.StatusMisdirectedRequest, http.StatusUpgradeRequired},
+		{http.StatusPreconditionRequired, http.StatusTooManyRequests},
+		{http.StatusRequestHeaderFieldsTooLarge, http.StatusRequestHeaderFieldsTooLarge},
+		{http.StatusUnavailableForLegalReasons, http.StatusUnavailableForLegalReasons},
+	},
+	5: {
+		{http.StatusInternalServerError, http.StatusLoopDetected},
+		{http.StatusNotExtended, http.StatusNetworkAuthenticationRequired},
+	},
+}
+
+// validateHTTPStatusCode validates the HTTP status code and returns
+// corresponding span status code. If the `code` is not a valid HTTP status
+// code, returns span status Error and false.
+func validateHTTPStatusCode(code int) (codes.Code, bool) {
+	category := code / 100
+	ranges, ok := validRangesPerCategory[category]
+	if !ok {
+		return codes.Error, false
+	}
+	ok = false
+	for _, crange := range ranges {
+		ok = crange.contains(code)
+		if ok {
+			break
+		}
+	}
+	if !ok {
+		return codes.Error, false
+	}
+	if category > 0 && category < 4 {
+		return codes.Unset, true
+	}
+	return codes.Error, true
+}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/internal/v2/net.go b/vendor/go.opentelemetry.io/otel/semconv/internal/v2/net.go
new file mode 100644
index 00000000..aa9e1017
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/internal/v2/net.go
@@ -0,0 +1,313 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package internal // import "go.opentelemetry.io/otel/semconv/internal/v2"
+
+import (
+	"net"
+	"strconv"
+	"strings"
+
+	"go.opentelemetry.io/otel/attribute"
+)
+
+// NetConv are the network semantic convention attributes defined for a version
+// of the OpenTelemetry specification.
+type NetConv struct {
+	NetHostNameKey     attribute.Key
+	NetHostPortKey     attribute.Key
+	NetPeerNameKey     attribute.Key
+	NetPeerPortKey     attribute.Key
+	NetSockFamilyKey   attribute.Key
+	NetSockPeerAddrKey attribute.Key
+	NetSockPeerPortKey attribute.Key
+	NetSockHostAddrKey attribute.Key
+	NetSockHostPortKey attribute.Key
+	NetTransportOther  attribute.KeyValue
+	NetTransportTCP    attribute.KeyValue
+	NetTransportUDP    attribute.KeyValue
+	NetTransportInProc attribute.KeyValue
+}
+
+func (c *NetConv) Transport(network string) attribute.KeyValue {
+	switch network {
+	case "tcp", "tcp4", "tcp6":
+		return c.NetTransportTCP
+	case "udp", "udp4", "udp6":
+		return c.NetTransportUDP
+	case "unix", "unixgram", "unixpacket":
+		return c.NetTransportInProc
+	default:
+		// "ip:*", "ip4:*", and "ip6:*" all are considered other.
+		return c.NetTransportOther
+	}
+}
+
+// Host returns attributes for a network host address.
+func (c *NetConv) Host(address string) []attribute.KeyValue {
+	h, p := splitHostPort(address)
+	var n int
+	if h != "" {
+		n++
+		if p > 0 {
+			n++
+		}
+	}
+
+	if n == 0 {
+		return nil
+	}
+
+	attrs := make([]attribute.KeyValue, 0, n)
+	attrs = append(attrs, c.HostName(h))
+	if p > 0 {
+		attrs = append(attrs, c.HostPort(p))
+	}
+	return attrs
+}
+
+// Server returns attributes for a network listener listening at address. See
+// net.Listen for information about acceptable address values, address should
+// be the same as the one used to create ln. If ln is nil, only network host
+// attributes will be returned that describe address. Otherwise, the socket
+// level information about ln will also be included.
+func (c *NetConv) Server(address string, ln net.Listener) []attribute.KeyValue {
+	if ln == nil {
+		return c.Host(address)
+	}
+
+	lAddr := ln.Addr()
+	if lAddr == nil {
+		return c.Host(address)
+	}
+
+	hostName, hostPort := splitHostPort(address)
+	sockHostAddr, sockHostPort := splitHostPort(lAddr.String())
+	network := lAddr.Network()
+	sockFamily := family(network, sockHostAddr)
+
+	n := nonZeroStr(hostName, network, sockHostAddr, sockFamily)
+	n += positiveInt(hostPort, sockHostPort)
+	attr := make([]attribute.KeyValue, 0, n)
+	if hostName != "" {
+		attr = append(attr, c.HostName(hostName))
+		if hostPort > 0 {
+			// Only if net.host.name is set should net.host.port be.
+			attr = append(attr, c.HostPort(hostPort))
+		}
+	}
+	if network != "" {
+		attr = append(attr, c.Transport(network))
+	}
+	if sockFamily != "" {
+		attr = append(attr, c.NetSockFamilyKey.String(sockFamily))
+	}
+	if sockHostAddr != "" {
+		attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr))
+		if sockHostPort > 0 {
+			// Only if net.sock.host.addr is set should net.sock.host.port be.
+			attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort))
+		}
+	}
+	return attr
+}
+
+func (c *NetConv) HostName(name string) attribute.KeyValue {
+	return c.NetHostNameKey.String(name)
+}
+
+func (c *NetConv) HostPort(port int) attribute.KeyValue {
+	return c.NetHostPortKey.Int(port)
+}
+
+// Client returns attributes for a client network connection to address. See
+// net.Dial for information about acceptable address values, address should be
+// the same as the one used to create conn. If conn is nil, only network peer
+// attributes will be returned that describe address. Otherwise, the socket
+// level information about conn will also be included.
+func (c *NetConv) Client(address string, conn net.Conn) []attribute.KeyValue {
+	if conn == nil {
+		return c.Peer(address)
+	}
+
+	lAddr, rAddr := conn.LocalAddr(), conn.RemoteAddr()
+
+	var network string
+	switch {
+	case lAddr != nil:
+		network = lAddr.Network()
+	case rAddr != nil:
+		network = rAddr.Network()
+	default:
+		return c.Peer(address)
+	}
+
+	peerName, peerPort := splitHostPort(address)
+	var (
+		sockFamily   string
+		sockPeerAddr string
+		sockPeerPort int
+		sockHostAddr string
+		sockHostPort int
+	)
+
+	if lAddr != nil {
+		sockHostAddr, sockHostPort = splitHostPort(lAddr.String())
+	}
+
+	if rAddr != nil {
+		sockPeerAddr, sockPeerPort = splitHostPort(rAddr.String())
+	}
+
+	switch {
+	case sockHostAddr != "":
+		sockFamily = family(network, sockHostAddr)
+	case sockPeerAddr != "":
+		sockFamily = family(network, sockPeerAddr)
+	}
+
+	n := nonZeroStr(peerName, network, sockPeerAddr, sockHostAddr, sockFamily)
+	n += positiveInt(peerPort, sockPeerPort, sockHostPort)
+	attr := make([]attribute.KeyValue, 0, n)
+	if peerName != "" {
+		attr = append(attr, c.PeerName(peerName))
+		if peerPort > 0 {
+			// Only if net.peer.name is set should net.peer.port be.
+			attr = append(attr, c.PeerPort(peerPort))
+		}
+	}
+	if network != "" {
+		attr = append(attr, c.Transport(network))
+	}
+	if sockFamily != "" {
+		attr = append(attr, c.NetSockFamilyKey.String(sockFamily))
+	}
+	if sockPeerAddr != "" {
+		attr = append(attr, c.NetSockPeerAddrKey.String(sockPeerAddr))
+		if sockPeerPort > 0 {
+			// Only if net.sock.peer.addr is set should net.sock.peer.port be.
+			attr = append(attr, c.NetSockPeerPortKey.Int(sockPeerPort))
+		}
+	}
+	if sockHostAddr != "" {
+		attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr))
+		if sockHostPort > 0 {
+			// Only if net.sock.host.addr is set should net.sock.host.port be.
+			attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort))
+		}
+	}
+	return attr
+}
+
+func family(network, address string) string {
+	switch network {
+	case "unix", "unixgram", "unixpacket":
+		return "unix"
+	default:
+		if ip := net.ParseIP(address); ip != nil {
+			if ip.To4() == nil {
+				return "inet6"
+			}
+			return "inet"
+		}
+	}
+	return ""
+}
+
+func nonZeroStr(strs ...string) int {
+	var n int
+	for _, str := range strs {
+		if str != "" {
+			n++
+		}
+	}
+	return n
+}
+
+func positiveInt(ints ...int) int {
+	var n int
+	for _, i := range ints {
+		if i > 0 {
+			n++
+		}
+	}
+	return n
+}
+
+// Peer returns attributes for a network peer address.
+func (c *NetConv) Peer(address string) []attribute.KeyValue {
+	h, p := splitHostPort(address)
+	var n int
+	if h != "" {
+		n++
+		if p > 0 {
+			n++
+		}
+	}
+
+	if n == 0 {
+		return nil
+	}
+
+	attrs := make([]attribute.KeyValue, 0, n)
+	attrs = append(attrs, c.PeerName(h))
+	if p > 0 {
+		attrs = append(attrs, c.PeerPort(p))
+	}
+	return attrs
+}
+
+func (c *NetConv) PeerName(name string) attribute.KeyValue {
+	return c.NetPeerNameKey.String(name)
+}
+
+func (c *NetConv) PeerPort(port int) attribute.KeyValue {
+	return c.NetPeerPortKey.Int(port)
+}
+
+func (c *NetConv) SockPeerAddr(addr string) attribute.KeyValue {
+	return c.NetSockPeerAddrKey.String(addr)
+}
+
+func (c *NetConv) SockPeerPort(port int) attribute.KeyValue {
+	return c.NetSockPeerPortKey.Int(port)
+}
+
+// splitHostPort splits a network address hostport of the form "host",
+// "host%zone", "[host]", "[host%zone], "host:port", "host%zone:port",
+// "[host]:port", "[host%zone]:port", or ":port" into host or host%zone and
+// port.
+//
+// An empty host is returned if it is not provided or unparsable. A negative
+// port is returned if it is not provided or unparsable.
+func splitHostPort(hostport string) (host string, port int) {
+	port = -1
+
+	if strings.HasPrefix(hostport, "[") {
+		addrEnd := strings.LastIndex(hostport, "]")
+		if addrEnd < 0 {
+			// Invalid hostport.
+			return
+		}
+		if i := strings.LastIndex(hostport[addrEnd:], ":"); i < 0 {
+			host = hostport[1:addrEnd]
+			return
+		}
+	} else {
+		if i := strings.LastIndex(hostport, ":"); i < 0 {
+			host = hostport
+			return
+		}
+	}
+
+	host, pStr, err := net.SplitHostPort(hostport)
+	if err != nil {
+		return
+	}
+
+	p, err := strconv.ParseUint(pStr, 10, 16)
+	if err != nil {
+		return
+	}
+	return host, int(p)
+}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/doc.go b/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/doc.go
deleted file mode 100644
index 181fcc9c..00000000
--- a/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/doc.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright The OpenTelemetry 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 semconv implements OpenTelemetry semantic conventions.
-//
-// OpenTelemetry semantic conventions are agreed standardized naming
-// patterns for OpenTelemetry things. This package represents the conventions
-// as of the v1.12.0 version of the OpenTelemetry specification.
-package semconv // import "go.opentelemetry.io/otel/semconv/v1.12.0"
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/exception.go b/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/exception.go
deleted file mode 100644
index d6892709..00000000
--- a/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/exception.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright The OpenTelemetry 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 semconv // import "go.opentelemetry.io/otel/semconv/v1.12.0"
-
-const (
-	// ExceptionEventName is the name of the Span event representing an exception.
-	ExceptionEventName = "exception"
-)
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/http.go b/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/http.go
deleted file mode 100644
index 4b4f3cba..00000000
--- a/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/http.go
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright The OpenTelemetry 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 semconv // import "go.opentelemetry.io/otel/semconv/v1.12.0"
-
-import (
-	"net/http"
-
-	"go.opentelemetry.io/otel/attribute"
-	"go.opentelemetry.io/otel/codes"
-	"go.opentelemetry.io/otel/semconv/internal"
-	"go.opentelemetry.io/otel/trace"
-)
-
-// HTTP scheme attributes.
-var (
-	HTTPSchemeHTTP  = HTTPSchemeKey.String("http")
-	HTTPSchemeHTTPS = HTTPSchemeKey.String("https")
-)
-
-var sc = &internal.SemanticConventions{
-	EnduserIDKey:                EnduserIDKey,
-	HTTPClientIPKey:             HTTPClientIPKey,
-	HTTPFlavorKey:               HTTPFlavorKey,
-	HTTPHostKey:                 HTTPHostKey,
-	HTTPMethodKey:               HTTPMethodKey,
-	HTTPRequestContentLengthKey: HTTPRequestContentLengthKey,
-	HTTPRouteKey:                HTTPRouteKey,
-	HTTPSchemeHTTP:              HTTPSchemeHTTP,
-	HTTPSchemeHTTPS:             HTTPSchemeHTTPS,
-	HTTPServerNameKey:           HTTPServerNameKey,
-	HTTPStatusCodeKey:           HTTPStatusCodeKey,
-	HTTPTargetKey:               HTTPTargetKey,
-	HTTPURLKey:                  HTTPURLKey,
-	HTTPUserAgentKey:            HTTPUserAgentKey,
-	NetHostIPKey:                NetHostIPKey,
-	NetHostNameKey:              NetHostNameKey,
-	NetHostPortKey:              NetHostPortKey,
-	NetPeerIPKey:                NetPeerIPKey,
-	NetPeerNameKey:              NetPeerNameKey,
-	NetPeerPortKey:              NetPeerPortKey,
-	NetTransportIP:              NetTransportIP,
-	NetTransportOther:           NetTransportOther,
-	NetTransportTCP:             NetTransportTCP,
-	NetTransportUDP:             NetTransportUDP,
-	NetTransportUnix:            NetTransportUnix,
-}
-
-// NetAttributesFromHTTPRequest generates attributes of the net
-// namespace as specified by the OpenTelemetry specification for a
-// span.  The network parameter is a string that net.Dial function
-// from standard library can understand.
-func NetAttributesFromHTTPRequest(network string, request *http.Request) []attribute.KeyValue {
-	return sc.NetAttributesFromHTTPRequest(network, request)
-}
-
-// EndUserAttributesFromHTTPRequest generates attributes of the
-// enduser namespace as specified by the OpenTelemetry specification
-// for a span.
-func EndUserAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
-	return sc.EndUserAttributesFromHTTPRequest(request)
-}
-
-// HTTPClientAttributesFromHTTPRequest generates attributes of the
-// http namespace as specified by the OpenTelemetry specification for
-// a span on the client side.
-func HTTPClientAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {
-	return sc.HTTPClientAttributesFromHTTPRequest(request)
-}
-
-// HTTPServerMetricAttributesFromHTTPRequest generates low-cardinality attributes
-// to be used with server-side HTTP metrics.
-func HTTPServerMetricAttributesFromHTTPRequest(serverName string, request *http.Request) []attribute.KeyValue {
-	return sc.HTTPServerMetricAttributesFromHTTPRequest(serverName, request)
-}
-
-// HTTPServerAttributesFromHTTPRequest generates attributes of the
-// http namespace as specified by the OpenTelemetry specification for
-// a span on the server side. Currently, only basic authentication is
-// supported.
-func HTTPServerAttributesFromHTTPRequest(serverName, route string, request *http.Request) []attribute.KeyValue {
-	return sc.HTTPServerAttributesFromHTTPRequest(serverName, route, request)
-}
-
-// HTTPAttributesFromHTTPStatusCode generates attributes of the http
-// namespace as specified by the OpenTelemetry specification for a
-// span.
-func HTTPAttributesFromHTTPStatusCode(code int) []attribute.KeyValue {
-	return sc.HTTPAttributesFromHTTPStatusCode(code)
-}
-
-// SpanStatusFromHTTPStatusCode generates a status code and a message
-// as specified by the OpenTelemetry specification for a span.
-func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
-	return internal.SpanStatusFromHTTPStatusCode(code)
-}
-
-// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
-// as specified by the OpenTelemetry specification for a span.
-// Exclude 4xx for SERVER to set the appropriate status.
-func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
-	return internal.SpanStatusFromHTTPStatusCodeAndSpanKind(code, spanKind)
-}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/resource.go b/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/resource.go
deleted file mode 100644
index b2155676..00000000
--- a/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/resource.go
+++ /dev/null
@@ -1,1042 +0,0 @@
-// Copyright The OpenTelemetry 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.
-
-// Code generated from semantic convention specification. DO NOT EDIT.
-
-package semconv // import "go.opentelemetry.io/otel/semconv/v1.12.0"
-
-import "go.opentelemetry.io/otel/attribute"
-
-// The web browser in which the application represented by the resource is running. The `browser.*` attributes MUST be used only for resources that represent applications running in a web browser (regardless of whether running on a mobile or desktop device).
-const (
-	// Array of brand name and version separated by a space
-	//
-	// Type: string[]
-	// Required: No
-	// Stability: stable
-	// Examples: ' Not A;Brand 99', 'Chromium 99', 'Chrome 99'
-	// Note: This value is intended to be taken from the [UA client hints
-	// API](https://wicg.github.io/ua-client-hints/#interface)
-	// (navigator.userAgentData.brands).
-	BrowserBrandsKey = attribute.Key("browser.brands")
-	// The platform on which the browser is running
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'Windows', 'macOS', 'Android'
-	// Note: This value is intended to be taken from the [UA client hints
-	// API](https://wicg.github.io/ua-client-hints/#interface)
-	// (navigator.userAgentData.platform). If unavailable, the legacy
-	// `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD
-	// be left unset in order for the values to be consistent.
-	// The list of possible values is defined in the [W3C User-Agent Client Hints
-	// specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform).
-	// Note that some (but not all) of these values can overlap with values in the
-	// [os.type and os.name attributes](./os.md). However, for consistency, the values
-	// in the `browser.platform` attribute should capture the exact value that the
-	// user agent provides.
-	BrowserPlatformKey = attribute.Key("browser.platform")
-	// Full user-agent string provided by the browser
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36
-	// (KHTML, '
-	//  'like Gecko) Chrome/95.0.4638.54 Safari/537.36'
-	// Note: The user-agent value SHOULD be provided only from browsers that do not
-	// have a mechanism to retrieve brands and platform individually from the User-
-	// Agent Client Hints API. To retrieve the value, the legacy `navigator.userAgent`
-	// API can be used.
-	BrowserUserAgentKey = attribute.Key("browser.user_agent")
-)
-
-// A cloud environment (e.g. GCP, Azure, AWS)
-const (
-	// Name of the cloud provider.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	CloudProviderKey = attribute.Key("cloud.provider")
-	// The cloud account ID the resource is assigned to.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '111111111111', 'opentelemetry'
-	CloudAccountIDKey = attribute.Key("cloud.account.id")
-	// The geographical region the resource is running.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'us-central1', 'us-east-1'
-	// Note: Refer to your provider's docs to see the available regions, for example
-	// [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-
-	// detail/40654.htm), [AWS regions](https://aws.amazon.com/about-aws/global-
-	// infrastructure/regions_az/), [Azure regions](https://azure.microsoft.com/en-
-	// us/global-infrastructure/geographies/), [Google Cloud
-	// regions](https://cloud.google.com/about/locations), or [Tencent Cloud
-	// regions](https://intl.cloud.tencent.com/document/product/213/6091).
-	CloudRegionKey = attribute.Key("cloud.region")
-	// Cloud regions often have multiple, isolated locations known as zones to
-	// increase availability. Availability zone represents the zone where the resource
-	// is running.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'us-east-1c'
-	// Note: Availability zones are called "zones" on Alibaba Cloud and Google Cloud.
-	CloudAvailabilityZoneKey = attribute.Key("cloud.availability_zone")
-	// The cloud platform in use.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	// Note: The prefix of the service SHOULD match the one specified in
-	// `cloud.provider`.
-	CloudPlatformKey = attribute.Key("cloud.platform")
-)
-
-var (
-	// Alibaba Cloud
-	CloudProviderAlibabaCloud = CloudProviderKey.String("alibaba_cloud")
-	// Amazon Web Services
-	CloudProviderAWS = CloudProviderKey.String("aws")
-	// Microsoft Azure
-	CloudProviderAzure = CloudProviderKey.String("azure")
-	// Google Cloud Platform
-	CloudProviderGCP = CloudProviderKey.String("gcp")
-	// Tencent Cloud
-	CloudProviderTencentCloud = CloudProviderKey.String("tencent_cloud")
-)
-
-var (
-	// Alibaba Cloud Elastic Compute Service
-	CloudPlatformAlibabaCloudECS = CloudPlatformKey.String("alibaba_cloud_ecs")
-	// Alibaba Cloud Function Compute
-	CloudPlatformAlibabaCloudFc = CloudPlatformKey.String("alibaba_cloud_fc")
-	// AWS Elastic Compute Cloud
-	CloudPlatformAWSEC2 = CloudPlatformKey.String("aws_ec2")
-	// AWS Elastic Container Service
-	CloudPlatformAWSECS = CloudPlatformKey.String("aws_ecs")
-	// AWS Elastic Kubernetes Service
-	CloudPlatformAWSEKS = CloudPlatformKey.String("aws_eks")
-	// AWS Lambda
-	CloudPlatformAWSLambda = CloudPlatformKey.String("aws_lambda")
-	// AWS Elastic Beanstalk
-	CloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String("aws_elastic_beanstalk")
-	// AWS App Runner
-	CloudPlatformAWSAppRunner = CloudPlatformKey.String("aws_app_runner")
-	// Azure Virtual Machines
-	CloudPlatformAzureVM = CloudPlatformKey.String("azure_vm")
-	// Azure Container Instances
-	CloudPlatformAzureContainerInstances = CloudPlatformKey.String("azure_container_instances")
-	// Azure Kubernetes Service
-	CloudPlatformAzureAKS = CloudPlatformKey.String("azure_aks")
-	// Azure Functions
-	CloudPlatformAzureFunctions = CloudPlatformKey.String("azure_functions")
-	// Azure App Service
-	CloudPlatformAzureAppService = CloudPlatformKey.String("azure_app_service")
-	// Google Cloud Compute Engine (GCE)
-	CloudPlatformGCPComputeEngine = CloudPlatformKey.String("gcp_compute_engine")
-	// Google Cloud Run
-	CloudPlatformGCPCloudRun = CloudPlatformKey.String("gcp_cloud_run")
-	// Google Cloud Kubernetes Engine (GKE)
-	CloudPlatformGCPKubernetesEngine = CloudPlatformKey.String("gcp_kubernetes_engine")
-	// Google Cloud Functions (GCF)
-	CloudPlatformGCPCloudFunctions = CloudPlatformKey.String("gcp_cloud_functions")
-	// Google Cloud App Engine (GAE)
-	CloudPlatformGCPAppEngine = CloudPlatformKey.String("gcp_app_engine")
-	// Tencent Cloud Cloud Virtual Machine (CVM)
-	CloudPlatformTencentCloudCvm = CloudPlatformKey.String("tencent_cloud_cvm")
-	// Tencent Cloud Elastic Kubernetes Service (EKS)
-	CloudPlatformTencentCloudEKS = CloudPlatformKey.String("tencent_cloud_eks")
-	// Tencent Cloud Serverless Cloud Function (SCF)
-	CloudPlatformTencentCloudScf = CloudPlatformKey.String("tencent_cloud_scf")
-)
-
-// Resources used by AWS Elastic Container Service (ECS).
-const (
-	// The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.
-	// amazon.com/AmazonECS/latest/developerguide/ECS_instances.html).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'arn:aws:ecs:us-
-	// west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9'
-	AWSECSContainerARNKey = attribute.Key("aws.ecs.container.arn")
-	// The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/develo
-	// perguide/clusters.html).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'
-	AWSECSClusterARNKey = attribute.Key("aws.ecs.cluster.arn")
-	// The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/l
-	// aunch_types.html) for an ECS task.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	AWSECSLaunchtypeKey = attribute.Key("aws.ecs.launchtype")
-	// The ARN of an [ECS task definition](https://docs.aws.amazon.com/AmazonECS/lates
-	// t/developerguide/task_definitions.html).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'arn:aws:ecs:us-
-	// west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b'
-	AWSECSTaskARNKey = attribute.Key("aws.ecs.task.arn")
-	// The task definition family this task definition is a member of.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'opentelemetry-family'
-	AWSECSTaskFamilyKey = attribute.Key("aws.ecs.task.family")
-	// The revision for this task definition.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '8', '26'
-	AWSECSTaskRevisionKey = attribute.Key("aws.ecs.task.revision")
-)
-
-var (
-	// ec2
-	AWSECSLaunchtypeEC2 = AWSECSLaunchtypeKey.String("ec2")
-	// fargate
-	AWSECSLaunchtypeFargate = AWSECSLaunchtypeKey.String("fargate")
-)
-
-// Resources used by AWS Elastic Kubernetes Service (EKS).
-const (
-	// The ARN of an EKS cluster.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'
-	AWSEKSClusterARNKey = attribute.Key("aws.eks.cluster.arn")
-)
-
-// Resources specific to Amazon Web Services.
-const (
-	// The name(s) of the AWS log group(s) an application is writing to.
-	//
-	// Type: string[]
-	// Required: No
-	// Stability: stable
-	// Examples: '/aws/lambda/my-function', 'opentelemetry-service'
-	// Note: Multiple log groups must be supported for cases like multi-container
-	// applications, where a single application has sidecar containers, and each write
-	// to their own log group.
-	AWSLogGroupNamesKey = attribute.Key("aws.log.group.names")
-	// The Amazon Resource Name(s) (ARN) of the AWS log group(s).
-	//
-	// Type: string[]
-	// Required: No
-	// Stability: stable
-	// Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*'
-	// Note: See the [log group ARN format
-	// documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-
-	// access-control-overview-cwl.html#CWL_ARN_Format).
-	AWSLogGroupARNsKey = attribute.Key("aws.log.group.arns")
-	// The name(s) of the AWS log stream(s) an application is writing to.
-	//
-	// Type: string[]
-	// Required: No
-	// Stability: stable
-	// Examples: 'logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'
-	AWSLogStreamNamesKey = attribute.Key("aws.log.stream.names")
-	// The ARN(s) of the AWS log stream(s).
-	//
-	// Type: string[]
-	// Required: No
-	// Stability: stable
-	// Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-
-	// stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'
-	// Note: See the [log stream ARN format
-	// documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-
-	// access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain
-	// several log streams, so these ARNs necessarily identify both a log group and a
-	// log stream.
-	AWSLogStreamARNsKey = attribute.Key("aws.log.stream.arns")
-)
-
-// A container instance.
-const (
-	// Container name used by container runtime.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'opentelemetry-autoconf'
-	ContainerNameKey = attribute.Key("container.name")
-	// Container ID. Usually a UUID, as for example used to [identify Docker
-	// containers](https://docs.docker.com/engine/reference/run/#container-
-	// identification). The UUID might be abbreviated.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'a3bf90e006b2'
-	ContainerIDKey = attribute.Key("container.id")
-	// The container runtime managing this container.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'docker', 'containerd', 'rkt'
-	ContainerRuntimeKey = attribute.Key("container.runtime")
-	// Name of the image the container was built on.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'gcr.io/opentelemetry/operator'
-	ContainerImageNameKey = attribute.Key("container.image.name")
-	// Container image tag.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '0.1'
-	ContainerImageTagKey = attribute.Key("container.image.tag")
-)
-
-// The software deployment.
-const (
-	// Name of the [deployment
-	// environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka
-	// deployment tier).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'staging', 'production'
-	DeploymentEnvironmentKey = attribute.Key("deployment.environment")
-)
-
-// The device on which the process represented by this resource is running.
-const (
-	// A unique identifier representing the device
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '2ab2916d-a51f-4ac8-80ee-45ac31a28092'
-	// Note: The device identifier MUST only be defined using the values outlined
-	// below. This value is not an advertising identifier and MUST NOT be used as
-	// such. On iOS (Swift or Objective-C), this value MUST be equal to the [vendor id
-	// entifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-iden
-	// tifierforvendor). On Android (Java or Kotlin), this value MUST be equal to the
-	// Firebase Installation ID or a globally unique UUID which is persisted across
-	// sessions in your application. More information can be found
-	// [here](https://developer.android.com/training/articles/user-data-ids) on best
-	// practices and exact implementation details. Caution should be taken when
-	// storing personal data or anything which can identify a user. GDPR and data
-	// protection laws may apply, ensure you do your own due diligence.
-	DeviceIDKey = attribute.Key("device.id")
-	// The model identifier for the device
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'iPhone3,4', 'SM-G920F'
-	// Note: It's recommended this value represents a machine readable version of the
-	// model identifier rather than the market or consumer-friendly name of the
-	// device.
-	DeviceModelIdentifierKey = attribute.Key("device.model.identifier")
-	// The marketing name for the device model
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'iPhone 6s Plus', 'Samsung Galaxy S6'
-	// Note: It's recommended this value represents a human readable version of the
-	// device model rather than a machine readable alternative.
-	DeviceModelNameKey = attribute.Key("device.model.name")
-	// The name of the device manufacturer
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'Apple', 'Samsung'
-	// Note: The Android OS provides this field via
-	// [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER).
-	// iOS apps SHOULD hardcode the value `Apple`.
-	DeviceManufacturerKey = attribute.Key("device.manufacturer")
-)
-
-// A serverless instance.
-const (
-	// The name of the single function that this runtime instance executes.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'my-function', 'myazurefunctionapp/some-function-name'
-	// Note: This is the name of the function as configured/deployed on the FaaS
-	// platform and is usually different from the name of the callback
-	// function (which may be stored in the
-	// [`code.namespace`/`code.function`](../../trace/semantic_conventions/span-
-	// general.md#source-code-attributes)
-	// span attributes).
-
-	// For some cloud providers, the above definition is ambiguous. The following
-	// definition of function name MUST be used for this attribute
-	// (and consequently the span name) for the listed cloud providers/products:
-
-	// * **Azure:**  The full name `<FUNCAPP>/<FUNC>`, i.e., function app name
-	//   followed by a forward slash followed by the function name (this form
-	//   can also be seen in the resource JSON for the function).
-	//   This means that a span attribute MUST be used, as an Azure function
-	//   app can host multiple functions that would usually share
-	//   a TracerProvider (see also the `faas.id` attribute).
-	FaaSNameKey = attribute.Key("faas.name")
-	// The unique ID of the single function that this runtime instance executes.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'arn:aws:lambda:us-west-2:123456789012:function:my-function'
-	// Note: On some cloud providers, it may not be possible to determine the full ID
-	// at startup,
-	// so consider setting `faas.id` as a span attribute instead.
-
-	// The exact value to use for `faas.id` depends on the cloud provider:
-
-	// * **AWS Lambda:** The function
-	// [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-
-	// namespaces.html).
-	//   Take care not to use the "invoked ARN" directly but replace any
-	//   [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-
-	// aliases.html)
-	//   with the resolved function version, as the same runtime instance may be
-	// invokable with
-	//   multiple different aliases.
-	// * **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-
-	// resource-names)
-	// * **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-
-	// us/rest/api/resources/resources/get-by-id) of the invoked function,
-	//   *not* the function app, having the form
-	//   `/subscriptions/<SUBSCIPTION_GUID>/resourceGroups/<RG>/providers/Microsoft.We
-	// b/sites/<FUNCAPP>/functions/<FUNC>`.
-	//   This means that a span attribute MUST be used, as an Azure function app can
-	// host multiple functions that would usually share
-	//   a TracerProvider.
-	FaaSIDKey = attribute.Key("faas.id")
-	// The immutable version of the function being executed.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '26', 'pinkfroid-00002'
-	// Note: Depending on the cloud provider and platform, use:
-
-	// * **AWS Lambda:** The [function
-	// version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-
-	// versions.html)
-	//   (an integer represented as a decimal string).
-	// * **Google Cloud Run:** The
-	// [revision](https://cloud.google.com/run/docs/managing/revisions)
-	//   (i.e., the function name plus the revision suffix).
-	// * **Google Cloud Functions:** The value of the
-	//   [`K_REVISION` environment
-	// variable](https://cloud.google.com/functions/docs/env-
-	// var#runtime_environment_variables_set_automatically).
-	// * **Azure Functions:** Not applicable. Do not set this attribute.
-	FaaSVersionKey = attribute.Key("faas.version")
-	// The execution environment ID as a string, that will be potentially reused for
-	// other invocations to the same function/function version.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de'
-	// Note: * **AWS Lambda:** Use the (full) log stream name.
-	FaaSInstanceKey = attribute.Key("faas.instance")
-	// The amount of memory available to the serverless function in MiB.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 128
-	// Note: It's recommended to set this attribute since e.g. too little memory can
-	// easily stop a Java AWS Lambda function from working correctly. On AWS Lambda,
-	// the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this
-	// information.
-	FaaSMaxMemoryKey = attribute.Key("faas.max_memory")
-)
-
-// A host is defined as a general computing instance.
-const (
-	// Unique host ID. For Cloud, this must be the instance_id assigned by the cloud
-	// provider.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'opentelemetry-test'
-	HostIDKey = attribute.Key("host.id")
-	// Name of the host. On Unix systems, it may contain what the hostname command
-	// returns, or the fully qualified hostname, or another name specified by the
-	// user.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'opentelemetry-test'
-	HostNameKey = attribute.Key("host.name")
-	// Type of host. For Cloud, this must be the machine type.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'n1-standard-1'
-	HostTypeKey = attribute.Key("host.type")
-	// The CPU architecture the host system is running on.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	HostArchKey = attribute.Key("host.arch")
-	// Name of the VM image or OS install the host was instantiated from.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905'
-	HostImageNameKey = attribute.Key("host.image.name")
-	// VM image ID. For Cloud, this value is from the provider.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'ami-07b06b442921831e5'
-	HostImageIDKey = attribute.Key("host.image.id")
-	// The version string of the VM image as defined in [Version
-	// Attributes](README.md#version-attributes).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '0.1'
-	HostImageVersionKey = attribute.Key("host.image.version")
-)
-
-var (
-	// AMD64
-	HostArchAMD64 = HostArchKey.String("amd64")
-	// ARM32
-	HostArchARM32 = HostArchKey.String("arm32")
-	// ARM64
-	HostArchARM64 = HostArchKey.String("arm64")
-	// Itanium
-	HostArchIA64 = HostArchKey.String("ia64")
-	// 32-bit PowerPC
-	HostArchPPC32 = HostArchKey.String("ppc32")
-	// 64-bit PowerPC
-	HostArchPPC64 = HostArchKey.String("ppc64")
-	// IBM z/Architecture
-	HostArchS390x = HostArchKey.String("s390x")
-	// 32-bit x86
-	HostArchX86 = HostArchKey.String("x86")
-)
-
-// A Kubernetes Cluster.
-const (
-	// The name of the cluster.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'opentelemetry-cluster'
-	K8SClusterNameKey = attribute.Key("k8s.cluster.name")
-)
-
-// A Kubernetes Node object.
-const (
-	// The name of the Node.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'node-1'
-	K8SNodeNameKey = attribute.Key("k8s.node.name")
-	// The UID of the Node.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2'
-	K8SNodeUIDKey = attribute.Key("k8s.node.uid")
-)
-
-// A Kubernetes Namespace.
-const (
-	// The name of the namespace that the pod is running in.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'default'
-	K8SNamespaceNameKey = attribute.Key("k8s.namespace.name")
-)
-
-// A Kubernetes Pod object.
-const (
-	// The UID of the Pod.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
-	K8SPodUIDKey = attribute.Key("k8s.pod.uid")
-	// The name of the Pod.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'opentelemetry-pod-autoconf'
-	K8SPodNameKey = attribute.Key("k8s.pod.name")
-)
-
-// A container in a [PodTemplate](https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates).
-const (
-	// The name of the Container from Pod specification, must be unique within a Pod.
-	// Container runtime usually uses different globally unique name
-	// (`container.name`).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'redis'
-	K8SContainerNameKey = attribute.Key("k8s.container.name")
-	// Number of times the container was restarted. This attribute can be used to
-	// identify a particular container (running or stopped) within a container spec.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 0, 2
-	K8SContainerRestartCountKey = attribute.Key("k8s.container.restart_count")
-)
-
-// A Kubernetes ReplicaSet object.
-const (
-	// The UID of the ReplicaSet.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
-	K8SReplicaSetUIDKey = attribute.Key("k8s.replicaset.uid")
-	// The name of the ReplicaSet.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'opentelemetry'
-	K8SReplicaSetNameKey = attribute.Key("k8s.replicaset.name")
-)
-
-// A Kubernetes Deployment object.
-const (
-	// The UID of the Deployment.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
-	K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid")
-	// The name of the Deployment.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'opentelemetry'
-	K8SDeploymentNameKey = attribute.Key("k8s.deployment.name")
-)
-
-// A Kubernetes StatefulSet object.
-const (
-	// The UID of the StatefulSet.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
-	K8SStatefulSetUIDKey = attribute.Key("k8s.statefulset.uid")
-	// The name of the StatefulSet.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'opentelemetry'
-	K8SStatefulSetNameKey = attribute.Key("k8s.statefulset.name")
-)
-
-// A Kubernetes DaemonSet object.
-const (
-	// The UID of the DaemonSet.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
-	K8SDaemonSetUIDKey = attribute.Key("k8s.daemonset.uid")
-	// The name of the DaemonSet.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'opentelemetry'
-	K8SDaemonSetNameKey = attribute.Key("k8s.daemonset.name")
-)
-
-// A Kubernetes Job object.
-const (
-	// The UID of the Job.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
-	K8SJobUIDKey = attribute.Key("k8s.job.uid")
-	// The name of the Job.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'opentelemetry'
-	K8SJobNameKey = attribute.Key("k8s.job.name")
-)
-
-// A Kubernetes CronJob object.
-const (
-	// The UID of the CronJob.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
-	K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid")
-	// The name of the CronJob.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'opentelemetry'
-	K8SCronJobNameKey = attribute.Key("k8s.cronjob.name")
-)
-
-// The operating system (OS) on which the process represented by this resource is running.
-const (
-	// The operating system type.
-	//
-	// Type: Enum
-	// Required: Always
-	// Stability: stable
-	OSTypeKey = attribute.Key("os.type")
-	// Human readable (not intended to be parsed) OS version information, like e.g.
-	// reported by `ver` or `lsb_release -a` commands.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1 LTS'
-	OSDescriptionKey = attribute.Key("os.description")
-	// Human readable operating system name.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'iOS', 'Android', 'Ubuntu'
-	OSNameKey = attribute.Key("os.name")
-	// The version string of the operating system as defined in [Version
-	// Attributes](../../resource/semantic_conventions/README.md#version-attributes).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '14.2.1', '18.04.1'
-	OSVersionKey = attribute.Key("os.version")
-)
-
-var (
-	// Microsoft Windows
-	OSTypeWindows = OSTypeKey.String("windows")
-	// Linux
-	OSTypeLinux = OSTypeKey.String("linux")
-	// Apple Darwin
-	OSTypeDarwin = OSTypeKey.String("darwin")
-	// FreeBSD
-	OSTypeFreeBSD = OSTypeKey.String("freebsd")
-	// NetBSD
-	OSTypeNetBSD = OSTypeKey.String("netbsd")
-	// OpenBSD
-	OSTypeOpenBSD = OSTypeKey.String("openbsd")
-	// DragonFly BSD
-	OSTypeDragonflyBSD = OSTypeKey.String("dragonflybsd")
-	// HP-UX (Hewlett Packard Unix)
-	OSTypeHPUX = OSTypeKey.String("hpux")
-	// AIX (Advanced Interactive eXecutive)
-	OSTypeAIX = OSTypeKey.String("aix")
-	// SunOS, Oracle Solaris
-	OSTypeSolaris = OSTypeKey.String("solaris")
-	// IBM z/OS
-	OSTypeZOS = OSTypeKey.String("z_os")
-)
-
-// An operating system process.
-const (
-	// Process identifier (PID).
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 1234
-	ProcessPIDKey = attribute.Key("process.pid")
-	// The name of the process executable. On Linux based systems, can be set to the
-	// `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of
-	// `GetProcessImageFileNameW`.
-	//
-	// Type: string
-	// Required: See below
-	// Stability: stable
-	// Examples: 'otelcol'
-	ProcessExecutableNameKey = attribute.Key("process.executable.name")
-	// The full path to the process executable. On Linux based systems, can be set to
-	// the target of `proc/[pid]/exe`. On Windows, can be set to the result of
-	// `GetProcessImageFileNameW`.
-	//
-	// Type: string
-	// Required: See below
-	// Stability: stable
-	// Examples: '/usr/bin/cmd/otelcol'
-	ProcessExecutablePathKey = attribute.Key("process.executable.path")
-	// The command used to launch the process (i.e. the command name). On Linux based
-	// systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows,
-	// can be set to the first parameter extracted from `GetCommandLineW`.
-	//
-	// Type: string
-	// Required: See below
-	// Stability: stable
-	// Examples: 'cmd/otelcol'
-	ProcessCommandKey = attribute.Key("process.command")
-	// The full command used to launch the process as a single string representing the
-	// full command. On Windows, can be set to the result of `GetCommandLineW`. Do not
-	// set this if you have to assemble it just for monitoring; use
-	// `process.command_args` instead.
-	//
-	// Type: string
-	// Required: See below
-	// Stability: stable
-	// Examples: 'C:\\cmd\\otecol --config="my directory\\config.yaml"'
-	ProcessCommandLineKey = attribute.Key("process.command_line")
-	// All the command arguments (including the command/executable itself) as received
-	// by the process. On Linux-based systems (and some other Unixoid systems
-	// supporting procfs), can be set according to the list of null-delimited strings
-	// extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be
-	// the full argv vector passed to `main`.
-	//
-	// Type: string[]
-	// Required: See below
-	// Stability: stable
-	// Examples: 'cmd/otecol', '--config=config.yaml'
-	ProcessCommandArgsKey = attribute.Key("process.command_args")
-	// The username of the user that owns the process.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'root'
-	ProcessOwnerKey = attribute.Key("process.owner")
-)
-
-// The single (language) runtime instance which is monitored.
-const (
-	// The name of the runtime of this process. For compiled native binaries, this
-	// SHOULD be the name of the compiler.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'OpenJDK Runtime Environment'
-	ProcessRuntimeNameKey = attribute.Key("process.runtime.name")
-	// The version of the runtime of this process, as returned by the runtime without
-	// modification.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '14.0.2'
-	ProcessRuntimeVersionKey = attribute.Key("process.runtime.version")
-	// An additional description about the runtime of the process, for example a
-	// specific vendor customization of the runtime environment.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0'
-	ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description")
-)
-
-// A service instance.
-const (
-	// Logical name of the service.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'shoppingcart'
-	// Note: MUST be the same for all instances of horizontally scaled services. If
-	// the value was not specified, SDKs MUST fallback to `unknown_service:`
-	// concatenated with [`process.executable.name`](process.md#process), e.g.
-	// `unknown_service:bash`. If `process.executable.name` is not available, the
-	// value MUST be set to `unknown_service`.
-	ServiceNameKey = attribute.Key("service.name")
-	// A namespace for `service.name`.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'Shop'
-	// Note: A string value having a meaning that helps to distinguish a group of
-	// services, for example the team name that owns a group of services.
-	// `service.name` is expected to be unique within the same namespace. If
-	// `service.namespace` is not specified in the Resource then `service.name` is
-	// expected to be unique for all services that have no explicit namespace defined
-	// (so the empty/unspecified namespace is simply one more valid namespace). Zero-
-	// length namespace string is assumed equal to unspecified namespace.
-	ServiceNamespaceKey = attribute.Key("service.namespace")
-	// The string ID of the service instance.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '627cc493-f310-47de-96bd-71410b7dec09'
-	// Note: MUST be unique for each instance of the same
-	// `service.namespace,service.name` pair (in other words
-	// `service.namespace,service.name,service.instance.id` triplet MUST be globally
-	// unique). The ID helps to distinguish instances of the same service that exist
-	// at the same time (e.g. instances of a horizontally scaled service). It is
-	// preferable for the ID to be persistent and stay the same for the lifetime of
-	// the service instance, however it is acceptable that the ID is ephemeral and
-	// changes during important lifetime events for the service (e.g. service
-	// restarts). If the service has no inherent unique ID that can be used as the
-	// value of this attribute it is recommended to generate a random Version 1 or
-	// Version 4 RFC 4122 UUID (services aiming for reproducible UUIDs may also use
-	// Version 5, see RFC 4122 for more recommendations).
-	ServiceInstanceIDKey = attribute.Key("service.instance.id")
-	// The version string of the service API or implementation.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '2.0.0'
-	ServiceVersionKey = attribute.Key("service.version")
-)
-
-// The telemetry SDK used to capture data recorded by the instrumentation libraries.
-const (
-	// The name of the telemetry SDK as defined above.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'opentelemetry'
-	TelemetrySDKNameKey = attribute.Key("telemetry.sdk.name")
-	// The language of the telemetry SDK.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	TelemetrySDKLanguageKey = attribute.Key("telemetry.sdk.language")
-	// The version string of the telemetry SDK.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '1.2.3'
-	TelemetrySDKVersionKey = attribute.Key("telemetry.sdk.version")
-	// The version string of the auto instrumentation agent, if used.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '1.2.3'
-	TelemetryAutoVersionKey = attribute.Key("telemetry.auto.version")
-)
-
-var (
-	// cpp
-	TelemetrySDKLanguageCPP = TelemetrySDKLanguageKey.String("cpp")
-	// dotnet
-	TelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String("dotnet")
-	// erlang
-	TelemetrySDKLanguageErlang = TelemetrySDKLanguageKey.String("erlang")
-	// go
-	TelemetrySDKLanguageGo = TelemetrySDKLanguageKey.String("go")
-	// java
-	TelemetrySDKLanguageJava = TelemetrySDKLanguageKey.String("java")
-	// nodejs
-	TelemetrySDKLanguageNodejs = TelemetrySDKLanguageKey.String("nodejs")
-	// php
-	TelemetrySDKLanguagePHP = TelemetrySDKLanguageKey.String("php")
-	// python
-	TelemetrySDKLanguagePython = TelemetrySDKLanguageKey.String("python")
-	// ruby
-	TelemetrySDKLanguageRuby = TelemetrySDKLanguageKey.String("ruby")
-	// webjs
-	TelemetrySDKLanguageWebjs = TelemetrySDKLanguageKey.String("webjs")
-	// swift
-	TelemetrySDKLanguageSwift = TelemetrySDKLanguageKey.String("swift")
-)
-
-// Resource describing the packaged software running the application code. Web engines are typically executed using process.runtime.
-const (
-	// The name of the web engine.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'WildFly'
-	WebEngineNameKey = attribute.Key("webengine.name")
-	// The version of the web engine.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '21.0.0'
-	WebEngineVersionKey = attribute.Key("webengine.version")
-	// Additional description of the web engine (e.g. detailed version and edition
-	// information).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final'
-	WebEngineDescriptionKey = attribute.Key("webengine.description")
-)
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/schema.go b/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/schema.go
deleted file mode 100644
index 2f2a019e..00000000
--- a/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/schema.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright The OpenTelemetry 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 semconv // import "go.opentelemetry.io/otel/semconv/v1.12.0"
-
-// SchemaURL is the schema URL that matches the version of the semantic conventions
-// that this package defines. Semconv packages starting from v1.4.0 must declare
-// non-empty schema URL in the form https://opentelemetry.io/schemas/<version>
-const SchemaURL = "https://opentelemetry.io/schemas/1.12.0"
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/trace.go b/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/trace.go
deleted file mode 100644
index 047d8e95..00000000
--- a/vendor/go.opentelemetry.io/otel/semconv/v1.12.0/trace.go
+++ /dev/null
@@ -1,1704 +0,0 @@
-// Copyright The OpenTelemetry 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.
-
-// Code generated from semantic convention specification. DO NOT EDIT.
-
-package semconv // import "go.opentelemetry.io/otel/semconv/v1.12.0"
-
-import "go.opentelemetry.io/otel/attribute"
-
-// Span attributes used by AWS Lambda (in addition to general `faas` attributes).
-const (
-	// The full invoked ARN as provided on the `Context` passed to the function
-	// (`Lambda-Runtime-Invoked-Function-ARN` header on the `/runtime/invocation/next`
-	// applicable).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'arn:aws:lambda:us-east-1:123456:function:myfunction:myalias'
-	// Note: This may be different from `faas.id` if an alias is involved.
-	AWSLambdaInvokedARNKey = attribute.Key("aws.lambda.invoked_arn")
-)
-
-// This document defines attributes for CloudEvents. CloudEvents is a specification on how to define event data in a standard way. These attributes can be attached to spans when performing operations with CloudEvents, regardless of the protocol being used.
-const (
-	// The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec
-	// .md#id) uniquely identifies the event.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: '123e4567-e89b-12d3-a456-426614174000', '0001'
-	CloudeventsEventIDKey = attribute.Key("cloudevents.event_id")
-	// The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.m
-	// d#source-1) identifies the context in which an event happened.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'https://github.com/cloudevents', '/cloudevents/spec/pull/123', 'my-
-	// service'
-	CloudeventsEventSourceKey = attribute.Key("cloudevents.event_source")
-	// The [version of the CloudEvents specification](https://github.com/cloudevents/s
-	// pec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: '1.0'
-	CloudeventsEventSpecVersionKey = attribute.Key("cloudevents.event_spec_version")
-	// The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/sp
-	// ec.md#type) contains a value describing the type of event related to the
-	// originating occurrence.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'com.github.pull_request.opened', 'com.example.object.deleted.v2'
-	CloudeventsEventTypeKey = attribute.Key("cloudevents.event_type")
-	// The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.
-	// md#subject) of the event in the context of the event producer (identified by
-	// source).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'mynewfile.jpg'
-	CloudeventsEventSubjectKey = attribute.Key("cloudevents.event_subject")
-)
-
-// This document defines semantic conventions for the OpenTracing Shim
-const (
-	// Parent-child Reference type
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	// Note: The causal relationship between a child Span and a parent Span.
-	OpentracingRefTypeKey = attribute.Key("opentracing.ref_type")
-)
-
-var (
-	// The parent Span depends on the child Span in some capacity
-	OpentracingRefTypeChildOf = OpentracingRefTypeKey.String("child_of")
-	// The parent Span does not depend in any way on the result of the child Span
-	OpentracingRefTypeFollowsFrom = OpentracingRefTypeKey.String("follows_from")
-)
-
-// This document defines the attributes used to perform database client calls.
-const (
-	// An identifier for the database management system (DBMS) product being used. See
-	// below for a list of well-known identifiers.
-	//
-	// Type: Enum
-	// Required: Always
-	// Stability: stable
-	DBSystemKey = attribute.Key("db.system")
-	// The connection string used to connect to the database. It is recommended to
-	// remove embedded credentials.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'Server=(localdb)\\v11.0;Integrated Security=true;'
-	DBConnectionStringKey = attribute.Key("db.connection_string")
-	// Username for accessing the database.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'readonly_user', 'reporting_user'
-	DBUserKey = attribute.Key("db.user")
-	// The fully-qualified class name of the [Java Database Connectivity
-	// (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver
-	// used to connect.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'org.postgresql.Driver',
-	// 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
-	DBJDBCDriverClassnameKey = attribute.Key("db.jdbc.driver_classname")
-	// This attribute is used to report the name of the database being accessed. For
-	// commands that switch the database, this should be set to the target database
-	// (even if the command fails).
-	//
-	// Type: string
-	// Required: Required, if applicable.
-	// Stability: stable
-	// Examples: 'customers', 'main'
-	// Note: In some SQL databases, the database name to be used is called "schema
-	// name". In case there are multiple layers that could be considered for database
-	// name (e.g. Oracle instance name and schema name), the database name to be used
-	// is the more specific layer (e.g. Oracle schema name).
-	DBNameKey = attribute.Key("db.name")
-	// The database statement being executed.
-	//
-	// Type: string
-	// Required: Required if applicable and not explicitly disabled via
-	// instrumentation configuration.
-	// Stability: stable
-	// Examples: 'SELECT * FROM wuser_table', 'SET mykey "WuValue"'
-	// Note: The value may be sanitized to exclude sensitive information.
-	DBStatementKey = attribute.Key("db.statement")
-	// The name of the operation being executed, e.g. the [MongoDB command
-	// name](https://docs.mongodb.com/manual/reference/command/#database-operations)
-	// such as `findAndModify`, or the SQL keyword.
-	//
-	// Type: string
-	// Required: Required, if `db.statement` is not applicable.
-	// Stability: stable
-	// Examples: 'findAndModify', 'HMSET', 'SELECT'
-	// Note: When setting this to an SQL keyword, it is not recommended to attempt any
-	// client-side parsing of `db.statement` just to get this property, but it should
-	// be set if the operation name is provided by the library being instrumented. If
-	// the SQL statement has an ambiguous operation, or performs more than one
-	// operation, this value may be omitted.
-	DBOperationKey = attribute.Key("db.operation")
-)
-
-var (
-	// Some other SQL database. Fallback only. See notes
-	DBSystemOtherSQL = DBSystemKey.String("other_sql")
-	// Microsoft SQL Server
-	DBSystemMSSQL = DBSystemKey.String("mssql")
-	// MySQL
-	DBSystemMySQL = DBSystemKey.String("mysql")
-	// Oracle Database
-	DBSystemOracle = DBSystemKey.String("oracle")
-	// IBM DB2
-	DBSystemDB2 = DBSystemKey.String("db2")
-	// PostgreSQL
-	DBSystemPostgreSQL = DBSystemKey.String("postgresql")
-	// Amazon Redshift
-	DBSystemRedshift = DBSystemKey.String("redshift")
-	// Apache Hive
-	DBSystemHive = DBSystemKey.String("hive")
-	// Cloudscape
-	DBSystemCloudscape = DBSystemKey.String("cloudscape")
-	// HyperSQL DataBase
-	DBSystemHSQLDB = DBSystemKey.String("hsqldb")
-	// Progress Database
-	DBSystemProgress = DBSystemKey.String("progress")
-	// SAP MaxDB
-	DBSystemMaxDB = DBSystemKey.String("maxdb")
-	// SAP HANA
-	DBSystemHanaDB = DBSystemKey.String("hanadb")
-	// Ingres
-	DBSystemIngres = DBSystemKey.String("ingres")
-	// FirstSQL
-	DBSystemFirstSQL = DBSystemKey.String("firstsql")
-	// EnterpriseDB
-	DBSystemEDB = DBSystemKey.String("edb")
-	// InterSystems Caché
-	DBSystemCache = DBSystemKey.String("cache")
-	// Adabas (Adaptable Database System)
-	DBSystemAdabas = DBSystemKey.String("adabas")
-	// Firebird
-	DBSystemFirebird = DBSystemKey.String("firebird")
-	// Apache Derby
-	DBSystemDerby = DBSystemKey.String("derby")
-	// FileMaker
-	DBSystemFilemaker = DBSystemKey.String("filemaker")
-	// Informix
-	DBSystemInformix = DBSystemKey.String("informix")
-	// InstantDB
-	DBSystemInstantDB = DBSystemKey.String("instantdb")
-	// InterBase
-	DBSystemInterbase = DBSystemKey.String("interbase")
-	// MariaDB
-	DBSystemMariaDB = DBSystemKey.String("mariadb")
-	// Netezza
-	DBSystemNetezza = DBSystemKey.String("netezza")
-	// Pervasive PSQL
-	DBSystemPervasive = DBSystemKey.String("pervasive")
-	// PointBase
-	DBSystemPointbase = DBSystemKey.String("pointbase")
-	// SQLite
-	DBSystemSqlite = DBSystemKey.String("sqlite")
-	// Sybase
-	DBSystemSybase = DBSystemKey.String("sybase")
-	// Teradata
-	DBSystemTeradata = DBSystemKey.String("teradata")
-	// Vertica
-	DBSystemVertica = DBSystemKey.String("vertica")
-	// H2
-	DBSystemH2 = DBSystemKey.String("h2")
-	// ColdFusion IMQ
-	DBSystemColdfusion = DBSystemKey.String("coldfusion")
-	// Apache Cassandra
-	DBSystemCassandra = DBSystemKey.String("cassandra")
-	// Apache HBase
-	DBSystemHBase = DBSystemKey.String("hbase")
-	// MongoDB
-	DBSystemMongoDB = DBSystemKey.String("mongodb")
-	// Redis
-	DBSystemRedis = DBSystemKey.String("redis")
-	// Couchbase
-	DBSystemCouchbase = DBSystemKey.String("couchbase")
-	// CouchDB
-	DBSystemCouchDB = DBSystemKey.String("couchdb")
-	// Microsoft Azure Cosmos DB
-	DBSystemCosmosDB = DBSystemKey.String("cosmosdb")
-	// Amazon DynamoDB
-	DBSystemDynamoDB = DBSystemKey.String("dynamodb")
-	// Neo4j
-	DBSystemNeo4j = DBSystemKey.String("neo4j")
-	// Apache Geode
-	DBSystemGeode = DBSystemKey.String("geode")
-	// Elasticsearch
-	DBSystemElasticsearch = DBSystemKey.String("elasticsearch")
-	// Memcached
-	DBSystemMemcached = DBSystemKey.String("memcached")
-	// CockroachDB
-	DBSystemCockroachdb = DBSystemKey.String("cockroachdb")
-)
-
-// Connection-level attributes for Microsoft SQL Server
-const (
-	// The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-
-	// us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15)
-	// connecting to. This name is used to determine the port of a named instance.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'MSSQLSERVER'
-	// Note: If setting a `db.mssql.instance_name`, `net.peer.port` is no longer
-	// required (but still recommended if non-standard).
-	DBMSSQLInstanceNameKey = attribute.Key("db.mssql.instance_name")
-)
-
-// Call-level attributes for Cassandra
-const (
-	// The fetch size used for paging, i.e. how many rows will be returned at once.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 5000
-	DBCassandraPageSizeKey = attribute.Key("db.cassandra.page_size")
-	// The consistency level of the query. Based on consistency values from
-	// [CQL](https://docs.datastax.com/en/cassandra-
-	// oss/3.0/cassandra/dml/dmlConfigConsistency.html).
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	DBCassandraConsistencyLevelKey = attribute.Key("db.cassandra.consistency_level")
-	// The name of the primary table that the operation is acting upon, including the
-	// keyspace name (if applicable).
-	//
-	// Type: string
-	// Required: Recommended if available.
-	// Stability: stable
-	// Examples: 'mytable'
-	// Note: This mirrors the db.sql.table attribute but references cassandra rather
-	// than sql. It is not recommended to attempt any client-side parsing of
-	// `db.statement` just to get this property, but it should be set if it is
-	// provided by the library being instrumented. If the operation is acting upon an
-	// anonymous table, or more than one table, this value MUST NOT be set.
-	DBCassandraTableKey = attribute.Key("db.cassandra.table")
-	// Whether or not the query is idempotent.
-	//
-	// Type: boolean
-	// Required: No
-	// Stability: stable
-	DBCassandraIdempotenceKey = attribute.Key("db.cassandra.idempotence")
-	// The number of times a query was speculatively executed. Not set or `0` if the
-	// query was not executed speculatively.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 0, 2
-	DBCassandraSpeculativeExecutionCountKey = attribute.Key("db.cassandra.speculative_execution_count")
-	// The ID of the coordinating node for a query.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af'
-	DBCassandraCoordinatorIDKey = attribute.Key("db.cassandra.coordinator.id")
-	// The data center of the coordinating node for a query.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'us-west-2'
-	DBCassandraCoordinatorDCKey = attribute.Key("db.cassandra.coordinator.dc")
-)
-
-var (
-	// all
-	DBCassandraConsistencyLevelAll = DBCassandraConsistencyLevelKey.String("all")
-	// each_quorum
-	DBCassandraConsistencyLevelEachQuorum = DBCassandraConsistencyLevelKey.String("each_quorum")
-	// quorum
-	DBCassandraConsistencyLevelQuorum = DBCassandraConsistencyLevelKey.String("quorum")
-	// local_quorum
-	DBCassandraConsistencyLevelLocalQuorum = DBCassandraConsistencyLevelKey.String("local_quorum")
-	// one
-	DBCassandraConsistencyLevelOne = DBCassandraConsistencyLevelKey.String("one")
-	// two
-	DBCassandraConsistencyLevelTwo = DBCassandraConsistencyLevelKey.String("two")
-	// three
-	DBCassandraConsistencyLevelThree = DBCassandraConsistencyLevelKey.String("three")
-	// local_one
-	DBCassandraConsistencyLevelLocalOne = DBCassandraConsistencyLevelKey.String("local_one")
-	// any
-	DBCassandraConsistencyLevelAny = DBCassandraConsistencyLevelKey.String("any")
-	// serial
-	DBCassandraConsistencyLevelSerial = DBCassandraConsistencyLevelKey.String("serial")
-	// local_serial
-	DBCassandraConsistencyLevelLocalSerial = DBCassandraConsistencyLevelKey.String("local_serial")
-)
-
-// Call-level attributes for Redis
-const (
-	// The index of the database being accessed as used in the [`SELECT`
-	// command](https://redis.io/commands/select), provided as an integer. To be used
-	// instead of the generic `db.name` attribute.
-	//
-	// Type: int
-	// Required: Required, if other than the default database (`0`).
-	// Stability: stable
-	// Examples: 0, 1, 15
-	DBRedisDBIndexKey = attribute.Key("db.redis.database_index")
-)
-
-// Call-level attributes for MongoDB
-const (
-	// The collection being accessed within the database stated in `db.name`.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'customers', 'products'
-	DBMongoDBCollectionKey = attribute.Key("db.mongodb.collection")
-)
-
-// Call-level attributes for SQL databases
-const (
-	// The name of the primary table that the operation is acting upon, including the
-	// database name (if applicable).
-	//
-	// Type: string
-	// Required: Recommended if available.
-	// Stability: stable
-	// Examples: 'public.users', 'customers'
-	// Note: It is not recommended to attempt any client-side parsing of
-	// `db.statement` just to get this property, but it should be set if it is
-	// provided by the library being instrumented. If the operation is acting upon an
-	// anonymous table, or more than one table, this value MUST NOT be set.
-	DBSQLTableKey = attribute.Key("db.sql.table")
-)
-
-// This document defines the attributes used to report a single exception associated with a span.
-const (
-	// The type of the exception (its fully-qualified class name, if applicable). The
-	// dynamic type of the exception should be preferred over the static type in
-	// languages that support it.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'java.net.ConnectException', 'OSError'
-	ExceptionTypeKey = attribute.Key("exception.type")
-	// The exception message.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'Division by zero', "Can't convert 'int' object to str implicitly"
-	ExceptionMessageKey = attribute.Key("exception.message")
-	// A stacktrace as a string in the natural representation for the language
-	// runtime. The representation is to be determined and documented by each language
-	// SIG.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'Exception in thread "main" java.lang.RuntimeException: Test
-	// exception\\n at '
-	//  'com.example.GenerateTrace.methodB(GenerateTrace.java:13)\\n at '
-	//  'com.example.GenerateTrace.methodA(GenerateTrace.java:9)\\n at '
-	//  'com.example.GenerateTrace.main(GenerateTrace.java:5)'
-	ExceptionStacktraceKey = attribute.Key("exception.stacktrace")
-	// SHOULD be set to true if the exception event is recorded at a point where it is
-	// known that the exception is escaping the scope of the span.
-	//
-	// Type: boolean
-	// Required: No
-	// Stability: stable
-	// Note: An exception is considered to have escaped (or left) the scope of a span,
-	// if that span is ended while the exception is still logically "in flight".
-	// This may be actually "in flight" in some languages (e.g. if the exception
-	// is passed to a Context manager's `__exit__` method in Python) but will
-	// usually be caught at the point of recording the exception in most languages.
-
-	// It is usually not possible to determine at the point where an exception is
-	// thrown
-	// whether it will escape the scope of a span.
-	// However, it is trivial to know that an exception
-	// will escape, if one checks for an active exception just before ending the span,
-	// as done in the [example above](#recording-an-exception).
-
-	// It follows that an exception may still escape the scope of the span
-	// even if the `exception.escaped` attribute was not set or set to false,
-	// since the event might have been recorded at a time where it was not
-	// clear whether the exception will escape.
-	ExceptionEscapedKey = attribute.Key("exception.escaped")
-)
-
-// This semantic convention describes an instance of a function that runs without provisioning or managing of servers (also known as serverless functions or Function as a Service (FaaS)) with spans.
-const (
-	// Type of the trigger which caused this function execution.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	// Note: For the server/consumer span on the incoming side,
-	// `faas.trigger` MUST be set.
-
-	// Clients invoking FaaS instances usually cannot set `faas.trigger`,
-	// since they would typically need to look in the payload to determine
-	// the event type. If clients set it, it should be the same as the
-	// trigger that corresponding incoming would have (i.e., this has
-	// nothing to do with the underlying transport used to make the API
-	// call to invoke the lambda, which is often HTTP).
-	FaaSTriggerKey = attribute.Key("faas.trigger")
-	// The execution ID of the current function execution.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28'
-	FaaSExecutionKey = attribute.Key("faas.execution")
-)
-
-var (
-	// A response to some data source operation such as a database or filesystem read/write
-	FaaSTriggerDatasource = FaaSTriggerKey.String("datasource")
-	// To provide an answer to an inbound HTTP request
-	FaaSTriggerHTTP = FaaSTriggerKey.String("http")
-	// A function is set to be executed when messages are sent to a messaging system
-	FaaSTriggerPubsub = FaaSTriggerKey.String("pubsub")
-	// A function is scheduled to be executed regularly
-	FaaSTriggerTimer = FaaSTriggerKey.String("timer")
-	// If none of the others apply
-	FaaSTriggerOther = FaaSTriggerKey.String("other")
-)
-
-// Semantic Convention for FaaS triggered as a response to some data source operation such as a database or filesystem read/write.
-const (
-	// The name of the source on which the triggering operation was performed. For
-	// example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos
-	// DB to the database name.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'myBucketName', 'myDBName'
-	FaaSDocumentCollectionKey = attribute.Key("faas.document.collection")
-	// Describes the type of the operation that was performed on the data.
-	//
-	// Type: Enum
-	// Required: Always
-	// Stability: stable
-	FaaSDocumentOperationKey = attribute.Key("faas.document.operation")
-	// A string containing the time when the data was accessed in the [ISO
-	// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed
-	// in [UTC](https://www.w3.org/TR/NOTE-datetime).
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: '2020-01-23T13:47:06Z'
-	FaaSDocumentTimeKey = attribute.Key("faas.document.time")
-	// The document name/table subjected to the operation. For example, in Cloud
-	// Storage or S3 is the name of the file, and in Cosmos DB the table name.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'myFile.txt', 'myTableName'
-	FaaSDocumentNameKey = attribute.Key("faas.document.name")
-)
-
-var (
-	// When a new object is created
-	FaaSDocumentOperationInsert = FaaSDocumentOperationKey.String("insert")
-	// When an object is modified
-	FaaSDocumentOperationEdit = FaaSDocumentOperationKey.String("edit")
-	// When an object is deleted
-	FaaSDocumentOperationDelete = FaaSDocumentOperationKey.String("delete")
-)
-
-// Semantic Convention for FaaS scheduled to be executed regularly.
-const (
-	// A string containing the function invocation time in the [ISO
-	// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed
-	// in [UTC](https://www.w3.org/TR/NOTE-datetime).
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: '2020-01-23T13:47:06Z'
-	FaaSTimeKey = attribute.Key("faas.time")
-	// A string containing the schedule period as [Cron Expression](https://docs.oracl
-	// e.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '0/5 * * * ? *'
-	FaaSCronKey = attribute.Key("faas.cron")
-)
-
-// Contains additional attributes for incoming FaaS spans.
-const (
-	// A boolean that is true if the serverless function is executed for the first
-	// time (aka cold-start).
-	//
-	// Type: boolean
-	// Required: No
-	// Stability: stable
-	FaaSColdstartKey = attribute.Key("faas.coldstart")
-)
-
-// Contains additional attributes for outgoing FaaS spans.
-const (
-	// The name of the invoked function.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'my-function'
-	// Note: SHOULD be equal to the `faas.name` resource attribute of the invoked
-	// function.
-	FaaSInvokedNameKey = attribute.Key("faas.invoked_name")
-	// The cloud provider of the invoked function.
-	//
-	// Type: Enum
-	// Required: Always
-	// Stability: stable
-	// Note: SHOULD be equal to the `cloud.provider` resource attribute of the invoked
-	// function.
-	FaaSInvokedProviderKey = attribute.Key("faas.invoked_provider")
-	// The cloud region of the invoked function.
-	//
-	// Type: string
-	// Required: For some cloud providers, like AWS or GCP, the region in which a
-	// function is hosted is essential to uniquely identify the function and also part
-	// of its endpoint. Since it's part of the endpoint being called, the region is
-	// always known to clients. In these cases, `faas.invoked_region` MUST be set
-	// accordingly. If the region is unknown to the client or not required for
-	// identifying the invoked function, setting `faas.invoked_region` is optional.
-	// Stability: stable
-	// Examples: 'eu-central-1'
-	// Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked
-	// function.
-	FaaSInvokedRegionKey = attribute.Key("faas.invoked_region")
-)
-
-var (
-	// Alibaba Cloud
-	FaaSInvokedProviderAlibabaCloud = FaaSInvokedProviderKey.String("alibaba_cloud")
-	// Amazon Web Services
-	FaaSInvokedProviderAWS = FaaSInvokedProviderKey.String("aws")
-	// Microsoft Azure
-	FaaSInvokedProviderAzure = FaaSInvokedProviderKey.String("azure")
-	// Google Cloud Platform
-	FaaSInvokedProviderGCP = FaaSInvokedProviderKey.String("gcp")
-	// Tencent Cloud
-	FaaSInvokedProviderTencentCloud = FaaSInvokedProviderKey.String("tencent_cloud")
-)
-
-// These attributes may be used for any network related operation.
-const (
-	// Transport protocol used. See note below.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	NetTransportKey = attribute.Key("net.transport")
-	// Remote address of the peer (dotted decimal for IPv4 or
-	// [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6)
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '127.0.0.1'
-	NetPeerIPKey = attribute.Key("net.peer.ip")
-	// Remote port number.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 80, 8080, 443
-	NetPeerPortKey = attribute.Key("net.peer.port")
-	// Remote hostname or similar, see note below.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'example.com'
-	// Note: `net.peer.name` SHOULD NOT be set if capturing it would require an extra
-	// DNS lookup.
-	NetPeerNameKey = attribute.Key("net.peer.name")
-	// Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '192.168.0.1'
-	NetHostIPKey = attribute.Key("net.host.ip")
-	// Like `net.peer.port` but for the host port.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 35555
-	NetHostPortKey = attribute.Key("net.host.port")
-	// Local hostname or similar, see note below.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'localhost'
-	NetHostNameKey = attribute.Key("net.host.name")
-	// The internet connection type currently being used by the host.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	// Examples: 'wifi'
-	NetHostConnectionTypeKey = attribute.Key("net.host.connection.type")
-	// This describes more details regarding the connection.type. It may be the type
-	// of cell technology connection, but it could be used for describing details
-	// about a wifi connection.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	// Examples: 'LTE'
-	NetHostConnectionSubtypeKey = attribute.Key("net.host.connection.subtype")
-	// The name of the mobile carrier.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'sprint'
-	NetHostCarrierNameKey = attribute.Key("net.host.carrier.name")
-	// The mobile carrier country code.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '310'
-	NetHostCarrierMccKey = attribute.Key("net.host.carrier.mcc")
-	// The mobile carrier network code.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '001'
-	NetHostCarrierMncKey = attribute.Key("net.host.carrier.mnc")
-	// The ISO 3166-1 alpha-2 2-character country code associated with the mobile
-	// carrier network.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'DE'
-	NetHostCarrierIccKey = attribute.Key("net.host.carrier.icc")
-)
-
-var (
-	// ip_tcp
-	NetTransportTCP = NetTransportKey.String("ip_tcp")
-	// ip_udp
-	NetTransportUDP = NetTransportKey.String("ip_udp")
-	// Another IP-based protocol
-	NetTransportIP = NetTransportKey.String("ip")
-	// Unix Domain socket. See below
-	NetTransportUnix = NetTransportKey.String("unix")
-	// Named or anonymous pipe. See note below
-	NetTransportPipe = NetTransportKey.String("pipe")
-	// In-process communication
-	NetTransportInProc = NetTransportKey.String("inproc")
-	// Something else (non IP-based)
-	NetTransportOther = NetTransportKey.String("other")
-)
-
-var (
-	// wifi
-	NetHostConnectionTypeWifi = NetHostConnectionTypeKey.String("wifi")
-	// wired
-	NetHostConnectionTypeWired = NetHostConnectionTypeKey.String("wired")
-	// cell
-	NetHostConnectionTypeCell = NetHostConnectionTypeKey.String("cell")
-	// unavailable
-	NetHostConnectionTypeUnavailable = NetHostConnectionTypeKey.String("unavailable")
-	// unknown
-	NetHostConnectionTypeUnknown = NetHostConnectionTypeKey.String("unknown")
-)
-
-var (
-	// GPRS
-	NetHostConnectionSubtypeGprs = NetHostConnectionSubtypeKey.String("gprs")
-	// EDGE
-	NetHostConnectionSubtypeEdge = NetHostConnectionSubtypeKey.String("edge")
-	// UMTS
-	NetHostConnectionSubtypeUmts = NetHostConnectionSubtypeKey.String("umts")
-	// CDMA
-	NetHostConnectionSubtypeCdma = NetHostConnectionSubtypeKey.String("cdma")
-	// EVDO Rel. 0
-	NetHostConnectionSubtypeEvdo0 = NetHostConnectionSubtypeKey.String("evdo_0")
-	// EVDO Rev. A
-	NetHostConnectionSubtypeEvdoA = NetHostConnectionSubtypeKey.String("evdo_a")
-	// CDMA2000 1XRTT
-	NetHostConnectionSubtypeCdma20001xrtt = NetHostConnectionSubtypeKey.String("cdma2000_1xrtt")
-	// HSDPA
-	NetHostConnectionSubtypeHsdpa = NetHostConnectionSubtypeKey.String("hsdpa")
-	// HSUPA
-	NetHostConnectionSubtypeHsupa = NetHostConnectionSubtypeKey.String("hsupa")
-	// HSPA
-	NetHostConnectionSubtypeHspa = NetHostConnectionSubtypeKey.String("hspa")
-	// IDEN
-	NetHostConnectionSubtypeIden = NetHostConnectionSubtypeKey.String("iden")
-	// EVDO Rev. B
-	NetHostConnectionSubtypeEvdoB = NetHostConnectionSubtypeKey.String("evdo_b")
-	// LTE
-	NetHostConnectionSubtypeLte = NetHostConnectionSubtypeKey.String("lte")
-	// EHRPD
-	NetHostConnectionSubtypeEhrpd = NetHostConnectionSubtypeKey.String("ehrpd")
-	// HSPAP
-	NetHostConnectionSubtypeHspap = NetHostConnectionSubtypeKey.String("hspap")
-	// GSM
-	NetHostConnectionSubtypeGsm = NetHostConnectionSubtypeKey.String("gsm")
-	// TD-SCDMA
-	NetHostConnectionSubtypeTdScdma = NetHostConnectionSubtypeKey.String("td_scdma")
-	// IWLAN
-	NetHostConnectionSubtypeIwlan = NetHostConnectionSubtypeKey.String("iwlan")
-	// 5G NR (New Radio)
-	NetHostConnectionSubtypeNr = NetHostConnectionSubtypeKey.String("nr")
-	// 5G NRNSA (New Radio Non-Standalone)
-	NetHostConnectionSubtypeNrnsa = NetHostConnectionSubtypeKey.String("nrnsa")
-	// LTE CA
-	NetHostConnectionSubtypeLteCa = NetHostConnectionSubtypeKey.String("lte_ca")
-)
-
-// Operations that access some remote service.
-const (
-	// The [`service.name`](../../resource/semantic_conventions/README.md#service) of
-	// the remote service. SHOULD be equal to the actual `service.name` resource
-	// attribute of the remote service if any.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'AuthTokenCache'
-	PeerServiceKey = attribute.Key("peer.service")
-)
-
-// These attributes may be used for any operation with an authenticated and/or authorized enduser.
-const (
-	// Username or client_id extracted from the access token or
-	// [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the
-	// inbound request from outside the system.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'username'
-	EnduserIDKey = attribute.Key("enduser.id")
-	// Actual/assumed role the client is making the request under extracted from token
-	// or application security context.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'admin'
-	EnduserRoleKey = attribute.Key("enduser.role")
-	// Scopes or granted authorities the client currently possesses extracted from
-	// token or application security context. The value would come from the scope
-	// associated with an [OAuth 2.0 Access
-	// Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value
-	// in a [SAML 2.0 Assertion](http://docs.oasis-
-	// open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'read:message, write:files'
-	EnduserScopeKey = attribute.Key("enduser.scope")
-)
-
-// These attributes may be used for any operation to store information about a thread that started a span.
-const (
-	// Current "managed" thread ID (as opposed to OS thread ID).
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 42
-	ThreadIDKey = attribute.Key("thread.id")
-	// Current thread name.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'main'
-	ThreadNameKey = attribute.Key("thread.name")
-)
-
-// These attributes allow to report this unit of code and therefore to provide more context about the span.
-const (
-	// The method or function name, or equivalent (usually rightmost part of the code
-	// unit's name).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'serveRequest'
-	CodeFunctionKey = attribute.Key("code.function")
-	// The "namespace" within which `code.function` is defined. Usually the qualified
-	// class or module name, such that `code.namespace` + some separator +
-	// `code.function` form a unique identifier for the code unit.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'com.example.MyHTTPService'
-	CodeNamespaceKey = attribute.Key("code.namespace")
-	// The source code file name that identifies the code unit as uniquely as possible
-	// (preferably an absolute file path).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '/usr/local/MyApplication/content_root/app/index.php'
-	CodeFilepathKey = attribute.Key("code.filepath")
-	// The line number in `code.filepath` best representing the operation. It SHOULD
-	// point within the code unit named in `code.function`.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 42
-	CodeLineNumberKey = attribute.Key("code.lineno")
-)
-
-// This document defines semantic conventions for HTTP client and server Spans.
-const (
-	// HTTP request method.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'GET', 'POST', 'HEAD'
-	HTTPMethodKey = attribute.Key("http.method")
-	// Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`.
-	// Usually the fragment is not transmitted over HTTP, but if it is known, it
-	// should be included nevertheless.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'https://www.foo.bar/search?q=OpenTelemetry#SemConv'
-	// Note: `http.url` MUST NOT contain credentials passed via URL in form of
-	// `https://username:password@www.example.com/`. In such case the attribute's
-	// value should be `https://www.example.com/`.
-	HTTPURLKey = attribute.Key("http.url")
-	// The full request target as passed in a HTTP request line or equivalent.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '/path/12314/?q=ddds#123'
-	HTTPTargetKey = attribute.Key("http.target")
-	// The value of the [HTTP host
-	// header](https://tools.ietf.org/html/rfc7230#section-5.4). An empty Host header
-	// should also be reported, see note.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'www.example.org'
-	// Note: When the header is present but empty the attribute SHOULD be set to the
-	// empty string. Note that this is a valid situation that is expected in certain
-	// cases, according the aforementioned [section of RFC
-	// 7230](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is not
-	// set the attribute MUST NOT be set.
-	HTTPHostKey = attribute.Key("http.host")
-	// The URI scheme identifying the used protocol.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'http', 'https'
-	HTTPSchemeKey = attribute.Key("http.scheme")
-	// [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).
-	//
-	// Type: int
-	// Required: If and only if one was received/sent.
-	// Stability: stable
-	// Examples: 200
-	HTTPStatusCodeKey = attribute.Key("http.status_code")
-	// Kind of HTTP protocol used.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	// Note: If `net.transport` is not specified, it can be assumed to be `IP.TCP`
-	// except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed.
-	HTTPFlavorKey = attribute.Key("http.flavor")
-	// Value of the [HTTP User-
-	// Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the
-	// client.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'CERN-LineMode/2.15 libwww/2.17b3'
-	HTTPUserAgentKey = attribute.Key("http.user_agent")
-	// The size of the request payload body in bytes. This is the number of bytes
-	// transferred excluding headers and is often, but not always, present as the
-	// [Content-Length](https://tools.ietf.org/html/rfc7230#section-3.3.2) header. For
-	// requests using transport encoding, this should be the compressed size.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 3495
-	HTTPRequestContentLengthKey = attribute.Key("http.request_content_length")
-	// The size of the uncompressed request payload body after transport decoding. Not
-	// set if transport encoding not used.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 5493
-	HTTPRequestContentLengthUncompressedKey = attribute.Key("http.request_content_length_uncompressed")
-	// The size of the response payload body in bytes. This is the number of bytes
-	// transferred excluding headers and is often, but not always, present as the
-	// [Content-Length](https://tools.ietf.org/html/rfc7230#section-3.3.2) header. For
-	// requests using transport encoding, this should be the compressed size.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 3495
-	HTTPResponseContentLengthKey = attribute.Key("http.response_content_length")
-	// The size of the uncompressed response payload body after transport decoding.
-	// Not set if transport encoding not used.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 5493
-	HTTPResponseContentLengthUncompressedKey = attribute.Key("http.response_content_length_uncompressed")
-	// The ordinal number of request re-sending attempt.
-	//
-	// Type: int
-	// Required: If and only if a request was retried.
-	// Stability: stable
-	// Examples: 3
-	HTTPRetryCountKey = attribute.Key("http.retry_count")
-)
-
-var (
-	// HTTP/1.0
-	HTTPFlavorHTTP10 = HTTPFlavorKey.String("1.0")
-	// HTTP/1.1
-	HTTPFlavorHTTP11 = HTTPFlavorKey.String("1.1")
-	// HTTP/2
-	HTTPFlavorHTTP20 = HTTPFlavorKey.String("2.0")
-	// HTTP/3
-	HTTPFlavorHTTP30 = HTTPFlavorKey.String("3.0")
-	// SPDY protocol
-	HTTPFlavorSPDY = HTTPFlavorKey.String("SPDY")
-	// QUIC protocol
-	HTTPFlavorQUIC = HTTPFlavorKey.String("QUIC")
-)
-
-// Semantic Convention for HTTP Server
-const (
-	// The primary server name of the matched virtual host. This should be obtained
-	// via configuration. If no such configuration can be obtained, this attribute
-	// MUST NOT be set ( `net.host.name` should be used instead).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'example.com'
-	// Note: `http.url` is usually not readily available on the server side but would
-	// have to be assembled in a cumbersome and sometimes lossy process from other
-	// information (see e.g. open-telemetry/opentelemetry-python/pull/148). It is thus
-	// preferred to supply the raw data that is available.
-	HTTPServerNameKey = attribute.Key("http.server_name")
-	// The matched route (path template).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '/users/:userID?'
-	HTTPRouteKey = attribute.Key("http.route")
-	// The IP address of the original client behind all proxies, if known (e.g. from
-	// [X-Forwarded-For](https://developer.mozilla.org/en-
-	// US/docs/Web/HTTP/Headers/X-Forwarded-For)).
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '83.164.160.102'
-	// Note: This is not necessarily the same as `net.peer.ip`, which would
-	// identify the network-level peer, which may be a proxy.
-
-	// This attribute should be set when a source of information different
-	// from the one used for `net.peer.ip`, is available even if that other
-	// source just confirms the same value as `net.peer.ip`.
-	// Rationale: For `net.peer.ip`, one typically does not know if it
-	// comes from a proxy, reverse proxy, or the actual client. Setting
-	// `http.client_ip` when it's the same as `net.peer.ip` means that
-	// one is at least somewhat confident that the address is not that of
-	// the closest proxy.
-	HTTPClientIPKey = attribute.Key("http.client_ip")
-)
-
-// Attributes that exist for multiple DynamoDB request types.
-const (
-	// The keys in the `RequestItems` object field.
-	//
-	// Type: string[]
-	// Required: No
-	// Stability: stable
-	// Examples: 'Users', 'Cats'
-	AWSDynamoDBTableNamesKey = attribute.Key("aws.dynamodb.table_names")
-	// The JSON-serialized value of each item in the `ConsumedCapacity` response
-	// field.
-	//
-	// Type: string[]
-	// Required: No
-	// Stability: stable
-	// Examples: '{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : {
-	// "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits":
-	// number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number,
-	// "ReadCapacityUnits": number, "WriteCapacityUnits": number } },
-	// "ReadCapacityUnits": number, "Table": { "CapacityUnits": number,
-	// "ReadCapacityUnits": number, "WriteCapacityUnits": number }, "TableName":
-	// "string", "WriteCapacityUnits": number }'
-	AWSDynamoDBConsumedCapacityKey = attribute.Key("aws.dynamodb.consumed_capacity")
-	// The JSON-serialized value of the `ItemCollectionMetrics` response field.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob,
-	// "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" :
-	// "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S":
-	// "string", "SS": [ "string" ] } }, "SizeEstimateRangeGB": [ number ] } ] }'
-	AWSDynamoDBItemCollectionMetricsKey = attribute.Key("aws.dynamodb.item_collection_metrics")
-	// The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter.
-	//
-	// Type: double
-	// Required: No
-	// Stability: stable
-	// Examples: 1.0, 2.0
-	AWSDynamoDBProvisionedReadCapacityKey = attribute.Key("aws.dynamodb.provisioned_read_capacity")
-	// The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter.
-	//
-	// Type: double
-	// Required: No
-	// Stability: stable
-	// Examples: 1.0, 2.0
-	AWSDynamoDBProvisionedWriteCapacityKey = attribute.Key("aws.dynamodb.provisioned_write_capacity")
-	// The value of the `ConsistentRead` request parameter.
-	//
-	// Type: boolean
-	// Required: No
-	// Stability: stable
-	AWSDynamoDBConsistentReadKey = attribute.Key("aws.dynamodb.consistent_read")
-	// The value of the `ProjectionExpression` request parameter.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'Title', 'Title, Price, Color', 'Title, Description, RelatedItems,
-	// ProductReviews'
-	AWSDynamoDBProjectionKey = attribute.Key("aws.dynamodb.projection")
-	// The value of the `Limit` request parameter.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 10
-	AWSDynamoDBLimitKey = attribute.Key("aws.dynamodb.limit")
-	// The value of the `AttributesToGet` request parameter.
-	//
-	// Type: string[]
-	// Required: No
-	// Stability: stable
-	// Examples: 'lives', 'id'
-	AWSDynamoDBAttributesToGetKey = attribute.Key("aws.dynamodb.attributes_to_get")
-	// The value of the `IndexName` request parameter.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'name_to_group'
-	AWSDynamoDBIndexNameKey = attribute.Key("aws.dynamodb.index_name")
-	// The value of the `Select` request parameter.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'ALL_ATTRIBUTES', 'COUNT'
-	AWSDynamoDBSelectKey = attribute.Key("aws.dynamodb.select")
-)
-
-// DynamoDB.CreateTable
-const (
-	// The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request
-	// field
-	//
-	// Type: string[]
-	// Required: No
-	// Stability: stable
-	// Examples: '{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string",
-	// "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ],
-	// "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits":
-	// number, "WriteCapacityUnits": number } }'
-	AWSDynamoDBGlobalSecondaryIndexesKey = attribute.Key("aws.dynamodb.global_secondary_indexes")
-	// The JSON-serialized value of each item of the `LocalSecondaryIndexes` request
-	// field.
-	//
-	// Type: string[]
-	// Required: No
-	// Stability: stable
-	// Examples: '{ "IndexARN": "string", "IndexName": "string", "IndexSizeBytes":
-	// number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string",
-	// "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ],
-	// "ProjectionType": "string" } }'
-	AWSDynamoDBLocalSecondaryIndexesKey = attribute.Key("aws.dynamodb.local_secondary_indexes")
-)
-
-// DynamoDB.ListTables
-const (
-	// The value of the `ExclusiveStartTableName` request parameter.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'Users', 'CatsTable'
-	AWSDynamoDBExclusiveStartTableKey = attribute.Key("aws.dynamodb.exclusive_start_table")
-	// The the number of items in the `TableNames` response parameter.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 20
-	AWSDynamoDBTableCountKey = attribute.Key("aws.dynamodb.table_count")
-)
-
-// DynamoDB.Query
-const (
-	// The value of the `ScanIndexForward` request parameter.
-	//
-	// Type: boolean
-	// Required: No
-	// Stability: stable
-	AWSDynamoDBScanForwardKey = attribute.Key("aws.dynamodb.scan_forward")
-)
-
-// DynamoDB.Scan
-const (
-	// The value of the `Segment` request parameter.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 10
-	AWSDynamoDBSegmentKey = attribute.Key("aws.dynamodb.segment")
-	// The value of the `TotalSegments` request parameter.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 100
-	AWSDynamoDBTotalSegmentsKey = attribute.Key("aws.dynamodb.total_segments")
-	// The value of the `Count` response parameter.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 10
-	AWSDynamoDBCountKey = attribute.Key("aws.dynamodb.count")
-	// The value of the `ScannedCount` response parameter.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 50
-	AWSDynamoDBScannedCountKey = attribute.Key("aws.dynamodb.scanned_count")
-)
-
-// DynamoDB.UpdateTable
-const (
-	// The JSON-serialized value of each item in the `AttributeDefinitions` request
-	// field.
-	//
-	// Type: string[]
-	// Required: No
-	// Stability: stable
-	// Examples: '{ "AttributeName": "string", "AttributeType": "string" }'
-	AWSDynamoDBAttributeDefinitionsKey = attribute.Key("aws.dynamodb.attribute_definitions")
-	// The JSON-serialized value of each item in the the `GlobalSecondaryIndexUpdates`
-	// request field.
-	//
-	// Type: string[]
-	// Required: No
-	// Stability: stable
-	// Examples: '{ "Create": { "IndexName": "string", "KeySchema": [ {
-	// "AttributeName": "string", "KeyType": "string" } ], "Projection": {
-	// "NonKeyAttributes": [ "string" ], "ProjectionType": "string" },
-	// "ProvisionedThroughput": { "ReadCapacityUnits": number, "WriteCapacityUnits":
-	// number } }'
-	AWSDynamoDBGlobalSecondaryIndexUpdatesKey = attribute.Key("aws.dynamodb.global_secondary_index_updates")
-)
-
-// This document defines the attributes used in messaging systems.
-const (
-	// A string identifying the messaging system.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'kafka', 'rabbitmq', 'rocketmq', 'activemq', 'AmazonSQS'
-	MessagingSystemKey = attribute.Key("messaging.system")
-	// The message destination name. This might be equal to the span name but is
-	// required nevertheless.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'MyQueue', 'MyTopic'
-	MessagingDestinationKey = attribute.Key("messaging.destination")
-	// The kind of message destination
-	//
-	// Type: Enum
-	// Required: Required only if the message destination is either a `queue` or
-	// `topic`.
-	// Stability: stable
-	MessagingDestinationKindKey = attribute.Key("messaging.destination_kind")
-	// A boolean that is true if the message destination is temporary.
-	//
-	// Type: boolean
-	// Required: If missing, it is assumed to be false.
-	// Stability: stable
-	MessagingTempDestinationKey = attribute.Key("messaging.temp_destination")
-	// The name of the transport protocol.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'AMQP', 'MQTT'
-	MessagingProtocolKey = attribute.Key("messaging.protocol")
-	// The version of the transport protocol.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '0.9.1'
-	MessagingProtocolVersionKey = attribute.Key("messaging.protocol_version")
-	// Connection string.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'tibjmsnaming://localhost:7222',
-	// 'https://queue.amazonaws.com/80398EXAMPLE/MyQueue'
-	MessagingURLKey = attribute.Key("messaging.url")
-	// A value used by the messaging system as an identifier for the message,
-	// represented as a string.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '452a7c7c7c7048c2f887f61572b18fc2'
-	MessagingMessageIDKey = attribute.Key("messaging.message_id")
-	// The [conversation ID](#conversations) identifying the conversation to which the
-	// message belongs, represented as a string. Sometimes called "Correlation ID".
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'MyConversationID'
-	MessagingConversationIDKey = attribute.Key("messaging.conversation_id")
-	// The (uncompressed) size of the message payload in bytes. Also use this
-	// attribute if it is unknown whether the compressed or uncompressed payload size
-	// is reported.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 2738
-	MessagingMessagePayloadSizeBytesKey = attribute.Key("messaging.message_payload_size_bytes")
-	// The compressed size of the message payload in bytes.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 2048
-	MessagingMessagePayloadCompressedSizeBytesKey = attribute.Key("messaging.message_payload_compressed_size_bytes")
-)
-
-var (
-	// A message sent to a queue
-	MessagingDestinationKindQueue = MessagingDestinationKindKey.String("queue")
-	// A message sent to a topic
-	MessagingDestinationKindTopic = MessagingDestinationKindKey.String("topic")
-)
-
-// Semantic convention for a consumer of messages received from a messaging system
-const (
-	// A string identifying the kind of message consumption as defined in the
-	// [Operation names](#operation-names) section above. If the operation is "send",
-	// this attribute MUST NOT be set, since the operation can be inferred from the
-	// span kind in that case.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	MessagingOperationKey = attribute.Key("messaging.operation")
-	// The identifier for the consumer receiving a message. For Kafka, set it to
-	// `{messaging.kafka.consumer_group} - {messaging.kafka.client_id}`, if both are
-	// present, or only `messaging.kafka.consumer_group`. For brokers, such as
-	// RabbitMQ and Artemis, set it to the `client_id` of the client consuming the
-	// message.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'mygroup - client-6'
-	MessagingConsumerIDKey = attribute.Key("messaging.consumer_id")
-)
-
-var (
-	// receive
-	MessagingOperationReceive = MessagingOperationKey.String("receive")
-	// process
-	MessagingOperationProcess = MessagingOperationKey.String("process")
-)
-
-// Attributes for RabbitMQ
-const (
-	// RabbitMQ message routing key.
-	//
-	// Type: string
-	// Required: Unless it is empty.
-	// Stability: stable
-	// Examples: 'myKey'
-	MessagingRabbitmqRoutingKeyKey = attribute.Key("messaging.rabbitmq.routing_key")
-)
-
-// Attributes for Apache Kafka
-const (
-	// Message keys in Kafka are used for grouping alike messages to ensure they're
-	// processed on the same partition. They differ from `messaging.message_id` in
-	// that they're not unique. If the key is `null`, the attribute MUST NOT be set.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'myKey'
-	// Note: If the key type is not string, it's string representation has to be
-	// supplied for the attribute. If the key has no unambiguous, canonical string
-	// form, don't include its value.
-	MessagingKafkaMessageKeyKey = attribute.Key("messaging.kafka.message_key")
-	// Name of the Kafka Consumer Group that is handling the message. Only applies to
-	// consumers, not producers.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'my-group'
-	MessagingKafkaConsumerGroupKey = attribute.Key("messaging.kafka.consumer_group")
-	// Client ID for the Consumer or Producer that is handling the message.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'client-5'
-	MessagingKafkaClientIDKey = attribute.Key("messaging.kafka.client_id")
-	// Partition the message is sent to.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Examples: 2
-	MessagingKafkaPartitionKey = attribute.Key("messaging.kafka.partition")
-	// A boolean that is true if the message is a tombstone.
-	//
-	// Type: boolean
-	// Required: If missing, it is assumed to be false.
-	// Stability: stable
-	MessagingKafkaTombstoneKey = attribute.Key("messaging.kafka.tombstone")
-)
-
-// Attributes for Apache RocketMQ
-const (
-	// Namespace of RocketMQ resources, resources in different namespaces are
-	// individual.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'myNamespace'
-	MessagingRocketmqNamespaceKey = attribute.Key("messaging.rocketmq.namespace")
-	// Name of the RocketMQ producer/consumer group that is handling the message. The
-	// client type is identified by the SpanKind.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'myConsumerGroup'
-	MessagingRocketmqClientGroupKey = attribute.Key("messaging.rocketmq.client_group")
-	// The unique identifier for each client.
-	//
-	// Type: string
-	// Required: Always
-	// Stability: stable
-	// Examples: 'myhost@8742@s8083jm'
-	MessagingRocketmqClientIDKey = attribute.Key("messaging.rocketmq.client_id")
-	// Type of message.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	MessagingRocketmqMessageTypeKey = attribute.Key("messaging.rocketmq.message_type")
-	// The secondary classifier of message besides topic.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'tagA'
-	MessagingRocketmqMessageTagKey = attribute.Key("messaging.rocketmq.message_tag")
-	// Key(s) of message, another way to mark message besides message id.
-	//
-	// Type: string[]
-	// Required: No
-	// Stability: stable
-	// Examples: 'keyA', 'keyB'
-	MessagingRocketmqMessageKeysKey = attribute.Key("messaging.rocketmq.message_keys")
-	// Model of message consumption. This only applies to consumer spans.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	MessagingRocketmqConsumptionModelKey = attribute.Key("messaging.rocketmq.consumption_model")
-)
-
-var (
-	// Normal message
-	MessagingRocketmqMessageTypeNormal = MessagingRocketmqMessageTypeKey.String("normal")
-	// FIFO message
-	MessagingRocketmqMessageTypeFifo = MessagingRocketmqMessageTypeKey.String("fifo")
-	// Delay message
-	MessagingRocketmqMessageTypeDelay = MessagingRocketmqMessageTypeKey.String("delay")
-	// Transaction message
-	MessagingRocketmqMessageTypeTransaction = MessagingRocketmqMessageTypeKey.String("transaction")
-)
-
-var (
-	// Clustering consumption model
-	MessagingRocketmqConsumptionModelClustering = MessagingRocketmqConsumptionModelKey.String("clustering")
-	// Broadcasting consumption model
-	MessagingRocketmqConsumptionModelBroadcasting = MessagingRocketmqConsumptionModelKey.String("broadcasting")
-)
-
-// This document defines semantic conventions for remote procedure calls.
-const (
-	// A string identifying the remoting system. See below for a list of well-known
-	// identifiers.
-	//
-	// Type: Enum
-	// Required: Always
-	// Stability: stable
-	RPCSystemKey = attribute.Key("rpc.system")
-	// The full (logical) name of the service being called, including its package
-	// name, if applicable.
-	//
-	// Type: string
-	// Required: No, but recommended
-	// Stability: stable
-	// Examples: 'myservice.EchoService'
-	// Note: This is the logical name of the service from the RPC interface
-	// perspective, which can be different from the name of any implementing class.
-	// The `code.namespace` attribute may be used to store the latter (despite the
-	// attribute name, it may include a class name; e.g., class with method actually
-	// executing the call on the server side, RPC client stub class on the client
-	// side).
-	RPCServiceKey = attribute.Key("rpc.service")
-	// The name of the (logical) method being called, must be equal to the $method
-	// part in the span name.
-	//
-	// Type: string
-	// Required: No, but recommended
-	// Stability: stable
-	// Examples: 'exampleMethod'
-	// Note: This is the logical name of the method from the RPC interface
-	// perspective, which can be different from the name of any implementing
-	// method/function. The `code.function` attribute may be used to store the latter
-	// (e.g., method actually executing the call on the server side, RPC client stub
-	// method on the client side).
-	RPCMethodKey = attribute.Key("rpc.method")
-)
-
-var (
-	// gRPC
-	RPCSystemGRPC = RPCSystemKey.String("grpc")
-	// Java RMI
-	RPCSystemJavaRmi = RPCSystemKey.String("java_rmi")
-	// .NET WCF
-	RPCSystemDotnetWcf = RPCSystemKey.String("dotnet_wcf")
-	// Apache Dubbo
-	RPCSystemApacheDubbo = RPCSystemKey.String("apache_dubbo")
-)
-
-// Tech-specific attributes for gRPC.
-const (
-	// The [numeric status
-	// code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC
-	// request.
-	//
-	// Type: Enum
-	// Required: Always
-	// Stability: stable
-	RPCGRPCStatusCodeKey = attribute.Key("rpc.grpc.status_code")
-)
-
-var (
-	// OK
-	RPCGRPCStatusCodeOk = RPCGRPCStatusCodeKey.Int(0)
-	// CANCELLED
-	RPCGRPCStatusCodeCancelled = RPCGRPCStatusCodeKey.Int(1)
-	// UNKNOWN
-	RPCGRPCStatusCodeUnknown = RPCGRPCStatusCodeKey.Int(2)
-	// INVALID_ARGUMENT
-	RPCGRPCStatusCodeInvalidArgument = RPCGRPCStatusCodeKey.Int(3)
-	// DEADLINE_EXCEEDED
-	RPCGRPCStatusCodeDeadlineExceeded = RPCGRPCStatusCodeKey.Int(4)
-	// NOT_FOUND
-	RPCGRPCStatusCodeNotFound = RPCGRPCStatusCodeKey.Int(5)
-	// ALREADY_EXISTS
-	RPCGRPCStatusCodeAlreadyExists = RPCGRPCStatusCodeKey.Int(6)
-	// PERMISSION_DENIED
-	RPCGRPCStatusCodePermissionDenied = RPCGRPCStatusCodeKey.Int(7)
-	// RESOURCE_EXHAUSTED
-	RPCGRPCStatusCodeResourceExhausted = RPCGRPCStatusCodeKey.Int(8)
-	// FAILED_PRECONDITION
-	RPCGRPCStatusCodeFailedPrecondition = RPCGRPCStatusCodeKey.Int(9)
-	// ABORTED
-	RPCGRPCStatusCodeAborted = RPCGRPCStatusCodeKey.Int(10)
-	// OUT_OF_RANGE
-	RPCGRPCStatusCodeOutOfRange = RPCGRPCStatusCodeKey.Int(11)
-	// UNIMPLEMENTED
-	RPCGRPCStatusCodeUnimplemented = RPCGRPCStatusCodeKey.Int(12)
-	// INTERNAL
-	RPCGRPCStatusCodeInternal = RPCGRPCStatusCodeKey.Int(13)
-	// UNAVAILABLE
-	RPCGRPCStatusCodeUnavailable = RPCGRPCStatusCodeKey.Int(14)
-	// DATA_LOSS
-	RPCGRPCStatusCodeDataLoss = RPCGRPCStatusCodeKey.Int(15)
-	// UNAUTHENTICATED
-	RPCGRPCStatusCodeUnauthenticated = RPCGRPCStatusCodeKey.Int(16)
-)
-
-// Tech-specific attributes for [JSON RPC](https://www.jsonrpc.org/).
-const (
-	// Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC
-	// 1.0 does not specify this, the value can be omitted.
-	//
-	// Type: string
-	// Required: If missing, it is assumed to be "1.0".
-	// Stability: stable
-	// Examples: '2.0', '1.0'
-	RPCJsonrpcVersionKey = attribute.Key("rpc.jsonrpc.version")
-	// `id` property of request or response. Since protocol allows id to be int,
-	// string, `null` or missing (for notifications), value is expected to be cast to
-	// string for simplicity. Use empty string in case of `null` value. Omit entirely
-	// if this is a notification.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: '10', 'request-7', ''
-	RPCJsonrpcRequestIDKey = attribute.Key("rpc.jsonrpc.request_id")
-	// `error.code` property of response if it is an error response.
-	//
-	// Type: int
-	// Required: If missing, response is assumed to be successful.
-	// Stability: stable
-	// Examples: -32700, 100
-	RPCJsonrpcErrorCodeKey = attribute.Key("rpc.jsonrpc.error_code")
-	// `error.message` property of response if it is an error response.
-	//
-	// Type: string
-	// Required: No
-	// Stability: stable
-	// Examples: 'Parse error', 'User already exists'
-	RPCJsonrpcErrorMessageKey = attribute.Key("rpc.jsonrpc.error_message")
-)
-
-// RPC received/sent message.
-const (
-	// Whether this is a received or sent message.
-	//
-	// Type: Enum
-	// Required: No
-	// Stability: stable
-	MessageTypeKey = attribute.Key("message.type")
-	// MUST be calculated as two different counters starting from `1` one for sent
-	// messages and one for received message.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	// Note: This way we guarantee that the values will be consistent between
-	// different implementations.
-	MessageIDKey = attribute.Key("message.id")
-	// Compressed size of the message in bytes.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	MessageCompressedSizeKey = attribute.Key("message.compressed_size")
-	// Uncompressed size of the message in bytes.
-	//
-	// Type: int
-	// Required: No
-	// Stability: stable
-	MessageUncompressedSizeKey = attribute.Key("message.uncompressed_size")
-)
-
-var (
-	// sent
-	MessageTypeSent = MessageTypeKey.String("SENT")
-	// received
-	MessageTypeReceived = MessageTypeKey.String("RECEIVED")
-)
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/README.md b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/README.md
new file mode 100644
index 00000000..87b842c5
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/README.md
@@ -0,0 +1,3 @@
+# Semconv v1.17.0
+
+[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/semconv/v1.17.0)](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.17.0)
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/doc.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/doc.go
new file mode 100644
index 00000000..e087c9c0
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/doc.go
@@ -0,0 +1,9 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Package semconv implements OpenTelemetry semantic conventions.
+//
+// OpenTelemetry semantic conventions are agreed standardized naming
+// patterns for OpenTelemetry things. This package represents the conventions
+// as of the v1.17.0 version of the OpenTelemetry specification.
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0"
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/event.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/event.go
new file mode 100644
index 00000000..c7b804bb
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/event.go
@@ -0,0 +1,188 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Code generated from semantic convention specification. DO NOT EDIT.
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0"
+
+import "go.opentelemetry.io/otel/attribute"
+
+// This semantic convention defines the attributes used to represent a feature
+// flag evaluation as an event.
+const (
+	// FeatureFlagKeyKey is the attribute Key conforming to the
+	// "feature_flag.key" semantic conventions. It represents the unique
+	// identifier of the feature flag.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'logo-color'
+	FeatureFlagKeyKey = attribute.Key("feature_flag.key")
+
+	// FeatureFlagProviderNameKey is the attribute Key conforming to the
+	// "feature_flag.provider_name" semantic conventions. It represents the
+	// name of the service provider that performs the flag evaluation.
+	//
+	// Type: string
+	// RequirementLevel: Recommended
+	// Stability: stable
+	// Examples: 'Flag Manager'
+	FeatureFlagProviderNameKey = attribute.Key("feature_flag.provider_name")
+
+	// FeatureFlagVariantKey is the attribute Key conforming to the
+	// "feature_flag.variant" semantic conventions. It represents the sHOULD be
+	// a semantic identifier for a value. If one is unavailable, a stringified
+	// version of the value can be used.
+	//
+	// Type: string
+	// RequirementLevel: Recommended
+	// Stability: stable
+	// Examples: 'red', 'true', 'on'
+	// Note: A semantic identifier, commonly referred to as a variant, provides
+	// a means
+	// for referring to a value without including the value itself. This can
+	// provide additional context for understanding the meaning behind a value.
+	// For example, the variant `red` maybe be used for the value `#c05543`.
+	//
+	// A stringified version of the value can be used in situations where a
+	// semantic identifier is unavailable. String representation of the value
+	// should be determined by the implementer.
+	FeatureFlagVariantKey = attribute.Key("feature_flag.variant")
+)
+
+// FeatureFlagKey returns an attribute KeyValue conforming to the
+// "feature_flag.key" semantic conventions. It represents the unique identifier
+// of the feature flag.
+func FeatureFlagKey(val string) attribute.KeyValue {
+	return FeatureFlagKeyKey.String(val)
+}
+
+// FeatureFlagProviderName returns an attribute KeyValue conforming to the
+// "feature_flag.provider_name" semantic conventions. It represents the name of
+// the service provider that performs the flag evaluation.
+func FeatureFlagProviderName(val string) attribute.KeyValue {
+	return FeatureFlagProviderNameKey.String(val)
+}
+
+// FeatureFlagVariant returns an attribute KeyValue conforming to the
+// "feature_flag.variant" semantic conventions. It represents the sHOULD be a
+// semantic identifier for a value. If one is unavailable, a stringified
+// version of the value can be used.
+func FeatureFlagVariant(val string) attribute.KeyValue {
+	return FeatureFlagVariantKey.String(val)
+}
+
+// RPC received/sent message.
+const (
+	// MessageTypeKey is the attribute Key conforming to the "message.type"
+	// semantic conventions. It represents the whether this is a received or
+	// sent message.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	MessageTypeKey = attribute.Key("message.type")
+
+	// MessageIDKey is the attribute Key conforming to the "message.id"
+	// semantic conventions. It represents the mUST be calculated as two
+	// different counters starting from `1` one for sent messages and one for
+	// received message.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Note: This way we guarantee that the values will be consistent between
+	// different implementations.
+	MessageIDKey = attribute.Key("message.id")
+
+	// MessageCompressedSizeKey is the attribute Key conforming to the
+	// "message.compressed_size" semantic conventions. It represents the
+	// compressed size of the message in bytes.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	MessageCompressedSizeKey = attribute.Key("message.compressed_size")
+
+	// MessageUncompressedSizeKey is the attribute Key conforming to the
+	// "message.uncompressed_size" semantic conventions. It represents the
+	// uncompressed size of the message in bytes.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	MessageUncompressedSizeKey = attribute.Key("message.uncompressed_size")
+)
+
+var (
+	// sent
+	MessageTypeSent = MessageTypeKey.String("SENT")
+	// received
+	MessageTypeReceived = MessageTypeKey.String("RECEIVED")
+)
+
+// MessageID returns an attribute KeyValue conforming to the "message.id"
+// semantic conventions. It represents the mUST be calculated as two different
+// counters starting from `1` one for sent messages and one for received
+// message.
+func MessageID(val int) attribute.KeyValue {
+	return MessageIDKey.Int(val)
+}
+
+// MessageCompressedSize returns an attribute KeyValue conforming to the
+// "message.compressed_size" semantic conventions. It represents the compressed
+// size of the message in bytes.
+func MessageCompressedSize(val int) attribute.KeyValue {
+	return MessageCompressedSizeKey.Int(val)
+}
+
+// MessageUncompressedSize returns an attribute KeyValue conforming to the
+// "message.uncompressed_size" semantic conventions. It represents the
+// uncompressed size of the message in bytes.
+func MessageUncompressedSize(val int) attribute.KeyValue {
+	return MessageUncompressedSizeKey.Int(val)
+}
+
+// The attributes used to report a single exception associated with a span.
+const (
+	// ExceptionEscapedKey is the attribute Key conforming to the
+	// "exception.escaped" semantic conventions. It represents the sHOULD be
+	// set to true if the exception event is recorded at a point where it is
+	// known that the exception is escaping the scope of the span.
+	//
+	// Type: boolean
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Note: An exception is considered to have escaped (or left) the scope of
+	// a span,
+	// if that span is ended while the exception is still logically "in
+	// flight".
+	// This may be actually "in flight" in some languages (e.g. if the
+	// exception
+	// is passed to a Context manager's `__exit__` method in Python) but will
+	// usually be caught at the point of recording the exception in most
+	// languages.
+	//
+	// It is usually not possible to determine at the point where an exception
+	// is thrown
+	// whether it will escape the scope of a span.
+	// However, it is trivial to know that an exception
+	// will escape, if one checks for an active exception just before ending
+	// the span,
+	// as done in the [example above](#recording-an-exception).
+	//
+	// It follows that an exception may still escape the scope of the span
+	// even if the `exception.escaped` attribute was not set or set to false,
+	// since the event might have been recorded at a time where it was not
+	// clear whether the exception will escape.
+	ExceptionEscapedKey = attribute.Key("exception.escaped")
+)
+
+// ExceptionEscaped returns an attribute KeyValue conforming to the
+// "exception.escaped" semantic conventions. It represents the sHOULD be set to
+// true if the exception event is recorded at a point where it is known that
+// the exception is escaping the scope of the span.
+func ExceptionEscaped(val bool) attribute.KeyValue {
+	return ExceptionEscapedKey.Bool(val)
+}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/exception.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/exception.go
new file mode 100644
index 00000000..137acc67
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/exception.go
@@ -0,0 +1,9 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0"
+
+const (
+	// ExceptionEventName is the name of the Span event representing an exception.
+	ExceptionEventName = "exception"
+)
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/http.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/http.go
new file mode 100644
index 00000000..d318221e
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/http.go
@@ -0,0 +1,10 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0"
+
+// HTTP scheme attributes.
+var (
+	HTTPSchemeHTTP  = HTTPSchemeKey.String("http")
+	HTTPSchemeHTTPS = HTTPSchemeKey.String("https")
+)
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv/README.md b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv/README.md
new file mode 100644
index 00000000..18ee2f3d
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv/README.md
@@ -0,0 +1,3 @@
+# Semconv v1.17.0 HTTP conv
+
+[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv)](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv)
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv/http.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv/http.go
new file mode 100644
index 00000000..76d1dc86
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv/http.go
@@ -0,0 +1,141 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Package httpconv provides OpenTelemetry HTTP semantic conventions for
+// tracing telemetry.
+package httpconv // import "go.opentelemetry.io/otel/semconv/v1.17.0/httpconv"
+
+import (
+	"net/http"
+
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/semconv/internal/v2"
+	semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
+)
+
+var (
+	nc = &internal.NetConv{
+		NetHostNameKey:     semconv.NetHostNameKey,
+		NetHostPortKey:     semconv.NetHostPortKey,
+		NetPeerNameKey:     semconv.NetPeerNameKey,
+		NetPeerPortKey:     semconv.NetPeerPortKey,
+		NetSockPeerAddrKey: semconv.NetSockPeerAddrKey,
+		NetSockPeerPortKey: semconv.NetSockPeerPortKey,
+		NetTransportOther:  semconv.NetTransportOther,
+		NetTransportTCP:    semconv.NetTransportTCP,
+		NetTransportUDP:    semconv.NetTransportUDP,
+		NetTransportInProc: semconv.NetTransportInProc,
+	}
+
+	hc = &internal.HTTPConv{
+		NetConv: nc,
+
+		EnduserIDKey:                 semconv.EnduserIDKey,
+		HTTPClientIPKey:              semconv.HTTPClientIPKey,
+		HTTPFlavorKey:                semconv.HTTPFlavorKey,
+		HTTPMethodKey:                semconv.HTTPMethodKey,
+		HTTPRequestContentLengthKey:  semconv.HTTPRequestContentLengthKey,
+		HTTPResponseContentLengthKey: semconv.HTTPResponseContentLengthKey,
+		HTTPRouteKey:                 semconv.HTTPRouteKey,
+		HTTPSchemeHTTP:               semconv.HTTPSchemeHTTP,
+		HTTPSchemeHTTPS:              semconv.HTTPSchemeHTTPS,
+		HTTPStatusCodeKey:            semconv.HTTPStatusCodeKey,
+		HTTPTargetKey:                semconv.HTTPTargetKey,
+		HTTPURLKey:                   semconv.HTTPURLKey,
+		HTTPUserAgentKey:             semconv.HTTPUserAgentKey,
+	}
+)
+
+// ClientResponse returns trace attributes for an HTTP response received by a
+// client from a server. It will return the following attributes if the related
+// values are defined in resp: "http.status.code",
+// "http.response_content_length".
+//
+// This does not add all OpenTelemetry required attributes for an HTTP event,
+// it assumes ClientRequest was used to create the span with a complete set of
+// attributes. If a complete set of attributes can be generated using the
+// request contained in resp. For example:
+//
+//	append(ClientResponse(resp), ClientRequest(resp.Request)...)
+func ClientResponse(resp *http.Response) []attribute.KeyValue {
+	return hc.ClientResponse(resp)
+}
+
+// ClientRequest returns trace attributes for an HTTP request made by a client.
+// The following attributes are always returned: "http.url", "http.flavor",
+// "http.method", "net.peer.name". The following attributes are returned if the
+// related values are defined in req: "net.peer.port", "http.user_agent",
+// "http.request_content_length", "enduser.id".
+func ClientRequest(req *http.Request) []attribute.KeyValue {
+	return hc.ClientRequest(req)
+}
+
+// ClientStatus returns a span status code and message for an HTTP status code
+// value received by a client.
+func ClientStatus(code int) (codes.Code, string) {
+	return hc.ClientStatus(code)
+}
+
+// ServerRequest returns trace attributes for an HTTP request received by a
+// server.
+//
+// The server must be the primary server name if it is known. For example this
+// would be the ServerName directive
+// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache
+// server, and the server_name directive
+// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an
+// nginx server. More generically, the primary server name would be the host
+// header value that matches the default virtual host of an HTTP server. It
+// should include the host identifier and if a port is used to route to the
+// server that port identifier should be included as an appropriate port
+// suffix.
+//
+// If the primary server name is not known, server should be an empty string.
+// The req Host will be used to determine the server instead.
+//
+// The following attributes are always returned: "http.method", "http.scheme",
+// "http.flavor", "http.target", "net.host.name". The following attributes are
+// returned if they related values are defined in req: "net.host.port",
+// "net.sock.peer.addr", "net.sock.peer.port", "http.user_agent", "enduser.id",
+// "http.client_ip".
+func ServerRequest(server string, req *http.Request) []attribute.KeyValue {
+	return hc.ServerRequest(server, req)
+}
+
+// ServerStatus returns a span status code and message for an HTTP status code
+// value returned by a server. Status codes in the 400-499 range are not
+// returned as errors.
+func ServerStatus(code int) (codes.Code, string) {
+	return hc.ServerStatus(code)
+}
+
+// RequestHeader returns the contents of h as attributes.
+//
+// Instrumentation should require an explicit configuration of which headers to
+// captured and then prune what they pass here. Including all headers can be a
+// security risk - explicit configuration helps avoid leaking sensitive
+// information.
+//
+// The User-Agent header is already captured in the http.user_agent attribute
+// from ClientRequest and ServerRequest. Instrumentation may provide an option
+// to capture that header here even though it is not recommended. Otherwise,
+// instrumentation should filter that out of what is passed.
+func RequestHeader(h http.Header) []attribute.KeyValue {
+	return hc.RequestHeader(h)
+}
+
+// ResponseHeader returns the contents of h as attributes.
+//
+// Instrumentation should require an explicit configuration of which headers to
+// captured and then prune what they pass here. Including all headers can be a
+// security risk - explicit configuration helps avoid leaking sensitive
+// information.
+//
+// The User-Agent header is already captured in the http.user_agent attribute
+// from ClientRequest and ServerRequest. Instrumentation may provide an option
+// to capture that header here even though it is not recommended. Otherwise,
+// instrumentation should filter that out of what is passed.
+func ResponseHeader(h http.Header) []attribute.KeyValue {
+	return hc.ResponseHeader(h)
+}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/resource.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/resource.go
new file mode 100644
index 00000000..7e365e82
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/resource.go
@@ -0,0 +1,1999 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Code generated from semantic convention specification. DO NOT EDIT.
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0"
+
+import "go.opentelemetry.io/otel/attribute"
+
+// The web browser in which the application represented by the resource is
+// running. The `browser.*` attributes MUST be used only for resources that
+// represent applications running in a web browser (regardless of whether
+// running on a mobile or desktop device).
+const (
+	// BrowserBrandsKey is the attribute Key conforming to the "browser.brands"
+	// semantic conventions. It represents the array of brand name and version
+	// separated by a space
+	//
+	// Type: string[]
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: ' Not A;Brand 99', 'Chromium 99', 'Chrome 99'
+	// Note: This value is intended to be taken from the [UA client hints
+	// API](https://wicg.github.io/ua-client-hints/#interface)
+	// (`navigator.userAgentData.brands`).
+	BrowserBrandsKey = attribute.Key("browser.brands")
+
+	// BrowserPlatformKey is the attribute Key conforming to the
+	// "browser.platform" semantic conventions. It represents the platform on
+	// which the browser is running
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'Windows', 'macOS', 'Android'
+	// Note: This value is intended to be taken from the [UA client hints
+	// API](https://wicg.github.io/ua-client-hints/#interface)
+	// (`navigator.userAgentData.platform`). If unavailable, the legacy
+	// `navigator.platform` API SHOULD NOT be used instead and this attribute
+	// SHOULD be left unset in order for the values to be consistent.
+	// The list of possible values is defined in the [W3C User-Agent Client
+	// Hints
+	// specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform).
+	// Note that some (but not all) of these values can overlap with values in
+	// the [`os.type` and `os.name` attributes](./os.md). However, for
+	// consistency, the values in the `browser.platform` attribute should
+	// capture the exact value that the user agent provides.
+	BrowserPlatformKey = attribute.Key("browser.platform")
+
+	// BrowserMobileKey is the attribute Key conforming to the "browser.mobile"
+	// semantic conventions. It represents a boolean that is true if the
+	// browser is running on a mobile device
+	//
+	// Type: boolean
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Note: This value is intended to be taken from the [UA client hints
+	// API](https://wicg.github.io/ua-client-hints/#interface)
+	// (`navigator.userAgentData.mobile`). If unavailable, this attribute
+	// SHOULD be left unset.
+	BrowserMobileKey = attribute.Key("browser.mobile")
+
+	// BrowserUserAgentKey is the attribute Key conforming to the
+	// "browser.user_agent" semantic conventions. It represents the full
+	// user-agent string provided by the browser
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
+	// AppleWebKit/537.36 (KHTML, '
+	//  'like Gecko) Chrome/95.0.4638.54 Safari/537.36'
+	// Note: The user-agent value SHOULD be provided only from browsers that do
+	// not have a mechanism to retrieve brands and platform individually from
+	// the User-Agent Client Hints API. To retrieve the value, the legacy
+	// `navigator.userAgent` API can be used.
+	BrowserUserAgentKey = attribute.Key("browser.user_agent")
+
+	// BrowserLanguageKey is the attribute Key conforming to the
+	// "browser.language" semantic conventions. It represents the preferred
+	// language of the user using the browser
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'en', 'en-US', 'fr', 'fr-FR'
+	// Note: This value is intended to be taken from the Navigator API
+	// `navigator.language`.
+	BrowserLanguageKey = attribute.Key("browser.language")
+)
+
+// BrowserBrands returns an attribute KeyValue conforming to the
+// "browser.brands" semantic conventions. It represents the array of brand name
+// and version separated by a space
+func BrowserBrands(val ...string) attribute.KeyValue {
+	return BrowserBrandsKey.StringSlice(val)
+}
+
+// BrowserPlatform returns an attribute KeyValue conforming to the
+// "browser.platform" semantic conventions. It represents the platform on which
+// the browser is running
+func BrowserPlatform(val string) attribute.KeyValue {
+	return BrowserPlatformKey.String(val)
+}
+
+// BrowserMobile returns an attribute KeyValue conforming to the
+// "browser.mobile" semantic conventions. It represents a boolean that is true
+// if the browser is running on a mobile device
+func BrowserMobile(val bool) attribute.KeyValue {
+	return BrowserMobileKey.Bool(val)
+}
+
+// BrowserUserAgent returns an attribute KeyValue conforming to the
+// "browser.user_agent" semantic conventions. It represents the full user-agent
+// string provided by the browser
+func BrowserUserAgent(val string) attribute.KeyValue {
+	return BrowserUserAgentKey.String(val)
+}
+
+// BrowserLanguage returns an attribute KeyValue conforming to the
+// "browser.language" semantic conventions. It represents the preferred
+// language of the user using the browser
+func BrowserLanguage(val string) attribute.KeyValue {
+	return BrowserLanguageKey.String(val)
+}
+
+// A cloud environment (e.g. GCP, Azure, AWS)
+const (
+	// CloudProviderKey is the attribute Key conforming to the "cloud.provider"
+	// semantic conventions. It represents the name of the cloud provider.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	CloudProviderKey = attribute.Key("cloud.provider")
+
+	// CloudAccountIDKey is the attribute Key conforming to the
+	// "cloud.account.id" semantic conventions. It represents the cloud account
+	// ID the resource is assigned to.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '111111111111', 'opentelemetry'
+	CloudAccountIDKey = attribute.Key("cloud.account.id")
+
+	// CloudRegionKey is the attribute Key conforming to the "cloud.region"
+	// semantic conventions. It represents the geographical region the resource
+	// is running.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'us-central1', 'us-east-1'
+	// Note: Refer to your provider's docs to see the available regions, for
+	// example [Alibaba Cloud
+	// regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS
+	// regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/),
+	// [Azure
+	// regions](https://azure.microsoft.com/en-us/global-infrastructure/geographies/),
+	// [Google Cloud regions](https://cloud.google.com/about/locations), or
+	// [Tencent Cloud
+	// regions](https://intl.cloud.tencent.com/document/product/213/6091).
+	CloudRegionKey = attribute.Key("cloud.region")
+
+	// CloudAvailabilityZoneKey is the attribute Key conforming to the
+	// "cloud.availability_zone" semantic conventions. It represents the cloud
+	// regions often have multiple, isolated locations known as zones to
+	// increase availability. Availability zone represents the zone where the
+	// resource is running.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'us-east-1c'
+	// Note: Availability zones are called "zones" on Alibaba Cloud and Google
+	// Cloud.
+	CloudAvailabilityZoneKey = attribute.Key("cloud.availability_zone")
+
+	// CloudPlatformKey is the attribute Key conforming to the "cloud.platform"
+	// semantic conventions. It represents the cloud platform in use.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Note: The prefix of the service SHOULD match the one specified in
+	// `cloud.provider`.
+	CloudPlatformKey = attribute.Key("cloud.platform")
+)
+
+var (
+	// Alibaba Cloud
+	CloudProviderAlibabaCloud = CloudProviderKey.String("alibaba_cloud")
+	// Amazon Web Services
+	CloudProviderAWS = CloudProviderKey.String("aws")
+	// Microsoft Azure
+	CloudProviderAzure = CloudProviderKey.String("azure")
+	// Google Cloud Platform
+	CloudProviderGCP = CloudProviderKey.String("gcp")
+	// IBM Cloud
+	CloudProviderIbmCloud = CloudProviderKey.String("ibm_cloud")
+	// Tencent Cloud
+	CloudProviderTencentCloud = CloudProviderKey.String("tencent_cloud")
+)
+
+var (
+	// Alibaba Cloud Elastic Compute Service
+	CloudPlatformAlibabaCloudECS = CloudPlatformKey.String("alibaba_cloud_ecs")
+	// Alibaba Cloud Function Compute
+	CloudPlatformAlibabaCloudFc = CloudPlatformKey.String("alibaba_cloud_fc")
+	// Red Hat OpenShift on Alibaba Cloud
+	CloudPlatformAlibabaCloudOpenshift = CloudPlatformKey.String("alibaba_cloud_openshift")
+	// AWS Elastic Compute Cloud
+	CloudPlatformAWSEC2 = CloudPlatformKey.String("aws_ec2")
+	// AWS Elastic Container Service
+	CloudPlatformAWSECS = CloudPlatformKey.String("aws_ecs")
+	// AWS Elastic Kubernetes Service
+	CloudPlatformAWSEKS = CloudPlatformKey.String("aws_eks")
+	// AWS Lambda
+	CloudPlatformAWSLambda = CloudPlatformKey.String("aws_lambda")
+	// AWS Elastic Beanstalk
+	CloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String("aws_elastic_beanstalk")
+	// AWS App Runner
+	CloudPlatformAWSAppRunner = CloudPlatformKey.String("aws_app_runner")
+	// Red Hat OpenShift on AWS (ROSA)
+	CloudPlatformAWSOpenshift = CloudPlatformKey.String("aws_openshift")
+	// Azure Virtual Machines
+	CloudPlatformAzureVM = CloudPlatformKey.String("azure_vm")
+	// Azure Container Instances
+	CloudPlatformAzureContainerInstances = CloudPlatformKey.String("azure_container_instances")
+	// Azure Kubernetes Service
+	CloudPlatformAzureAKS = CloudPlatformKey.String("azure_aks")
+	// Azure Functions
+	CloudPlatformAzureFunctions = CloudPlatformKey.String("azure_functions")
+	// Azure App Service
+	CloudPlatformAzureAppService = CloudPlatformKey.String("azure_app_service")
+	// Azure Red Hat OpenShift
+	CloudPlatformAzureOpenshift = CloudPlatformKey.String("azure_openshift")
+	// Google Cloud Compute Engine (GCE)
+	CloudPlatformGCPComputeEngine = CloudPlatformKey.String("gcp_compute_engine")
+	// Google Cloud Run
+	CloudPlatformGCPCloudRun = CloudPlatformKey.String("gcp_cloud_run")
+	// Google Cloud Kubernetes Engine (GKE)
+	CloudPlatformGCPKubernetesEngine = CloudPlatformKey.String("gcp_kubernetes_engine")
+	// Google Cloud Functions (GCF)
+	CloudPlatformGCPCloudFunctions = CloudPlatformKey.String("gcp_cloud_functions")
+	// Google Cloud App Engine (GAE)
+	CloudPlatformGCPAppEngine = CloudPlatformKey.String("gcp_app_engine")
+	// Red Hat OpenShift on Google Cloud
+	CloudPlatformGoogleCloudOpenshift = CloudPlatformKey.String("google_cloud_openshift")
+	// Red Hat OpenShift on IBM Cloud
+	CloudPlatformIbmCloudOpenshift = CloudPlatformKey.String("ibm_cloud_openshift")
+	// Tencent Cloud Cloud Virtual Machine (CVM)
+	CloudPlatformTencentCloudCvm = CloudPlatformKey.String("tencent_cloud_cvm")
+	// Tencent Cloud Elastic Kubernetes Service (EKS)
+	CloudPlatformTencentCloudEKS = CloudPlatformKey.String("tencent_cloud_eks")
+	// Tencent Cloud Serverless Cloud Function (SCF)
+	CloudPlatformTencentCloudScf = CloudPlatformKey.String("tencent_cloud_scf")
+)
+
+// CloudAccountID returns an attribute KeyValue conforming to the
+// "cloud.account.id" semantic conventions. It represents the cloud account ID
+// the resource is assigned to.
+func CloudAccountID(val string) attribute.KeyValue {
+	return CloudAccountIDKey.String(val)
+}
+
+// CloudRegion returns an attribute KeyValue conforming to the
+// "cloud.region" semantic conventions. It represents the geographical region
+// the resource is running.
+func CloudRegion(val string) attribute.KeyValue {
+	return CloudRegionKey.String(val)
+}
+
+// CloudAvailabilityZone returns an attribute KeyValue conforming to the
+// "cloud.availability_zone" semantic conventions. It represents the cloud
+// regions often have multiple, isolated locations known as zones to increase
+// availability. Availability zone represents the zone where the resource is
+// running.
+func CloudAvailabilityZone(val string) attribute.KeyValue {
+	return CloudAvailabilityZoneKey.String(val)
+}
+
+// Resources used by AWS Elastic Container Service (ECS).
+const (
+	// AWSECSContainerARNKey is the attribute Key conforming to the
+	// "aws.ecs.container.arn" semantic conventions. It represents the Amazon
+	// Resource Name (ARN) of an [ECS container
+	// instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples:
+	// 'arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9'
+	AWSECSContainerARNKey = attribute.Key("aws.ecs.container.arn")
+
+	// AWSECSClusterARNKey is the attribute Key conforming to the
+	// "aws.ecs.cluster.arn" semantic conventions. It represents the ARN of an
+	// [ECS
+	// cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'
+	AWSECSClusterARNKey = attribute.Key("aws.ecs.cluster.arn")
+
+	// AWSECSLaunchtypeKey is the attribute Key conforming to the
+	// "aws.ecs.launchtype" semantic conventions. It represents the [launch
+	// type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html)
+	// for an ECS task.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	AWSECSLaunchtypeKey = attribute.Key("aws.ecs.launchtype")
+
+	// AWSECSTaskARNKey is the attribute Key conforming to the
+	// "aws.ecs.task.arn" semantic conventions. It represents the ARN of an
+	// [ECS task
+	// definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples:
+	// 'arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b'
+	AWSECSTaskARNKey = attribute.Key("aws.ecs.task.arn")
+
+	// AWSECSTaskFamilyKey is the attribute Key conforming to the
+	// "aws.ecs.task.family" semantic conventions. It represents the task
+	// definition family this task definition is a member of.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'opentelemetry-family'
+	AWSECSTaskFamilyKey = attribute.Key("aws.ecs.task.family")
+
+	// AWSECSTaskRevisionKey is the attribute Key conforming to the
+	// "aws.ecs.task.revision" semantic conventions. It represents the revision
+	// for this task definition.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '8', '26'
+	AWSECSTaskRevisionKey = attribute.Key("aws.ecs.task.revision")
+)
+
+var (
+	// ec2
+	AWSECSLaunchtypeEC2 = AWSECSLaunchtypeKey.String("ec2")
+	// fargate
+	AWSECSLaunchtypeFargate = AWSECSLaunchtypeKey.String("fargate")
+)
+
+// AWSECSContainerARN returns an attribute KeyValue conforming to the
+// "aws.ecs.container.arn" semantic conventions. It represents the Amazon
+// Resource Name (ARN) of an [ECS container
+// instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html).
+func AWSECSContainerARN(val string) attribute.KeyValue {
+	return AWSECSContainerARNKey.String(val)
+}
+
+// AWSECSClusterARN returns an attribute KeyValue conforming to the
+// "aws.ecs.cluster.arn" semantic conventions. It represents the ARN of an [ECS
+// cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html).
+func AWSECSClusterARN(val string) attribute.KeyValue {
+	return AWSECSClusterARNKey.String(val)
+}
+
+// AWSECSTaskARN returns an attribute KeyValue conforming to the
+// "aws.ecs.task.arn" semantic conventions. It represents the ARN of an [ECS
+// task
+// definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html).
+func AWSECSTaskARN(val string) attribute.KeyValue {
+	return AWSECSTaskARNKey.String(val)
+}
+
+// AWSECSTaskFamily returns an attribute KeyValue conforming to the
+// "aws.ecs.task.family" semantic conventions. It represents the task
+// definition family this task definition is a member of.
+func AWSECSTaskFamily(val string) attribute.KeyValue {
+	return AWSECSTaskFamilyKey.String(val)
+}
+
+// AWSECSTaskRevision returns an attribute KeyValue conforming to the
+// "aws.ecs.task.revision" semantic conventions. It represents the revision for
+// this task definition.
+func AWSECSTaskRevision(val string) attribute.KeyValue {
+	return AWSECSTaskRevisionKey.String(val)
+}
+
+// Resources used by AWS Elastic Kubernetes Service (EKS).
+const (
+	// AWSEKSClusterARNKey is the attribute Key conforming to the
+	// "aws.eks.cluster.arn" semantic conventions. It represents the ARN of an
+	// EKS cluster.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'
+	AWSEKSClusterARNKey = attribute.Key("aws.eks.cluster.arn")
+)
+
+// AWSEKSClusterARN returns an attribute KeyValue conforming to the
+// "aws.eks.cluster.arn" semantic conventions. It represents the ARN of an EKS
+// cluster.
+func AWSEKSClusterARN(val string) attribute.KeyValue {
+	return AWSEKSClusterARNKey.String(val)
+}
+
+// Resources specific to Amazon Web Services.
+const (
+	// AWSLogGroupNamesKey is the attribute Key conforming to the
+	// "aws.log.group.names" semantic conventions. It represents the name(s) of
+	// the AWS log group(s) an application is writing to.
+	//
+	// Type: string[]
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '/aws/lambda/my-function', 'opentelemetry-service'
+	// Note: Multiple log groups must be supported for cases like
+	// multi-container applications, where a single application has sidecar
+	// containers, and each write to their own log group.
+	AWSLogGroupNamesKey = attribute.Key("aws.log.group.names")
+
+	// AWSLogGroupARNsKey is the attribute Key conforming to the
+	// "aws.log.group.arns" semantic conventions. It represents the Amazon
+	// Resource Name(s) (ARN) of the AWS log group(s).
+	//
+	// Type: string[]
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples:
+	// 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*'
+	// Note: See the [log group ARN format
+	// documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format).
+	AWSLogGroupARNsKey = attribute.Key("aws.log.group.arns")
+
+	// AWSLogStreamNamesKey is the attribute Key conforming to the
+	// "aws.log.stream.names" semantic conventions. It represents the name(s)
+	// of the AWS log stream(s) an application is writing to.
+	//
+	// Type: string[]
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'
+	AWSLogStreamNamesKey = attribute.Key("aws.log.stream.names")
+
+	// AWSLogStreamARNsKey is the attribute Key conforming to the
+	// "aws.log.stream.arns" semantic conventions. It represents the ARN(s) of
+	// the AWS log stream(s).
+	//
+	// Type: string[]
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples:
+	// 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'
+	// Note: See the [log stream ARN format
+	// documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format).
+	// One log group can contain several log streams, so these ARNs necessarily
+	// identify both a log group and a log stream.
+	AWSLogStreamARNsKey = attribute.Key("aws.log.stream.arns")
+)
+
+// AWSLogGroupNames returns an attribute KeyValue conforming to the
+// "aws.log.group.names" semantic conventions. It represents the name(s) of the
+// AWS log group(s) an application is writing to.
+func AWSLogGroupNames(val ...string) attribute.KeyValue {
+	return AWSLogGroupNamesKey.StringSlice(val)
+}
+
+// AWSLogGroupARNs returns an attribute KeyValue conforming to the
+// "aws.log.group.arns" semantic conventions. It represents the Amazon Resource
+// Name(s) (ARN) of the AWS log group(s).
+func AWSLogGroupARNs(val ...string) attribute.KeyValue {
+	return AWSLogGroupARNsKey.StringSlice(val)
+}
+
+// AWSLogStreamNames returns an attribute KeyValue conforming to the
+// "aws.log.stream.names" semantic conventions. It represents the name(s) of
+// the AWS log stream(s) an application is writing to.
+func AWSLogStreamNames(val ...string) attribute.KeyValue {
+	return AWSLogStreamNamesKey.StringSlice(val)
+}
+
+// AWSLogStreamARNs returns an attribute KeyValue conforming to the
+// "aws.log.stream.arns" semantic conventions. It represents the ARN(s) of the
+// AWS log stream(s).
+func AWSLogStreamARNs(val ...string) attribute.KeyValue {
+	return AWSLogStreamARNsKey.StringSlice(val)
+}
+
+// A container instance.
+const (
+	// ContainerNameKey is the attribute Key conforming to the "container.name"
+	// semantic conventions. It represents the container name used by container
+	// runtime.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'opentelemetry-autoconf'
+	ContainerNameKey = attribute.Key("container.name")
+
+	// ContainerIDKey is the attribute Key conforming to the "container.id"
+	// semantic conventions. It represents the container ID. Usually a UUID, as
+	// for example used to [identify Docker
+	// containers](https://docs.docker.com/engine/reference/run/#container-identification).
+	// The UUID might be abbreviated.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'a3bf90e006b2'
+	ContainerIDKey = attribute.Key("container.id")
+
+	// ContainerRuntimeKey is the attribute Key conforming to the
+	// "container.runtime" semantic conventions. It represents the container
+	// runtime managing this container.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'docker', 'containerd', 'rkt'
+	ContainerRuntimeKey = attribute.Key("container.runtime")
+
+	// ContainerImageNameKey is the attribute Key conforming to the
+	// "container.image.name" semantic conventions. It represents the name of
+	// the image the container was built on.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'gcr.io/opentelemetry/operator'
+	ContainerImageNameKey = attribute.Key("container.image.name")
+
+	// ContainerImageTagKey is the attribute Key conforming to the
+	// "container.image.tag" semantic conventions. It represents the container
+	// image tag.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '0.1'
+	ContainerImageTagKey = attribute.Key("container.image.tag")
+)
+
+// ContainerName returns an attribute KeyValue conforming to the
+// "container.name" semantic conventions. It represents the container name used
+// by container runtime.
+func ContainerName(val string) attribute.KeyValue {
+	return ContainerNameKey.String(val)
+}
+
+// ContainerID returns an attribute KeyValue conforming to the
+// "container.id" semantic conventions. It represents the container ID. Usually
+// a UUID, as for example used to [identify Docker
+// containers](https://docs.docker.com/engine/reference/run/#container-identification).
+// The UUID might be abbreviated.
+func ContainerID(val string) attribute.KeyValue {
+	return ContainerIDKey.String(val)
+}
+
+// ContainerRuntime returns an attribute KeyValue conforming to the
+// "container.runtime" semantic conventions. It represents the container
+// runtime managing this container.
+func ContainerRuntime(val string) attribute.KeyValue {
+	return ContainerRuntimeKey.String(val)
+}
+
+// ContainerImageName returns an attribute KeyValue conforming to the
+// "container.image.name" semantic conventions. It represents the name of the
+// image the container was built on.
+func ContainerImageName(val string) attribute.KeyValue {
+	return ContainerImageNameKey.String(val)
+}
+
+// ContainerImageTag returns an attribute KeyValue conforming to the
+// "container.image.tag" semantic conventions. It represents the container
+// image tag.
+func ContainerImageTag(val string) attribute.KeyValue {
+	return ContainerImageTagKey.String(val)
+}
+
+// The software deployment.
+const (
+	// DeploymentEnvironmentKey is the attribute Key conforming to the
+	// "deployment.environment" semantic conventions. It represents the name of
+	// the [deployment
+	// environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka
+	// deployment tier).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'staging', 'production'
+	DeploymentEnvironmentKey = attribute.Key("deployment.environment")
+)
+
+// DeploymentEnvironment returns an attribute KeyValue conforming to the
+// "deployment.environment" semantic conventions. It represents the name of the
+// [deployment
+// environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka
+// deployment tier).
+func DeploymentEnvironment(val string) attribute.KeyValue {
+	return DeploymentEnvironmentKey.String(val)
+}
+
+// The device on which the process represented by this resource is running.
+const (
+	// DeviceIDKey is the attribute Key conforming to the "device.id" semantic
+	// conventions. It represents a unique identifier representing the device
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '2ab2916d-a51f-4ac8-80ee-45ac31a28092'
+	// Note: The device identifier MUST only be defined using the values
+	// outlined below. This value is not an advertising identifier and MUST NOT
+	// be used as such. On iOS (Swift or Objective-C), this value MUST be equal
+	// to the [vendor
+	// identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor).
+	// On Android (Java or Kotlin), this value MUST be equal to the Firebase
+	// Installation ID or a globally unique UUID which is persisted across
+	// sessions in your application. More information can be found
+	// [here](https://developer.android.com/training/articles/user-data-ids) on
+	// best practices and exact implementation details. Caution should be taken
+	// when storing personal data or anything which can identify a user. GDPR
+	// and data protection laws may apply, ensure you do your own due
+	// diligence.
+	DeviceIDKey = attribute.Key("device.id")
+
+	// DeviceModelIdentifierKey is the attribute Key conforming to the
+	// "device.model.identifier" semantic conventions. It represents the model
+	// identifier for the device
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'iPhone3,4', 'SM-G920F'
+	// Note: It's recommended this value represents a machine readable version
+	// of the model identifier rather than the market or consumer-friendly name
+	// of the device.
+	DeviceModelIdentifierKey = attribute.Key("device.model.identifier")
+
+	// DeviceModelNameKey is the attribute Key conforming to the
+	// "device.model.name" semantic conventions. It represents the marketing
+	// name for the device model
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'iPhone 6s Plus', 'Samsung Galaxy S6'
+	// Note: It's recommended this value represents a human readable version of
+	// the device model rather than a machine readable alternative.
+	DeviceModelNameKey = attribute.Key("device.model.name")
+
+	// DeviceManufacturerKey is the attribute Key conforming to the
+	// "device.manufacturer" semantic conventions. It represents the name of
+	// the device manufacturer
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'Apple', 'Samsung'
+	// Note: The Android OS provides this field via
+	// [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER).
+	// iOS apps SHOULD hardcode the value `Apple`.
+	DeviceManufacturerKey = attribute.Key("device.manufacturer")
+)
+
+// DeviceID returns an attribute KeyValue conforming to the "device.id"
+// semantic conventions. It represents a unique identifier representing the
+// device
+func DeviceID(val string) attribute.KeyValue {
+	return DeviceIDKey.String(val)
+}
+
+// DeviceModelIdentifier returns an attribute KeyValue conforming to the
+// "device.model.identifier" semantic conventions. It represents the model
+// identifier for the device
+func DeviceModelIdentifier(val string) attribute.KeyValue {
+	return DeviceModelIdentifierKey.String(val)
+}
+
+// DeviceModelName returns an attribute KeyValue conforming to the
+// "device.model.name" semantic conventions. It represents the marketing name
+// for the device model
+func DeviceModelName(val string) attribute.KeyValue {
+	return DeviceModelNameKey.String(val)
+}
+
+// DeviceManufacturer returns an attribute KeyValue conforming to the
+// "device.manufacturer" semantic conventions. It represents the name of the
+// device manufacturer
+func DeviceManufacturer(val string) attribute.KeyValue {
+	return DeviceManufacturerKey.String(val)
+}
+
+// A serverless instance.
+const (
+	// FaaSNameKey is the attribute Key conforming to the "faas.name" semantic
+	// conventions. It represents the name of the single function that this
+	// runtime instance executes.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'my-function', 'myazurefunctionapp/some-function-name'
+	// Note: This is the name of the function as configured/deployed on the
+	// FaaS
+	// platform and is usually different from the name of the callback
+	// function (which may be stored in the
+	// [`code.namespace`/`code.function`](../../trace/semantic_conventions/span-general.md#source-code-attributes)
+	// span attributes).
+	//
+	// For some cloud providers, the above definition is ambiguous. The
+	// following
+	// definition of function name MUST be used for this attribute
+	// (and consequently the span name) for the listed cloud
+	// providers/products:
+	//
+	// * **Azure:**  The full name `<FUNCAPP>/<FUNC>`, i.e., function app name
+	//   followed by a forward slash followed by the function name (this form
+	//   can also be seen in the resource JSON for the function).
+	//   This means that a span attribute MUST be used, as an Azure function
+	//   app can host multiple functions that would usually share
+	//   a TracerProvider (see also the `faas.id` attribute).
+	FaaSNameKey = attribute.Key("faas.name")
+
+	// FaaSIDKey is the attribute Key conforming to the "faas.id" semantic
+	// conventions. It represents the unique ID of the single function that
+	// this runtime instance executes.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'arn:aws:lambda:us-west-2:123456789012:function:my-function'
+	// Note: On some cloud providers, it may not be possible to determine the
+	// full ID at startup,
+	// so consider setting `faas.id` as a span attribute instead.
+	//
+	// The exact value to use for `faas.id` depends on the cloud provider:
+	//
+	// * **AWS Lambda:** The function
+	// [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html).
+	//   Take care not to use the "invoked ARN" directly but replace any
+	//   [alias
+	// suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html)
+	//   with the resolved function version, as the same runtime instance may
+	// be invokable with
+	//   multiple different aliases.
+	// * **GCP:** The [URI of the
+	// resource](https://cloud.google.com/iam/docs/full-resource-names)
+	// * **Azure:** The [Fully Qualified Resource
+	// ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id)
+	// of the invoked function,
+	//   *not* the function app, having the form
+	// `/subscriptions/<SUBSCIPTION_GUID>/resourceGroups/<RG>/providers/Microsoft.Web/sites/<FUNCAPP>/functions/<FUNC>`.
+	//   This means that a span attribute MUST be used, as an Azure function
+	// app can host multiple functions that would usually share
+	//   a TracerProvider.
+	FaaSIDKey = attribute.Key("faas.id")
+
+	// FaaSVersionKey is the attribute Key conforming to the "faas.version"
+	// semantic conventions. It represents the immutable version of the
+	// function being executed.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '26', 'pinkfroid-00002'
+	// Note: Depending on the cloud provider and platform, use:
+	//
+	// * **AWS Lambda:** The [function
+	// version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html)
+	//   (an integer represented as a decimal string).
+	// * **Google Cloud Run:** The
+	// [revision](https://cloud.google.com/run/docs/managing/revisions)
+	//   (i.e., the function name plus the revision suffix).
+	// * **Google Cloud Functions:** The value of the
+	//   [`K_REVISION` environment
+	// variable](https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically).
+	// * **Azure Functions:** Not applicable. Do not set this attribute.
+	FaaSVersionKey = attribute.Key("faas.version")
+
+	// FaaSInstanceKey is the attribute Key conforming to the "faas.instance"
+	// semantic conventions. It represents the execution environment ID as a
+	// string, that will be potentially reused for other invocations to the
+	// same function/function version.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de'
+	// Note: * **AWS Lambda:** Use the (full) log stream name.
+	FaaSInstanceKey = attribute.Key("faas.instance")
+
+	// FaaSMaxMemoryKey is the attribute Key conforming to the
+	// "faas.max_memory" semantic conventions. It represents the amount of
+	// memory available to the serverless function in MiB.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 128
+	// Note: It's recommended to set this attribute since e.g. too little
+	// memory can easily stop a Java AWS Lambda function from working
+	// correctly. On AWS Lambda, the environment variable
+	// `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information.
+	FaaSMaxMemoryKey = attribute.Key("faas.max_memory")
+)
+
+// FaaSName returns an attribute KeyValue conforming to the "faas.name"
+// semantic conventions. It represents the name of the single function that
+// this runtime instance executes.
+func FaaSName(val string) attribute.KeyValue {
+	return FaaSNameKey.String(val)
+}
+
+// FaaSID returns an attribute KeyValue conforming to the "faas.id" semantic
+// conventions. It represents the unique ID of the single function that this
+// runtime instance executes.
+func FaaSID(val string) attribute.KeyValue {
+	return FaaSIDKey.String(val)
+}
+
+// FaaSVersion returns an attribute KeyValue conforming to the
+// "faas.version" semantic conventions. It represents the immutable version of
+// the function being executed.
+func FaaSVersion(val string) attribute.KeyValue {
+	return FaaSVersionKey.String(val)
+}
+
+// FaaSInstance returns an attribute KeyValue conforming to the
+// "faas.instance" semantic conventions. It represents the execution
+// environment ID as a string, that will be potentially reused for other
+// invocations to the same function/function version.
+func FaaSInstance(val string) attribute.KeyValue {
+	return FaaSInstanceKey.String(val)
+}
+
+// FaaSMaxMemory returns an attribute KeyValue conforming to the
+// "faas.max_memory" semantic conventions. It represents the amount of memory
+// available to the serverless function in MiB.
+func FaaSMaxMemory(val int) attribute.KeyValue {
+	return FaaSMaxMemoryKey.Int(val)
+}
+
+// A host is defined as a general computing instance.
+const (
+	// HostIDKey is the attribute Key conforming to the "host.id" semantic
+	// conventions. It represents the unique host ID. For Cloud, this must be
+	// the instance_id assigned by the cloud provider. For non-containerized
+	// Linux systems, the `machine-id` located in `/etc/machine-id` or
+	// `/var/lib/dbus/machine-id` may be used.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'fdbf79e8af94cb7f9e8df36789187052'
+	HostIDKey = attribute.Key("host.id")
+
+	// HostNameKey is the attribute Key conforming to the "host.name" semantic
+	// conventions. It represents the name of the host. On Unix systems, it may
+	// contain what the hostname command returns, or the fully qualified
+	// hostname, or another name specified by the user.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'opentelemetry-test'
+	HostNameKey = attribute.Key("host.name")
+
+	// HostTypeKey is the attribute Key conforming to the "host.type" semantic
+	// conventions. It represents the type of host. For Cloud, this must be the
+	// machine type.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'n1-standard-1'
+	HostTypeKey = attribute.Key("host.type")
+
+	// HostArchKey is the attribute Key conforming to the "host.arch" semantic
+	// conventions. It represents the CPU architecture the host system is
+	// running on.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	HostArchKey = attribute.Key("host.arch")
+
+	// HostImageNameKey is the attribute Key conforming to the
+	// "host.image.name" semantic conventions. It represents the name of the VM
+	// image or OS install the host was instantiated from.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905'
+	HostImageNameKey = attribute.Key("host.image.name")
+
+	// HostImageIDKey is the attribute Key conforming to the "host.image.id"
+	// semantic conventions. It represents the vM image ID. For Cloud, this
+	// value is from the provider.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'ami-07b06b442921831e5'
+	HostImageIDKey = attribute.Key("host.image.id")
+
+	// HostImageVersionKey is the attribute Key conforming to the
+	// "host.image.version" semantic conventions. It represents the version
+	// string of the VM image as defined in [Version
+	// Attributes](README.md#version-attributes).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '0.1'
+	HostImageVersionKey = attribute.Key("host.image.version")
+)
+
+var (
+	// AMD64
+	HostArchAMD64 = HostArchKey.String("amd64")
+	// ARM32
+	HostArchARM32 = HostArchKey.String("arm32")
+	// ARM64
+	HostArchARM64 = HostArchKey.String("arm64")
+	// Itanium
+	HostArchIA64 = HostArchKey.String("ia64")
+	// 32-bit PowerPC
+	HostArchPPC32 = HostArchKey.String("ppc32")
+	// 64-bit PowerPC
+	HostArchPPC64 = HostArchKey.String("ppc64")
+	// IBM z/Architecture
+	HostArchS390x = HostArchKey.String("s390x")
+	// 32-bit x86
+	HostArchX86 = HostArchKey.String("x86")
+)
+
+// HostID returns an attribute KeyValue conforming to the "host.id" semantic
+// conventions. It represents the unique host ID. For Cloud, this must be the
+// instance_id assigned by the cloud provider. For non-containerized Linux
+// systems, the `machine-id` located in `/etc/machine-id` or
+// `/var/lib/dbus/machine-id` may be used.
+func HostID(val string) attribute.KeyValue {
+	return HostIDKey.String(val)
+}
+
+// HostName returns an attribute KeyValue conforming to the "host.name"
+// semantic conventions. It represents the name of the host. On Unix systems,
+// it may contain what the hostname command returns, or the fully qualified
+// hostname, or another name specified by the user.
+func HostName(val string) attribute.KeyValue {
+	return HostNameKey.String(val)
+}
+
+// HostType returns an attribute KeyValue conforming to the "host.type"
+// semantic conventions. It represents the type of host. For Cloud, this must
+// be the machine type.
+func HostType(val string) attribute.KeyValue {
+	return HostTypeKey.String(val)
+}
+
+// HostImageName returns an attribute KeyValue conforming to the
+// "host.image.name" semantic conventions. It represents the name of the VM
+// image or OS install the host was instantiated from.
+func HostImageName(val string) attribute.KeyValue {
+	return HostImageNameKey.String(val)
+}
+
+// HostImageID returns an attribute KeyValue conforming to the
+// "host.image.id" semantic conventions. It represents the vM image ID. For
+// Cloud, this value is from the provider.
+func HostImageID(val string) attribute.KeyValue {
+	return HostImageIDKey.String(val)
+}
+
+// HostImageVersion returns an attribute KeyValue conforming to the
+// "host.image.version" semantic conventions. It represents the version string
+// of the VM image as defined in [Version
+// Attributes](README.md#version-attributes).
+func HostImageVersion(val string) attribute.KeyValue {
+	return HostImageVersionKey.String(val)
+}
+
+// A Kubernetes Cluster.
+const (
+	// K8SClusterNameKey is the attribute Key conforming to the
+	// "k8s.cluster.name" semantic conventions. It represents the name of the
+	// cluster.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'opentelemetry-cluster'
+	K8SClusterNameKey = attribute.Key("k8s.cluster.name")
+)
+
+// K8SClusterName returns an attribute KeyValue conforming to the
+// "k8s.cluster.name" semantic conventions. It represents the name of the
+// cluster.
+func K8SClusterName(val string) attribute.KeyValue {
+	return K8SClusterNameKey.String(val)
+}
+
+// A Kubernetes Node object.
+const (
+	// K8SNodeNameKey is the attribute Key conforming to the "k8s.node.name"
+	// semantic conventions. It represents the name of the Node.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'node-1'
+	K8SNodeNameKey = attribute.Key("k8s.node.name")
+
+	// K8SNodeUIDKey is the attribute Key conforming to the "k8s.node.uid"
+	// semantic conventions. It represents the UID of the Node.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2'
+	K8SNodeUIDKey = attribute.Key("k8s.node.uid")
+)
+
+// K8SNodeName returns an attribute KeyValue conforming to the
+// "k8s.node.name" semantic conventions. It represents the name of the Node.
+func K8SNodeName(val string) attribute.KeyValue {
+	return K8SNodeNameKey.String(val)
+}
+
+// K8SNodeUID returns an attribute KeyValue conforming to the "k8s.node.uid"
+// semantic conventions. It represents the UID of the Node.
+func K8SNodeUID(val string) attribute.KeyValue {
+	return K8SNodeUIDKey.String(val)
+}
+
+// A Kubernetes Namespace.
+const (
+	// K8SNamespaceNameKey is the attribute Key conforming to the
+	// "k8s.namespace.name" semantic conventions. It represents the name of the
+	// namespace that the pod is running in.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'default'
+	K8SNamespaceNameKey = attribute.Key("k8s.namespace.name")
+)
+
+// K8SNamespaceName returns an attribute KeyValue conforming to the
+// "k8s.namespace.name" semantic conventions. It represents the name of the
+// namespace that the pod is running in.
+func K8SNamespaceName(val string) attribute.KeyValue {
+	return K8SNamespaceNameKey.String(val)
+}
+
+// A Kubernetes Pod object.
+const (
+	// K8SPodUIDKey is the attribute Key conforming to the "k8s.pod.uid"
+	// semantic conventions. It represents the UID of the Pod.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
+	K8SPodUIDKey = attribute.Key("k8s.pod.uid")
+
+	// K8SPodNameKey is the attribute Key conforming to the "k8s.pod.name"
+	// semantic conventions. It represents the name of the Pod.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'opentelemetry-pod-autoconf'
+	K8SPodNameKey = attribute.Key("k8s.pod.name")
+)
+
+// K8SPodUID returns an attribute KeyValue conforming to the "k8s.pod.uid"
+// semantic conventions. It represents the UID of the Pod.
+func K8SPodUID(val string) attribute.KeyValue {
+	return K8SPodUIDKey.String(val)
+}
+
+// K8SPodName returns an attribute KeyValue conforming to the "k8s.pod.name"
+// semantic conventions. It represents the name of the Pod.
+func K8SPodName(val string) attribute.KeyValue {
+	return K8SPodNameKey.String(val)
+}
+
+// A container in a
+// [PodTemplate](https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates).
+const (
+	// K8SContainerNameKey is the attribute Key conforming to the
+	// "k8s.container.name" semantic conventions. It represents the name of the
+	// Container from Pod specification, must be unique within a Pod. Container
+	// runtime usually uses different globally unique name (`container.name`).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'redis'
+	K8SContainerNameKey = attribute.Key("k8s.container.name")
+
+	// K8SContainerRestartCountKey is the attribute Key conforming to the
+	// "k8s.container.restart_count" semantic conventions. It represents the
+	// number of times the container was restarted. This attribute can be used
+	// to identify a particular container (running or stopped) within a
+	// container spec.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 0, 2
+	K8SContainerRestartCountKey = attribute.Key("k8s.container.restart_count")
+)
+
+// K8SContainerName returns an attribute KeyValue conforming to the
+// "k8s.container.name" semantic conventions. It represents the name of the
+// Container from Pod specification, must be unique within a Pod. Container
+// runtime usually uses different globally unique name (`container.name`).
+func K8SContainerName(val string) attribute.KeyValue {
+	return K8SContainerNameKey.String(val)
+}
+
+// K8SContainerRestartCount returns an attribute KeyValue conforming to the
+// "k8s.container.restart_count" semantic conventions. It represents the number
+// of times the container was restarted. This attribute can be used to identify
+// a particular container (running or stopped) within a container spec.
+func K8SContainerRestartCount(val int) attribute.KeyValue {
+	return K8SContainerRestartCountKey.Int(val)
+}
+
+// A Kubernetes ReplicaSet object.
+const (
+	// K8SReplicaSetUIDKey is the attribute Key conforming to the
+	// "k8s.replicaset.uid" semantic conventions. It represents the UID of the
+	// ReplicaSet.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
+	K8SReplicaSetUIDKey = attribute.Key("k8s.replicaset.uid")
+
+	// K8SReplicaSetNameKey is the attribute Key conforming to the
+	// "k8s.replicaset.name" semantic conventions. It represents the name of
+	// the ReplicaSet.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'opentelemetry'
+	K8SReplicaSetNameKey = attribute.Key("k8s.replicaset.name")
+)
+
+// K8SReplicaSetUID returns an attribute KeyValue conforming to the
+// "k8s.replicaset.uid" semantic conventions. It represents the UID of the
+// ReplicaSet.
+func K8SReplicaSetUID(val string) attribute.KeyValue {
+	return K8SReplicaSetUIDKey.String(val)
+}
+
+// K8SReplicaSetName returns an attribute KeyValue conforming to the
+// "k8s.replicaset.name" semantic conventions. It represents the name of the
+// ReplicaSet.
+func K8SReplicaSetName(val string) attribute.KeyValue {
+	return K8SReplicaSetNameKey.String(val)
+}
+
+// A Kubernetes Deployment object.
+const (
+	// K8SDeploymentUIDKey is the attribute Key conforming to the
+	// "k8s.deployment.uid" semantic conventions. It represents the UID of the
+	// Deployment.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
+	K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid")
+
+	// K8SDeploymentNameKey is the attribute Key conforming to the
+	// "k8s.deployment.name" semantic conventions. It represents the name of
+	// the Deployment.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'opentelemetry'
+	K8SDeploymentNameKey = attribute.Key("k8s.deployment.name")
+)
+
+// K8SDeploymentUID returns an attribute KeyValue conforming to the
+// "k8s.deployment.uid" semantic conventions. It represents the UID of the
+// Deployment.
+func K8SDeploymentUID(val string) attribute.KeyValue {
+	return K8SDeploymentUIDKey.String(val)
+}
+
+// K8SDeploymentName returns an attribute KeyValue conforming to the
+// "k8s.deployment.name" semantic conventions. It represents the name of the
+// Deployment.
+func K8SDeploymentName(val string) attribute.KeyValue {
+	return K8SDeploymentNameKey.String(val)
+}
+
+// A Kubernetes StatefulSet object.
+const (
+	// K8SStatefulSetUIDKey is the attribute Key conforming to the
+	// "k8s.statefulset.uid" semantic conventions. It represents the UID of the
+	// StatefulSet.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
+	K8SStatefulSetUIDKey = attribute.Key("k8s.statefulset.uid")
+
+	// K8SStatefulSetNameKey is the attribute Key conforming to the
+	// "k8s.statefulset.name" semantic conventions. It represents the name of
+	// the StatefulSet.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'opentelemetry'
+	K8SStatefulSetNameKey = attribute.Key("k8s.statefulset.name")
+)
+
+// K8SStatefulSetUID returns an attribute KeyValue conforming to the
+// "k8s.statefulset.uid" semantic conventions. It represents the UID of the
+// StatefulSet.
+func K8SStatefulSetUID(val string) attribute.KeyValue {
+	return K8SStatefulSetUIDKey.String(val)
+}
+
+// K8SStatefulSetName returns an attribute KeyValue conforming to the
+// "k8s.statefulset.name" semantic conventions. It represents the name of the
+// StatefulSet.
+func K8SStatefulSetName(val string) attribute.KeyValue {
+	return K8SStatefulSetNameKey.String(val)
+}
+
+// A Kubernetes DaemonSet object.
+const (
+	// K8SDaemonSetUIDKey is the attribute Key conforming to the
+	// "k8s.daemonset.uid" semantic conventions. It represents the UID of the
+	// DaemonSet.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
+	K8SDaemonSetUIDKey = attribute.Key("k8s.daemonset.uid")
+
+	// K8SDaemonSetNameKey is the attribute Key conforming to the
+	// "k8s.daemonset.name" semantic conventions. It represents the name of the
+	// DaemonSet.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'opentelemetry'
+	K8SDaemonSetNameKey = attribute.Key("k8s.daemonset.name")
+)
+
+// K8SDaemonSetUID returns an attribute KeyValue conforming to the
+// "k8s.daemonset.uid" semantic conventions. It represents the UID of the
+// DaemonSet.
+func K8SDaemonSetUID(val string) attribute.KeyValue {
+	return K8SDaemonSetUIDKey.String(val)
+}
+
+// K8SDaemonSetName returns an attribute KeyValue conforming to the
+// "k8s.daemonset.name" semantic conventions. It represents the name of the
+// DaemonSet.
+func K8SDaemonSetName(val string) attribute.KeyValue {
+	return K8SDaemonSetNameKey.String(val)
+}
+
+// A Kubernetes Job object.
+const (
+	// K8SJobUIDKey is the attribute Key conforming to the "k8s.job.uid"
+	// semantic conventions. It represents the UID of the Job.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
+	K8SJobUIDKey = attribute.Key("k8s.job.uid")
+
+	// K8SJobNameKey is the attribute Key conforming to the "k8s.job.name"
+	// semantic conventions. It represents the name of the Job.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'opentelemetry'
+	K8SJobNameKey = attribute.Key("k8s.job.name")
+)
+
+// K8SJobUID returns an attribute KeyValue conforming to the "k8s.job.uid"
+// semantic conventions. It represents the UID of the Job.
+func K8SJobUID(val string) attribute.KeyValue {
+	return K8SJobUIDKey.String(val)
+}
+
+// K8SJobName returns an attribute KeyValue conforming to the "k8s.job.name"
+// semantic conventions. It represents the name of the Job.
+func K8SJobName(val string) attribute.KeyValue {
+	return K8SJobNameKey.String(val)
+}
+
+// A Kubernetes CronJob object.
+const (
+	// K8SCronJobUIDKey is the attribute Key conforming to the
+	// "k8s.cronjob.uid" semantic conventions. It represents the UID of the
+	// CronJob.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
+	K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid")
+
+	// K8SCronJobNameKey is the attribute Key conforming to the
+	// "k8s.cronjob.name" semantic conventions. It represents the name of the
+	// CronJob.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'opentelemetry'
+	K8SCronJobNameKey = attribute.Key("k8s.cronjob.name")
+)
+
+// K8SCronJobUID returns an attribute KeyValue conforming to the
+// "k8s.cronjob.uid" semantic conventions. It represents the UID of the
+// CronJob.
+func K8SCronJobUID(val string) attribute.KeyValue {
+	return K8SCronJobUIDKey.String(val)
+}
+
+// K8SCronJobName returns an attribute KeyValue conforming to the
+// "k8s.cronjob.name" semantic conventions. It represents the name of the
+// CronJob.
+func K8SCronJobName(val string) attribute.KeyValue {
+	return K8SCronJobNameKey.String(val)
+}
+
+// The operating system (OS) on which the process represented by this resource
+// is running.
+const (
+	// OSTypeKey is the attribute Key conforming to the "os.type" semantic
+	// conventions. It represents the operating system type.
+	//
+	// Type: Enum
+	// RequirementLevel: Required
+	// Stability: stable
+	OSTypeKey = attribute.Key("os.type")
+
+	// OSDescriptionKey is the attribute Key conforming to the "os.description"
+	// semantic conventions. It represents the human readable (not intended to
+	// be parsed) OS version information, like e.g. reported by `ver` or
+	// `lsb_release -a` commands.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1
+	// LTS'
+	OSDescriptionKey = attribute.Key("os.description")
+
+	// OSNameKey is the attribute Key conforming to the "os.name" semantic
+	// conventions. It represents the human readable operating system name.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'iOS', 'Android', 'Ubuntu'
+	OSNameKey = attribute.Key("os.name")
+
+	// OSVersionKey is the attribute Key conforming to the "os.version"
+	// semantic conventions. It represents the version string of the operating
+	// system as defined in [Version
+	// Attributes](../../resource/semantic_conventions/README.md#version-attributes).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '14.2.1', '18.04.1'
+	OSVersionKey = attribute.Key("os.version")
+)
+
+var (
+	// Microsoft Windows
+	OSTypeWindows = OSTypeKey.String("windows")
+	// Linux
+	OSTypeLinux = OSTypeKey.String("linux")
+	// Apple Darwin
+	OSTypeDarwin = OSTypeKey.String("darwin")
+	// FreeBSD
+	OSTypeFreeBSD = OSTypeKey.String("freebsd")
+	// NetBSD
+	OSTypeNetBSD = OSTypeKey.String("netbsd")
+	// OpenBSD
+	OSTypeOpenBSD = OSTypeKey.String("openbsd")
+	// DragonFly BSD
+	OSTypeDragonflyBSD = OSTypeKey.String("dragonflybsd")
+	// HP-UX (Hewlett Packard Unix)
+	OSTypeHPUX = OSTypeKey.String("hpux")
+	// AIX (Advanced Interactive eXecutive)
+	OSTypeAIX = OSTypeKey.String("aix")
+	// SunOS, Oracle Solaris
+	OSTypeSolaris = OSTypeKey.String("solaris")
+	// IBM z/OS
+	OSTypeZOS = OSTypeKey.String("z_os")
+)
+
+// OSDescription returns an attribute KeyValue conforming to the
+// "os.description" semantic conventions. It represents the human readable (not
+// intended to be parsed) OS version information, like e.g. reported by `ver`
+// or `lsb_release -a` commands.
+func OSDescription(val string) attribute.KeyValue {
+	return OSDescriptionKey.String(val)
+}
+
+// OSName returns an attribute KeyValue conforming to the "os.name" semantic
+// conventions. It represents the human readable operating system name.
+func OSName(val string) attribute.KeyValue {
+	return OSNameKey.String(val)
+}
+
+// OSVersion returns an attribute KeyValue conforming to the "os.version"
+// semantic conventions. It represents the version string of the operating
+// system as defined in [Version
+// Attributes](../../resource/semantic_conventions/README.md#version-attributes).
+func OSVersion(val string) attribute.KeyValue {
+	return OSVersionKey.String(val)
+}
+
+// An operating system process.
+const (
+	// ProcessPIDKey is the attribute Key conforming to the "process.pid"
+	// semantic conventions. It represents the process identifier (PID).
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 1234
+	ProcessPIDKey = attribute.Key("process.pid")
+
+	// ProcessParentPIDKey is the attribute Key conforming to the
+	// "process.parent_pid" semantic conventions. It represents the parent
+	// Process identifier (PID).
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 111
+	ProcessParentPIDKey = attribute.Key("process.parent_pid")
+
+	// ProcessExecutableNameKey is the attribute Key conforming to the
+	// "process.executable.name" semantic conventions. It represents the name
+	// of the process executable. On Linux based systems, can be set to the
+	// `Name` in `proc/[pid]/status`. On Windows, can be set to the base name
+	// of `GetProcessImageFileNameW`.
+	//
+	// Type: string
+	// RequirementLevel: ConditionallyRequired (See alternative attributes
+	// below.)
+	// Stability: stable
+	// Examples: 'otelcol'
+	ProcessExecutableNameKey = attribute.Key("process.executable.name")
+
+	// ProcessExecutablePathKey is the attribute Key conforming to the
+	// "process.executable.path" semantic conventions. It represents the full
+	// path to the process executable. On Linux based systems, can be set to
+	// the target of `proc/[pid]/exe`. On Windows, can be set to the result of
+	// `GetProcessImageFileNameW`.
+	//
+	// Type: string
+	// RequirementLevel: ConditionallyRequired (See alternative attributes
+	// below.)
+	// Stability: stable
+	// Examples: '/usr/bin/cmd/otelcol'
+	ProcessExecutablePathKey = attribute.Key("process.executable.path")
+
+	// ProcessCommandKey is the attribute Key conforming to the
+	// "process.command" semantic conventions. It represents the command used
+	// to launch the process (i.e. the command name). On Linux based systems,
+	// can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can
+	// be set to the first parameter extracted from `GetCommandLineW`.
+	//
+	// Type: string
+	// RequirementLevel: ConditionallyRequired (See alternative attributes
+	// below.)
+	// Stability: stable
+	// Examples: 'cmd/otelcol'
+	ProcessCommandKey = attribute.Key("process.command")
+
+	// ProcessCommandLineKey is the attribute Key conforming to the
+	// "process.command_line" semantic conventions. It represents the full
+	// command used to launch the process as a single string representing the
+	// full command. On Windows, can be set to the result of `GetCommandLineW`.
+	// Do not set this if you have to assemble it just for monitoring; use
+	// `process.command_args` instead.
+	//
+	// Type: string
+	// RequirementLevel: ConditionallyRequired (See alternative attributes
+	// below.)
+	// Stability: stable
+	// Examples: 'C:\\cmd\\otecol --config="my directory\\config.yaml"'
+	ProcessCommandLineKey = attribute.Key("process.command_line")
+
+	// ProcessCommandArgsKey is the attribute Key conforming to the
+	// "process.command_args" semantic conventions. It represents the all the
+	// command arguments (including the command/executable itself) as received
+	// by the process. On Linux-based systems (and some other Unixoid systems
+	// supporting procfs), can be set according to the list of null-delimited
+	// strings extracted from `proc/[pid]/cmdline`. For libc-based executables,
+	// this would be the full argv vector passed to `main`.
+	//
+	// Type: string[]
+	// RequirementLevel: ConditionallyRequired (See alternative attributes
+	// below.)
+	// Stability: stable
+	// Examples: 'cmd/otecol', '--config=config.yaml'
+	ProcessCommandArgsKey = attribute.Key("process.command_args")
+
+	// ProcessOwnerKey is the attribute Key conforming to the "process.owner"
+	// semantic conventions. It represents the username of the user that owns
+	// the process.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'root'
+	ProcessOwnerKey = attribute.Key("process.owner")
+)
+
+// ProcessPID returns an attribute KeyValue conforming to the "process.pid"
+// semantic conventions. It represents the process identifier (PID).
+func ProcessPID(val int) attribute.KeyValue {
+	return ProcessPIDKey.Int(val)
+}
+
+// ProcessParentPID returns an attribute KeyValue conforming to the
+// "process.parent_pid" semantic conventions. It represents the parent Process
+// identifier (PID).
+func ProcessParentPID(val int) attribute.KeyValue {
+	return ProcessParentPIDKey.Int(val)
+}
+
+// ProcessExecutableName returns an attribute KeyValue conforming to the
+// "process.executable.name" semantic conventions. It represents the name of
+// the process executable. On Linux based systems, can be set to the `Name` in
+// `proc/[pid]/status`. On Windows, can be set to the base name of
+// `GetProcessImageFileNameW`.
+func ProcessExecutableName(val string) attribute.KeyValue {
+	return ProcessExecutableNameKey.String(val)
+}
+
+// ProcessExecutablePath returns an attribute KeyValue conforming to the
+// "process.executable.path" semantic conventions. It represents the full path
+// to the process executable. On Linux based systems, can be set to the target
+// of `proc/[pid]/exe`. On Windows, can be set to the result of
+// `GetProcessImageFileNameW`.
+func ProcessExecutablePath(val string) attribute.KeyValue {
+	return ProcessExecutablePathKey.String(val)
+}
+
+// ProcessCommand returns an attribute KeyValue conforming to the
+// "process.command" semantic conventions. It represents the command used to
+// launch the process (i.e. the command name). On Linux based systems, can be
+// set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to
+// the first parameter extracted from `GetCommandLineW`.
+func ProcessCommand(val string) attribute.KeyValue {
+	return ProcessCommandKey.String(val)
+}
+
+// ProcessCommandLine returns an attribute KeyValue conforming to the
+// "process.command_line" semantic conventions. It represents the full command
+// used to launch the process as a single string representing the full command.
+// On Windows, can be set to the result of `GetCommandLineW`. Do not set this
+// if you have to assemble it just for monitoring; use `process.command_args`
+// instead.
+func ProcessCommandLine(val string) attribute.KeyValue {
+	return ProcessCommandLineKey.String(val)
+}
+
+// ProcessCommandArgs returns an attribute KeyValue conforming to the
+// "process.command_args" semantic conventions. It represents the all the
+// command arguments (including the command/executable itself) as received by
+// the process. On Linux-based systems (and some other Unixoid systems
+// supporting procfs), can be set according to the list of null-delimited
+// strings extracted from `proc/[pid]/cmdline`. For libc-based executables,
+// this would be the full argv vector passed to `main`.
+func ProcessCommandArgs(val ...string) attribute.KeyValue {
+	return ProcessCommandArgsKey.StringSlice(val)
+}
+
+// ProcessOwner returns an attribute KeyValue conforming to the
+// "process.owner" semantic conventions. It represents the username of the user
+// that owns the process.
+func ProcessOwner(val string) attribute.KeyValue {
+	return ProcessOwnerKey.String(val)
+}
+
+// The single (language) runtime instance which is monitored.
+const (
+	// ProcessRuntimeNameKey is the attribute Key conforming to the
+	// "process.runtime.name" semantic conventions. It represents the name of
+	// the runtime of this process. For compiled native binaries, this SHOULD
+	// be the name of the compiler.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'OpenJDK Runtime Environment'
+	ProcessRuntimeNameKey = attribute.Key("process.runtime.name")
+
+	// ProcessRuntimeVersionKey is the attribute Key conforming to the
+	// "process.runtime.version" semantic conventions. It represents the
+	// version of the runtime of this process, as returned by the runtime
+	// without modification.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '14.0.2'
+	ProcessRuntimeVersionKey = attribute.Key("process.runtime.version")
+
+	// ProcessRuntimeDescriptionKey is the attribute Key conforming to the
+	// "process.runtime.description" semantic conventions. It represents an
+	// additional description about the runtime of the process, for example a
+	// specific vendor customization of the runtime environment.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0'
+	ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description")
+)
+
+// ProcessRuntimeName returns an attribute KeyValue conforming to the
+// "process.runtime.name" semantic conventions. It represents the name of the
+// runtime of this process. For compiled native binaries, this SHOULD be the
+// name of the compiler.
+func ProcessRuntimeName(val string) attribute.KeyValue {
+	return ProcessRuntimeNameKey.String(val)
+}
+
+// ProcessRuntimeVersion returns an attribute KeyValue conforming to the
+// "process.runtime.version" semantic conventions. It represents the version of
+// the runtime of this process, as returned by the runtime without
+// modification.
+func ProcessRuntimeVersion(val string) attribute.KeyValue {
+	return ProcessRuntimeVersionKey.String(val)
+}
+
+// ProcessRuntimeDescription returns an attribute KeyValue conforming to the
+// "process.runtime.description" semantic conventions. It represents an
+// additional description about the runtime of the process, for example a
+// specific vendor customization of the runtime environment.
+func ProcessRuntimeDescription(val string) attribute.KeyValue {
+	return ProcessRuntimeDescriptionKey.String(val)
+}
+
+// A service instance.
+const (
+	// ServiceNameKey is the attribute Key conforming to the "service.name"
+	// semantic conventions. It represents the logical name of the service.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'shoppingcart'
+	// Note: MUST be the same for all instances of horizontally scaled
+	// services. If the value was not specified, SDKs MUST fallback to
+	// `unknown_service:` concatenated with
+	// [`process.executable.name`](process.md#process), e.g.
+	// `unknown_service:bash`. If `process.executable.name` is not available,
+	// the value MUST be set to `unknown_service`.
+	ServiceNameKey = attribute.Key("service.name")
+
+	// ServiceNamespaceKey is the attribute Key conforming to the
+	// "service.namespace" semantic conventions. It represents a namespace for
+	// `service.name`.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'Shop'
+	// Note: A string value having a meaning that helps to distinguish a group
+	// of services, for example the team name that owns a group of services.
+	// `service.name` is expected to be unique within the same namespace. If
+	// `service.namespace` is not specified in the Resource then `service.name`
+	// is expected to be unique for all services that have no explicit
+	// namespace defined (so the empty/unspecified namespace is simply one more
+	// valid namespace). Zero-length namespace string is assumed equal to
+	// unspecified namespace.
+	ServiceNamespaceKey = attribute.Key("service.namespace")
+
+	// ServiceInstanceIDKey is the attribute Key conforming to the
+	// "service.instance.id" semantic conventions. It represents the string ID
+	// of the service instance.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '627cc493-f310-47de-96bd-71410b7dec09'
+	// Note: MUST be unique for each instance of the same
+	// `service.namespace,service.name` pair (in other words
+	// `service.namespace,service.name,service.instance.id` triplet MUST be
+	// globally unique). The ID helps to distinguish instances of the same
+	// service that exist at the same time (e.g. instances of a horizontally
+	// scaled service). It is preferable for the ID to be persistent and stay
+	// the same for the lifetime of the service instance, however it is
+	// acceptable that the ID is ephemeral and changes during important
+	// lifetime events for the service (e.g. service restarts). If the service
+	// has no inherent unique ID that can be used as the value of this
+	// attribute it is recommended to generate a random Version 1 or Version 4
+	// RFC 4122 UUID (services aiming for reproducible UUIDs may also use
+	// Version 5, see RFC 4122 for more recommendations).
+	ServiceInstanceIDKey = attribute.Key("service.instance.id")
+
+	// ServiceVersionKey is the attribute Key conforming to the
+	// "service.version" semantic conventions. It represents the version string
+	// of the service API or implementation.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '2.0.0'
+	ServiceVersionKey = attribute.Key("service.version")
+)
+
+// ServiceName returns an attribute KeyValue conforming to the
+// "service.name" semantic conventions. It represents the logical name of the
+// service.
+func ServiceName(val string) attribute.KeyValue {
+	return ServiceNameKey.String(val)
+}
+
+// ServiceNamespace returns an attribute KeyValue conforming to the
+// "service.namespace" semantic conventions. It represents a namespace for
+// `service.name`.
+func ServiceNamespace(val string) attribute.KeyValue {
+	return ServiceNamespaceKey.String(val)
+}
+
+// ServiceInstanceID returns an attribute KeyValue conforming to the
+// "service.instance.id" semantic conventions. It represents the string ID of
+// the service instance.
+func ServiceInstanceID(val string) attribute.KeyValue {
+	return ServiceInstanceIDKey.String(val)
+}
+
+// ServiceVersion returns an attribute KeyValue conforming to the
+// "service.version" semantic conventions. It represents the version string of
+// the service API or implementation.
+func ServiceVersion(val string) attribute.KeyValue {
+	return ServiceVersionKey.String(val)
+}
+
+// The telemetry SDK used to capture data recorded by the instrumentation
+// libraries.
+const (
+	// TelemetrySDKNameKey is the attribute Key conforming to the
+	// "telemetry.sdk.name" semantic conventions. It represents the name of the
+	// telemetry SDK as defined above.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'opentelemetry'
+	TelemetrySDKNameKey = attribute.Key("telemetry.sdk.name")
+
+	// TelemetrySDKLanguageKey is the attribute Key conforming to the
+	// "telemetry.sdk.language" semantic conventions. It represents the
+	// language of the telemetry SDK.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	TelemetrySDKLanguageKey = attribute.Key("telemetry.sdk.language")
+
+	// TelemetrySDKVersionKey is the attribute Key conforming to the
+	// "telemetry.sdk.version" semantic conventions. It represents the version
+	// string of the telemetry SDK.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '1.2.3'
+	TelemetrySDKVersionKey = attribute.Key("telemetry.sdk.version")
+
+	// TelemetryAutoVersionKey is the attribute Key conforming to the
+	// "telemetry.auto.version" semantic conventions. It represents the version
+	// string of the auto instrumentation agent, if used.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '1.2.3'
+	TelemetryAutoVersionKey = attribute.Key("telemetry.auto.version")
+)
+
+var (
+	// cpp
+	TelemetrySDKLanguageCPP = TelemetrySDKLanguageKey.String("cpp")
+	// dotnet
+	TelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String("dotnet")
+	// erlang
+	TelemetrySDKLanguageErlang = TelemetrySDKLanguageKey.String("erlang")
+	// go
+	TelemetrySDKLanguageGo = TelemetrySDKLanguageKey.String("go")
+	// java
+	TelemetrySDKLanguageJava = TelemetrySDKLanguageKey.String("java")
+	// nodejs
+	TelemetrySDKLanguageNodejs = TelemetrySDKLanguageKey.String("nodejs")
+	// php
+	TelemetrySDKLanguagePHP = TelemetrySDKLanguageKey.String("php")
+	// python
+	TelemetrySDKLanguagePython = TelemetrySDKLanguageKey.String("python")
+	// ruby
+	TelemetrySDKLanguageRuby = TelemetrySDKLanguageKey.String("ruby")
+	// webjs
+	TelemetrySDKLanguageWebjs = TelemetrySDKLanguageKey.String("webjs")
+	// swift
+	TelemetrySDKLanguageSwift = TelemetrySDKLanguageKey.String("swift")
+)
+
+// TelemetrySDKName returns an attribute KeyValue conforming to the
+// "telemetry.sdk.name" semantic conventions. It represents the name of the
+// telemetry SDK as defined above.
+func TelemetrySDKName(val string) attribute.KeyValue {
+	return TelemetrySDKNameKey.String(val)
+}
+
+// TelemetrySDKVersion returns an attribute KeyValue conforming to the
+// "telemetry.sdk.version" semantic conventions. It represents the version
+// string of the telemetry SDK.
+func TelemetrySDKVersion(val string) attribute.KeyValue {
+	return TelemetrySDKVersionKey.String(val)
+}
+
+// TelemetryAutoVersion returns an attribute KeyValue conforming to the
+// "telemetry.auto.version" semantic conventions. It represents the version
+// string of the auto instrumentation agent, if used.
+func TelemetryAutoVersion(val string) attribute.KeyValue {
+	return TelemetryAutoVersionKey.String(val)
+}
+
+// Resource describing the packaged software running the application code. Web
+// engines are typically executed using process.runtime.
+const (
+	// WebEngineNameKey is the attribute Key conforming to the "webengine.name"
+	// semantic conventions. It represents the name of the web engine.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'WildFly'
+	WebEngineNameKey = attribute.Key("webengine.name")
+
+	// WebEngineVersionKey is the attribute Key conforming to the
+	// "webengine.version" semantic conventions. It represents the version of
+	// the web engine.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '21.0.0'
+	WebEngineVersionKey = attribute.Key("webengine.version")
+
+	// WebEngineDescriptionKey is the attribute Key conforming to the
+	// "webengine.description" semantic conventions. It represents the
+	// additional description of the web engine (e.g. detailed version and
+	// edition information).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) -
+	// 2.2.2.Final'
+	WebEngineDescriptionKey = attribute.Key("webengine.description")
+)
+
+// WebEngineName returns an attribute KeyValue conforming to the
+// "webengine.name" semantic conventions. It represents the name of the web
+// engine.
+func WebEngineName(val string) attribute.KeyValue {
+	return WebEngineNameKey.String(val)
+}
+
+// WebEngineVersion returns an attribute KeyValue conforming to the
+// "webengine.version" semantic conventions. It represents the version of the
+// web engine.
+func WebEngineVersion(val string) attribute.KeyValue {
+	return WebEngineVersionKey.String(val)
+}
+
+// WebEngineDescription returns an attribute KeyValue conforming to the
+// "webengine.description" semantic conventions. It represents the additional
+// description of the web engine (e.g. detailed version and edition
+// information).
+func WebEngineDescription(val string) attribute.KeyValue {
+	return WebEngineDescriptionKey.String(val)
+}
+
+// Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's
+// concepts.
+const (
+	// OtelScopeNameKey is the attribute Key conforming to the
+	// "otel.scope.name" semantic conventions. It represents the name of the
+	// instrumentation scope - (`InstrumentationScope.Name` in OTLP).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'io.opentelemetry.contrib.mongodb'
+	OtelScopeNameKey = attribute.Key("otel.scope.name")
+
+	// OtelScopeVersionKey is the attribute Key conforming to the
+	// "otel.scope.version" semantic conventions. It represents the version of
+	// the instrumentation scope - (`InstrumentationScope.Version` in OTLP).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '1.0.0'
+	OtelScopeVersionKey = attribute.Key("otel.scope.version")
+)
+
+// OtelScopeName returns an attribute KeyValue conforming to the
+// "otel.scope.name" semantic conventions. It represents the name of the
+// instrumentation scope - (`InstrumentationScope.Name` in OTLP).
+func OtelScopeName(val string) attribute.KeyValue {
+	return OtelScopeNameKey.String(val)
+}
+
+// OtelScopeVersion returns an attribute KeyValue conforming to the
+// "otel.scope.version" semantic conventions. It represents the version of the
+// instrumentation scope - (`InstrumentationScope.Version` in OTLP).
+func OtelScopeVersion(val string) attribute.KeyValue {
+	return OtelScopeVersionKey.String(val)
+}
+
+// Span attributes used by non-OTLP exporters to represent OpenTelemetry
+// Scope's concepts.
+const (
+	// OtelLibraryNameKey is the attribute Key conforming to the
+	// "otel.library.name" semantic conventions. It represents the deprecated,
+	// use the `otel.scope.name` attribute.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: deprecated
+	// Examples: 'io.opentelemetry.contrib.mongodb'
+	OtelLibraryNameKey = attribute.Key("otel.library.name")
+
+	// OtelLibraryVersionKey is the attribute Key conforming to the
+	// "otel.library.version" semantic conventions. It represents the
+	// deprecated, use the `otel.scope.version` attribute.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: deprecated
+	// Examples: '1.0.0'
+	OtelLibraryVersionKey = attribute.Key("otel.library.version")
+)
+
+// OtelLibraryName returns an attribute KeyValue conforming to the
+// "otel.library.name" semantic conventions. It represents the deprecated, use
+// the `otel.scope.name` attribute.
+func OtelLibraryName(val string) attribute.KeyValue {
+	return OtelLibraryNameKey.String(val)
+}
+
+// OtelLibraryVersion returns an attribute KeyValue conforming to the
+// "otel.library.version" semantic conventions. It represents the deprecated,
+// use the `otel.scope.version` attribute.
+func OtelLibraryVersion(val string) attribute.KeyValue {
+	return OtelLibraryVersionKey.String(val)
+}
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/schema.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/schema.go
new file mode 100644
index 00000000..634a1dce
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/schema.go
@@ -0,0 +1,9 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0"
+
+// SchemaURL is the schema URL that matches the version of the semantic conventions
+// that this package defines. Semconv packages starting from v1.4.0 must declare
+// non-empty schema URL in the form https://opentelemetry.io/schemas/<version>
+const SchemaURL = "https://opentelemetry.io/schemas/1.17.0"
diff --git a/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/trace.go b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/trace.go
new file mode 100644
index 00000000..21497bb6
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/semconv/v1.17.0/trace.go
@@ -0,0 +1,3364 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Code generated from semantic convention specification. DO NOT EDIT.
+
+package semconv // import "go.opentelemetry.io/otel/semconv/v1.17.0"
+
+import "go.opentelemetry.io/otel/attribute"
+
+// The shared attributes used to report a single exception associated with a
+// span or log.
+const (
+	// ExceptionTypeKey is the attribute Key conforming to the "exception.type"
+	// semantic conventions. It represents the type of the exception (its
+	// fully-qualified class name, if applicable). The dynamic type of the
+	// exception should be preferred over the static type in languages that
+	// support it.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'java.net.ConnectException', 'OSError'
+	ExceptionTypeKey = attribute.Key("exception.type")
+
+	// ExceptionMessageKey is the attribute Key conforming to the
+	// "exception.message" semantic conventions. It represents the exception
+	// message.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'Division by zero', "Can't convert 'int' object to str
+	// implicitly"
+	ExceptionMessageKey = attribute.Key("exception.message")
+
+	// ExceptionStacktraceKey is the attribute Key conforming to the
+	// "exception.stacktrace" semantic conventions. It represents a stacktrace
+	// as a string in the natural representation for the language runtime. The
+	// representation is to be determined and documented by each language SIG.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'Exception in thread "main" java.lang.RuntimeException: Test
+	// exception\\n at '
+	//  'com.example.GenerateTrace.methodB(GenerateTrace.java:13)\\n at '
+	//  'com.example.GenerateTrace.methodA(GenerateTrace.java:9)\\n at '
+	//  'com.example.GenerateTrace.main(GenerateTrace.java:5)'
+	ExceptionStacktraceKey = attribute.Key("exception.stacktrace")
+)
+
+// ExceptionType returns an attribute KeyValue conforming to the
+// "exception.type" semantic conventions. It represents the type of the
+// exception (its fully-qualified class name, if applicable). The dynamic type
+// of the exception should be preferred over the static type in languages that
+// support it.
+func ExceptionType(val string) attribute.KeyValue {
+	return ExceptionTypeKey.String(val)
+}
+
+// ExceptionMessage returns an attribute KeyValue conforming to the
+// "exception.message" semantic conventions. It represents the exception
+// message.
+func ExceptionMessage(val string) attribute.KeyValue {
+	return ExceptionMessageKey.String(val)
+}
+
+// ExceptionStacktrace returns an attribute KeyValue conforming to the
+// "exception.stacktrace" semantic conventions. It represents a stacktrace as a
+// string in the natural representation for the language runtime. The
+// representation is to be determined and documented by each language SIG.
+func ExceptionStacktrace(val string) attribute.KeyValue {
+	return ExceptionStacktraceKey.String(val)
+}
+
+// Attributes for Events represented using Log Records.
+const (
+	// EventNameKey is the attribute Key conforming to the "event.name"
+	// semantic conventions. It represents the name identifies the event.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'click', 'exception'
+	EventNameKey = attribute.Key("event.name")
+
+	// EventDomainKey is the attribute Key conforming to the "event.domain"
+	// semantic conventions. It represents the domain identifies the business
+	// context for the events.
+	//
+	// Type: Enum
+	// RequirementLevel: Required
+	// Stability: stable
+	// Note: Events across different domains may have same `event.name`, yet be
+	// unrelated events.
+	EventDomainKey = attribute.Key("event.domain")
+)
+
+var (
+	// Events from browser apps
+	EventDomainBrowser = EventDomainKey.String("browser")
+	// Events from mobile apps
+	EventDomainDevice = EventDomainKey.String("device")
+	// Events from Kubernetes
+	EventDomainK8S = EventDomainKey.String("k8s")
+)
+
+// EventName returns an attribute KeyValue conforming to the "event.name"
+// semantic conventions. It represents the name identifies the event.
+func EventName(val string) attribute.KeyValue {
+	return EventNameKey.String(val)
+}
+
+// Span attributes used by AWS Lambda (in addition to general `faas`
+// attributes).
+const (
+	// AWSLambdaInvokedARNKey is the attribute Key conforming to the
+	// "aws.lambda.invoked_arn" semantic conventions. It represents the full
+	// invoked ARN as provided on the `Context` passed to the function
+	// (`Lambda-Runtime-Invoked-Function-ARN` header on the
+	// `/runtime/invocation/next` applicable).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'arn:aws:lambda:us-east-1:123456:function:myfunction:myalias'
+	// Note: This may be different from `faas.id` if an alias is involved.
+	AWSLambdaInvokedARNKey = attribute.Key("aws.lambda.invoked_arn")
+)
+
+// AWSLambdaInvokedARN returns an attribute KeyValue conforming to the
+// "aws.lambda.invoked_arn" semantic conventions. It represents the full
+// invoked ARN as provided on the `Context` passed to the function
+// (`Lambda-Runtime-Invoked-Function-ARN` header on the
+// `/runtime/invocation/next` applicable).
+func AWSLambdaInvokedARN(val string) attribute.KeyValue {
+	return AWSLambdaInvokedARNKey.String(val)
+}
+
+// Attributes for CloudEvents. CloudEvents is a specification on how to define
+// event data in a standard way. These attributes can be attached to spans when
+// performing operations with CloudEvents, regardless of the protocol being
+// used.
+const (
+	// CloudeventsEventIDKey is the attribute Key conforming to the
+	// "cloudevents.event_id" semantic conventions. It represents the
+	// [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id)
+	// uniquely identifies the event.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: '123e4567-e89b-12d3-a456-426614174000', '0001'
+	CloudeventsEventIDKey = attribute.Key("cloudevents.event_id")
+
+	// CloudeventsEventSourceKey is the attribute Key conforming to the
+	// "cloudevents.event_source" semantic conventions. It represents the
+	// [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1)
+	// identifies the context in which an event happened.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'https://github.com/cloudevents',
+	// '/cloudevents/spec/pull/123', 'my-service'
+	CloudeventsEventSourceKey = attribute.Key("cloudevents.event_source")
+
+	// CloudeventsEventSpecVersionKey is the attribute Key conforming to the
+	// "cloudevents.event_spec_version" semantic conventions. It represents the
+	// [version of the CloudEvents
+	// specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion)
+	// which the event uses.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '1.0'
+	CloudeventsEventSpecVersionKey = attribute.Key("cloudevents.event_spec_version")
+
+	// CloudeventsEventTypeKey is the attribute Key conforming to the
+	// "cloudevents.event_type" semantic conventions. It represents the
+	// [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type)
+	// contains a value describing the type of event related to the originating
+	// occurrence.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'com.github.pull_request.opened',
+	// 'com.example.object.deleted.v2'
+	CloudeventsEventTypeKey = attribute.Key("cloudevents.event_type")
+
+	// CloudeventsEventSubjectKey is the attribute Key conforming to the
+	// "cloudevents.event_subject" semantic conventions. It represents the
+	// [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject)
+	// of the event in the context of the event producer (identified by
+	// source).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'mynewfile.jpg'
+	CloudeventsEventSubjectKey = attribute.Key("cloudevents.event_subject")
+)
+
+// CloudeventsEventID returns an attribute KeyValue conforming to the
+// "cloudevents.event_id" semantic conventions. It represents the
+// [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id)
+// uniquely identifies the event.
+func CloudeventsEventID(val string) attribute.KeyValue {
+	return CloudeventsEventIDKey.String(val)
+}
+
+// CloudeventsEventSource returns an attribute KeyValue conforming to the
+// "cloudevents.event_source" semantic conventions. It represents the
+// [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1)
+// identifies the context in which an event happened.
+func CloudeventsEventSource(val string) attribute.KeyValue {
+	return CloudeventsEventSourceKey.String(val)
+}
+
+// CloudeventsEventSpecVersion returns an attribute KeyValue conforming to
+// the "cloudevents.event_spec_version" semantic conventions. It represents the
+// [version of the CloudEvents
+// specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion)
+// which the event uses.
+func CloudeventsEventSpecVersion(val string) attribute.KeyValue {
+	return CloudeventsEventSpecVersionKey.String(val)
+}
+
+// CloudeventsEventType returns an attribute KeyValue conforming to the
+// "cloudevents.event_type" semantic conventions. It represents the
+// [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type)
+// contains a value describing the type of event related to the originating
+// occurrence.
+func CloudeventsEventType(val string) attribute.KeyValue {
+	return CloudeventsEventTypeKey.String(val)
+}
+
+// CloudeventsEventSubject returns an attribute KeyValue conforming to the
+// "cloudevents.event_subject" semantic conventions. It represents the
+// [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject)
+// of the event in the context of the event producer (identified by source).
+func CloudeventsEventSubject(val string) attribute.KeyValue {
+	return CloudeventsEventSubjectKey.String(val)
+}
+
+// Semantic conventions for the OpenTracing Shim
+const (
+	// OpentracingRefTypeKey is the attribute Key conforming to the
+	// "opentracing.ref_type" semantic conventions. It represents the
+	// parent-child Reference type
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Note: The causal relationship between a child Span and a parent Span.
+	OpentracingRefTypeKey = attribute.Key("opentracing.ref_type")
+)
+
+var (
+	// The parent Span depends on the child Span in some capacity
+	OpentracingRefTypeChildOf = OpentracingRefTypeKey.String("child_of")
+	// The parent Span does not depend in any way on the result of the child Span
+	OpentracingRefTypeFollowsFrom = OpentracingRefTypeKey.String("follows_from")
+)
+
+// The attributes used to perform database client calls.
+const (
+	// DBSystemKey is the attribute Key conforming to the "db.system" semantic
+	// conventions. It represents an identifier for the database management
+	// system (DBMS) product being used. See below for a list of well-known
+	// identifiers.
+	//
+	// Type: Enum
+	// RequirementLevel: Required
+	// Stability: stable
+	DBSystemKey = attribute.Key("db.system")
+
+	// DBConnectionStringKey is the attribute Key conforming to the
+	// "db.connection_string" semantic conventions. It represents the
+	// connection string used to connect to the database. It is recommended to
+	// remove embedded credentials.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'Server=(localdb)\\v11.0;Integrated Security=true;'
+	DBConnectionStringKey = attribute.Key("db.connection_string")
+
+	// DBUserKey is the attribute Key conforming to the "db.user" semantic
+	// conventions. It represents the username for accessing the database.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'readonly_user', 'reporting_user'
+	DBUserKey = attribute.Key("db.user")
+
+	// DBJDBCDriverClassnameKey is the attribute Key conforming to the
+	// "db.jdbc.driver_classname" semantic conventions. It represents the
+	// fully-qualified class name of the [Java Database Connectivity
+	// (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/)
+	// driver used to connect.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'org.postgresql.Driver',
+	// 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
+	DBJDBCDriverClassnameKey = attribute.Key("db.jdbc.driver_classname")
+
+	// DBNameKey is the attribute Key conforming to the "db.name" semantic
+	// conventions. It represents the this attribute is used to report the name
+	// of the database being accessed. For commands that switch the database,
+	// this should be set to the target database (even if the command fails).
+	//
+	// Type: string
+	// RequirementLevel: ConditionallyRequired (If applicable.)
+	// Stability: stable
+	// Examples: 'customers', 'main'
+	// Note: In some SQL databases, the database name to be used is called
+	// "schema name". In case there are multiple layers that could be
+	// considered for database name (e.g. Oracle instance name and schema
+	// name), the database name to be used is the more specific layer (e.g.
+	// Oracle schema name).
+	DBNameKey = attribute.Key("db.name")
+
+	// DBStatementKey is the attribute Key conforming to the "db.statement"
+	// semantic conventions. It represents the database statement being
+	// executed.
+	//
+	// Type: string
+	// RequirementLevel: ConditionallyRequired (If applicable and not
+	// explicitly disabled via instrumentation configuration.)
+	// Stability: stable
+	// Examples: 'SELECT * FROM wuser_table', 'SET mykey "WuValue"'
+	// Note: The value may be sanitized to exclude sensitive information.
+	DBStatementKey = attribute.Key("db.statement")
+
+	// DBOperationKey is the attribute Key conforming to the "db.operation"
+	// semantic conventions. It represents the name of the operation being
+	// executed, e.g. the [MongoDB command
+	// name](https://docs.mongodb.com/manual/reference/command/#database-operations)
+	// such as `findAndModify`, or the SQL keyword.
+	//
+	// Type: string
+	// RequirementLevel: ConditionallyRequired (If `db.statement` is not
+	// applicable.)
+	// Stability: stable
+	// Examples: 'findAndModify', 'HMSET', 'SELECT'
+	// Note: When setting this to an SQL keyword, it is not recommended to
+	// attempt any client-side parsing of `db.statement` just to get this
+	// property, but it should be set if the operation name is provided by the
+	// library being instrumented. If the SQL statement has an ambiguous
+	// operation, or performs more than one operation, this value may be
+	// omitted.
+	DBOperationKey = attribute.Key("db.operation")
+)
+
+var (
+	// Some other SQL database. Fallback only. See notes
+	DBSystemOtherSQL = DBSystemKey.String("other_sql")
+	// Microsoft SQL Server
+	DBSystemMSSQL = DBSystemKey.String("mssql")
+	// MySQL
+	DBSystemMySQL = DBSystemKey.String("mysql")
+	// Oracle Database
+	DBSystemOracle = DBSystemKey.String("oracle")
+	// IBM DB2
+	DBSystemDB2 = DBSystemKey.String("db2")
+	// PostgreSQL
+	DBSystemPostgreSQL = DBSystemKey.String("postgresql")
+	// Amazon Redshift
+	DBSystemRedshift = DBSystemKey.String("redshift")
+	// Apache Hive
+	DBSystemHive = DBSystemKey.String("hive")
+	// Cloudscape
+	DBSystemCloudscape = DBSystemKey.String("cloudscape")
+	// HyperSQL DataBase
+	DBSystemHSQLDB = DBSystemKey.String("hsqldb")
+	// Progress Database
+	DBSystemProgress = DBSystemKey.String("progress")
+	// SAP MaxDB
+	DBSystemMaxDB = DBSystemKey.String("maxdb")
+	// SAP HANA
+	DBSystemHanaDB = DBSystemKey.String("hanadb")
+	// Ingres
+	DBSystemIngres = DBSystemKey.String("ingres")
+	// FirstSQL
+	DBSystemFirstSQL = DBSystemKey.String("firstsql")
+	// EnterpriseDB
+	DBSystemEDB = DBSystemKey.String("edb")
+	// InterSystems Caché
+	DBSystemCache = DBSystemKey.String("cache")
+	// Adabas (Adaptable Database System)
+	DBSystemAdabas = DBSystemKey.String("adabas")
+	// Firebird
+	DBSystemFirebird = DBSystemKey.String("firebird")
+	// Apache Derby
+	DBSystemDerby = DBSystemKey.String("derby")
+	// FileMaker
+	DBSystemFilemaker = DBSystemKey.String("filemaker")
+	// Informix
+	DBSystemInformix = DBSystemKey.String("informix")
+	// InstantDB
+	DBSystemInstantDB = DBSystemKey.String("instantdb")
+	// InterBase
+	DBSystemInterbase = DBSystemKey.String("interbase")
+	// MariaDB
+	DBSystemMariaDB = DBSystemKey.String("mariadb")
+	// Netezza
+	DBSystemNetezza = DBSystemKey.String("netezza")
+	// Pervasive PSQL
+	DBSystemPervasive = DBSystemKey.String("pervasive")
+	// PointBase
+	DBSystemPointbase = DBSystemKey.String("pointbase")
+	// SQLite
+	DBSystemSqlite = DBSystemKey.String("sqlite")
+	// Sybase
+	DBSystemSybase = DBSystemKey.String("sybase")
+	// Teradata
+	DBSystemTeradata = DBSystemKey.String("teradata")
+	// Vertica
+	DBSystemVertica = DBSystemKey.String("vertica")
+	// H2
+	DBSystemH2 = DBSystemKey.String("h2")
+	// ColdFusion IMQ
+	DBSystemColdfusion = DBSystemKey.String("coldfusion")
+	// Apache Cassandra
+	DBSystemCassandra = DBSystemKey.String("cassandra")
+	// Apache HBase
+	DBSystemHBase = DBSystemKey.String("hbase")
+	// MongoDB
+	DBSystemMongoDB = DBSystemKey.String("mongodb")
+	// Redis
+	DBSystemRedis = DBSystemKey.String("redis")
+	// Couchbase
+	DBSystemCouchbase = DBSystemKey.String("couchbase")
+	// CouchDB
+	DBSystemCouchDB = DBSystemKey.String("couchdb")
+	// Microsoft Azure Cosmos DB
+	DBSystemCosmosDB = DBSystemKey.String("cosmosdb")
+	// Amazon DynamoDB
+	DBSystemDynamoDB = DBSystemKey.String("dynamodb")
+	// Neo4j
+	DBSystemNeo4j = DBSystemKey.String("neo4j")
+	// Apache Geode
+	DBSystemGeode = DBSystemKey.String("geode")
+	// Elasticsearch
+	DBSystemElasticsearch = DBSystemKey.String("elasticsearch")
+	// Memcached
+	DBSystemMemcached = DBSystemKey.String("memcached")
+	// CockroachDB
+	DBSystemCockroachdb = DBSystemKey.String("cockroachdb")
+	// OpenSearch
+	DBSystemOpensearch = DBSystemKey.String("opensearch")
+	// ClickHouse
+	DBSystemClickhouse = DBSystemKey.String("clickhouse")
+)
+
+// DBConnectionString returns an attribute KeyValue conforming to the
+// "db.connection_string" semantic conventions. It represents the connection
+// string used to connect to the database. It is recommended to remove embedded
+// credentials.
+func DBConnectionString(val string) attribute.KeyValue {
+	return DBConnectionStringKey.String(val)
+}
+
+// DBUser returns an attribute KeyValue conforming to the "db.user" semantic
+// conventions. It represents the username for accessing the database.
+func DBUser(val string) attribute.KeyValue {
+	return DBUserKey.String(val)
+}
+
+// DBJDBCDriverClassname returns an attribute KeyValue conforming to the
+// "db.jdbc.driver_classname" semantic conventions. It represents the
+// fully-qualified class name of the [Java Database Connectivity
+// (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver
+// used to connect.
+func DBJDBCDriverClassname(val string) attribute.KeyValue {
+	return DBJDBCDriverClassnameKey.String(val)
+}
+
+// DBName returns an attribute KeyValue conforming to the "db.name" semantic
+// conventions. It represents the this attribute is used to report the name of
+// the database being accessed. For commands that switch the database, this
+// should be set to the target database (even if the command fails).
+func DBName(val string) attribute.KeyValue {
+	return DBNameKey.String(val)
+}
+
+// DBStatement returns an attribute KeyValue conforming to the
+// "db.statement" semantic conventions. It represents the database statement
+// being executed.
+func DBStatement(val string) attribute.KeyValue {
+	return DBStatementKey.String(val)
+}
+
+// DBOperation returns an attribute KeyValue conforming to the
+// "db.operation" semantic conventions. It represents the name of the operation
+// being executed, e.g. the [MongoDB command
+// name](https://docs.mongodb.com/manual/reference/command/#database-operations)
+// such as `findAndModify`, or the SQL keyword.
+func DBOperation(val string) attribute.KeyValue {
+	return DBOperationKey.String(val)
+}
+
+// Connection-level attributes for Microsoft SQL Server
+const (
+	// DBMSSQLInstanceNameKey is the attribute Key conforming to the
+	// "db.mssql.instance_name" semantic conventions. It represents the
+	// Microsoft SQL Server [instance
+	// name](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15)
+	// connecting to. This name is used to determine the port of a named
+	// instance.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'MSSQLSERVER'
+	// Note: If setting a `db.mssql.instance_name`, `net.peer.port` is no
+	// longer required (but still recommended if non-standard).
+	DBMSSQLInstanceNameKey = attribute.Key("db.mssql.instance_name")
+)
+
+// DBMSSQLInstanceName returns an attribute KeyValue conforming to the
+// "db.mssql.instance_name" semantic conventions. It represents the Microsoft
+// SQL Server [instance
+// name](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15)
+// connecting to. This name is used to determine the port of a named instance.
+func DBMSSQLInstanceName(val string) attribute.KeyValue {
+	return DBMSSQLInstanceNameKey.String(val)
+}
+
+// Call-level attributes for Cassandra
+const (
+	// DBCassandraPageSizeKey is the attribute Key conforming to the
+	// "db.cassandra.page_size" semantic conventions. It represents the fetch
+	// size used for paging, i.e. how many rows will be returned at once.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 5000
+	DBCassandraPageSizeKey = attribute.Key("db.cassandra.page_size")
+
+	// DBCassandraConsistencyLevelKey is the attribute Key conforming to the
+	// "db.cassandra.consistency_level" semantic conventions. It represents the
+	// consistency level of the query. Based on consistency values from
+	// [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html).
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	DBCassandraConsistencyLevelKey = attribute.Key("db.cassandra.consistency_level")
+
+	// DBCassandraTableKey is the attribute Key conforming to the
+	// "db.cassandra.table" semantic conventions. It represents the name of the
+	// primary table that the operation is acting upon, including the keyspace
+	// name (if applicable).
+	//
+	// Type: string
+	// RequirementLevel: Recommended
+	// Stability: stable
+	// Examples: 'mytable'
+	// Note: This mirrors the db.sql.table attribute but references cassandra
+	// rather than sql. It is not recommended to attempt any client-side
+	// parsing of `db.statement` just to get this property, but it should be
+	// set if it is provided by the library being instrumented. If the
+	// operation is acting upon an anonymous table, or more than one table,
+	// this value MUST NOT be set.
+	DBCassandraTableKey = attribute.Key("db.cassandra.table")
+
+	// DBCassandraIdempotenceKey is the attribute Key conforming to the
+	// "db.cassandra.idempotence" semantic conventions. It represents the
+	// whether or not the query is idempotent.
+	//
+	// Type: boolean
+	// RequirementLevel: Optional
+	// Stability: stable
+	DBCassandraIdempotenceKey = attribute.Key("db.cassandra.idempotence")
+
+	// DBCassandraSpeculativeExecutionCountKey is the attribute Key conforming
+	// to the "db.cassandra.speculative_execution_count" semantic conventions.
+	// It represents the number of times a query was speculatively executed.
+	// Not set or `0` if the query was not executed speculatively.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 0, 2
+	DBCassandraSpeculativeExecutionCountKey = attribute.Key("db.cassandra.speculative_execution_count")
+
+	// DBCassandraCoordinatorIDKey is the attribute Key conforming to the
+	// "db.cassandra.coordinator.id" semantic conventions. It represents the ID
+	// of the coordinating node for a query.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af'
+	DBCassandraCoordinatorIDKey = attribute.Key("db.cassandra.coordinator.id")
+
+	// DBCassandraCoordinatorDCKey is the attribute Key conforming to the
+	// "db.cassandra.coordinator.dc" semantic conventions. It represents the
+	// data center of the coordinating node for a query.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'us-west-2'
+	DBCassandraCoordinatorDCKey = attribute.Key("db.cassandra.coordinator.dc")
+)
+
+var (
+	// all
+	DBCassandraConsistencyLevelAll = DBCassandraConsistencyLevelKey.String("all")
+	// each_quorum
+	DBCassandraConsistencyLevelEachQuorum = DBCassandraConsistencyLevelKey.String("each_quorum")
+	// quorum
+	DBCassandraConsistencyLevelQuorum = DBCassandraConsistencyLevelKey.String("quorum")
+	// local_quorum
+	DBCassandraConsistencyLevelLocalQuorum = DBCassandraConsistencyLevelKey.String("local_quorum")
+	// one
+	DBCassandraConsistencyLevelOne = DBCassandraConsistencyLevelKey.String("one")
+	// two
+	DBCassandraConsistencyLevelTwo = DBCassandraConsistencyLevelKey.String("two")
+	// three
+	DBCassandraConsistencyLevelThree = DBCassandraConsistencyLevelKey.String("three")
+	// local_one
+	DBCassandraConsistencyLevelLocalOne = DBCassandraConsistencyLevelKey.String("local_one")
+	// any
+	DBCassandraConsistencyLevelAny = DBCassandraConsistencyLevelKey.String("any")
+	// serial
+	DBCassandraConsistencyLevelSerial = DBCassandraConsistencyLevelKey.String("serial")
+	// local_serial
+	DBCassandraConsistencyLevelLocalSerial = DBCassandraConsistencyLevelKey.String("local_serial")
+)
+
+// DBCassandraPageSize returns an attribute KeyValue conforming to the
+// "db.cassandra.page_size" semantic conventions. It represents the fetch size
+// used for paging, i.e. how many rows will be returned at once.
+func DBCassandraPageSize(val int) attribute.KeyValue {
+	return DBCassandraPageSizeKey.Int(val)
+}
+
+// DBCassandraTable returns an attribute KeyValue conforming to the
+// "db.cassandra.table" semantic conventions. It represents the name of the
+// primary table that the operation is acting upon, including the keyspace name
+// (if applicable).
+func DBCassandraTable(val string) attribute.KeyValue {
+	return DBCassandraTableKey.String(val)
+}
+
+// DBCassandraIdempotence returns an attribute KeyValue conforming to the
+// "db.cassandra.idempotence" semantic conventions. It represents the whether
+// or not the query is idempotent.
+func DBCassandraIdempotence(val bool) attribute.KeyValue {
+	return DBCassandraIdempotenceKey.Bool(val)
+}
+
+// DBCassandraSpeculativeExecutionCount returns an attribute KeyValue
+// conforming to the "db.cassandra.speculative_execution_count" semantic
+// conventions. It represents the number of times a query was speculatively
+// executed. Not set or `0` if the query was not executed speculatively.
+func DBCassandraSpeculativeExecutionCount(val int) attribute.KeyValue {
+	return DBCassandraSpeculativeExecutionCountKey.Int(val)
+}
+
+// DBCassandraCoordinatorID returns an attribute KeyValue conforming to the
+// "db.cassandra.coordinator.id" semantic conventions. It represents the ID of
+// the coordinating node for a query.
+func DBCassandraCoordinatorID(val string) attribute.KeyValue {
+	return DBCassandraCoordinatorIDKey.String(val)
+}
+
+// DBCassandraCoordinatorDC returns an attribute KeyValue conforming to the
+// "db.cassandra.coordinator.dc" semantic conventions. It represents the data
+// center of the coordinating node for a query.
+func DBCassandraCoordinatorDC(val string) attribute.KeyValue {
+	return DBCassandraCoordinatorDCKey.String(val)
+}
+
+// Call-level attributes for Redis
+const (
+	// DBRedisDBIndexKey is the attribute Key conforming to the
+	// "db.redis.database_index" semantic conventions. It represents the index
+	// of the database being accessed as used in the [`SELECT`
+	// command](https://redis.io/commands/select), provided as an integer. To
+	// be used instead of the generic `db.name` attribute.
+	//
+	// Type: int
+	// RequirementLevel: ConditionallyRequired (If other than the default
+	// database (`0`).)
+	// Stability: stable
+	// Examples: 0, 1, 15
+	DBRedisDBIndexKey = attribute.Key("db.redis.database_index")
+)
+
+// DBRedisDBIndex returns an attribute KeyValue conforming to the
+// "db.redis.database_index" semantic conventions. It represents the index of
+// the database being accessed as used in the [`SELECT`
+// command](https://redis.io/commands/select), provided as an integer. To be
+// used instead of the generic `db.name` attribute.
+func DBRedisDBIndex(val int) attribute.KeyValue {
+	return DBRedisDBIndexKey.Int(val)
+}
+
+// Call-level attributes for MongoDB
+const (
+	// DBMongoDBCollectionKey is the attribute Key conforming to the
+	// "db.mongodb.collection" semantic conventions. It represents the
+	// collection being accessed within the database stated in `db.name`.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'customers', 'products'
+	DBMongoDBCollectionKey = attribute.Key("db.mongodb.collection")
+)
+
+// DBMongoDBCollection returns an attribute KeyValue conforming to the
+// "db.mongodb.collection" semantic conventions. It represents the collection
+// being accessed within the database stated in `db.name`.
+func DBMongoDBCollection(val string) attribute.KeyValue {
+	return DBMongoDBCollectionKey.String(val)
+}
+
+// Call-level attributes for SQL databases
+const (
+	// DBSQLTableKey is the attribute Key conforming to the "db.sql.table"
+	// semantic conventions. It represents the name of the primary table that
+	// the operation is acting upon, including the database name (if
+	// applicable).
+	//
+	// Type: string
+	// RequirementLevel: Recommended
+	// Stability: stable
+	// Examples: 'public.users', 'customers'
+	// Note: It is not recommended to attempt any client-side parsing of
+	// `db.statement` just to get this property, but it should be set if it is
+	// provided by the library being instrumented. If the operation is acting
+	// upon an anonymous table, or more than one table, this value MUST NOT be
+	// set.
+	DBSQLTableKey = attribute.Key("db.sql.table")
+)
+
+// DBSQLTable returns an attribute KeyValue conforming to the "db.sql.table"
+// semantic conventions. It represents the name of the primary table that the
+// operation is acting upon, including the database name (if applicable).
+func DBSQLTable(val string) attribute.KeyValue {
+	return DBSQLTableKey.String(val)
+}
+
+// Span attributes used by non-OTLP exporters to represent OpenTelemetry Span's
+// concepts.
+const (
+	// OtelStatusCodeKey is the attribute Key conforming to the
+	// "otel.status_code" semantic conventions. It represents the name of the
+	// code, either "OK" or "ERROR". MUST NOT be set if the status code is
+	// UNSET.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	OtelStatusCodeKey = attribute.Key("otel.status_code")
+
+	// OtelStatusDescriptionKey is the attribute Key conforming to the
+	// "otel.status_description" semantic conventions. It represents the
+	// description of the Status if it has a value, otherwise not set.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'resource not found'
+	OtelStatusDescriptionKey = attribute.Key("otel.status_description")
+)
+
+var (
+	// The operation has been validated by an Application developer or Operator to have completed successfully
+	OtelStatusCodeOk = OtelStatusCodeKey.String("OK")
+	// The operation contains an error
+	OtelStatusCodeError = OtelStatusCodeKey.String("ERROR")
+)
+
+// OtelStatusDescription returns an attribute KeyValue conforming to the
+// "otel.status_description" semantic conventions. It represents the
+// description of the Status if it has a value, otherwise not set.
+func OtelStatusDescription(val string) attribute.KeyValue {
+	return OtelStatusDescriptionKey.String(val)
+}
+
+// This semantic convention describes an instance of a function that runs
+// without provisioning or managing of servers (also known as serverless
+// functions or Function as a Service (FaaS)) with spans.
+const (
+	// FaaSTriggerKey is the attribute Key conforming to the "faas.trigger"
+	// semantic conventions. It represents the type of the trigger which caused
+	// this function execution.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Note: For the server/consumer span on the incoming side,
+	// `faas.trigger` MUST be set.
+	//
+	// Clients invoking FaaS instances usually cannot set `faas.trigger`,
+	// since they would typically need to look in the payload to determine
+	// the event type. If clients set it, it should be the same as the
+	// trigger that corresponding incoming would have (i.e., this has
+	// nothing to do with the underlying transport used to make the API
+	// call to invoke the lambda, which is often HTTP).
+	FaaSTriggerKey = attribute.Key("faas.trigger")
+
+	// FaaSExecutionKey is the attribute Key conforming to the "faas.execution"
+	// semantic conventions. It represents the execution ID of the current
+	// function execution.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28'
+	FaaSExecutionKey = attribute.Key("faas.execution")
+)
+
+var (
+	// A response to some data source operation such as a database or filesystem read/write
+	FaaSTriggerDatasource = FaaSTriggerKey.String("datasource")
+	// To provide an answer to an inbound HTTP request
+	FaaSTriggerHTTP = FaaSTriggerKey.String("http")
+	// A function is set to be executed when messages are sent to a messaging system
+	FaaSTriggerPubsub = FaaSTriggerKey.String("pubsub")
+	// A function is scheduled to be executed regularly
+	FaaSTriggerTimer = FaaSTriggerKey.String("timer")
+	// If none of the others apply
+	FaaSTriggerOther = FaaSTriggerKey.String("other")
+)
+
+// FaaSExecution returns an attribute KeyValue conforming to the
+// "faas.execution" semantic conventions. It represents the execution ID of the
+// current function execution.
+func FaaSExecution(val string) attribute.KeyValue {
+	return FaaSExecutionKey.String(val)
+}
+
+// Semantic Convention for FaaS triggered as a response to some data source
+// operation such as a database or filesystem read/write.
+const (
+	// FaaSDocumentCollectionKey is the attribute Key conforming to the
+	// "faas.document.collection" semantic conventions. It represents the name
+	// of the source on which the triggering operation was performed. For
+	// example, in Cloud Storage or S3 corresponds to the bucket name, and in
+	// Cosmos DB to the database name.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'myBucketName', 'myDBName'
+	FaaSDocumentCollectionKey = attribute.Key("faas.document.collection")
+
+	// FaaSDocumentOperationKey is the attribute Key conforming to the
+	// "faas.document.operation" semantic conventions. It represents the
+	// describes the type of the operation that was performed on the data.
+	//
+	// Type: Enum
+	// RequirementLevel: Required
+	// Stability: stable
+	FaaSDocumentOperationKey = attribute.Key("faas.document.operation")
+
+	// FaaSDocumentTimeKey is the attribute Key conforming to the
+	// "faas.document.time" semantic conventions. It represents a string
+	// containing the time when the data was accessed in the [ISO
+	// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format
+	// expressed in [UTC](https://www.w3.org/TR/NOTE-datetime).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '2020-01-23T13:47:06Z'
+	FaaSDocumentTimeKey = attribute.Key("faas.document.time")
+
+	// FaaSDocumentNameKey is the attribute Key conforming to the
+	// "faas.document.name" semantic conventions. It represents the document
+	// name/table subjected to the operation. For example, in Cloud Storage or
+	// S3 is the name of the file, and in Cosmos DB the table name.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'myFile.txt', 'myTableName'
+	FaaSDocumentNameKey = attribute.Key("faas.document.name")
+)
+
+var (
+	// When a new object is created
+	FaaSDocumentOperationInsert = FaaSDocumentOperationKey.String("insert")
+	// When an object is modified
+	FaaSDocumentOperationEdit = FaaSDocumentOperationKey.String("edit")
+	// When an object is deleted
+	FaaSDocumentOperationDelete = FaaSDocumentOperationKey.String("delete")
+)
+
+// FaaSDocumentCollection returns an attribute KeyValue conforming to the
+// "faas.document.collection" semantic conventions. It represents the name of
+// the source on which the triggering operation was performed. For example, in
+// Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the
+// database name.
+func FaaSDocumentCollection(val string) attribute.KeyValue {
+	return FaaSDocumentCollectionKey.String(val)
+}
+
+// FaaSDocumentTime returns an attribute KeyValue conforming to the
+// "faas.document.time" semantic conventions. It represents a string containing
+// the time when the data was accessed in the [ISO
+// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format
+// expressed in [UTC](https://www.w3.org/TR/NOTE-datetime).
+func FaaSDocumentTime(val string) attribute.KeyValue {
+	return FaaSDocumentTimeKey.String(val)
+}
+
+// FaaSDocumentName returns an attribute KeyValue conforming to the
+// "faas.document.name" semantic conventions. It represents the document
+// name/table subjected to the operation. For example, in Cloud Storage or S3
+// is the name of the file, and in Cosmos DB the table name.
+func FaaSDocumentName(val string) attribute.KeyValue {
+	return FaaSDocumentNameKey.String(val)
+}
+
+// Semantic Convention for FaaS scheduled to be executed regularly.
+const (
+	// FaaSTimeKey is the attribute Key conforming to the "faas.time" semantic
+	// conventions. It represents a string containing the function invocation
+	// time in the [ISO
+	// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format
+	// expressed in [UTC](https://www.w3.org/TR/NOTE-datetime).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '2020-01-23T13:47:06Z'
+	FaaSTimeKey = attribute.Key("faas.time")
+
+	// FaaSCronKey is the attribute Key conforming to the "faas.cron" semantic
+	// conventions. It represents a string containing the schedule period as
+	// [Cron
+	// Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '0/5 * * * ? *'
+	FaaSCronKey = attribute.Key("faas.cron")
+)
+
+// FaaSTime returns an attribute KeyValue conforming to the "faas.time"
+// semantic conventions. It represents a string containing the function
+// invocation time in the [ISO
+// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format
+// expressed in [UTC](https://www.w3.org/TR/NOTE-datetime).
+func FaaSTime(val string) attribute.KeyValue {
+	return FaaSTimeKey.String(val)
+}
+
+// FaaSCron returns an attribute KeyValue conforming to the "faas.cron"
+// semantic conventions. It represents a string containing the schedule period
+// as [Cron
+// Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm).
+func FaaSCron(val string) attribute.KeyValue {
+	return FaaSCronKey.String(val)
+}
+
+// Contains additional attributes for incoming FaaS spans.
+const (
+	// FaaSColdstartKey is the attribute Key conforming to the "faas.coldstart"
+	// semantic conventions. It represents a boolean that is true if the
+	// serverless function is executed for the first time (aka cold-start).
+	//
+	// Type: boolean
+	// RequirementLevel: Optional
+	// Stability: stable
+	FaaSColdstartKey = attribute.Key("faas.coldstart")
+)
+
+// FaaSColdstart returns an attribute KeyValue conforming to the
+// "faas.coldstart" semantic conventions. It represents a boolean that is true
+// if the serverless function is executed for the first time (aka cold-start).
+func FaaSColdstart(val bool) attribute.KeyValue {
+	return FaaSColdstartKey.Bool(val)
+}
+
+// Contains additional attributes for outgoing FaaS spans.
+const (
+	// FaaSInvokedNameKey is the attribute Key conforming to the
+	// "faas.invoked_name" semantic conventions. It represents the name of the
+	// invoked function.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'my-function'
+	// Note: SHOULD be equal to the `faas.name` resource attribute of the
+	// invoked function.
+	FaaSInvokedNameKey = attribute.Key("faas.invoked_name")
+
+	// FaaSInvokedProviderKey is the attribute Key conforming to the
+	// "faas.invoked_provider" semantic conventions. It represents the cloud
+	// provider of the invoked function.
+	//
+	// Type: Enum
+	// RequirementLevel: Required
+	// Stability: stable
+	// Note: SHOULD be equal to the `cloud.provider` resource attribute of the
+	// invoked function.
+	FaaSInvokedProviderKey = attribute.Key("faas.invoked_provider")
+
+	// FaaSInvokedRegionKey is the attribute Key conforming to the
+	// "faas.invoked_region" semantic conventions. It represents the cloud
+	// region of the invoked function.
+	//
+	// Type: string
+	// RequirementLevel: ConditionallyRequired (For some cloud providers, like
+	// AWS or GCP, the region in which a function is hosted is essential to
+	// uniquely identify the function and also part of its endpoint. Since it's
+	// part of the endpoint being called, the region is always known to
+	// clients. In these cases, `faas.invoked_region` MUST be set accordingly.
+	// If the region is unknown to the client or not required for identifying
+	// the invoked function, setting `faas.invoked_region` is optional.)
+	// Stability: stable
+	// Examples: 'eu-central-1'
+	// Note: SHOULD be equal to the `cloud.region` resource attribute of the
+	// invoked function.
+	FaaSInvokedRegionKey = attribute.Key("faas.invoked_region")
+)
+
+var (
+	// Alibaba Cloud
+	FaaSInvokedProviderAlibabaCloud = FaaSInvokedProviderKey.String("alibaba_cloud")
+	// Amazon Web Services
+	FaaSInvokedProviderAWS = FaaSInvokedProviderKey.String("aws")
+	// Microsoft Azure
+	FaaSInvokedProviderAzure = FaaSInvokedProviderKey.String("azure")
+	// Google Cloud Platform
+	FaaSInvokedProviderGCP = FaaSInvokedProviderKey.String("gcp")
+	// Tencent Cloud
+	FaaSInvokedProviderTencentCloud = FaaSInvokedProviderKey.String("tencent_cloud")
+)
+
+// FaaSInvokedName returns an attribute KeyValue conforming to the
+// "faas.invoked_name" semantic conventions. It represents the name of the
+// invoked function.
+func FaaSInvokedName(val string) attribute.KeyValue {
+	return FaaSInvokedNameKey.String(val)
+}
+
+// FaaSInvokedRegion returns an attribute KeyValue conforming to the
+// "faas.invoked_region" semantic conventions. It represents the cloud region
+// of the invoked function.
+func FaaSInvokedRegion(val string) attribute.KeyValue {
+	return FaaSInvokedRegionKey.String(val)
+}
+
+// These attributes may be used for any network related operation.
+const (
+	// NetTransportKey is the attribute Key conforming to the "net.transport"
+	// semantic conventions. It represents the transport protocol used. See
+	// note below.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	NetTransportKey = attribute.Key("net.transport")
+
+	// NetAppProtocolNameKey is the attribute Key conforming to the
+	// "net.app.protocol.name" semantic conventions. It represents the
+	// application layer protocol used. The value SHOULD be normalized to
+	// lowercase.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'amqp', 'http', 'mqtt'
+	NetAppProtocolNameKey = attribute.Key("net.app.protocol.name")
+
+	// NetAppProtocolVersionKey is the attribute Key conforming to the
+	// "net.app.protocol.version" semantic conventions. It represents the
+	// version of the application layer protocol used. See note below.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '3.1.1'
+	// Note: `net.app.protocol.version` refers to the version of the protocol
+	// used and might be different from the protocol client's version. If the
+	// HTTP client used has a version of `0.27.2`, but sends HTTP version
+	// `1.1`, this attribute should be set to `1.1`.
+	NetAppProtocolVersionKey = attribute.Key("net.app.protocol.version")
+
+	// NetSockPeerNameKey is the attribute Key conforming to the
+	// "net.sock.peer.name" semantic conventions. It represents the remote
+	// socket peer name.
+	//
+	// Type: string
+	// RequirementLevel: Recommended (If available and different from
+	// `net.peer.name` and if `net.sock.peer.addr` is set.)
+	// Stability: stable
+	// Examples: 'proxy.example.com'
+	NetSockPeerNameKey = attribute.Key("net.sock.peer.name")
+
+	// NetSockPeerAddrKey is the attribute Key conforming to the
+	// "net.sock.peer.addr" semantic conventions. It represents the remote
+	// socket peer address: IPv4 or IPv6 for internet protocols, path for local
+	// communication,
+	// [etc](https://man7.org/linux/man-pages/man7/address_families.7.html).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '127.0.0.1', '/tmp/mysql.sock'
+	NetSockPeerAddrKey = attribute.Key("net.sock.peer.addr")
+
+	// NetSockPeerPortKey is the attribute Key conforming to the
+	// "net.sock.peer.port" semantic conventions. It represents the remote
+	// socket peer port.
+	//
+	// Type: int
+	// RequirementLevel: Recommended (If defined for the address family and if
+	// different than `net.peer.port` and if `net.sock.peer.addr` is set.)
+	// Stability: stable
+	// Examples: 16456
+	NetSockPeerPortKey = attribute.Key("net.sock.peer.port")
+
+	// NetSockFamilyKey is the attribute Key conforming to the
+	// "net.sock.family" semantic conventions. It represents the protocol
+	// [address
+	// family](https://man7.org/linux/man-pages/man7/address_families.7.html)
+	// which is used for communication.
+	//
+	// Type: Enum
+	// RequirementLevel: ConditionallyRequired (If different than `inet` and if
+	// any of `net.sock.peer.addr` or `net.sock.host.addr` are set. Consumers
+	// of telemetry SHOULD accept both IPv4 and IPv6 formats for the address in
+	// `net.sock.peer.addr` if `net.sock.family` is not set. This is to support
+	// instrumentations that follow previous versions of this document.)
+	// Stability: stable
+	// Examples: 'inet6', 'bluetooth'
+	NetSockFamilyKey = attribute.Key("net.sock.family")
+
+	// NetPeerNameKey is the attribute Key conforming to the "net.peer.name"
+	// semantic conventions. It represents the logical remote hostname, see
+	// note below.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'example.com'
+	// Note: `net.peer.name` SHOULD NOT be set if capturing it would require an
+	// extra DNS lookup.
+	NetPeerNameKey = attribute.Key("net.peer.name")
+
+	// NetPeerPortKey is the attribute Key conforming to the "net.peer.port"
+	// semantic conventions. It represents the logical remote port number
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 80, 8080, 443
+	NetPeerPortKey = attribute.Key("net.peer.port")
+
+	// NetHostNameKey is the attribute Key conforming to the "net.host.name"
+	// semantic conventions. It represents the logical local hostname or
+	// similar, see note below.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'localhost'
+	NetHostNameKey = attribute.Key("net.host.name")
+
+	// NetHostPortKey is the attribute Key conforming to the "net.host.port"
+	// semantic conventions. It represents the logical local port number,
+	// preferably the one that the peer used to connect
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 8080
+	NetHostPortKey = attribute.Key("net.host.port")
+
+	// NetSockHostAddrKey is the attribute Key conforming to the
+	// "net.sock.host.addr" semantic conventions. It represents the local
+	// socket address. Useful in case of a multi-IP host.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '192.168.0.1'
+	NetSockHostAddrKey = attribute.Key("net.sock.host.addr")
+
+	// NetSockHostPortKey is the attribute Key conforming to the
+	// "net.sock.host.port" semantic conventions. It represents the local
+	// socket port number.
+	//
+	// Type: int
+	// RequirementLevel: Recommended (If defined for the address family and if
+	// different than `net.host.port` and if `net.sock.host.addr` is set.)
+	// Stability: stable
+	// Examples: 35555
+	NetSockHostPortKey = attribute.Key("net.sock.host.port")
+
+	// NetHostConnectionTypeKey is the attribute Key conforming to the
+	// "net.host.connection.type" semantic conventions. It represents the
+	// internet connection type currently being used by the host.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'wifi'
+	NetHostConnectionTypeKey = attribute.Key("net.host.connection.type")
+
+	// NetHostConnectionSubtypeKey is the attribute Key conforming to the
+	// "net.host.connection.subtype" semantic conventions. It represents the
+	// this describes more details regarding the connection.type. It may be the
+	// type of cell technology connection, but it could be used for describing
+	// details about a wifi connection.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'LTE'
+	NetHostConnectionSubtypeKey = attribute.Key("net.host.connection.subtype")
+
+	// NetHostCarrierNameKey is the attribute Key conforming to the
+	// "net.host.carrier.name" semantic conventions. It represents the name of
+	// the mobile carrier.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'sprint'
+	NetHostCarrierNameKey = attribute.Key("net.host.carrier.name")
+
+	// NetHostCarrierMccKey is the attribute Key conforming to the
+	// "net.host.carrier.mcc" semantic conventions. It represents the mobile
+	// carrier country code.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '310'
+	NetHostCarrierMccKey = attribute.Key("net.host.carrier.mcc")
+
+	// NetHostCarrierMncKey is the attribute Key conforming to the
+	// "net.host.carrier.mnc" semantic conventions. It represents the mobile
+	// carrier network code.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '001'
+	NetHostCarrierMncKey = attribute.Key("net.host.carrier.mnc")
+
+	// NetHostCarrierIccKey is the attribute Key conforming to the
+	// "net.host.carrier.icc" semantic conventions. It represents the ISO
+	// 3166-1 alpha-2 2-character country code associated with the mobile
+	// carrier network.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'DE'
+	NetHostCarrierIccKey = attribute.Key("net.host.carrier.icc")
+)
+
+var (
+	// ip_tcp
+	NetTransportTCP = NetTransportKey.String("ip_tcp")
+	// ip_udp
+	NetTransportUDP = NetTransportKey.String("ip_udp")
+	// Named or anonymous pipe. See note below
+	NetTransportPipe = NetTransportKey.String("pipe")
+	// In-process communication
+	NetTransportInProc = NetTransportKey.String("inproc")
+	// Something else (non IP-based)
+	NetTransportOther = NetTransportKey.String("other")
+)
+
+var (
+	// IPv4 address
+	NetSockFamilyInet = NetSockFamilyKey.String("inet")
+	// IPv6 address
+	NetSockFamilyInet6 = NetSockFamilyKey.String("inet6")
+	// Unix domain socket path
+	NetSockFamilyUnix = NetSockFamilyKey.String("unix")
+)
+
+var (
+	// wifi
+	NetHostConnectionTypeWifi = NetHostConnectionTypeKey.String("wifi")
+	// wired
+	NetHostConnectionTypeWired = NetHostConnectionTypeKey.String("wired")
+	// cell
+	NetHostConnectionTypeCell = NetHostConnectionTypeKey.String("cell")
+	// unavailable
+	NetHostConnectionTypeUnavailable = NetHostConnectionTypeKey.String("unavailable")
+	// unknown
+	NetHostConnectionTypeUnknown = NetHostConnectionTypeKey.String("unknown")
+)
+
+var (
+	// GPRS
+	NetHostConnectionSubtypeGprs = NetHostConnectionSubtypeKey.String("gprs")
+	// EDGE
+	NetHostConnectionSubtypeEdge = NetHostConnectionSubtypeKey.String("edge")
+	// UMTS
+	NetHostConnectionSubtypeUmts = NetHostConnectionSubtypeKey.String("umts")
+	// CDMA
+	NetHostConnectionSubtypeCdma = NetHostConnectionSubtypeKey.String("cdma")
+	// EVDO Rel. 0
+	NetHostConnectionSubtypeEvdo0 = NetHostConnectionSubtypeKey.String("evdo_0")
+	// EVDO Rev. A
+	NetHostConnectionSubtypeEvdoA = NetHostConnectionSubtypeKey.String("evdo_a")
+	// CDMA2000 1XRTT
+	NetHostConnectionSubtypeCdma20001xrtt = NetHostConnectionSubtypeKey.String("cdma2000_1xrtt")
+	// HSDPA
+	NetHostConnectionSubtypeHsdpa = NetHostConnectionSubtypeKey.String("hsdpa")
+	// HSUPA
+	NetHostConnectionSubtypeHsupa = NetHostConnectionSubtypeKey.String("hsupa")
+	// HSPA
+	NetHostConnectionSubtypeHspa = NetHostConnectionSubtypeKey.String("hspa")
+	// IDEN
+	NetHostConnectionSubtypeIden = NetHostConnectionSubtypeKey.String("iden")
+	// EVDO Rev. B
+	NetHostConnectionSubtypeEvdoB = NetHostConnectionSubtypeKey.String("evdo_b")
+	// LTE
+	NetHostConnectionSubtypeLte = NetHostConnectionSubtypeKey.String("lte")
+	// EHRPD
+	NetHostConnectionSubtypeEhrpd = NetHostConnectionSubtypeKey.String("ehrpd")
+	// HSPAP
+	NetHostConnectionSubtypeHspap = NetHostConnectionSubtypeKey.String("hspap")
+	// GSM
+	NetHostConnectionSubtypeGsm = NetHostConnectionSubtypeKey.String("gsm")
+	// TD-SCDMA
+	NetHostConnectionSubtypeTdScdma = NetHostConnectionSubtypeKey.String("td_scdma")
+	// IWLAN
+	NetHostConnectionSubtypeIwlan = NetHostConnectionSubtypeKey.String("iwlan")
+	// 5G NR (New Radio)
+	NetHostConnectionSubtypeNr = NetHostConnectionSubtypeKey.String("nr")
+	// 5G NRNSA (New Radio Non-Standalone)
+	NetHostConnectionSubtypeNrnsa = NetHostConnectionSubtypeKey.String("nrnsa")
+	// LTE CA
+	NetHostConnectionSubtypeLteCa = NetHostConnectionSubtypeKey.String("lte_ca")
+)
+
+// NetAppProtocolName returns an attribute KeyValue conforming to the
+// "net.app.protocol.name" semantic conventions. It represents the application
+// layer protocol used. The value SHOULD be normalized to lowercase.
+func NetAppProtocolName(val string) attribute.KeyValue {
+	return NetAppProtocolNameKey.String(val)
+}
+
+// NetAppProtocolVersion returns an attribute KeyValue conforming to the
+// "net.app.protocol.version" semantic conventions. It represents the version
+// of the application layer protocol used. See note below.
+func NetAppProtocolVersion(val string) attribute.KeyValue {
+	return NetAppProtocolVersionKey.String(val)
+}
+
+// NetSockPeerName returns an attribute KeyValue conforming to the
+// "net.sock.peer.name" semantic conventions. It represents the remote socket
+// peer name.
+func NetSockPeerName(val string) attribute.KeyValue {
+	return NetSockPeerNameKey.String(val)
+}
+
+// NetSockPeerAddr returns an attribute KeyValue conforming to the
+// "net.sock.peer.addr" semantic conventions. It represents the remote socket
+// peer address: IPv4 or IPv6 for internet protocols, path for local
+// communication,
+// [etc](https://man7.org/linux/man-pages/man7/address_families.7.html).
+func NetSockPeerAddr(val string) attribute.KeyValue {
+	return NetSockPeerAddrKey.String(val)
+}
+
+// NetSockPeerPort returns an attribute KeyValue conforming to the
+// "net.sock.peer.port" semantic conventions. It represents the remote socket
+// peer port.
+func NetSockPeerPort(val int) attribute.KeyValue {
+	return NetSockPeerPortKey.Int(val)
+}
+
+// NetPeerName returns an attribute KeyValue conforming to the
+// "net.peer.name" semantic conventions. It represents the logical remote
+// hostname, see note below.
+func NetPeerName(val string) attribute.KeyValue {
+	return NetPeerNameKey.String(val)
+}
+
+// NetPeerPort returns an attribute KeyValue conforming to the
+// "net.peer.port" semantic conventions. It represents the logical remote port
+// number
+func NetPeerPort(val int) attribute.KeyValue {
+	return NetPeerPortKey.Int(val)
+}
+
+// NetHostName returns an attribute KeyValue conforming to the
+// "net.host.name" semantic conventions. It represents the logical local
+// hostname or similar, see note below.
+func NetHostName(val string) attribute.KeyValue {
+	return NetHostNameKey.String(val)
+}
+
+// NetHostPort returns an attribute KeyValue conforming to the
+// "net.host.port" semantic conventions. It represents the logical local port
+// number, preferably the one that the peer used to connect
+func NetHostPort(val int) attribute.KeyValue {
+	return NetHostPortKey.Int(val)
+}
+
+// NetSockHostAddr returns an attribute KeyValue conforming to the
+// "net.sock.host.addr" semantic conventions. It represents the local socket
+// address. Useful in case of a multi-IP host.
+func NetSockHostAddr(val string) attribute.KeyValue {
+	return NetSockHostAddrKey.String(val)
+}
+
+// NetSockHostPort returns an attribute KeyValue conforming to the
+// "net.sock.host.port" semantic conventions. It represents the local socket
+// port number.
+func NetSockHostPort(val int) attribute.KeyValue {
+	return NetSockHostPortKey.Int(val)
+}
+
+// NetHostCarrierName returns an attribute KeyValue conforming to the
+// "net.host.carrier.name" semantic conventions. It represents the name of the
+// mobile carrier.
+func NetHostCarrierName(val string) attribute.KeyValue {
+	return NetHostCarrierNameKey.String(val)
+}
+
+// NetHostCarrierMcc returns an attribute KeyValue conforming to the
+// "net.host.carrier.mcc" semantic conventions. It represents the mobile
+// carrier country code.
+func NetHostCarrierMcc(val string) attribute.KeyValue {
+	return NetHostCarrierMccKey.String(val)
+}
+
+// NetHostCarrierMnc returns an attribute KeyValue conforming to the
+// "net.host.carrier.mnc" semantic conventions. It represents the mobile
+// carrier network code.
+func NetHostCarrierMnc(val string) attribute.KeyValue {
+	return NetHostCarrierMncKey.String(val)
+}
+
+// NetHostCarrierIcc returns an attribute KeyValue conforming to the
+// "net.host.carrier.icc" semantic conventions. It represents the ISO 3166-1
+// alpha-2 2-character country code associated with the mobile carrier network.
+func NetHostCarrierIcc(val string) attribute.KeyValue {
+	return NetHostCarrierIccKey.String(val)
+}
+
+// Operations that access some remote service.
+const (
+	// PeerServiceKey is the attribute Key conforming to the "peer.service"
+	// semantic conventions. It represents the
+	// [`service.name`](../../resource/semantic_conventions/README.md#service)
+	// of the remote service. SHOULD be equal to the actual `service.name`
+	// resource attribute of the remote service if any.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'AuthTokenCache'
+	PeerServiceKey = attribute.Key("peer.service")
+)
+
+// PeerService returns an attribute KeyValue conforming to the
+// "peer.service" semantic conventions. It represents the
+// [`service.name`](../../resource/semantic_conventions/README.md#service) of
+// the remote service. SHOULD be equal to the actual `service.name` resource
+// attribute of the remote service if any.
+func PeerService(val string) attribute.KeyValue {
+	return PeerServiceKey.String(val)
+}
+
+// These attributes may be used for any operation with an authenticated and/or
+// authorized enduser.
+const (
+	// EnduserIDKey is the attribute Key conforming to the "enduser.id"
+	// semantic conventions. It represents the username or client_id extracted
+	// from the access token or
+	// [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header
+	// in the inbound request from outside the system.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'username'
+	EnduserIDKey = attribute.Key("enduser.id")
+
+	// EnduserRoleKey is the attribute Key conforming to the "enduser.role"
+	// semantic conventions. It represents the actual/assumed role the client
+	// is making the request under extracted from token or application security
+	// context.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'admin'
+	EnduserRoleKey = attribute.Key("enduser.role")
+
+	// EnduserScopeKey is the attribute Key conforming to the "enduser.scope"
+	// semantic conventions. It represents the scopes or granted authorities
+	// the client currently possesses extracted from token or application
+	// security context. The value would come from the scope associated with an
+	// [OAuth 2.0 Access
+	// Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute
+	// value in a [SAML 2.0
+	// Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'read:message, write:files'
+	EnduserScopeKey = attribute.Key("enduser.scope")
+)
+
+// EnduserID returns an attribute KeyValue conforming to the "enduser.id"
+// semantic conventions. It represents the username or client_id extracted from
+// the access token or
+// [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in
+// the inbound request from outside the system.
+func EnduserID(val string) attribute.KeyValue {
+	return EnduserIDKey.String(val)
+}
+
+// EnduserRole returns an attribute KeyValue conforming to the
+// "enduser.role" semantic conventions. It represents the actual/assumed role
+// the client is making the request under extracted from token or application
+// security context.
+func EnduserRole(val string) attribute.KeyValue {
+	return EnduserRoleKey.String(val)
+}
+
+// EnduserScope returns an attribute KeyValue conforming to the
+// "enduser.scope" semantic conventions. It represents the scopes or granted
+// authorities the client currently possesses extracted from token or
+// application security context. The value would come from the scope associated
+// with an [OAuth 2.0 Access
+// Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute
+// value in a [SAML 2.0
+// Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html).
+func EnduserScope(val string) attribute.KeyValue {
+	return EnduserScopeKey.String(val)
+}
+
+// These attributes may be used for any operation to store information about a
+// thread that started a span.
+const (
+	// ThreadIDKey is the attribute Key conforming to the "thread.id" semantic
+	// conventions. It represents the current "managed" thread ID (as opposed
+	// to OS thread ID).
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 42
+	ThreadIDKey = attribute.Key("thread.id")
+
+	// ThreadNameKey is the attribute Key conforming to the "thread.name"
+	// semantic conventions. It represents the current thread name.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'main'
+	ThreadNameKey = attribute.Key("thread.name")
+)
+
+// ThreadID returns an attribute KeyValue conforming to the "thread.id"
+// semantic conventions. It represents the current "managed" thread ID (as
+// opposed to OS thread ID).
+func ThreadID(val int) attribute.KeyValue {
+	return ThreadIDKey.Int(val)
+}
+
+// ThreadName returns an attribute KeyValue conforming to the "thread.name"
+// semantic conventions. It represents the current thread name.
+func ThreadName(val string) attribute.KeyValue {
+	return ThreadNameKey.String(val)
+}
+
+// These attributes allow to report this unit of code and therefore to provide
+// more context about the span.
+const (
+	// CodeFunctionKey is the attribute Key conforming to the "code.function"
+	// semantic conventions. It represents the method or function name, or
+	// equivalent (usually rightmost part of the code unit's name).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'serveRequest'
+	CodeFunctionKey = attribute.Key("code.function")
+
+	// CodeNamespaceKey is the attribute Key conforming to the "code.namespace"
+	// semantic conventions. It represents the "namespace" within which
+	// `code.function` is defined. Usually the qualified class or module name,
+	// such that `code.namespace` + some separator + `code.function` form a
+	// unique identifier for the code unit.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'com.example.MyHTTPService'
+	CodeNamespaceKey = attribute.Key("code.namespace")
+
+	// CodeFilepathKey is the attribute Key conforming to the "code.filepath"
+	// semantic conventions. It represents the source code file name that
+	// identifies the code unit as uniquely as possible (preferably an absolute
+	// file path).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '/usr/local/MyApplication/content_root/app/index.php'
+	CodeFilepathKey = attribute.Key("code.filepath")
+
+	// CodeLineNumberKey is the attribute Key conforming to the "code.lineno"
+	// semantic conventions. It represents the line number in `code.filepath`
+	// best representing the operation. It SHOULD point within the code unit
+	// named in `code.function`.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 42
+	CodeLineNumberKey = attribute.Key("code.lineno")
+
+	// CodeColumnKey is the attribute Key conforming to the "code.column"
+	// semantic conventions. It represents the column number in `code.filepath`
+	// best representing the operation. It SHOULD point within the code unit
+	// named in `code.function`.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 16
+	CodeColumnKey = attribute.Key("code.column")
+)
+
+// CodeFunction returns an attribute KeyValue conforming to the
+// "code.function" semantic conventions. It represents the method or function
+// name, or equivalent (usually rightmost part of the code unit's name).
+func CodeFunction(val string) attribute.KeyValue {
+	return CodeFunctionKey.String(val)
+}
+
+// CodeNamespace returns an attribute KeyValue conforming to the
+// "code.namespace" semantic conventions. It represents the "namespace" within
+// which `code.function` is defined. Usually the qualified class or module
+// name, such that `code.namespace` + some separator + `code.function` form a
+// unique identifier for the code unit.
+func CodeNamespace(val string) attribute.KeyValue {
+	return CodeNamespaceKey.String(val)
+}
+
+// CodeFilepath returns an attribute KeyValue conforming to the
+// "code.filepath" semantic conventions. It represents the source code file
+// name that identifies the code unit as uniquely as possible (preferably an
+// absolute file path).
+func CodeFilepath(val string) attribute.KeyValue {
+	return CodeFilepathKey.String(val)
+}
+
+// CodeLineNumber returns an attribute KeyValue conforming to the "code.lineno"
+// semantic conventions. It represents the line number in `code.filepath` best
+// representing the operation. It SHOULD point within the code unit named in
+// `code.function`.
+func CodeLineNumber(val int) attribute.KeyValue {
+	return CodeLineNumberKey.Int(val)
+}
+
+// CodeColumn returns an attribute KeyValue conforming to the "code.column"
+// semantic conventions. It represents the column number in `code.filepath`
+// best representing the operation. It SHOULD point within the code unit named
+// in `code.function`.
+func CodeColumn(val int) attribute.KeyValue {
+	return CodeColumnKey.Int(val)
+}
+
+// Semantic conventions for HTTP client and server Spans.
+const (
+	// HTTPMethodKey is the attribute Key conforming to the "http.method"
+	// semantic conventions. It represents the hTTP request method.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'GET', 'POST', 'HEAD'
+	HTTPMethodKey = attribute.Key("http.method")
+
+	// HTTPStatusCodeKey is the attribute Key conforming to the
+	// "http.status_code" semantic conventions. It represents the [HTTP
+	// response status code](https://tools.ietf.org/html/rfc7231#section-6).
+	//
+	// Type: int
+	// RequirementLevel: ConditionallyRequired (If and only if one was
+	// received/sent.)
+	// Stability: stable
+	// Examples: 200
+	HTTPStatusCodeKey = attribute.Key("http.status_code")
+
+	// HTTPFlavorKey is the attribute Key conforming to the "http.flavor"
+	// semantic conventions. It represents the kind of HTTP protocol used.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Note: If `net.transport` is not specified, it can be assumed to be
+	// `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is
+	// assumed.
+	HTTPFlavorKey = attribute.Key("http.flavor")
+
+	// HTTPUserAgentKey is the attribute Key conforming to the
+	// "http.user_agent" semantic conventions. It represents the value of the
+	// [HTTP
+	// User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent)
+	// header sent by the client.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'CERN-LineMode/2.15 libwww/2.17b3'
+	HTTPUserAgentKey = attribute.Key("http.user_agent")
+
+	// HTTPRequestContentLengthKey is the attribute Key conforming to the
+	// "http.request_content_length" semantic conventions. It represents the
+	// size of the request payload body in bytes. This is the number of bytes
+	// transferred excluding headers and is often, but not always, present as
+	// the
+	// [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length)
+	// header. For requests using transport encoding, this should be the
+	// compressed size.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 3495
+	HTTPRequestContentLengthKey = attribute.Key("http.request_content_length")
+
+	// HTTPResponseContentLengthKey is the attribute Key conforming to the
+	// "http.response_content_length" semantic conventions. It represents the
+	// size of the response payload body in bytes. This is the number of bytes
+	// transferred excluding headers and is often, but not always, present as
+	// the
+	// [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length)
+	// header. For requests using transport encoding, this should be the
+	// compressed size.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 3495
+	HTTPResponseContentLengthKey = attribute.Key("http.response_content_length")
+)
+
+var (
+	// HTTP/1.0
+	HTTPFlavorHTTP10 = HTTPFlavorKey.String("1.0")
+	// HTTP/1.1
+	HTTPFlavorHTTP11 = HTTPFlavorKey.String("1.1")
+	// HTTP/2
+	HTTPFlavorHTTP20 = HTTPFlavorKey.String("2.0")
+	// HTTP/3
+	HTTPFlavorHTTP30 = HTTPFlavorKey.String("3.0")
+	// SPDY protocol
+	HTTPFlavorSPDY = HTTPFlavorKey.String("SPDY")
+	// QUIC protocol
+	HTTPFlavorQUIC = HTTPFlavorKey.String("QUIC")
+)
+
+// HTTPMethod returns an attribute KeyValue conforming to the "http.method"
+// semantic conventions. It represents the hTTP request method.
+func HTTPMethod(val string) attribute.KeyValue {
+	return HTTPMethodKey.String(val)
+}
+
+// HTTPStatusCode returns an attribute KeyValue conforming to the
+// "http.status_code" semantic conventions. It represents the [HTTP response
+// status code](https://tools.ietf.org/html/rfc7231#section-6).
+func HTTPStatusCode(val int) attribute.KeyValue {
+	return HTTPStatusCodeKey.Int(val)
+}
+
+// HTTPUserAgent returns an attribute KeyValue conforming to the
+// "http.user_agent" semantic conventions. It represents the value of the [HTTP
+// User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent)
+// header sent by the client.
+func HTTPUserAgent(val string) attribute.KeyValue {
+	return HTTPUserAgentKey.String(val)
+}
+
+// HTTPRequestContentLength returns an attribute KeyValue conforming to the
+// "http.request_content_length" semantic conventions. It represents the size
+// of the request payload body in bytes. This is the number of bytes
+// transferred excluding headers and is often, but not always, present as the
+// [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length)
+// header. For requests using transport encoding, this should be the compressed
+// size.
+func HTTPRequestContentLength(val int) attribute.KeyValue {
+	return HTTPRequestContentLengthKey.Int(val)
+}
+
+// HTTPResponseContentLength returns an attribute KeyValue conforming to the
+// "http.response_content_length" semantic conventions. It represents the size
+// of the response payload body in bytes. This is the number of bytes
+// transferred excluding headers and is often, but not always, present as the
+// [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length)
+// header. For requests using transport encoding, this should be the compressed
+// size.
+func HTTPResponseContentLength(val int) attribute.KeyValue {
+	return HTTPResponseContentLengthKey.Int(val)
+}
+
+// Semantic Convention for HTTP Client
+const (
+	// HTTPURLKey is the attribute Key conforming to the "http.url" semantic
+	// conventions. It represents the full HTTP request URL in the form
+	// `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is
+	// not transmitted over HTTP, but if it is known, it should be included
+	// nevertheless.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'https://www.foo.bar/search?q=OpenTelemetry#SemConv'
+	// Note: `http.url` MUST NOT contain credentials passed via URL in form of
+	// `https://username:password@www.example.com/`. In such case the
+	// attribute's value should be `https://www.example.com/`.
+	HTTPURLKey = attribute.Key("http.url")
+
+	// HTTPResendCountKey is the attribute Key conforming to the
+	// "http.resend_count" semantic conventions. It represents the ordinal
+	// number of request resending attempt (for any reason, including
+	// redirects).
+	//
+	// Type: int
+	// RequirementLevel: Recommended (if and only if request was retried.)
+	// Stability: stable
+	// Examples: 3
+	// Note: The resend count SHOULD be updated each time an HTTP request gets
+	// resent by the client, regardless of what was the cause of the resending
+	// (e.g. redirection, authorization failure, 503 Server Unavailable,
+	// network issues, or any other).
+	HTTPResendCountKey = attribute.Key("http.resend_count")
+)
+
+// HTTPURL returns an attribute KeyValue conforming to the "http.url"
+// semantic conventions. It represents the full HTTP request URL in the form
+// `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not
+// transmitted over HTTP, but if it is known, it should be included
+// nevertheless.
+func HTTPURL(val string) attribute.KeyValue {
+	return HTTPURLKey.String(val)
+}
+
+// HTTPResendCount returns an attribute KeyValue conforming to the
+// "http.resend_count" semantic conventions. It represents the ordinal number
+// of request resending attempt (for any reason, including redirects).
+func HTTPResendCount(val int) attribute.KeyValue {
+	return HTTPResendCountKey.Int(val)
+}
+
+// Semantic Convention for HTTP Server
+const (
+	// HTTPSchemeKey is the attribute Key conforming to the "http.scheme"
+	// semantic conventions. It represents the URI scheme identifying the used
+	// protocol.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'http', 'https'
+	HTTPSchemeKey = attribute.Key("http.scheme")
+
+	// HTTPTargetKey is the attribute Key conforming to the "http.target"
+	// semantic conventions. It represents the full request target as passed in
+	// a HTTP request line or equivalent.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: '/path/12314/?q=ddds'
+	HTTPTargetKey = attribute.Key("http.target")
+
+	// HTTPRouteKey is the attribute Key conforming to the "http.route"
+	// semantic conventions. It represents the matched route (path template in
+	// the format used by the respective server framework). See note below
+	//
+	// Type: string
+	// RequirementLevel: ConditionallyRequired (If and only if it's available)
+	// Stability: stable
+	// Examples: '/users/:userID?', '{controller}/{action}/{id?}'
+	// Note: 'http.route' MUST NOT be populated when this is not supported by
+	// the HTTP server framework as the route attribute should have
+	// low-cardinality and the URI path can NOT substitute it.
+	HTTPRouteKey = attribute.Key("http.route")
+
+	// HTTPClientIPKey is the attribute Key conforming to the "http.client_ip"
+	// semantic conventions. It represents the IP address of the original
+	// client behind all proxies, if known (e.g. from
+	// [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)).
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '83.164.160.102'
+	// Note: This is not necessarily the same as `net.sock.peer.addr`, which
+	// would
+	// identify the network-level peer, which may be a proxy.
+	//
+	// This attribute should be set when a source of information different
+	// from the one used for `net.sock.peer.addr`, is available even if that
+	// other
+	// source just confirms the same value as `net.sock.peer.addr`.
+	// Rationale: For `net.sock.peer.addr`, one typically does not know if it
+	// comes from a proxy, reverse proxy, or the actual client. Setting
+	// `http.client_ip` when it's the same as `net.sock.peer.addr` means that
+	// one is at least somewhat confident that the address is not that of
+	// the closest proxy.
+	HTTPClientIPKey = attribute.Key("http.client_ip")
+)
+
+// HTTPScheme returns an attribute KeyValue conforming to the "http.scheme"
+// semantic conventions. It represents the URI scheme identifying the used
+// protocol.
+func HTTPScheme(val string) attribute.KeyValue {
+	return HTTPSchemeKey.String(val)
+}
+
+// HTTPTarget returns an attribute KeyValue conforming to the "http.target"
+// semantic conventions. It represents the full request target as passed in a
+// HTTP request line or equivalent.
+func HTTPTarget(val string) attribute.KeyValue {
+	return HTTPTargetKey.String(val)
+}
+
+// HTTPRoute returns an attribute KeyValue conforming to the "http.route"
+// semantic conventions. It represents the matched route (path template in the
+// format used by the respective server framework). See note below
+func HTTPRoute(val string) attribute.KeyValue {
+	return HTTPRouteKey.String(val)
+}
+
+// HTTPClientIP returns an attribute KeyValue conforming to the
+// "http.client_ip" semantic conventions. It represents the IP address of the
+// original client behind all proxies, if known (e.g. from
+// [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)).
+func HTTPClientIP(val string) attribute.KeyValue {
+	return HTTPClientIPKey.String(val)
+}
+
+// Attributes that exist for multiple DynamoDB request types.
+const (
+	// AWSDynamoDBTableNamesKey is the attribute Key conforming to the
+	// "aws.dynamodb.table_names" semantic conventions. It represents the keys
+	// in the `RequestItems` object field.
+	//
+	// Type: string[]
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'Users', 'Cats'
+	AWSDynamoDBTableNamesKey = attribute.Key("aws.dynamodb.table_names")
+
+	// AWSDynamoDBConsumedCapacityKey is the attribute Key conforming to the
+	// "aws.dynamodb.consumed_capacity" semantic conventions. It represents the
+	// JSON-serialized value of each item in the `ConsumedCapacity` response
+	// field.
+	//
+	// Type: string[]
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '{ "CapacityUnits": number, "GlobalSecondaryIndexes": {
+	// "string" : { "CapacityUnits": number, "ReadCapacityUnits": number,
+	// "WriteCapacityUnits": number } }, "LocalSecondaryIndexes": { "string" :
+	// { "CapacityUnits": number, "ReadCapacityUnits": number,
+	// "WriteCapacityUnits": number } }, "ReadCapacityUnits": number, "Table":
+	// { "CapacityUnits": number, "ReadCapacityUnits": number,
+	// "WriteCapacityUnits": number }, "TableName": "string",
+	// "WriteCapacityUnits": number }'
+	AWSDynamoDBConsumedCapacityKey = attribute.Key("aws.dynamodb.consumed_capacity")
+
+	// AWSDynamoDBItemCollectionMetricsKey is the attribute Key conforming to
+	// the "aws.dynamodb.item_collection_metrics" semantic conventions. It
+	// represents the JSON-serialized value of the `ItemCollectionMetrics`
+	// response field.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '{ "string" : [ { "ItemCollectionKey": { "string" : { "B":
+	// blob, "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": {
+	// "string" : "AttributeValue" }, "N": "string", "NS": [ "string" ],
+	// "NULL": boolean, "S": "string", "SS": [ "string" ] } },
+	// "SizeEstimateRangeGB": [ number ] } ] }'
+	AWSDynamoDBItemCollectionMetricsKey = attribute.Key("aws.dynamodb.item_collection_metrics")
+
+	// AWSDynamoDBProvisionedReadCapacityKey is the attribute Key conforming to
+	// the "aws.dynamodb.provisioned_read_capacity" semantic conventions. It
+	// represents the value of the `ProvisionedThroughput.ReadCapacityUnits`
+	// request parameter.
+	//
+	// Type: double
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 1.0, 2.0
+	AWSDynamoDBProvisionedReadCapacityKey = attribute.Key("aws.dynamodb.provisioned_read_capacity")
+
+	// AWSDynamoDBProvisionedWriteCapacityKey is the attribute Key conforming
+	// to the "aws.dynamodb.provisioned_write_capacity" semantic conventions.
+	// It represents the value of the
+	// `ProvisionedThroughput.WriteCapacityUnits` request parameter.
+	//
+	// Type: double
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 1.0, 2.0
+	AWSDynamoDBProvisionedWriteCapacityKey = attribute.Key("aws.dynamodb.provisioned_write_capacity")
+
+	// AWSDynamoDBConsistentReadKey is the attribute Key conforming to the
+	// "aws.dynamodb.consistent_read" semantic conventions. It represents the
+	// value of the `ConsistentRead` request parameter.
+	//
+	// Type: boolean
+	// RequirementLevel: Optional
+	// Stability: stable
+	AWSDynamoDBConsistentReadKey = attribute.Key("aws.dynamodb.consistent_read")
+
+	// AWSDynamoDBProjectionKey is the attribute Key conforming to the
+	// "aws.dynamodb.projection" semantic conventions. It represents the value
+	// of the `ProjectionExpression` request parameter.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'Title', 'Title, Price, Color', 'Title, Description,
+	// RelatedItems, ProductReviews'
+	AWSDynamoDBProjectionKey = attribute.Key("aws.dynamodb.projection")
+
+	// AWSDynamoDBLimitKey is the attribute Key conforming to the
+	// "aws.dynamodb.limit" semantic conventions. It represents the value of
+	// the `Limit` request parameter.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 10
+	AWSDynamoDBLimitKey = attribute.Key("aws.dynamodb.limit")
+
+	// AWSDynamoDBAttributesToGetKey is the attribute Key conforming to the
+	// "aws.dynamodb.attributes_to_get" semantic conventions. It represents the
+	// value of the `AttributesToGet` request parameter.
+	//
+	// Type: string[]
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'lives', 'id'
+	AWSDynamoDBAttributesToGetKey = attribute.Key("aws.dynamodb.attributes_to_get")
+
+	// AWSDynamoDBIndexNameKey is the attribute Key conforming to the
+	// "aws.dynamodb.index_name" semantic conventions. It represents the value
+	// of the `IndexName` request parameter.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'name_to_group'
+	AWSDynamoDBIndexNameKey = attribute.Key("aws.dynamodb.index_name")
+
+	// AWSDynamoDBSelectKey is the attribute Key conforming to the
+	// "aws.dynamodb.select" semantic conventions. It represents the value of
+	// the `Select` request parameter.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'ALL_ATTRIBUTES', 'COUNT'
+	AWSDynamoDBSelectKey = attribute.Key("aws.dynamodb.select")
+)
+
+// AWSDynamoDBTableNames returns an attribute KeyValue conforming to the
+// "aws.dynamodb.table_names" semantic conventions. It represents the keys in
+// the `RequestItems` object field.
+func AWSDynamoDBTableNames(val ...string) attribute.KeyValue {
+	return AWSDynamoDBTableNamesKey.StringSlice(val)
+}
+
+// AWSDynamoDBConsumedCapacity returns an attribute KeyValue conforming to
+// the "aws.dynamodb.consumed_capacity" semantic conventions. It represents the
+// JSON-serialized value of each item in the `ConsumedCapacity` response field.
+func AWSDynamoDBConsumedCapacity(val ...string) attribute.KeyValue {
+	return AWSDynamoDBConsumedCapacityKey.StringSlice(val)
+}
+
+// AWSDynamoDBItemCollectionMetrics returns an attribute KeyValue conforming
+// to the "aws.dynamodb.item_collection_metrics" semantic conventions. It
+// represents the JSON-serialized value of the `ItemCollectionMetrics` response
+// field.
+func AWSDynamoDBItemCollectionMetrics(val string) attribute.KeyValue {
+	return AWSDynamoDBItemCollectionMetricsKey.String(val)
+}
+
+// AWSDynamoDBProvisionedReadCapacity returns an attribute KeyValue
+// conforming to the "aws.dynamodb.provisioned_read_capacity" semantic
+// conventions. It represents the value of the
+// `ProvisionedThroughput.ReadCapacityUnits` request parameter.
+func AWSDynamoDBProvisionedReadCapacity(val float64) attribute.KeyValue {
+	return AWSDynamoDBProvisionedReadCapacityKey.Float64(val)
+}
+
+// AWSDynamoDBProvisionedWriteCapacity returns an attribute KeyValue
+// conforming to the "aws.dynamodb.provisioned_write_capacity" semantic
+// conventions. It represents the value of the
+// `ProvisionedThroughput.WriteCapacityUnits` request parameter.
+func AWSDynamoDBProvisionedWriteCapacity(val float64) attribute.KeyValue {
+	return AWSDynamoDBProvisionedWriteCapacityKey.Float64(val)
+}
+
+// AWSDynamoDBConsistentRead returns an attribute KeyValue conforming to the
+// "aws.dynamodb.consistent_read" semantic conventions. It represents the value
+// of the `ConsistentRead` request parameter.
+func AWSDynamoDBConsistentRead(val bool) attribute.KeyValue {
+	return AWSDynamoDBConsistentReadKey.Bool(val)
+}
+
+// AWSDynamoDBProjection returns an attribute KeyValue conforming to the
+// "aws.dynamodb.projection" semantic conventions. It represents the value of
+// the `ProjectionExpression` request parameter.
+func AWSDynamoDBProjection(val string) attribute.KeyValue {
+	return AWSDynamoDBProjectionKey.String(val)
+}
+
+// AWSDynamoDBLimit returns an attribute KeyValue conforming to the
+// "aws.dynamodb.limit" semantic conventions. It represents the value of the
+// `Limit` request parameter.
+func AWSDynamoDBLimit(val int) attribute.KeyValue {
+	return AWSDynamoDBLimitKey.Int(val)
+}
+
+// AWSDynamoDBAttributesToGet returns an attribute KeyValue conforming to
+// the "aws.dynamodb.attributes_to_get" semantic conventions. It represents the
+// value of the `AttributesToGet` request parameter.
+func AWSDynamoDBAttributesToGet(val ...string) attribute.KeyValue {
+	return AWSDynamoDBAttributesToGetKey.StringSlice(val)
+}
+
+// AWSDynamoDBIndexName returns an attribute KeyValue conforming to the
+// "aws.dynamodb.index_name" semantic conventions. It represents the value of
+// the `IndexName` request parameter.
+func AWSDynamoDBIndexName(val string) attribute.KeyValue {
+	return AWSDynamoDBIndexNameKey.String(val)
+}
+
+// AWSDynamoDBSelect returns an attribute KeyValue conforming to the
+// "aws.dynamodb.select" semantic conventions. It represents the value of the
+// `Select` request parameter.
+func AWSDynamoDBSelect(val string) attribute.KeyValue {
+	return AWSDynamoDBSelectKey.String(val)
+}
+
+// DynamoDB.CreateTable
+const (
+	// AWSDynamoDBGlobalSecondaryIndexesKey is the attribute Key conforming to
+	// the "aws.dynamodb.global_secondary_indexes" semantic conventions. It
+	// represents the JSON-serialized value of each item of the
+	// `GlobalSecondaryIndexes` request field
+	//
+	// Type: string[]
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '{ "IndexName": "string", "KeySchema": [ { "AttributeName":
+	// "string", "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [
+	// "string" ], "ProjectionType": "string" }, "ProvisionedThroughput": {
+	// "ReadCapacityUnits": number, "WriteCapacityUnits": number } }'
+	AWSDynamoDBGlobalSecondaryIndexesKey = attribute.Key("aws.dynamodb.global_secondary_indexes")
+
+	// AWSDynamoDBLocalSecondaryIndexesKey is the attribute Key conforming to
+	// the "aws.dynamodb.local_secondary_indexes" semantic conventions. It
+	// represents the JSON-serialized value of each item of the
+	// `LocalSecondaryIndexes` request field.
+	//
+	// Type: string[]
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '{ "IndexARN": "string", "IndexName": "string",
+	// "IndexSizeBytes": number, "ItemCount": number, "KeySchema": [ {
+	// "AttributeName": "string", "KeyType": "string" } ], "Projection": {
+	// "NonKeyAttributes": [ "string" ], "ProjectionType": "string" } }'
+	AWSDynamoDBLocalSecondaryIndexesKey = attribute.Key("aws.dynamodb.local_secondary_indexes")
+)
+
+// AWSDynamoDBGlobalSecondaryIndexes returns an attribute KeyValue
+// conforming to the "aws.dynamodb.global_secondary_indexes" semantic
+// conventions. It represents the JSON-serialized value of each item of the
+// `GlobalSecondaryIndexes` request field
+func AWSDynamoDBGlobalSecondaryIndexes(val ...string) attribute.KeyValue {
+	return AWSDynamoDBGlobalSecondaryIndexesKey.StringSlice(val)
+}
+
+// AWSDynamoDBLocalSecondaryIndexes returns an attribute KeyValue conforming
+// to the "aws.dynamodb.local_secondary_indexes" semantic conventions. It
+// represents the JSON-serialized value of each item of the
+// `LocalSecondaryIndexes` request field.
+func AWSDynamoDBLocalSecondaryIndexes(val ...string) attribute.KeyValue {
+	return AWSDynamoDBLocalSecondaryIndexesKey.StringSlice(val)
+}
+
+// DynamoDB.ListTables
+const (
+	// AWSDynamoDBExclusiveStartTableKey is the attribute Key conforming to the
+	// "aws.dynamodb.exclusive_start_table" semantic conventions. It represents
+	// the value of the `ExclusiveStartTableName` request parameter.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'Users', 'CatsTable'
+	AWSDynamoDBExclusiveStartTableKey = attribute.Key("aws.dynamodb.exclusive_start_table")
+
+	// AWSDynamoDBTableCountKey is the attribute Key conforming to the
+	// "aws.dynamodb.table_count" semantic conventions. It represents the the
+	// number of items in the `TableNames` response parameter.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 20
+	AWSDynamoDBTableCountKey = attribute.Key("aws.dynamodb.table_count")
+)
+
+// AWSDynamoDBExclusiveStartTable returns an attribute KeyValue conforming
+// to the "aws.dynamodb.exclusive_start_table" semantic conventions. It
+// represents the value of the `ExclusiveStartTableName` request parameter.
+func AWSDynamoDBExclusiveStartTable(val string) attribute.KeyValue {
+	return AWSDynamoDBExclusiveStartTableKey.String(val)
+}
+
+// AWSDynamoDBTableCount returns an attribute KeyValue conforming to the
+// "aws.dynamodb.table_count" semantic conventions. It represents the the
+// number of items in the `TableNames` response parameter.
+func AWSDynamoDBTableCount(val int) attribute.KeyValue {
+	return AWSDynamoDBTableCountKey.Int(val)
+}
+
+// DynamoDB.Query
+const (
+	// AWSDynamoDBScanForwardKey is the attribute Key conforming to the
+	// "aws.dynamodb.scan_forward" semantic conventions. It represents the
+	// value of the `ScanIndexForward` request parameter.
+	//
+	// Type: boolean
+	// RequirementLevel: Optional
+	// Stability: stable
+	AWSDynamoDBScanForwardKey = attribute.Key("aws.dynamodb.scan_forward")
+)
+
+// AWSDynamoDBScanForward returns an attribute KeyValue conforming to the
+// "aws.dynamodb.scan_forward" semantic conventions. It represents the value of
+// the `ScanIndexForward` request parameter.
+func AWSDynamoDBScanForward(val bool) attribute.KeyValue {
+	return AWSDynamoDBScanForwardKey.Bool(val)
+}
+
+// DynamoDB.Scan
+const (
+	// AWSDynamoDBSegmentKey is the attribute Key conforming to the
+	// "aws.dynamodb.segment" semantic conventions. It represents the value of
+	// the `Segment` request parameter.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 10
+	AWSDynamoDBSegmentKey = attribute.Key("aws.dynamodb.segment")
+
+	// AWSDynamoDBTotalSegmentsKey is the attribute Key conforming to the
+	// "aws.dynamodb.total_segments" semantic conventions. It represents the
+	// value of the `TotalSegments` request parameter.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 100
+	AWSDynamoDBTotalSegmentsKey = attribute.Key("aws.dynamodb.total_segments")
+
+	// AWSDynamoDBCountKey is the attribute Key conforming to the
+	// "aws.dynamodb.count" semantic conventions. It represents the value of
+	// the `Count` response parameter.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 10
+	AWSDynamoDBCountKey = attribute.Key("aws.dynamodb.count")
+
+	// AWSDynamoDBScannedCountKey is the attribute Key conforming to the
+	// "aws.dynamodb.scanned_count" semantic conventions. It represents the
+	// value of the `ScannedCount` response parameter.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 50
+	AWSDynamoDBScannedCountKey = attribute.Key("aws.dynamodb.scanned_count")
+)
+
+// AWSDynamoDBSegment returns an attribute KeyValue conforming to the
+// "aws.dynamodb.segment" semantic conventions. It represents the value of the
+// `Segment` request parameter.
+func AWSDynamoDBSegment(val int) attribute.KeyValue {
+	return AWSDynamoDBSegmentKey.Int(val)
+}
+
+// AWSDynamoDBTotalSegments returns an attribute KeyValue conforming to the
+// "aws.dynamodb.total_segments" semantic conventions. It represents the value
+// of the `TotalSegments` request parameter.
+func AWSDynamoDBTotalSegments(val int) attribute.KeyValue {
+	return AWSDynamoDBTotalSegmentsKey.Int(val)
+}
+
+// AWSDynamoDBCount returns an attribute KeyValue conforming to the
+// "aws.dynamodb.count" semantic conventions. It represents the value of the
+// `Count` response parameter.
+func AWSDynamoDBCount(val int) attribute.KeyValue {
+	return AWSDynamoDBCountKey.Int(val)
+}
+
+// AWSDynamoDBScannedCount returns an attribute KeyValue conforming to the
+// "aws.dynamodb.scanned_count" semantic conventions. It represents the value
+// of the `ScannedCount` response parameter.
+func AWSDynamoDBScannedCount(val int) attribute.KeyValue {
+	return AWSDynamoDBScannedCountKey.Int(val)
+}
+
+// DynamoDB.UpdateTable
+const (
+	// AWSDynamoDBAttributeDefinitionsKey is the attribute Key conforming to
+	// the "aws.dynamodb.attribute_definitions" semantic conventions. It
+	// represents the JSON-serialized value of each item in the
+	// `AttributeDefinitions` request field.
+	//
+	// Type: string[]
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '{ "AttributeName": "string", "AttributeType": "string" }'
+	AWSDynamoDBAttributeDefinitionsKey = attribute.Key("aws.dynamodb.attribute_definitions")
+
+	// AWSDynamoDBGlobalSecondaryIndexUpdatesKey is the attribute Key
+	// conforming to the "aws.dynamodb.global_secondary_index_updates" semantic
+	// conventions. It represents the JSON-serialized value of each item in the
+	// the `GlobalSecondaryIndexUpdates` request field.
+	//
+	// Type: string[]
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '{ "Create": { "IndexName": "string", "KeySchema": [ {
+	// "AttributeName": "string", "KeyType": "string" } ], "Projection": {
+	// "NonKeyAttributes": [ "string" ], "ProjectionType": "string" },
+	// "ProvisionedThroughput": { "ReadCapacityUnits": number,
+	// "WriteCapacityUnits": number } }'
+	AWSDynamoDBGlobalSecondaryIndexUpdatesKey = attribute.Key("aws.dynamodb.global_secondary_index_updates")
+)
+
+// AWSDynamoDBAttributeDefinitions returns an attribute KeyValue conforming
+// to the "aws.dynamodb.attribute_definitions" semantic conventions. It
+// represents the JSON-serialized value of each item in the
+// `AttributeDefinitions` request field.
+func AWSDynamoDBAttributeDefinitions(val ...string) attribute.KeyValue {
+	return AWSDynamoDBAttributeDefinitionsKey.StringSlice(val)
+}
+
+// AWSDynamoDBGlobalSecondaryIndexUpdates returns an attribute KeyValue
+// conforming to the "aws.dynamodb.global_secondary_index_updates" semantic
+// conventions. It represents the JSON-serialized value of each item in the the
+// `GlobalSecondaryIndexUpdates` request field.
+func AWSDynamoDBGlobalSecondaryIndexUpdates(val ...string) attribute.KeyValue {
+	return AWSDynamoDBGlobalSecondaryIndexUpdatesKey.StringSlice(val)
+}
+
+// Semantic conventions to apply when instrumenting the GraphQL implementation.
+// They map GraphQL operations to attributes on a Span.
+const (
+	// GraphqlOperationNameKey is the attribute Key conforming to the
+	// "graphql.operation.name" semantic conventions. It represents the name of
+	// the operation being executed.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'findBookByID'
+	GraphqlOperationNameKey = attribute.Key("graphql.operation.name")
+
+	// GraphqlOperationTypeKey is the attribute Key conforming to the
+	// "graphql.operation.type" semantic conventions. It represents the type of
+	// the operation being executed.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'query', 'mutation', 'subscription'
+	GraphqlOperationTypeKey = attribute.Key("graphql.operation.type")
+
+	// GraphqlDocumentKey is the attribute Key conforming to the
+	// "graphql.document" semantic conventions. It represents the GraphQL
+	// document being executed.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'query findBookByID { bookByID(id: ?) { name } }'
+	// Note: The value may be sanitized to exclude sensitive information.
+	GraphqlDocumentKey = attribute.Key("graphql.document")
+)
+
+var (
+	// GraphQL query
+	GraphqlOperationTypeQuery = GraphqlOperationTypeKey.String("query")
+	// GraphQL mutation
+	GraphqlOperationTypeMutation = GraphqlOperationTypeKey.String("mutation")
+	// GraphQL subscription
+	GraphqlOperationTypeSubscription = GraphqlOperationTypeKey.String("subscription")
+)
+
+// GraphqlOperationName returns an attribute KeyValue conforming to the
+// "graphql.operation.name" semantic conventions. It represents the name of the
+// operation being executed.
+func GraphqlOperationName(val string) attribute.KeyValue {
+	return GraphqlOperationNameKey.String(val)
+}
+
+// GraphqlDocument returns an attribute KeyValue conforming to the
+// "graphql.document" semantic conventions. It represents the GraphQL document
+// being executed.
+func GraphqlDocument(val string) attribute.KeyValue {
+	return GraphqlDocumentKey.String(val)
+}
+
+// Semantic convention describing per-message attributes populated on messaging
+// spans or links.
+const (
+	// MessagingMessageIDKey is the attribute Key conforming to the
+	// "messaging.message.id" semantic conventions. It represents a value used
+	// by the messaging system as an identifier for the message, represented as
+	// a string.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '452a7c7c7c7048c2f887f61572b18fc2'
+	MessagingMessageIDKey = attribute.Key("messaging.message.id")
+
+	// MessagingMessageConversationIDKey is the attribute Key conforming to the
+	// "messaging.message.conversation_id" semantic conventions. It represents
+	// the [conversation ID](#conversations) identifying the conversation to
+	// which the message belongs, represented as a string. Sometimes called
+	// "Correlation ID".
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'MyConversationID'
+	MessagingMessageConversationIDKey = attribute.Key("messaging.message.conversation_id")
+
+	// MessagingMessagePayloadSizeBytesKey is the attribute Key conforming to
+	// the "messaging.message.payload_size_bytes" semantic conventions. It
+	// represents the (uncompressed) size of the message payload in bytes. Also
+	// use this attribute if it is unknown whether the compressed or
+	// uncompressed payload size is reported.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 2738
+	MessagingMessagePayloadSizeBytesKey = attribute.Key("messaging.message.payload_size_bytes")
+
+	// MessagingMessagePayloadCompressedSizeBytesKey is the attribute Key
+	// conforming to the "messaging.message.payload_compressed_size_bytes"
+	// semantic conventions. It represents the compressed size of the message
+	// payload in bytes.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 2048
+	MessagingMessagePayloadCompressedSizeBytesKey = attribute.Key("messaging.message.payload_compressed_size_bytes")
+)
+
+// MessagingMessageID returns an attribute KeyValue conforming to the
+// "messaging.message.id" semantic conventions. It represents a value used by
+// the messaging system as an identifier for the message, represented as a
+// string.
+func MessagingMessageID(val string) attribute.KeyValue {
+	return MessagingMessageIDKey.String(val)
+}
+
+// MessagingMessageConversationID returns an attribute KeyValue conforming
+// to the "messaging.message.conversation_id" semantic conventions. It
+// represents the [conversation ID](#conversations) identifying the
+// conversation to which the message belongs, represented as a string.
+// Sometimes called "Correlation ID".
+func MessagingMessageConversationID(val string) attribute.KeyValue {
+	return MessagingMessageConversationIDKey.String(val)
+}
+
+// MessagingMessagePayloadSizeBytes returns an attribute KeyValue conforming
+// to the "messaging.message.payload_size_bytes" semantic conventions. It
+// represents the (uncompressed) size of the message payload in bytes. Also use
+// this attribute if it is unknown whether the compressed or uncompressed
+// payload size is reported.
+func MessagingMessagePayloadSizeBytes(val int) attribute.KeyValue {
+	return MessagingMessagePayloadSizeBytesKey.Int(val)
+}
+
+// MessagingMessagePayloadCompressedSizeBytes returns an attribute KeyValue
+// conforming to the "messaging.message.payload_compressed_size_bytes" semantic
+// conventions. It represents the compressed size of the message payload in
+// bytes.
+func MessagingMessagePayloadCompressedSizeBytes(val int) attribute.KeyValue {
+	return MessagingMessagePayloadCompressedSizeBytesKey.Int(val)
+}
+
+// Semantic convention for attributes that describe messaging destination on
+// broker
+const (
+	// MessagingDestinationNameKey is the attribute Key conforming to the
+	// "messaging.destination.name" semantic conventions. It represents the
+	// message destination name
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'MyQueue', 'MyTopic'
+	// Note: Destination name SHOULD uniquely identify a specific queue, topic
+	// or other entity within the broker. If
+	// the broker does not have such notion, the destination name SHOULD
+	// uniquely identify the broker.
+	MessagingDestinationNameKey = attribute.Key("messaging.destination.name")
+
+	// MessagingDestinationKindKey is the attribute Key conforming to the
+	// "messaging.destination.kind" semantic conventions. It represents the
+	// kind of message destination
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	MessagingDestinationKindKey = attribute.Key("messaging.destination.kind")
+
+	// MessagingDestinationTemplateKey is the attribute Key conforming to the
+	// "messaging.destination.template" semantic conventions. It represents the
+	// low cardinality representation of the messaging destination name
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '/customers/{customerID}'
+	// Note: Destination names could be constructed from templates. An example
+	// would be a destination name involving a user name or product id.
+	// Although the destination name in this case is of high cardinality, the
+	// underlying template is of low cardinality and can be effectively used
+	// for grouping and aggregation.
+	MessagingDestinationTemplateKey = attribute.Key("messaging.destination.template")
+
+	// MessagingDestinationTemporaryKey is the attribute Key conforming to the
+	// "messaging.destination.temporary" semantic conventions. It represents a
+	// boolean that is true if the message destination is temporary and might
+	// not exist anymore after messages are processed.
+	//
+	// Type: boolean
+	// RequirementLevel: Optional
+	// Stability: stable
+	MessagingDestinationTemporaryKey = attribute.Key("messaging.destination.temporary")
+
+	// MessagingDestinationAnonymousKey is the attribute Key conforming to the
+	// "messaging.destination.anonymous" semantic conventions. It represents a
+	// boolean that is true if the message destination is anonymous (could be
+	// unnamed or have auto-generated name).
+	//
+	// Type: boolean
+	// RequirementLevel: Optional
+	// Stability: stable
+	MessagingDestinationAnonymousKey = attribute.Key("messaging.destination.anonymous")
+)
+
+var (
+	// A message sent to a queue
+	MessagingDestinationKindQueue = MessagingDestinationKindKey.String("queue")
+	// A message sent to a topic
+	MessagingDestinationKindTopic = MessagingDestinationKindKey.String("topic")
+)
+
+// MessagingDestinationName returns an attribute KeyValue conforming to the
+// "messaging.destination.name" semantic conventions. It represents the message
+// destination name
+func MessagingDestinationName(val string) attribute.KeyValue {
+	return MessagingDestinationNameKey.String(val)
+}
+
+// MessagingDestinationTemplate returns an attribute KeyValue conforming to
+// the "messaging.destination.template" semantic conventions. It represents the
+// low cardinality representation of the messaging destination name
+func MessagingDestinationTemplate(val string) attribute.KeyValue {
+	return MessagingDestinationTemplateKey.String(val)
+}
+
+// MessagingDestinationTemporary returns an attribute KeyValue conforming to
+// the "messaging.destination.temporary" semantic conventions. It represents a
+// boolean that is true if the message destination is temporary and might not
+// exist anymore after messages are processed.
+func MessagingDestinationTemporary(val bool) attribute.KeyValue {
+	return MessagingDestinationTemporaryKey.Bool(val)
+}
+
+// MessagingDestinationAnonymous returns an attribute KeyValue conforming to
+// the "messaging.destination.anonymous" semantic conventions. It represents a
+// boolean that is true if the message destination is anonymous (could be
+// unnamed or have auto-generated name).
+func MessagingDestinationAnonymous(val bool) attribute.KeyValue {
+	return MessagingDestinationAnonymousKey.Bool(val)
+}
+
+// Semantic convention for attributes that describe messaging source on broker
+const (
+	// MessagingSourceNameKey is the attribute Key conforming to the
+	// "messaging.source.name" semantic conventions. It represents the message
+	// source name
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'MyQueue', 'MyTopic'
+	// Note: Source name SHOULD uniquely identify a specific queue, topic, or
+	// other entity within the broker. If
+	// the broker does not have such notion, the source name SHOULD uniquely
+	// identify the broker.
+	MessagingSourceNameKey = attribute.Key("messaging.source.name")
+
+	// MessagingSourceKindKey is the attribute Key conforming to the
+	// "messaging.source.kind" semantic conventions. It represents the kind of
+	// message source
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	MessagingSourceKindKey = attribute.Key("messaging.source.kind")
+
+	// MessagingSourceTemplateKey is the attribute Key conforming to the
+	// "messaging.source.template" semantic conventions. It represents the low
+	// cardinality representation of the messaging source name
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '/customers/{customerID}'
+	// Note: Source names could be constructed from templates. An example would
+	// be a source name involving a user name or product id. Although the
+	// source name in this case is of high cardinality, the underlying template
+	// is of low cardinality and can be effectively used for grouping and
+	// aggregation.
+	MessagingSourceTemplateKey = attribute.Key("messaging.source.template")
+
+	// MessagingSourceTemporaryKey is the attribute Key conforming to the
+	// "messaging.source.temporary" semantic conventions. It represents a
+	// boolean that is true if the message source is temporary and might not
+	// exist anymore after messages are processed.
+	//
+	// Type: boolean
+	// RequirementLevel: Optional
+	// Stability: stable
+	MessagingSourceTemporaryKey = attribute.Key("messaging.source.temporary")
+
+	// MessagingSourceAnonymousKey is the attribute Key conforming to the
+	// "messaging.source.anonymous" semantic conventions. It represents a
+	// boolean that is true if the message source is anonymous (could be
+	// unnamed or have auto-generated name).
+	//
+	// Type: boolean
+	// RequirementLevel: Optional
+	// Stability: stable
+	MessagingSourceAnonymousKey = attribute.Key("messaging.source.anonymous")
+)
+
+var (
+	// A message received from a queue
+	MessagingSourceKindQueue = MessagingSourceKindKey.String("queue")
+	// A message received from a topic
+	MessagingSourceKindTopic = MessagingSourceKindKey.String("topic")
+)
+
+// MessagingSourceName returns an attribute KeyValue conforming to the
+// "messaging.source.name" semantic conventions. It represents the message
+// source name
+func MessagingSourceName(val string) attribute.KeyValue {
+	return MessagingSourceNameKey.String(val)
+}
+
+// MessagingSourceTemplate returns an attribute KeyValue conforming to the
+// "messaging.source.template" semantic conventions. It represents the low
+// cardinality representation of the messaging source name
+func MessagingSourceTemplate(val string) attribute.KeyValue {
+	return MessagingSourceTemplateKey.String(val)
+}
+
+// MessagingSourceTemporary returns an attribute KeyValue conforming to the
+// "messaging.source.temporary" semantic conventions. It represents a boolean
+// that is true if the message source is temporary and might not exist anymore
+// after messages are processed.
+func MessagingSourceTemporary(val bool) attribute.KeyValue {
+	return MessagingSourceTemporaryKey.Bool(val)
+}
+
+// MessagingSourceAnonymous returns an attribute KeyValue conforming to the
+// "messaging.source.anonymous" semantic conventions. It represents a boolean
+// that is true if the message source is anonymous (could be unnamed or have
+// auto-generated name).
+func MessagingSourceAnonymous(val bool) attribute.KeyValue {
+	return MessagingSourceAnonymousKey.Bool(val)
+}
+
+// General attributes used in messaging systems.
+const (
+	// MessagingSystemKey is the attribute Key conforming to the
+	// "messaging.system" semantic conventions. It represents a string
+	// identifying the messaging system.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'kafka', 'rabbitmq', 'rocketmq', 'activemq', 'AmazonSQS'
+	MessagingSystemKey = attribute.Key("messaging.system")
+
+	// MessagingOperationKey is the attribute Key conforming to the
+	// "messaging.operation" semantic conventions. It represents a string
+	// identifying the kind of messaging operation as defined in the [Operation
+	// names](#operation-names) section above.
+	//
+	// Type: Enum
+	// RequirementLevel: Required
+	// Stability: stable
+	// Note: If a custom value is used, it MUST be of low cardinality.
+	MessagingOperationKey = attribute.Key("messaging.operation")
+
+	// MessagingBatchMessageCountKey is the attribute Key conforming to the
+	// "messaging.batch.message_count" semantic conventions. It represents the
+	// number of messages sent, received, or processed in the scope of the
+	// batching operation.
+	//
+	// Type: int
+	// RequirementLevel: ConditionallyRequired (If the span describes an
+	// operation on a batch of messages.)
+	// Stability: stable
+	// Examples: 0, 1, 2
+	// Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on
+	// spans that operate with a single message. When a messaging client
+	// library supports both batch and single-message API for the same
+	// operation, instrumentations SHOULD use `messaging.batch.message_count`
+	// for batching APIs and SHOULD NOT use it for single-message APIs.
+	MessagingBatchMessageCountKey = attribute.Key("messaging.batch.message_count")
+)
+
+var (
+	// publish
+	MessagingOperationPublish = MessagingOperationKey.String("publish")
+	// receive
+	MessagingOperationReceive = MessagingOperationKey.String("receive")
+	// process
+	MessagingOperationProcess = MessagingOperationKey.String("process")
+)
+
+// MessagingSystem returns an attribute KeyValue conforming to the
+// "messaging.system" semantic conventions. It represents a string identifying
+// the messaging system.
+func MessagingSystem(val string) attribute.KeyValue {
+	return MessagingSystemKey.String(val)
+}
+
+// MessagingBatchMessageCount returns an attribute KeyValue conforming to
+// the "messaging.batch.message_count" semantic conventions. It represents the
+// number of messages sent, received, or processed in the scope of the batching
+// operation.
+func MessagingBatchMessageCount(val int) attribute.KeyValue {
+	return MessagingBatchMessageCountKey.Int(val)
+}
+
+// Semantic convention for a consumer of messages received from a messaging
+// system
+const (
+	// MessagingConsumerIDKey is the attribute Key conforming to the
+	// "messaging.consumer.id" semantic conventions. It represents the
+	// identifier for the consumer receiving a message. For Kafka, set it to
+	// `{messaging.kafka.consumer.group} - {messaging.kafka.client_id}`, if
+	// both are present, or only `messaging.kafka.consumer.group`. For brokers,
+	// such as RabbitMQ and Artemis, set it to the `client_id` of the client
+	// consuming the message.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'mygroup - client-6'
+	MessagingConsumerIDKey = attribute.Key("messaging.consumer.id")
+)
+
+// MessagingConsumerID returns an attribute KeyValue conforming to the
+// "messaging.consumer.id" semantic conventions. It represents the identifier
+// for the consumer receiving a message. For Kafka, set it to
+// `{messaging.kafka.consumer.group} - {messaging.kafka.client_id}`, if both
+// are present, or only `messaging.kafka.consumer.group`. For brokers, such as
+// RabbitMQ and Artemis, set it to the `client_id` of the client consuming the
+// message.
+func MessagingConsumerID(val string) attribute.KeyValue {
+	return MessagingConsumerIDKey.String(val)
+}
+
+// Attributes for RabbitMQ
+const (
+	// MessagingRabbitmqDestinationRoutingKeyKey is the attribute Key
+	// conforming to the "messaging.rabbitmq.destination.routing_key" semantic
+	// conventions. It represents the rabbitMQ message routing key.
+	//
+	// Type: string
+	// RequirementLevel: ConditionallyRequired (If not empty.)
+	// Stability: stable
+	// Examples: 'myKey'
+	MessagingRabbitmqDestinationRoutingKeyKey = attribute.Key("messaging.rabbitmq.destination.routing_key")
+)
+
+// MessagingRabbitmqDestinationRoutingKey returns an attribute KeyValue
+// conforming to the "messaging.rabbitmq.destination.routing_key" semantic
+// conventions. It represents the rabbitMQ message routing key.
+func MessagingRabbitmqDestinationRoutingKey(val string) attribute.KeyValue {
+	return MessagingRabbitmqDestinationRoutingKeyKey.String(val)
+}
+
+// Attributes for Apache Kafka
+const (
+	// MessagingKafkaMessageKeyKey is the attribute Key conforming to the
+	// "messaging.kafka.message.key" semantic conventions. It represents the
+	// message keys in Kafka are used for grouping alike messages to ensure
+	// they're processed on the same partition. They differ from
+	// `messaging.message.id` in that they're not unique. If the key is `null`,
+	// the attribute MUST NOT be set.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'myKey'
+	// Note: If the key type is not string, it's string representation has to
+	// be supplied for the attribute. If the key has no unambiguous, canonical
+	// string form, don't include its value.
+	MessagingKafkaMessageKeyKey = attribute.Key("messaging.kafka.message.key")
+
+	// MessagingKafkaConsumerGroupKey is the attribute Key conforming to the
+	// "messaging.kafka.consumer.group" semantic conventions. It represents the
+	// name of the Kafka Consumer Group that is handling the message. Only
+	// applies to consumers, not producers.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'my-group'
+	MessagingKafkaConsumerGroupKey = attribute.Key("messaging.kafka.consumer.group")
+
+	// MessagingKafkaClientIDKey is the attribute Key conforming to the
+	// "messaging.kafka.client_id" semantic conventions. It represents the
+	// client ID for the Consumer or Producer that is handling the message.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'client-5'
+	MessagingKafkaClientIDKey = attribute.Key("messaging.kafka.client_id")
+
+	// MessagingKafkaDestinationPartitionKey is the attribute Key conforming to
+	// the "messaging.kafka.destination.partition" semantic conventions. It
+	// represents the partition the message is sent to.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 2
+	MessagingKafkaDestinationPartitionKey = attribute.Key("messaging.kafka.destination.partition")
+
+	// MessagingKafkaSourcePartitionKey is the attribute Key conforming to the
+	// "messaging.kafka.source.partition" semantic conventions. It represents
+	// the partition the message is received from.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 2
+	MessagingKafkaSourcePartitionKey = attribute.Key("messaging.kafka.source.partition")
+
+	// MessagingKafkaMessageOffsetKey is the attribute Key conforming to the
+	// "messaging.kafka.message.offset" semantic conventions. It represents the
+	// offset of a record in the corresponding Kafka partition.
+	//
+	// Type: int
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 42
+	MessagingKafkaMessageOffsetKey = attribute.Key("messaging.kafka.message.offset")
+
+	// MessagingKafkaMessageTombstoneKey is the attribute Key conforming to the
+	// "messaging.kafka.message.tombstone" semantic conventions. It represents
+	// a boolean that is true if the message is a tombstone.
+	//
+	// Type: boolean
+	// RequirementLevel: ConditionallyRequired (If value is `true`. When
+	// missing, the value is assumed to be `false`.)
+	// Stability: stable
+	MessagingKafkaMessageTombstoneKey = attribute.Key("messaging.kafka.message.tombstone")
+)
+
+// MessagingKafkaMessageKey returns an attribute KeyValue conforming to the
+// "messaging.kafka.message.key" semantic conventions. It represents the
+// message keys in Kafka are used for grouping alike messages to ensure they're
+// processed on the same partition. They differ from `messaging.message.id` in
+// that they're not unique. If the key is `null`, the attribute MUST NOT be
+// set.
+func MessagingKafkaMessageKey(val string) attribute.KeyValue {
+	return MessagingKafkaMessageKeyKey.String(val)
+}
+
+// MessagingKafkaConsumerGroup returns an attribute KeyValue conforming to
+// the "messaging.kafka.consumer.group" semantic conventions. It represents the
+// name of the Kafka Consumer Group that is handling the message. Only applies
+// to consumers, not producers.
+func MessagingKafkaConsumerGroup(val string) attribute.KeyValue {
+	return MessagingKafkaConsumerGroupKey.String(val)
+}
+
+// MessagingKafkaClientID returns an attribute KeyValue conforming to the
+// "messaging.kafka.client_id" semantic conventions. It represents the client
+// ID for the Consumer or Producer that is handling the message.
+func MessagingKafkaClientID(val string) attribute.KeyValue {
+	return MessagingKafkaClientIDKey.String(val)
+}
+
+// MessagingKafkaDestinationPartition returns an attribute KeyValue
+// conforming to the "messaging.kafka.destination.partition" semantic
+// conventions. It represents the partition the message is sent to.
+func MessagingKafkaDestinationPartition(val int) attribute.KeyValue {
+	return MessagingKafkaDestinationPartitionKey.Int(val)
+}
+
+// MessagingKafkaSourcePartition returns an attribute KeyValue conforming to
+// the "messaging.kafka.source.partition" semantic conventions. It represents
+// the partition the message is received from.
+func MessagingKafkaSourcePartition(val int) attribute.KeyValue {
+	return MessagingKafkaSourcePartitionKey.Int(val)
+}
+
+// MessagingKafkaMessageOffset returns an attribute KeyValue conforming to
+// the "messaging.kafka.message.offset" semantic conventions. It represents the
+// offset of a record in the corresponding Kafka partition.
+func MessagingKafkaMessageOffset(val int) attribute.KeyValue {
+	return MessagingKafkaMessageOffsetKey.Int(val)
+}
+
+// MessagingKafkaMessageTombstone returns an attribute KeyValue conforming
+// to the "messaging.kafka.message.tombstone" semantic conventions. It
+// represents a boolean that is true if the message is a tombstone.
+func MessagingKafkaMessageTombstone(val bool) attribute.KeyValue {
+	return MessagingKafkaMessageTombstoneKey.Bool(val)
+}
+
+// Attributes for Apache RocketMQ
+const (
+	// MessagingRocketmqNamespaceKey is the attribute Key conforming to the
+	// "messaging.rocketmq.namespace" semantic conventions. It represents the
+	// namespace of RocketMQ resources, resources in different namespaces are
+	// individual.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'myNamespace'
+	MessagingRocketmqNamespaceKey = attribute.Key("messaging.rocketmq.namespace")
+
+	// MessagingRocketmqClientGroupKey is the attribute Key conforming to the
+	// "messaging.rocketmq.client_group" semantic conventions. It represents
+	// the name of the RocketMQ producer/consumer group that is handling the
+	// message. The client type is identified by the SpanKind.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'myConsumerGroup'
+	MessagingRocketmqClientGroupKey = attribute.Key("messaging.rocketmq.client_group")
+
+	// MessagingRocketmqClientIDKey is the attribute Key conforming to the
+	// "messaging.rocketmq.client_id" semantic conventions. It represents the
+	// unique identifier for each client.
+	//
+	// Type: string
+	// RequirementLevel: Required
+	// Stability: stable
+	// Examples: 'myhost@8742@s8083jm'
+	MessagingRocketmqClientIDKey = attribute.Key("messaging.rocketmq.client_id")
+
+	// MessagingRocketmqMessageDeliveryTimestampKey is the attribute Key
+	// conforming to the "messaging.rocketmq.message.delivery_timestamp"
+	// semantic conventions. It represents the timestamp in milliseconds that
+	// the delay message is expected to be delivered to consumer.
+	//
+	// Type: int
+	// RequirementLevel: ConditionallyRequired (If the message type is delay
+	// and delay time level is not specified.)
+	// Stability: stable
+	// Examples: 1665987217045
+	MessagingRocketmqMessageDeliveryTimestampKey = attribute.Key("messaging.rocketmq.message.delivery_timestamp")
+
+	// MessagingRocketmqMessageDelayTimeLevelKey is the attribute Key
+	// conforming to the "messaging.rocketmq.message.delay_time_level" semantic
+	// conventions. It represents the delay time level for delay message, which
+	// determines the message delay time.
+	//
+	// Type: int
+	// RequirementLevel: ConditionallyRequired (If the message type is delay
+	// and delivery timestamp is not specified.)
+	// Stability: stable
+	// Examples: 3
+	MessagingRocketmqMessageDelayTimeLevelKey = attribute.Key("messaging.rocketmq.message.delay_time_level")
+
+	// MessagingRocketmqMessageGroupKey is the attribute Key conforming to the
+	// "messaging.rocketmq.message.group" semantic conventions. It represents
+	// the it is essential for FIFO message. Messages that belong to the same
+	// message group are always processed one by one within the same consumer
+	// group.
+	//
+	// Type: string
+	// RequirementLevel: ConditionallyRequired (If the message type is FIFO.)
+	// Stability: stable
+	// Examples: 'myMessageGroup'
+	MessagingRocketmqMessageGroupKey = attribute.Key("messaging.rocketmq.message.group")
+
+	// MessagingRocketmqMessageTypeKey is the attribute Key conforming to the
+	// "messaging.rocketmq.message.type" semantic conventions. It represents
+	// the type of message.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	MessagingRocketmqMessageTypeKey = attribute.Key("messaging.rocketmq.message.type")
+
+	// MessagingRocketmqMessageTagKey is the attribute Key conforming to the
+	// "messaging.rocketmq.message.tag" semantic conventions. It represents the
+	// secondary classifier of message besides topic.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'tagA'
+	MessagingRocketmqMessageTagKey = attribute.Key("messaging.rocketmq.message.tag")
+
+	// MessagingRocketmqMessageKeysKey is the attribute Key conforming to the
+	// "messaging.rocketmq.message.keys" semantic conventions. It represents
+	// the key(s) of message, another way to mark message besides message id.
+	//
+	// Type: string[]
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'keyA', 'keyB'
+	MessagingRocketmqMessageKeysKey = attribute.Key("messaging.rocketmq.message.keys")
+
+	// MessagingRocketmqConsumptionModelKey is the attribute Key conforming to
+	// the "messaging.rocketmq.consumption_model" semantic conventions. It
+	// represents the model of message consumption. This only applies to
+	// consumer spans.
+	//
+	// Type: Enum
+	// RequirementLevel: Optional
+	// Stability: stable
+	MessagingRocketmqConsumptionModelKey = attribute.Key("messaging.rocketmq.consumption_model")
+)
+
+var (
+	// Normal message
+	MessagingRocketmqMessageTypeNormal = MessagingRocketmqMessageTypeKey.String("normal")
+	// FIFO message
+	MessagingRocketmqMessageTypeFifo = MessagingRocketmqMessageTypeKey.String("fifo")
+	// Delay message
+	MessagingRocketmqMessageTypeDelay = MessagingRocketmqMessageTypeKey.String("delay")
+	// Transaction message
+	MessagingRocketmqMessageTypeTransaction = MessagingRocketmqMessageTypeKey.String("transaction")
+)
+
+var (
+	// Clustering consumption model
+	MessagingRocketmqConsumptionModelClustering = MessagingRocketmqConsumptionModelKey.String("clustering")
+	// Broadcasting consumption model
+	MessagingRocketmqConsumptionModelBroadcasting = MessagingRocketmqConsumptionModelKey.String("broadcasting")
+)
+
+// MessagingRocketmqNamespace returns an attribute KeyValue conforming to
+// the "messaging.rocketmq.namespace" semantic conventions. It represents the
+// namespace of RocketMQ resources, resources in different namespaces are
+// individual.
+func MessagingRocketmqNamespace(val string) attribute.KeyValue {
+	return MessagingRocketmqNamespaceKey.String(val)
+}
+
+// MessagingRocketmqClientGroup returns an attribute KeyValue conforming to
+// the "messaging.rocketmq.client_group" semantic conventions. It represents
+// the name of the RocketMQ producer/consumer group that is handling the
+// message. The client type is identified by the SpanKind.
+func MessagingRocketmqClientGroup(val string) attribute.KeyValue {
+	return MessagingRocketmqClientGroupKey.String(val)
+}
+
+// MessagingRocketmqClientID returns an attribute KeyValue conforming to the
+// "messaging.rocketmq.client_id" semantic conventions. It represents the
+// unique identifier for each client.
+func MessagingRocketmqClientID(val string) attribute.KeyValue {
+	return MessagingRocketmqClientIDKey.String(val)
+}
+
+// MessagingRocketmqMessageDeliveryTimestamp returns an attribute KeyValue
+// conforming to the "messaging.rocketmq.message.delivery_timestamp" semantic
+// conventions. It represents the timestamp in milliseconds that the delay
+// message is expected to be delivered to consumer.
+func MessagingRocketmqMessageDeliveryTimestamp(val int) attribute.KeyValue {
+	return MessagingRocketmqMessageDeliveryTimestampKey.Int(val)
+}
+
+// MessagingRocketmqMessageDelayTimeLevel returns an attribute KeyValue
+// conforming to the "messaging.rocketmq.message.delay_time_level" semantic
+// conventions. It represents the delay time level for delay message, which
+// determines the message delay time.
+func MessagingRocketmqMessageDelayTimeLevel(val int) attribute.KeyValue {
+	return MessagingRocketmqMessageDelayTimeLevelKey.Int(val)
+}
+
+// MessagingRocketmqMessageGroup returns an attribute KeyValue conforming to
+// the "messaging.rocketmq.message.group" semantic conventions. It represents
+// the it is essential for FIFO message. Messages that belong to the same
+// message group are always processed one by one within the same consumer
+// group.
+func MessagingRocketmqMessageGroup(val string) attribute.KeyValue {
+	return MessagingRocketmqMessageGroupKey.String(val)
+}
+
+// MessagingRocketmqMessageTag returns an attribute KeyValue conforming to
+// the "messaging.rocketmq.message.tag" semantic conventions. It represents the
+// secondary classifier of message besides topic.
+func MessagingRocketmqMessageTag(val string) attribute.KeyValue {
+	return MessagingRocketmqMessageTagKey.String(val)
+}
+
+// MessagingRocketmqMessageKeys returns an attribute KeyValue conforming to
+// the "messaging.rocketmq.message.keys" semantic conventions. It represents
+// the key(s) of message, another way to mark message besides message id.
+func MessagingRocketmqMessageKeys(val ...string) attribute.KeyValue {
+	return MessagingRocketmqMessageKeysKey.StringSlice(val)
+}
+
+// Semantic conventions for remote procedure calls.
+const (
+	// RPCSystemKey is the attribute Key conforming to the "rpc.system"
+	// semantic conventions. It represents a string identifying the remoting
+	// system. See below for a list of well-known identifiers.
+	//
+	// Type: Enum
+	// RequirementLevel: Required
+	// Stability: stable
+	RPCSystemKey = attribute.Key("rpc.system")
+
+	// RPCServiceKey is the attribute Key conforming to the "rpc.service"
+	// semantic conventions. It represents the full (logical) name of the
+	// service being called, including its package name, if applicable.
+	//
+	// Type: string
+	// RequirementLevel: Recommended
+	// Stability: stable
+	// Examples: 'myservice.EchoService'
+	// Note: This is the logical name of the service from the RPC interface
+	// perspective, which can be different from the name of any implementing
+	// class. The `code.namespace` attribute may be used to store the latter
+	// (despite the attribute name, it may include a class name; e.g., class
+	// with method actually executing the call on the server side, RPC client
+	// stub class on the client side).
+	RPCServiceKey = attribute.Key("rpc.service")
+
+	// RPCMethodKey is the attribute Key conforming to the "rpc.method"
+	// semantic conventions. It represents the name of the (logical) method
+	// being called, must be equal to the $method part in the span name.
+	//
+	// Type: string
+	// RequirementLevel: Recommended
+	// Stability: stable
+	// Examples: 'exampleMethod'
+	// Note: This is the logical name of the method from the RPC interface
+	// perspective, which can be different from the name of any implementing
+	// method/function. The `code.function` attribute may be used to store the
+	// latter (e.g., method actually executing the call on the server side, RPC
+	// client stub method on the client side).
+	RPCMethodKey = attribute.Key("rpc.method")
+)
+
+var (
+	// gRPC
+	RPCSystemGRPC = RPCSystemKey.String("grpc")
+	// Java RMI
+	RPCSystemJavaRmi = RPCSystemKey.String("java_rmi")
+	// .NET WCF
+	RPCSystemDotnetWcf = RPCSystemKey.String("dotnet_wcf")
+	// Apache Dubbo
+	RPCSystemApacheDubbo = RPCSystemKey.String("apache_dubbo")
+)
+
+// RPCService returns an attribute KeyValue conforming to the "rpc.service"
+// semantic conventions. It represents the full (logical) name of the service
+// being called, including its package name, if applicable.
+func RPCService(val string) attribute.KeyValue {
+	return RPCServiceKey.String(val)
+}
+
+// RPCMethod returns an attribute KeyValue conforming to the "rpc.method"
+// semantic conventions. It represents the name of the (logical) method being
+// called, must be equal to the $method part in the span name.
+func RPCMethod(val string) attribute.KeyValue {
+	return RPCMethodKey.String(val)
+}
+
+// Tech-specific attributes for gRPC.
+const (
+	// RPCGRPCStatusCodeKey is the attribute Key conforming to the
+	// "rpc.grpc.status_code" semantic conventions. It represents the [numeric
+	// status
+	// code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of
+	// the gRPC request.
+	//
+	// Type: Enum
+	// RequirementLevel: Required
+	// Stability: stable
+	RPCGRPCStatusCodeKey = attribute.Key("rpc.grpc.status_code")
+)
+
+var (
+	// OK
+	RPCGRPCStatusCodeOk = RPCGRPCStatusCodeKey.Int(0)
+	// CANCELLED
+	RPCGRPCStatusCodeCancelled = RPCGRPCStatusCodeKey.Int(1)
+	// UNKNOWN
+	RPCGRPCStatusCodeUnknown = RPCGRPCStatusCodeKey.Int(2)
+	// INVALID_ARGUMENT
+	RPCGRPCStatusCodeInvalidArgument = RPCGRPCStatusCodeKey.Int(3)
+	// DEADLINE_EXCEEDED
+	RPCGRPCStatusCodeDeadlineExceeded = RPCGRPCStatusCodeKey.Int(4)
+	// NOT_FOUND
+	RPCGRPCStatusCodeNotFound = RPCGRPCStatusCodeKey.Int(5)
+	// ALREADY_EXISTS
+	RPCGRPCStatusCodeAlreadyExists = RPCGRPCStatusCodeKey.Int(6)
+	// PERMISSION_DENIED
+	RPCGRPCStatusCodePermissionDenied = RPCGRPCStatusCodeKey.Int(7)
+	// RESOURCE_EXHAUSTED
+	RPCGRPCStatusCodeResourceExhausted = RPCGRPCStatusCodeKey.Int(8)
+	// FAILED_PRECONDITION
+	RPCGRPCStatusCodeFailedPrecondition = RPCGRPCStatusCodeKey.Int(9)
+	// ABORTED
+	RPCGRPCStatusCodeAborted = RPCGRPCStatusCodeKey.Int(10)
+	// OUT_OF_RANGE
+	RPCGRPCStatusCodeOutOfRange = RPCGRPCStatusCodeKey.Int(11)
+	// UNIMPLEMENTED
+	RPCGRPCStatusCodeUnimplemented = RPCGRPCStatusCodeKey.Int(12)
+	// INTERNAL
+	RPCGRPCStatusCodeInternal = RPCGRPCStatusCodeKey.Int(13)
+	// UNAVAILABLE
+	RPCGRPCStatusCodeUnavailable = RPCGRPCStatusCodeKey.Int(14)
+	// DATA_LOSS
+	RPCGRPCStatusCodeDataLoss = RPCGRPCStatusCodeKey.Int(15)
+	// UNAUTHENTICATED
+	RPCGRPCStatusCodeUnauthenticated = RPCGRPCStatusCodeKey.Int(16)
+)
+
+// Tech-specific attributes for [JSON RPC](https://www.jsonrpc.org/).
+const (
+	// RPCJsonrpcVersionKey is the attribute Key conforming to the
+	// "rpc.jsonrpc.version" semantic conventions. It represents the protocol
+	// version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0
+	// does not specify this, the value can be omitted.
+	//
+	// Type: string
+	// RequirementLevel: ConditionallyRequired (If other than the default
+	// version (`1.0`))
+	// Stability: stable
+	// Examples: '2.0', '1.0'
+	RPCJsonrpcVersionKey = attribute.Key("rpc.jsonrpc.version")
+
+	// RPCJsonrpcRequestIDKey is the attribute Key conforming to the
+	// "rpc.jsonrpc.request_id" semantic conventions. It represents the `id`
+	// property of request or response. Since protocol allows id to be int,
+	// string, `null` or missing (for notifications), value is expected to be
+	// cast to string for simplicity. Use empty string in case of `null` value.
+	// Omit entirely if this is a notification.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: '10', 'request-7', ''
+	RPCJsonrpcRequestIDKey = attribute.Key("rpc.jsonrpc.request_id")
+
+	// RPCJsonrpcErrorCodeKey is the attribute Key conforming to the
+	// "rpc.jsonrpc.error_code" semantic conventions. It represents the
+	// `error.code` property of response if it is an error response.
+	//
+	// Type: int
+	// RequirementLevel: ConditionallyRequired (If response is not successful.)
+	// Stability: stable
+	// Examples: -32700, 100
+	RPCJsonrpcErrorCodeKey = attribute.Key("rpc.jsonrpc.error_code")
+
+	// RPCJsonrpcErrorMessageKey is the attribute Key conforming to the
+	// "rpc.jsonrpc.error_message" semantic conventions. It represents the
+	// `error.message` property of response if it is an error response.
+	//
+	// Type: string
+	// RequirementLevel: Optional
+	// Stability: stable
+	// Examples: 'Parse error', 'User already exists'
+	RPCJsonrpcErrorMessageKey = attribute.Key("rpc.jsonrpc.error_message")
+)
+
+// RPCJsonrpcVersion returns an attribute KeyValue conforming to the
+// "rpc.jsonrpc.version" semantic conventions. It represents the protocol
+// version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0
+// does not specify this, the value can be omitted.
+func RPCJsonrpcVersion(val string) attribute.KeyValue {
+	return RPCJsonrpcVersionKey.String(val)
+}
+
+// RPCJsonrpcRequestID returns an attribute KeyValue conforming to the
+// "rpc.jsonrpc.request_id" semantic conventions. It represents the `id`
+// property of request or response. Since protocol allows id to be int, string,
+// `null` or missing (for notifications), value is expected to be cast to
+// string for simplicity. Use empty string in case of `null` value. Omit
+// entirely if this is a notification.
+func RPCJsonrpcRequestID(val string) attribute.KeyValue {
+	return RPCJsonrpcRequestIDKey.String(val)
+}
+
+// RPCJsonrpcErrorCode returns an attribute KeyValue conforming to the
+// "rpc.jsonrpc.error_code" semantic conventions. It represents the
+// `error.code` property of response if it is an error response.
+func RPCJsonrpcErrorCode(val int) attribute.KeyValue {
+	return RPCJsonrpcErrorCodeKey.Int(val)
+}
+
+// RPCJsonrpcErrorMessage returns an attribute KeyValue conforming to the
+// "rpc.jsonrpc.error_message" semantic conventions. It represents the
+// `error.message` property of response if it is an error response.
+func RPCJsonrpcErrorMessage(val string) attribute.KeyValue {
+	return RPCJsonrpcErrorMessageKey.String(val)
+}
diff --git a/vendor/go.opentelemetry.io/otel/trace.go b/vendor/go.opentelemetry.io/otel/trace.go
index caf7249d..6836c654 100644
--- a/vendor/go.opentelemetry.io/otel/trace.go
+++ b/vendor/go.opentelemetry.io/otel/trace.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package otel // import "go.opentelemetry.io/otel"
 
diff --git a/vendor/go.opentelemetry.io/otel/trace/README.md b/vendor/go.opentelemetry.io/otel/trace/README.md
new file mode 100644
index 00000000..58ccaba6
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/trace/README.md
@@ -0,0 +1,3 @@
+# Trace API
+
+[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/trace)](https://pkg.go.dev/go.opentelemetry.io/otel/trace)
diff --git a/vendor/go.opentelemetry.io/otel/trace/config.go b/vendor/go.opentelemetry.io/otel/trace/config.go
index cb3efbb9..273d58e0 100644
--- a/vendor/go.opentelemetry.io/otel/trace/config.go
+++ b/vendor/go.opentelemetry.io/otel/trace/config.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package trace // import "go.opentelemetry.io/otel/trace"
 
@@ -268,6 +257,7 @@ func (o stackTraceOption) applyEvent(c EventConfig) EventConfig {
 	c.stackTrace = bool(o)
 	return c
 }
+
 func (o stackTraceOption) applySpan(c SpanConfig) SpanConfig {
 	c.stackTrace = bool(o)
 	return c
diff --git a/vendor/go.opentelemetry.io/otel/trace/context.go b/vendor/go.opentelemetry.io/otel/trace/context.go
index 76f9a083..5650a174 100644
--- a/vendor/go.opentelemetry.io/otel/trace/context.go
+++ b/vendor/go.opentelemetry.io/otel/trace/context.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package trace // import "go.opentelemetry.io/otel/trace"
 
@@ -47,12 +36,12 @@ func ContextWithRemoteSpanContext(parent context.Context, rsc SpanContext) conte
 // performs no operations is returned.
 func SpanFromContext(ctx context.Context) Span {
 	if ctx == nil {
-		return noopSpan{}
+		return noopSpanInstance
 	}
 	if span, ok := ctx.Value(currentSpanKey).(Span); ok {
 		return span
 	}
-	return noopSpan{}
+	return noopSpanInstance
 }
 
 // SpanContextFromContext returns the current Span's SpanContext.
diff --git a/vendor/go.opentelemetry.io/otel/trace/doc.go b/vendor/go.opentelemetry.io/otel/trace/doc.go
index ab0346f9..d661c5d1 100644
--- a/vendor/go.opentelemetry.io/otel/trace/doc.go
+++ b/vendor/go.opentelemetry.io/otel/trace/doc.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 /*
 Package trace provides an implementation of the tracing part of the
@@ -62,5 +51,69 @@ a default.
 		defer span.End()
 		// ...
 	}
+
+# API Implementations
+
+This package does not conform to the standard Go versioning policy; all of its
+interfaces may have methods added to them without a package major version bump.
+This non-standard API evolution could surprise an uninformed implementation
+author. They could unknowingly build their implementation in a way that would
+result in a runtime panic for their users that update to the new API.
+
+The API is designed to help inform an instrumentation author about this
+non-standard API evolution. It requires them to choose a default behavior for
+unimplemented interface methods. There are three behavior choices they can
+make:
+
+  - Compilation failure
+  - Panic
+  - Default to another implementation
+
+All interfaces in this API embed a corresponding interface from
+[go.opentelemetry.io/otel/trace/embedded]. If an author wants the default
+behavior of their implementations to be a compilation failure, signaling to
+their users they need to update to the latest version of that implementation,
+they need to embed the corresponding interface from
+[go.opentelemetry.io/otel/trace/embedded] in their implementation. For
+example,
+
+	import "go.opentelemetry.io/otel/trace/embedded"
+
+	type TracerProvider struct {
+		embedded.TracerProvider
+		// ...
+	}
+
+If an author wants the default behavior of their implementations to panic, they
+can embed the API interface directly.
+
+	import "go.opentelemetry.io/otel/trace"
+
+	type TracerProvider struct {
+		trace.TracerProvider
+		// ...
+	}
+
+This option is not recommended. It will lead to publishing packages that
+contain runtime panics when users update to newer versions of
+[go.opentelemetry.io/otel/trace], which may be done with a trasitive
+dependency.
+
+Finally, an author can embed another implementation in theirs. The embedded
+implementation will be used for methods not defined by the author. For example,
+an author who wants to default to silently dropping the call can use
+[go.opentelemetry.io/otel/trace/noop]:
+
+	import "go.opentelemetry.io/otel/trace/noop"
+
+	type TracerProvider struct {
+		noop.TracerProvider
+		// ...
+	}
+
+It is strongly recommended that authors only embed
+[go.opentelemetry.io/otel/trace/noop] if they choose this default behavior.
+That implementation is the only one OpenTelemetry authors can guarantee will
+fully implement all the API interfaces when a user updates their API.
 */
 package trace // import "go.opentelemetry.io/otel/trace"
diff --git a/vendor/go.opentelemetry.io/otel/trace/embedded/README.md b/vendor/go.opentelemetry.io/otel/trace/embedded/README.md
new file mode 100644
index 00000000..7754a239
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/trace/embedded/README.md
@@ -0,0 +1,3 @@
+# Trace Embedded
+
+[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/trace/embedded)](https://pkg.go.dev/go.opentelemetry.io/otel/trace/embedded)
diff --git a/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go b/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go
new file mode 100644
index 00000000..3e359a00
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go
@@ -0,0 +1,45 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Package embedded provides interfaces embedded within the [OpenTelemetry
+// trace API].
+//
+// Implementers of the [OpenTelemetry trace API] can embed the relevant type
+// from this package into their implementation directly. Doing so will result
+// in a compilation error for users when the [OpenTelemetry trace API] is
+// extended (which is something that can happen without a major version bump of
+// the API package).
+//
+// [OpenTelemetry trace API]: https://pkg.go.dev/go.opentelemetry.io/otel/trace
+package embedded // import "go.opentelemetry.io/otel/trace/embedded"
+
+// TracerProvider is embedded in
+// [go.opentelemetry.io/otel/trace.TracerProvider].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/trace.TracerProvider] if you want users to
+// experience a compilation error, signaling they need to update to your latest
+// implementation, when the [go.opentelemetry.io/otel/trace.TracerProvider]
+// interface is extended (which is something that can happen without a major
+// version bump of the API package).
+type TracerProvider interface{ tracerProvider() }
+
+// Tracer is embedded in [go.opentelemetry.io/otel/trace.Tracer].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/trace.Tracer] if you want users to experience a
+// compilation error, signaling they need to update to your latest
+// implementation, when the [go.opentelemetry.io/otel/trace.Tracer] interface
+// is extended (which is something that can happen without a major version bump
+// of the API package).
+type Tracer interface{ tracer() }
+
+// Span is embedded in [go.opentelemetry.io/otel/trace.Span].
+//
+// Embed this interface in your implementation of the
+// [go.opentelemetry.io/otel/trace.Span] if you want users to experience a
+// compilation error, signaling they need to update to your latest
+// implementation, when the [go.opentelemetry.io/otel/trace.Span] interface is
+// extended (which is something that can happen without a major version bump of
+// the API package).
+type Span interface{ span() }
diff --git a/vendor/go.opentelemetry.io/otel/trace/nonrecording.go b/vendor/go.opentelemetry.io/otel/trace/nonrecording.go
index 88fcb816..c00221e7 100644
--- a/vendor/go.opentelemetry.io/otel/trace/nonrecording.go
+++ b/vendor/go.opentelemetry.io/otel/trace/nonrecording.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package trace // import "go.opentelemetry.io/otel/trace"
 
diff --git a/vendor/go.opentelemetry.io/otel/trace/noop.go b/vendor/go.opentelemetry.io/otel/trace/noop.go
index 73950f20..ca20e999 100644
--- a/vendor/go.opentelemetry.io/otel/trace/noop.go
+++ b/vendor/go.opentelemetry.io/otel/trace/noop.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package trace // import "go.opentelemetry.io/otel/trace"
 
@@ -19,16 +8,20 @@ import (
 
 	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/trace/embedded"
 )
 
 // NewNoopTracerProvider returns an implementation of TracerProvider that
 // performs no operations. The Tracer and Spans created from the returned
 // TracerProvider also perform no operations.
+//
+// Deprecated: Use [go.opentelemetry.io/otel/trace/noop.NewTracerProvider]
+// instead.
 func NewNoopTracerProvider() TracerProvider {
 	return noopTracerProvider{}
 }
 
-type noopTracerProvider struct{}
+type noopTracerProvider struct{ embedded.TracerProvider }
 
 var _ TracerProvider = noopTracerProvider{}
 
@@ -37,8 +30,8 @@ func (p noopTracerProvider) Tracer(string, ...TracerOption) Tracer {
 	return noopTracer{}
 }
 
-// noopTracer is an implementation of Tracer that preforms no operations.
-type noopTracer struct{}
+// noopTracer is an implementation of Tracer that performs no operations.
+type noopTracer struct{ embedded.Tracer }
 
 var _ Tracer = noopTracer{}
 
@@ -48,15 +41,15 @@ func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanStartOption
 	span := SpanFromContext(ctx)
 	if _, ok := span.(nonRecordingSpan); !ok {
 		// span is likely already a noopSpan, but let's be sure
-		span = noopSpan{}
+		span = noopSpanInstance
 	}
 	return ContextWithSpan(ctx, span), span
 }
 
-// noopSpan is an implementation of Span that preforms no operations.
-type noopSpan struct{}
+// noopSpan is an implementation of Span that performs no operations.
+type noopSpan struct{ embedded.Span }
 
-var _ Span = noopSpan{}
+var noopSpanInstance Span = noopSpan{}
 
 // SpanContext returns an empty span context.
 func (noopSpan) SpanContext() SpanContext { return SpanContext{} }
@@ -82,6 +75,9 @@ func (noopSpan) RecordError(error, ...EventOption) {}
 // AddEvent does nothing.
 func (noopSpan) AddEvent(string, ...EventOption) {}
 
+// AddLink does nothing.
+func (noopSpan) AddLink(Link) {}
+
 // SetName does nothing.
 func (noopSpan) SetName(string) {}
 
diff --git a/vendor/go.opentelemetry.io/otel/trace/trace.go b/vendor/go.opentelemetry.io/otel/trace/trace.go
index 4aa94f79..28877d4a 100644
--- a/vendor/go.opentelemetry.io/otel/trace/trace.go
+++ b/vendor/go.opentelemetry.io/otel/trace/trace.go
@@ -1,16 +1,5 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package trace // import "go.opentelemetry.io/otel/trace"
 
@@ -22,6 +11,7 @@ import (
 
 	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/codes"
+	"go.opentelemetry.io/otel/trace/embedded"
 )
 
 const (
@@ -48,8 +38,10 @@ func (e errorConst) Error() string {
 // nolint:revive // revive complains about stutter of `trace.TraceID`.
 type TraceID [16]byte
 
-var nilTraceID TraceID
-var _ json.Marshaler = nilTraceID
+var (
+	nilTraceID TraceID
+	_          json.Marshaler = nilTraceID
+)
 
 // IsValid checks whether the trace TraceID is valid. A valid trace ID does
 // not consist of zeros only.
@@ -71,8 +63,10 @@ func (t TraceID) String() string {
 // SpanID is a unique identity of a span in a trace.
 type SpanID [8]byte
 
-var nilSpanID SpanID
-var _ json.Marshaler = nilSpanID
+var (
+	nilSpanID SpanID
+	_         json.Marshaler = nilSpanID
+)
 
 // IsValid checks whether the SpanID is valid. A valid SpanID does not consist
 // of zeros only.
@@ -338,8 +332,15 @@ func (sc SpanContext) MarshalJSON() ([]byte, error) {
 // create a Span and it is then up to the operation the Span represents to
 // properly end the Span when the operation itself ends.
 //
-// Warning: methods may be added to this interface in minor releases.
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
 type Span interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Span
+
 	// End completes the Span. The Span is considered complete and ready to be
 	// delivered through the rest of the telemetry pipeline after this method
 	// is called. Therefore, updates to the Span are not allowed after this
@@ -349,6 +350,12 @@ type Span interface {
 	// AddEvent adds an event with the provided name and options.
 	AddEvent(name string, options ...EventOption)
 
+	// AddLink adds a link.
+	// Adding links at span creation using WithLinks is preferred to calling AddLink
+	// later, for contexts that are available during span creation, because head
+	// sampling decisions can only consider information present during span creation.
+	AddLink(link Link)
+
 	// IsRecording returns the recording state of the Span. It will return
 	// true if the Span is active and events can be recorded.
 	IsRecording() bool
@@ -486,8 +493,15 @@ func (sk SpanKind) String() string {
 
 // Tracer is the creator of Spans.
 //
-// Warning: methods may be added to this interface in minor releases.
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
 type Tracer interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.Tracer
+
 	// Start creates a span and a context.Context containing the newly-created span.
 	//
 	// If the context.Context provided in `ctx` contains a Span then the newly-created
@@ -518,8 +532,15 @@ type Tracer interface {
 // at runtime from its users or it can simply use the globally registered one
 // (see https://pkg.go.dev/go.opentelemetry.io/otel#GetTracerProvider).
 //
-// Warning: methods may be added to this interface in minor releases.
+// Warning: Methods may be added to this interface in minor releases. See
+// package documentation on API implementation for information on how to set
+// default behavior for unimplemented methods.
 type TracerProvider interface {
+	// Users of the interface can ignore this. This embedded type is only used
+	// by implementations of this interface. See the "API Implementations"
+	// section of the package documentation for more information.
+	embedded.TracerProvider
+
 	// Tracer returns a unique Tracer scoped to be used by instrumentation code
 	// to trace computational workflows. The scope and identity of that
 	// instrumentation code is uniquely defined by the name and options passed.
diff --git a/vendor/go.opentelemetry.io/otel/trace/tracestate.go b/vendor/go.opentelemetry.io/otel/trace/tracestate.go
index ca68a82e..20b5cf24 100644
--- a/vendor/go.opentelemetry.io/otel/trace/tracestate.go
+++ b/vendor/go.opentelemetry.io/otel/trace/tracestate.go
@@ -1,36 +1,19 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package trace // import "go.opentelemetry.io/otel/trace"
 
 import (
 	"encoding/json"
 	"fmt"
-	"regexp"
 	"strings"
 )
 
 const (
 	maxListMembers = 32
 
-	listDelimiter = ","
-
-	// based on the W3C Trace Context specification, see
-	// https://www.w3.org/TR/trace-context-1/#tracestate-header
-	noTenantKeyFormat   = `[a-z][_0-9a-z\-\*\/]{0,255}`
-	withTenantKeyFormat = `[a-z0-9][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}`
-	valueFormat         = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]`
+	listDelimiters  = ","
+	memberDelimiter = "="
 
 	errInvalidKey    errorConst = "invalid tracestate key"
 	errInvalidValue  errorConst = "invalid tracestate value"
@@ -39,43 +22,138 @@ const (
 	errDuplicate     errorConst = "duplicate list-member in tracestate"
 )
 
-var (
-	keyRe    = regexp.MustCompile(`^((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))$`)
-	valueRe  = regexp.MustCompile(`^(` + valueFormat + `)$`)
-	memberRe = regexp.MustCompile(`^\s*((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))=(` + valueFormat + `)\s*$`)
-)
-
 type member struct {
 	Key   string
 	Value string
 }
 
+// according to (chr = %x20 / (nblk-char = %x21-2B / %x2D-3C / %x3E-7E) )
+// means (chr = %x20-2B / %x2D-3C / %x3E-7E) .
+func checkValueChar(v byte) bool {
+	return v >= '\x20' && v <= '\x7e' && v != '\x2c' && v != '\x3d'
+}
+
+// according to (nblk-chr = %x21-2B / %x2D-3C / %x3E-7E) .
+func checkValueLast(v byte) bool {
+	return v >= '\x21' && v <= '\x7e' && v != '\x2c' && v != '\x3d'
+}
+
+// based on the W3C Trace Context specification
+//
+//	value    = (0*255(chr)) nblk-chr
+//	nblk-chr = %x21-2B / %x2D-3C / %x3E-7E
+//	chr      = %x20 / nblk-chr
+//
+// see https://www.w3.org/TR/trace-context-1/#value
+func checkValue(val string) bool {
+	n := len(val)
+	if n == 0 || n > 256 {
+		return false
+	}
+	for i := 0; i < n-1; i++ {
+		if !checkValueChar(val[i]) {
+			return false
+		}
+	}
+	return checkValueLast(val[n-1])
+}
+
+func checkKeyRemain(key string) bool {
+	// ( lcalpha / DIGIT / "_" / "-"/ "*" / "/" )
+	for _, v := range key {
+		if isAlphaNum(byte(v)) {
+			continue
+		}
+		switch v {
+		case '_', '-', '*', '/':
+			continue
+		}
+		return false
+	}
+	return true
+}
+
+// according to
+//
+//	simple-key = lcalpha (0*255( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ))
+//	system-id = lcalpha (0*13( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ))
+//
+// param n is remain part length, should be 255 in simple-key or 13 in system-id.
+func checkKeyPart(key string, n int) bool {
+	if len(key) == 0 {
+		return false
+	}
+	first := key[0] // key's first char
+	ret := len(key[1:]) <= n
+	ret = ret && first >= 'a' && first <= 'z'
+	return ret && checkKeyRemain(key[1:])
+}
+
+func isAlphaNum(c byte) bool {
+	if c >= 'a' && c <= 'z' {
+		return true
+	}
+	return c >= '0' && c <= '9'
+}
+
+// according to
+//
+//	tenant-id = ( lcalpha / DIGIT ) 0*240( lcalpha / DIGIT / "_" / "-"/ "*" / "/" )
+//
+// param n is remain part length, should be 240 exactly.
+func checkKeyTenant(key string, n int) bool {
+	if len(key) == 0 {
+		return false
+	}
+	return isAlphaNum(key[0]) && len(key[1:]) <= n && checkKeyRemain(key[1:])
+}
+
+// based on the W3C Trace Context specification
+//
+//	key = simple-key / multi-tenant-key
+//	simple-key = lcalpha (0*255( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ))
+//	multi-tenant-key = tenant-id "@" system-id
+//	tenant-id = ( lcalpha / DIGIT ) (0*240( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ))
+//	system-id = lcalpha (0*13( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ))
+//	lcalpha    = %x61-7A ; a-z
+//
+// see https://www.w3.org/TR/trace-context-1/#tracestate-header.
+func checkKey(key string) bool {
+	tenant, system, ok := strings.Cut(key, "@")
+	if !ok {
+		return checkKeyPart(key, 255)
+	}
+	return checkKeyTenant(tenant, 240) && checkKeyPart(system, 13)
+}
+
 func newMember(key, value string) (member, error) {
-	if !keyRe.MatchString(key) {
-		return member{}, fmt.Errorf("%w: %s", errInvalidKey, key)
+	if !checkKey(key) {
+		return member{}, errInvalidKey
 	}
-	if !valueRe.MatchString(value) {
-		return member{}, fmt.Errorf("%w: %s", errInvalidValue, value)
+	if !checkValue(value) {
+		return member{}, errInvalidValue
 	}
 	return member{Key: key, Value: value}, nil
 }
 
 func parseMember(m string) (member, error) {
-	matches := memberRe.FindStringSubmatch(m)
-	if len(matches) != 5 {
+	key, val, ok := strings.Cut(m, memberDelimiter)
+	if !ok {
 		return member{}, fmt.Errorf("%w: %s", errInvalidMember, m)
 	}
-
-	return member{
-		Key:   matches[1],
-		Value: matches[4],
-	}, nil
+	key = strings.TrimLeft(key, " \t")
+	val = strings.TrimRight(val, " \t")
+	result, e := newMember(key, val)
+	if e != nil {
+		return member{}, fmt.Errorf("%w: %s", errInvalidMember, m)
+	}
+	return result, nil
 }
 
 // String encodes member into a string compliant with the W3C Trace Context
 // specification.
 func (m member) String() string {
-	return fmt.Sprintf("%s=%s", m.Key, m.Value)
+	return m.Key + "=" + m.Value
 }
 
 // TraceState provides additional vendor-specific trace identification
@@ -99,8 +177,8 @@ var _ json.Marshaler = TraceState{}
 // ParseTraceState attempts to decode a TraceState from the passed
 // string. It returns an error if the input is invalid according to the W3C
 // Trace Context specification.
-func ParseTraceState(tracestate string) (TraceState, error) {
-	if tracestate == "" {
+func ParseTraceState(ts string) (TraceState, error) {
+	if ts == "" {
 		return TraceState{}, nil
 	}
 
@@ -110,7 +188,9 @@ func ParseTraceState(tracestate string) (TraceState, error) {
 
 	var members []member
 	found := make(map[string]struct{})
-	for _, memberStr := range strings.Split(tracestate, listDelimiter) {
+	for ts != "" {
+		var memberStr string
+		memberStr, ts, _ = strings.Cut(ts, listDelimiters)
 		if len(memberStr) == 0 {
 			continue
 		}
@@ -143,11 +223,29 @@ func (ts TraceState) MarshalJSON() ([]byte, error) {
 // Trace Context specification. The returned string will be invalid if the
 // TraceState contains any invalid members.
 func (ts TraceState) String() string {
-	members := make([]string, len(ts.list))
-	for i, m := range ts.list {
-		members[i] = m.String()
+	if len(ts.list) == 0 {
+		return ""
+	}
+	var n int
+	n += len(ts.list)     // member delimiters: '='
+	n += len(ts.list) - 1 // list delimiters: ','
+	for _, mem := range ts.list {
+		n += len(mem.Key)
+		n += len(mem.Value)
 	}
-	return strings.Join(members, listDelimiter)
+
+	var sb strings.Builder
+	sb.Grow(n)
+	_, _ = sb.WriteString(ts.list[0].Key)
+	_ = sb.WriteByte('=')
+	_, _ = sb.WriteString(ts.list[0].Value)
+	for i := 1; i < len(ts.list); i++ {
+		_ = sb.WriteByte(listDelimiters[0])
+		_, _ = sb.WriteString(ts.list[i].Key)
+		_ = sb.WriteByte('=')
+		_, _ = sb.WriteString(ts.list[i].Value)
+	}
+	return sb.String()
 }
 
 // Get returns the value paired with key from the corresponding TraceState
@@ -179,15 +277,25 @@ func (ts TraceState) Insert(key, value string) (TraceState, error) {
 	if err != nil {
 		return ts, err
 	}
-
-	cTS := ts.Delete(key)
-	if cTS.Len()+1 <= maxListMembers {
-		cTS.list = append(cTS.list, member{})
+	n := len(ts.list)
+	found := n
+	for i := range ts.list {
+		if ts.list[i].Key == key {
+			found = i
+		}
+	}
+	cTS := TraceState{}
+	if found == n && n < maxListMembers {
+		cTS.list = make([]member, n+1)
+	} else {
+		cTS.list = make([]member, n)
 	}
-	// When the number of members exceeds capacity, drop the "right-most".
-	copy(cTS.list[1:], cTS.list)
 	cTS.list[0] = m
-
+	// When the number of members exceeds capacity, drop the "right-most".
+	copy(cTS.list[1:], ts.list[0:found])
+	if found < n {
+		copy(cTS.list[1+found:], ts.list[found+1:])
+	}
 	return cTS, nil
 }
 
diff --git a/vendor/go.opentelemetry.io/otel/verify_examples.sh b/vendor/go.opentelemetry.io/otel/verify_examples.sh
index dbb61a42..e57bf57f 100644
--- a/vendor/go.opentelemetry.io/otel/verify_examples.sh
+++ b/vendor/go.opentelemetry.io/otel/verify_examples.sh
@@ -1,18 +1,7 @@
 #!/bin/bash
 
 # Copyright The OpenTelemetry 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.
+# SPDX-License-Identifier: Apache-2.0
 
 set -euo pipefail
 
diff --git a/vendor/go.opentelemetry.io/otel/verify_readmes.sh b/vendor/go.opentelemetry.io/otel/verify_readmes.sh
new file mode 100644
index 00000000..1e87855e
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/verify_readmes.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+set -euo pipefail
+
+dirs=$(find . -type d -not -path "*/internal*" -not -path "*/test*" -not -path "*/example*" -not -path "*/.*" | sort)
+
+missingReadme=false
+for dir in $dirs; do
+	if [ ! -f "$dir/README.md" ]; then
+		echo "couldn't find README.md for $dir"
+		missingReadme=true
+	fi
+done
+
+if [ "$missingReadme" = true ] ; then
+	echo "Error: some READMEs couldn't be found."
+	exit 1
+fi
diff --git a/vendor/go.opentelemetry.io/otel/version.go b/vendor/go.opentelemetry.io/otel/version.go
index 0e8e5e02..ab289605 100644
--- a/vendor/go.opentelemetry.io/otel/version.go
+++ b/vendor/go.opentelemetry.io/otel/version.go
@@ -1,20 +1,9 @@
 // Copyright The OpenTelemetry 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.
+// SPDX-License-Identifier: Apache-2.0
 
 package otel // import "go.opentelemetry.io/otel"
 
 // Version is the current release version of OpenTelemetry in use.
 func Version() string {
-	return "1.14.0"
+	return "1.28.0"
 }
diff --git a/vendor/go.opentelemetry.io/otel/versions.yaml b/vendor/go.opentelemetry.io/otel/versions.yaml
index 40df1fae..241cfc82 100644
--- a/vendor/go.opentelemetry.io/otel/versions.yaml
+++ b/vendor/go.opentelemetry.io/otel/versions.yaml
@@ -1,57 +1,49 @@
 # Copyright The OpenTelemetry 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.
+# SPDX-License-Identifier: Apache-2.0
 
 module-sets:
   stable-v1:
-    version: v1.14.0
+    version: v1.28.0
     modules:
       - go.opentelemetry.io/otel
+      - go.opentelemetry.io/otel/bridge/opencensus
+      - go.opentelemetry.io/otel/bridge/opencensus/test
       - go.opentelemetry.io/otel/bridge/opentracing
       - go.opentelemetry.io/otel/bridge/opentracing/test
-      - go.opentelemetry.io/otel/example/fib
-      - go.opentelemetry.io/otel/example/jaeger
+      - go.opentelemetry.io/otel/example/dice
       - go.opentelemetry.io/otel/example/namedtracer
+      - go.opentelemetry.io/otel/example/opencensus
       - go.opentelemetry.io/otel/example/otel-collector
       - go.opentelemetry.io/otel/example/passthrough
       - go.opentelemetry.io/otel/example/zipkin
-      - go.opentelemetry.io/otel/exporters/jaeger
-      - go.opentelemetry.io/otel/exporters/zipkin
+      - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc
+      - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp
       - go.opentelemetry.io/otel/exporters/otlp/otlptrace
       - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
       - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp
-      - go.opentelemetry.io/otel/exporters/otlp/internal/retry
+      - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric
       - go.opentelemetry.io/otel/exporters/stdout/stdouttrace
-      - go.opentelemetry.io/otel/trace
+      - go.opentelemetry.io/otel/exporters/zipkin
+      - go.opentelemetry.io/otel/metric
       - go.opentelemetry.io/otel/sdk
+      - go.opentelemetry.io/otel/sdk/metric
+      - go.opentelemetry.io/otel/trace
   experimental-metrics:
-    version: v0.37.0
+    version: v0.50.0
     modules:
-      - go.opentelemetry.io/otel/example/opencensus
       - go.opentelemetry.io/otel/example/prometheus
-      - go.opentelemetry.io/otel/exporters/otlp/otlpmetric
-      - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc
-      - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp
       - go.opentelemetry.io/otel/exporters/prometheus
-      - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric
-      - go.opentelemetry.io/otel/metric
-      - go.opentelemetry.io/otel/sdk/metric
-      - go.opentelemetry.io/otel/bridge/opencensus
-      - go.opentelemetry.io/otel/bridge/opencensus/test
-      - go.opentelemetry.io/otel/example/view
+  experimental-logs:
+    version: v0.4.0
+    modules:
+      - go.opentelemetry.io/otel/log
+      - go.opentelemetry.io/otel/sdk/log
+      - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp
+      - go.opentelemetry.io/otel/exporters/stdout/stdoutlog
   experimental-schema:
-    version: v0.0.4
+    version: v0.0.8
     modules:
       - go.opentelemetry.io/otel/schema
 excluded-modules:
   - go.opentelemetry.io/otel/internal/tools
+  - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b.go b/vendor/golang.org/x/crypto/blake2b/blake2b.go
new file mode 100644
index 00000000..d2e98d42
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2b.go
@@ -0,0 +1,291 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package blake2b implements the BLAKE2b hash algorithm defined by RFC 7693
+// and the extendable output function (XOF) BLAKE2Xb.
+//
+// BLAKE2b is optimized for 64-bit platforms—including NEON-enabled ARMs—and
+// produces digests of any size between 1 and 64 bytes.
+// For a detailed specification of BLAKE2b see https://blake2.net/blake2.pdf
+// and for BLAKE2Xb see https://blake2.net/blake2x.pdf
+//
+// If you aren't sure which function you need, use BLAKE2b (Sum512 or New512).
+// If you need a secret-key MAC (message authentication code), use the New512
+// function with a non-nil key.
+//
+// BLAKE2X is a construction to compute hash values larger than 64 bytes. It
+// can produce hash values between 0 and 4 GiB.
+package blake2b
+
+import (
+	"encoding/binary"
+	"errors"
+	"hash"
+)
+
+const (
+	// The blocksize of BLAKE2b in bytes.
+	BlockSize = 128
+	// The hash size of BLAKE2b-512 in bytes.
+	Size = 64
+	// The hash size of BLAKE2b-384 in bytes.
+	Size384 = 48
+	// The hash size of BLAKE2b-256 in bytes.
+	Size256 = 32
+)
+
+var (
+	useAVX2 bool
+	useAVX  bool
+	useSSE4 bool
+)
+
+var (
+	errKeySize  = errors.New("blake2b: invalid key size")
+	errHashSize = errors.New("blake2b: invalid hash size")
+)
+
+var iv = [8]uint64{
+	0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
+	0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
+}
+
+// Sum512 returns the BLAKE2b-512 checksum of the data.
+func Sum512(data []byte) [Size]byte {
+	var sum [Size]byte
+	checkSum(&sum, Size, data)
+	return sum
+}
+
+// Sum384 returns the BLAKE2b-384 checksum of the data.
+func Sum384(data []byte) [Size384]byte {
+	var sum [Size]byte
+	var sum384 [Size384]byte
+	checkSum(&sum, Size384, data)
+	copy(sum384[:], sum[:Size384])
+	return sum384
+}
+
+// Sum256 returns the BLAKE2b-256 checksum of the data.
+func Sum256(data []byte) [Size256]byte {
+	var sum [Size]byte
+	var sum256 [Size256]byte
+	checkSum(&sum, Size256, data)
+	copy(sum256[:], sum[:Size256])
+	return sum256
+}
+
+// New512 returns a new hash.Hash computing the BLAKE2b-512 checksum. A non-nil
+// key turns the hash into a MAC. The key must be between zero and 64 bytes long.
+func New512(key []byte) (hash.Hash, error) { return newDigest(Size, key) }
+
+// New384 returns a new hash.Hash computing the BLAKE2b-384 checksum. A non-nil
+// key turns the hash into a MAC. The key must be between zero and 64 bytes long.
+func New384(key []byte) (hash.Hash, error) { return newDigest(Size384, key) }
+
+// New256 returns a new hash.Hash computing the BLAKE2b-256 checksum. A non-nil
+// key turns the hash into a MAC. The key must be between zero and 64 bytes long.
+func New256(key []byte) (hash.Hash, error) { return newDigest(Size256, key) }
+
+// New returns a new hash.Hash computing the BLAKE2b checksum with a custom length.
+// A non-nil key turns the hash into a MAC. The key must be between zero and 64 bytes long.
+// The hash size can be a value between 1 and 64 but it is highly recommended to use
+// values equal or greater than:
+// - 32 if BLAKE2b is used as a hash function (The key is zero bytes long).
+// - 16 if BLAKE2b is used as a MAC function (The key is at least 16 bytes long).
+// When the key is nil, the returned hash.Hash implements BinaryMarshaler
+// and BinaryUnmarshaler for state (de)serialization as documented by hash.Hash.
+func New(size int, key []byte) (hash.Hash, error) { return newDigest(size, key) }
+
+func newDigest(hashSize int, key []byte) (*digest, error) {
+	if hashSize < 1 || hashSize > Size {
+		return nil, errHashSize
+	}
+	if len(key) > Size {
+		return nil, errKeySize
+	}
+	d := &digest{
+		size:   hashSize,
+		keyLen: len(key),
+	}
+	copy(d.key[:], key)
+	d.Reset()
+	return d, nil
+}
+
+func checkSum(sum *[Size]byte, hashSize int, data []byte) {
+	h := iv
+	h[0] ^= uint64(hashSize) | (1 << 16) | (1 << 24)
+	var c [2]uint64
+
+	if length := len(data); length > BlockSize {
+		n := length &^ (BlockSize - 1)
+		if length == n {
+			n -= BlockSize
+		}
+		hashBlocks(&h, &c, 0, data[:n])
+		data = data[n:]
+	}
+
+	var block [BlockSize]byte
+	offset := copy(block[:], data)
+	remaining := uint64(BlockSize - offset)
+	if c[0] < remaining {
+		c[1]--
+	}
+	c[0] -= remaining
+
+	hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:])
+
+	for i, v := range h[:(hashSize+7)/8] {
+		binary.LittleEndian.PutUint64(sum[8*i:], v)
+	}
+}
+
+type digest struct {
+	h      [8]uint64
+	c      [2]uint64
+	size   int
+	block  [BlockSize]byte
+	offset int
+
+	key    [BlockSize]byte
+	keyLen int
+}
+
+const (
+	magic         = "b2b"
+	marshaledSize = len(magic) + 8*8 + 2*8 + 1 + BlockSize + 1
+)
+
+func (d *digest) MarshalBinary() ([]byte, error) {
+	if d.keyLen != 0 {
+		return nil, errors.New("crypto/blake2b: cannot marshal MACs")
+	}
+	b := make([]byte, 0, marshaledSize)
+	b = append(b, magic...)
+	for i := 0; i < 8; i++ {
+		b = appendUint64(b, d.h[i])
+	}
+	b = appendUint64(b, d.c[0])
+	b = appendUint64(b, d.c[1])
+	// Maximum value for size is 64
+	b = append(b, byte(d.size))
+	b = append(b, d.block[:]...)
+	b = append(b, byte(d.offset))
+	return b, nil
+}
+
+func (d *digest) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic) || string(b[:len(magic)]) != magic {
+		return errors.New("crypto/blake2b: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize {
+		return errors.New("crypto/blake2b: invalid hash state size")
+	}
+	b = b[len(magic):]
+	for i := 0; i < 8; i++ {
+		b, d.h[i] = consumeUint64(b)
+	}
+	b, d.c[0] = consumeUint64(b)
+	b, d.c[1] = consumeUint64(b)
+	d.size = int(b[0])
+	b = b[1:]
+	copy(d.block[:], b[:BlockSize])
+	b = b[BlockSize:]
+	d.offset = int(b[0])
+	return nil
+}
+
+func (d *digest) BlockSize() int { return BlockSize }
+
+func (d *digest) Size() int { return d.size }
+
+func (d *digest) Reset() {
+	d.h = iv
+	d.h[0] ^= uint64(d.size) | (uint64(d.keyLen) << 8) | (1 << 16) | (1 << 24)
+	d.offset, d.c[0], d.c[1] = 0, 0, 0
+	if d.keyLen > 0 {
+		d.block = d.key
+		d.offset = BlockSize
+	}
+}
+
+func (d *digest) Write(p []byte) (n int, err error) {
+	n = len(p)
+
+	if d.offset > 0 {
+		remaining := BlockSize - d.offset
+		if n <= remaining {
+			d.offset += copy(d.block[d.offset:], p)
+			return
+		}
+		copy(d.block[d.offset:], p[:remaining])
+		hashBlocks(&d.h, &d.c, 0, d.block[:])
+		d.offset = 0
+		p = p[remaining:]
+	}
+
+	if length := len(p); length > BlockSize {
+		nn := length &^ (BlockSize - 1)
+		if length == nn {
+			nn -= BlockSize
+		}
+		hashBlocks(&d.h, &d.c, 0, p[:nn])
+		p = p[nn:]
+	}
+
+	if len(p) > 0 {
+		d.offset += copy(d.block[:], p)
+	}
+
+	return
+}
+
+func (d *digest) Sum(sum []byte) []byte {
+	var hash [Size]byte
+	d.finalize(&hash)
+	return append(sum, hash[:d.size]...)
+}
+
+func (d *digest) finalize(hash *[Size]byte) {
+	var block [BlockSize]byte
+	copy(block[:], d.block[:d.offset])
+	remaining := uint64(BlockSize - d.offset)
+
+	c := d.c
+	if c[0] < remaining {
+		c[1]--
+	}
+	c[0] -= remaining
+
+	h := d.h
+	hashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:])
+
+	for i, v := range h {
+		binary.LittleEndian.PutUint64(hash[8*i:], v)
+	}
+}
+
+func appendUint64(b []byte, x uint64) []byte {
+	var a [8]byte
+	binary.BigEndian.PutUint64(a[:], x)
+	return append(b, a[:]...)
+}
+
+func appendUint32(b []byte, x uint32) []byte {
+	var a [4]byte
+	binary.BigEndian.PutUint32(a[:], x)
+	return append(b, a[:]...)
+}
+
+func consumeUint64(b []byte) ([]byte, uint64) {
+	x := binary.BigEndian.Uint64(b)
+	return b[8:], x
+}
+
+func consumeUint32(b []byte) ([]byte, uint32) {
+	x := binary.BigEndian.Uint32(b)
+	return b[4:], x
+}
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
new file mode 100644
index 00000000..199c21d2
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
@@ -0,0 +1,37 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && gc && !purego
+
+package blake2b
+
+import "golang.org/x/sys/cpu"
+
+func init() {
+	useAVX2 = cpu.X86.HasAVX2
+	useAVX = cpu.X86.HasAVX
+	useSSE4 = cpu.X86.HasSSE41
+}
+
+//go:noescape
+func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
+
+//go:noescape
+func hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
+
+//go:noescape
+func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
+
+func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
+	switch {
+	case useAVX2:
+		hashBlocksAVX2(h, c, flag, blocks)
+	case useAVX:
+		hashBlocksAVX(h, c, flag, blocks)
+	case useSSE4:
+		hashBlocksSSE4(h, c, flag, blocks)
+	default:
+		hashBlocksGeneric(h, c, flag, blocks)
+	}
+}
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
new file mode 100644
index 00000000..9ae8206c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
@@ -0,0 +1,744 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && gc && !purego
+
+#include "textflag.h"
+
+DATA ·AVX2_iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
+DATA ·AVX2_iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
+DATA ·AVX2_iv0<>+0x10(SB)/8, $0x3c6ef372fe94f82b
+DATA ·AVX2_iv0<>+0x18(SB)/8, $0xa54ff53a5f1d36f1
+GLOBL ·AVX2_iv0<>(SB), (NOPTR+RODATA), $32
+
+DATA ·AVX2_iv1<>+0x00(SB)/8, $0x510e527fade682d1
+DATA ·AVX2_iv1<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
+DATA ·AVX2_iv1<>+0x10(SB)/8, $0x1f83d9abfb41bd6b
+DATA ·AVX2_iv1<>+0x18(SB)/8, $0x5be0cd19137e2179
+GLOBL ·AVX2_iv1<>(SB), (NOPTR+RODATA), $32
+
+DATA ·AVX2_c40<>+0x00(SB)/8, $0x0201000706050403
+DATA ·AVX2_c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
+DATA ·AVX2_c40<>+0x10(SB)/8, $0x0201000706050403
+DATA ·AVX2_c40<>+0x18(SB)/8, $0x0a09080f0e0d0c0b
+GLOBL ·AVX2_c40<>(SB), (NOPTR+RODATA), $32
+
+DATA ·AVX2_c48<>+0x00(SB)/8, $0x0100070605040302
+DATA ·AVX2_c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
+DATA ·AVX2_c48<>+0x10(SB)/8, $0x0100070605040302
+DATA ·AVX2_c48<>+0x18(SB)/8, $0x09080f0e0d0c0b0a
+GLOBL ·AVX2_c48<>(SB), (NOPTR+RODATA), $32
+
+DATA ·AVX_iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
+DATA ·AVX_iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
+GLOBL ·AVX_iv0<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_iv1<>+0x00(SB)/8, $0x3c6ef372fe94f82b
+DATA ·AVX_iv1<>+0x08(SB)/8, $0xa54ff53a5f1d36f1
+GLOBL ·AVX_iv1<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_iv2<>+0x00(SB)/8, $0x510e527fade682d1
+DATA ·AVX_iv2<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
+GLOBL ·AVX_iv2<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_iv3<>+0x00(SB)/8, $0x1f83d9abfb41bd6b
+DATA ·AVX_iv3<>+0x08(SB)/8, $0x5be0cd19137e2179
+GLOBL ·AVX_iv3<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_c40<>+0x00(SB)/8, $0x0201000706050403
+DATA ·AVX_c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
+GLOBL ·AVX_c40<>(SB), (NOPTR+RODATA), $16
+
+DATA ·AVX_c48<>+0x00(SB)/8, $0x0100070605040302
+DATA ·AVX_c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
+GLOBL ·AVX_c48<>(SB), (NOPTR+RODATA), $16
+
+#define VPERMQ_0x39_Y1_Y1 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x39
+#define VPERMQ_0x93_Y1_Y1 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xc9; BYTE $0x93
+#define VPERMQ_0x4E_Y2_Y2 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xd2; BYTE $0x4e
+#define VPERMQ_0x93_Y3_Y3 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x93
+#define VPERMQ_0x39_Y3_Y3 BYTE $0xc4; BYTE $0xe3; BYTE $0xfd; BYTE $0x00; BYTE $0xdb; BYTE $0x39
+
+#define ROUND_AVX2(m0, m1, m2, m3, t, c40, c48) \
+	VPADDQ  m0, Y0, Y0;   \
+	VPADDQ  Y1, Y0, Y0;   \
+	VPXOR   Y0, Y3, Y3;   \
+	VPSHUFD $-79, Y3, Y3; \
+	VPADDQ  Y3, Y2, Y2;   \
+	VPXOR   Y2, Y1, Y1;   \
+	VPSHUFB c40, Y1, Y1;  \
+	VPADDQ  m1, Y0, Y0;   \
+	VPADDQ  Y1, Y0, Y0;   \
+	VPXOR   Y0, Y3, Y3;   \
+	VPSHUFB c48, Y3, Y3;  \
+	VPADDQ  Y3, Y2, Y2;   \
+	VPXOR   Y2, Y1, Y1;   \
+	VPADDQ  Y1, Y1, t;    \
+	VPSRLQ  $63, Y1, Y1;  \
+	VPXOR   t, Y1, Y1;    \
+	VPERMQ_0x39_Y1_Y1;    \
+	VPERMQ_0x4E_Y2_Y2;    \
+	VPERMQ_0x93_Y3_Y3;    \
+	VPADDQ  m2, Y0, Y0;   \
+	VPADDQ  Y1, Y0, Y0;   \
+	VPXOR   Y0, Y3, Y3;   \
+	VPSHUFD $-79, Y3, Y3; \
+	VPADDQ  Y3, Y2, Y2;   \
+	VPXOR   Y2, Y1, Y1;   \
+	VPSHUFB c40, Y1, Y1;  \
+	VPADDQ  m3, Y0, Y0;   \
+	VPADDQ  Y1, Y0, Y0;   \
+	VPXOR   Y0, Y3, Y3;   \
+	VPSHUFB c48, Y3, Y3;  \
+	VPADDQ  Y3, Y2, Y2;   \
+	VPXOR   Y2, Y1, Y1;   \
+	VPADDQ  Y1, Y1, t;    \
+	VPSRLQ  $63, Y1, Y1;  \
+	VPXOR   t, Y1, Y1;    \
+	VPERMQ_0x39_Y3_Y3;    \
+	VPERMQ_0x4E_Y2_Y2;    \
+	VPERMQ_0x93_Y1_Y1
+
+#define VMOVQ_SI_X11_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x1E
+#define VMOVQ_SI_X12_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x26
+#define VMOVQ_SI_X13_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x2E
+#define VMOVQ_SI_X14_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x36
+#define VMOVQ_SI_X15_0 BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x3E
+
+#define VMOVQ_SI_X11(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x5E; BYTE $n
+#define VMOVQ_SI_X12(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x66; BYTE $n
+#define VMOVQ_SI_X13(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x6E; BYTE $n
+#define VMOVQ_SI_X14(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x76; BYTE $n
+#define VMOVQ_SI_X15(n) BYTE $0xC5; BYTE $0x7A; BYTE $0x7E; BYTE $0x7E; BYTE $n
+
+#define VPINSRQ_1_SI_X11_0 BYTE $0xC4; BYTE $0x63; BYTE $0xA1; BYTE $0x22; BYTE $0x1E; BYTE $0x01
+#define VPINSRQ_1_SI_X12_0 BYTE $0xC4; BYTE $0x63; BYTE $0x99; BYTE $0x22; BYTE $0x26; BYTE $0x01
+#define VPINSRQ_1_SI_X13_0 BYTE $0xC4; BYTE $0x63; BYTE $0x91; BYTE $0x22; BYTE $0x2E; BYTE $0x01
+#define VPINSRQ_1_SI_X14_0 BYTE $0xC4; BYTE $0x63; BYTE $0x89; BYTE $0x22; BYTE $0x36; BYTE $0x01
+#define VPINSRQ_1_SI_X15_0 BYTE $0xC4; BYTE $0x63; BYTE $0x81; BYTE $0x22; BYTE $0x3E; BYTE $0x01
+
+#define VPINSRQ_1_SI_X11(n) BYTE $0xC4; BYTE $0x63; BYTE $0xA1; BYTE $0x22; BYTE $0x5E; BYTE $n; BYTE $0x01
+#define VPINSRQ_1_SI_X12(n) BYTE $0xC4; BYTE $0x63; BYTE $0x99; BYTE $0x22; BYTE $0x66; BYTE $n; BYTE $0x01
+#define VPINSRQ_1_SI_X13(n) BYTE $0xC4; BYTE $0x63; BYTE $0x91; BYTE $0x22; BYTE $0x6E; BYTE $n; BYTE $0x01
+#define VPINSRQ_1_SI_X14(n) BYTE $0xC4; BYTE $0x63; BYTE $0x89; BYTE $0x22; BYTE $0x76; BYTE $n; BYTE $0x01
+#define VPINSRQ_1_SI_X15(n) BYTE $0xC4; BYTE $0x63; BYTE $0x81; BYTE $0x22; BYTE $0x7E; BYTE $n; BYTE $0x01
+
+#define VMOVQ_R8_X15 BYTE $0xC4; BYTE $0x41; BYTE $0xF9; BYTE $0x6E; BYTE $0xF8
+#define VPINSRQ_1_R9_X15 BYTE $0xC4; BYTE $0x43; BYTE $0x81; BYTE $0x22; BYTE $0xF9; BYTE $0x01
+
+// load msg: Y12 = (i0, i1, i2, i3)
+// i0, i1, i2, i3 must not be 0
+#define LOAD_MSG_AVX2_Y12(i0, i1, i2, i3) \
+	VMOVQ_SI_X12(i0*8);           \
+	VMOVQ_SI_X11(i2*8);           \
+	VPINSRQ_1_SI_X12(i1*8);       \
+	VPINSRQ_1_SI_X11(i3*8);       \
+	VINSERTI128 $1, X11, Y12, Y12
+
+// load msg: Y13 = (i0, i1, i2, i3)
+// i0, i1, i2, i3 must not be 0
+#define LOAD_MSG_AVX2_Y13(i0, i1, i2, i3) \
+	VMOVQ_SI_X13(i0*8);           \
+	VMOVQ_SI_X11(i2*8);           \
+	VPINSRQ_1_SI_X13(i1*8);       \
+	VPINSRQ_1_SI_X11(i3*8);       \
+	VINSERTI128 $1, X11, Y13, Y13
+
+// load msg: Y14 = (i0, i1, i2, i3)
+// i0, i1, i2, i3 must not be 0
+#define LOAD_MSG_AVX2_Y14(i0, i1, i2, i3) \
+	VMOVQ_SI_X14(i0*8);           \
+	VMOVQ_SI_X11(i2*8);           \
+	VPINSRQ_1_SI_X14(i1*8);       \
+	VPINSRQ_1_SI_X11(i3*8);       \
+	VINSERTI128 $1, X11, Y14, Y14
+
+// load msg: Y15 = (i0, i1, i2, i3)
+// i0, i1, i2, i3 must not be 0
+#define LOAD_MSG_AVX2_Y15(i0, i1, i2, i3) \
+	VMOVQ_SI_X15(i0*8);           \
+	VMOVQ_SI_X11(i2*8);           \
+	VPINSRQ_1_SI_X15(i1*8);       \
+	VPINSRQ_1_SI_X11(i3*8);       \
+	VINSERTI128 $1, X11, Y15, Y15
+
+#define LOAD_MSG_AVX2_0_2_4_6_1_3_5_7_8_10_12_14_9_11_13_15() \
+	VMOVQ_SI_X12_0;                   \
+	VMOVQ_SI_X11(4*8);                \
+	VPINSRQ_1_SI_X12(2*8);            \
+	VPINSRQ_1_SI_X11(6*8);            \
+	VINSERTI128 $1, X11, Y12, Y12;    \
+	LOAD_MSG_AVX2_Y13(1, 3, 5, 7);    \
+	LOAD_MSG_AVX2_Y14(8, 10, 12, 14); \
+	LOAD_MSG_AVX2_Y15(9, 11, 13, 15)
+
+#define LOAD_MSG_AVX2_14_4_9_13_10_8_15_6_1_0_11_5_12_2_7_3() \
+	LOAD_MSG_AVX2_Y12(14, 4, 9, 13); \
+	LOAD_MSG_AVX2_Y13(10, 8, 15, 6); \
+	VMOVQ_SI_X11(11*8);              \
+	VPSHUFD     $0x4E, 0*8(SI), X14; \
+	VPINSRQ_1_SI_X11(5*8);           \
+	VINSERTI128 $1, X11, Y14, Y14;   \
+	LOAD_MSG_AVX2_Y15(12, 2, 7, 3)
+
+#define LOAD_MSG_AVX2_11_12_5_15_8_0_2_13_10_3_7_9_14_6_1_4() \
+	VMOVQ_SI_X11(5*8);              \
+	VMOVDQU     11*8(SI), X12;      \
+	VPINSRQ_1_SI_X11(15*8);         \
+	VINSERTI128 $1, X11, Y12, Y12;  \
+	VMOVQ_SI_X13(8*8);              \
+	VMOVQ_SI_X11(2*8);              \
+	VPINSRQ_1_SI_X13_0;             \
+	VPINSRQ_1_SI_X11(13*8);         \
+	VINSERTI128 $1, X11, Y13, Y13;  \
+	LOAD_MSG_AVX2_Y14(10, 3, 7, 9); \
+	LOAD_MSG_AVX2_Y15(14, 6, 1, 4)
+
+#define LOAD_MSG_AVX2_7_3_13_11_9_1_12_14_2_5_4_15_6_10_0_8() \
+	LOAD_MSG_AVX2_Y12(7, 3, 13, 11); \
+	LOAD_MSG_AVX2_Y13(9, 1, 12, 14); \
+	LOAD_MSG_AVX2_Y14(2, 5, 4, 15);  \
+	VMOVQ_SI_X15(6*8);               \
+	VMOVQ_SI_X11_0;                  \
+	VPINSRQ_1_SI_X15(10*8);          \
+	VPINSRQ_1_SI_X11(8*8);           \
+	VINSERTI128 $1, X11, Y15, Y15
+
+#define LOAD_MSG_AVX2_9_5_2_10_0_7_4_15_14_11_6_3_1_12_8_13() \
+	LOAD_MSG_AVX2_Y12(9, 5, 2, 10);  \
+	VMOVQ_SI_X13_0;                  \
+	VMOVQ_SI_X11(4*8);               \
+	VPINSRQ_1_SI_X13(7*8);           \
+	VPINSRQ_1_SI_X11(15*8);          \
+	VINSERTI128 $1, X11, Y13, Y13;   \
+	LOAD_MSG_AVX2_Y14(14, 11, 6, 3); \
+	LOAD_MSG_AVX2_Y15(1, 12, 8, 13)
+
+#define LOAD_MSG_AVX2_2_6_0_8_12_10_11_3_4_7_15_1_13_5_14_9() \
+	VMOVQ_SI_X12(2*8);                \
+	VMOVQ_SI_X11_0;                   \
+	VPINSRQ_1_SI_X12(6*8);            \
+	VPINSRQ_1_SI_X11(8*8);            \
+	VINSERTI128 $1, X11, Y12, Y12;    \
+	LOAD_MSG_AVX2_Y13(12, 10, 11, 3); \
+	LOAD_MSG_AVX2_Y14(4, 7, 15, 1);   \
+	LOAD_MSG_AVX2_Y15(13, 5, 14, 9)
+
+#define LOAD_MSG_AVX2_12_1_14_4_5_15_13_10_0_6_9_8_7_3_2_11() \
+	LOAD_MSG_AVX2_Y12(12, 1, 14, 4);  \
+	LOAD_MSG_AVX2_Y13(5, 15, 13, 10); \
+	VMOVQ_SI_X14_0;                   \
+	VPSHUFD     $0x4E, 8*8(SI), X11;  \
+	VPINSRQ_1_SI_X14(6*8);            \
+	VINSERTI128 $1, X11, Y14, Y14;    \
+	LOAD_MSG_AVX2_Y15(7, 3, 2, 11)
+
+#define LOAD_MSG_AVX2_13_7_12_3_11_14_1_9_5_15_8_2_0_4_6_10() \
+	LOAD_MSG_AVX2_Y12(13, 7, 12, 3); \
+	LOAD_MSG_AVX2_Y13(11, 14, 1, 9); \
+	LOAD_MSG_AVX2_Y14(5, 15, 8, 2);  \
+	VMOVQ_SI_X15_0;                  \
+	VMOVQ_SI_X11(6*8);               \
+	VPINSRQ_1_SI_X15(4*8);           \
+	VPINSRQ_1_SI_X11(10*8);          \
+	VINSERTI128 $1, X11, Y15, Y15
+
+#define LOAD_MSG_AVX2_6_14_11_0_15_9_3_8_12_13_1_10_2_7_4_5() \
+	VMOVQ_SI_X12(6*8);              \
+	VMOVQ_SI_X11(11*8);             \
+	VPINSRQ_1_SI_X12(14*8);         \
+	VPINSRQ_1_SI_X11_0;             \
+	VINSERTI128 $1, X11, Y12, Y12;  \
+	LOAD_MSG_AVX2_Y13(15, 9, 3, 8); \
+	VMOVQ_SI_X11(1*8);              \
+	VMOVDQU     12*8(SI), X14;      \
+	VPINSRQ_1_SI_X11(10*8);         \
+	VINSERTI128 $1, X11, Y14, Y14;  \
+	VMOVQ_SI_X15(2*8);              \
+	VMOVDQU     4*8(SI), X11;       \
+	VPINSRQ_1_SI_X15(7*8);          \
+	VINSERTI128 $1, X11, Y15, Y15
+
+#define LOAD_MSG_AVX2_10_8_7_1_2_4_6_5_15_9_3_13_11_14_12_0() \
+	LOAD_MSG_AVX2_Y12(10, 8, 7, 1);  \
+	VMOVQ_SI_X13(2*8);               \
+	VPSHUFD     $0x4E, 5*8(SI), X11; \
+	VPINSRQ_1_SI_X13(4*8);           \
+	VINSERTI128 $1, X11, Y13, Y13;   \
+	LOAD_MSG_AVX2_Y14(15, 9, 3, 13); \
+	VMOVQ_SI_X15(11*8);              \
+	VMOVQ_SI_X11(12*8);              \
+	VPINSRQ_1_SI_X15(14*8);          \
+	VPINSRQ_1_SI_X11_0;              \
+	VINSERTI128 $1, X11, Y15, Y15
+
+// func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
+TEXT ·hashBlocksAVX2(SB), 4, $320-48 // frame size = 288 + 32 byte alignment
+	MOVQ h+0(FP), AX
+	MOVQ c+8(FP), BX
+	MOVQ flag+16(FP), CX
+	MOVQ blocks_base+24(FP), SI
+	MOVQ blocks_len+32(FP), DI
+
+	MOVQ SP, DX
+	ADDQ $31, DX
+	ANDQ $~31, DX
+
+	MOVQ CX, 16(DX)
+	XORQ CX, CX
+	MOVQ CX, 24(DX)
+
+	VMOVDQU ·AVX2_c40<>(SB), Y4
+	VMOVDQU ·AVX2_c48<>(SB), Y5
+
+	VMOVDQU 0(AX), Y8
+	VMOVDQU 32(AX), Y9
+	VMOVDQU ·AVX2_iv0<>(SB), Y6
+	VMOVDQU ·AVX2_iv1<>(SB), Y7
+
+	MOVQ 0(BX), R8
+	MOVQ 8(BX), R9
+	MOVQ R9, 8(DX)
+
+loop:
+	ADDQ $128, R8
+	MOVQ R8, 0(DX)
+	CMPQ R8, $128
+	JGE  noinc
+	INCQ R9
+	MOVQ R9, 8(DX)
+
+noinc:
+	VMOVDQA Y8, Y0
+	VMOVDQA Y9, Y1
+	VMOVDQA Y6, Y2
+	VPXOR   0(DX), Y7, Y3
+
+	LOAD_MSG_AVX2_0_2_4_6_1_3_5_7_8_10_12_14_9_11_13_15()
+	VMOVDQA Y12, 32(DX)
+	VMOVDQA Y13, 64(DX)
+	VMOVDQA Y14, 96(DX)
+	VMOVDQA Y15, 128(DX)
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_14_4_9_13_10_8_15_6_1_0_11_5_12_2_7_3()
+	VMOVDQA Y12, 160(DX)
+	VMOVDQA Y13, 192(DX)
+	VMOVDQA Y14, 224(DX)
+	VMOVDQA Y15, 256(DX)
+
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_11_12_5_15_8_0_2_13_10_3_7_9_14_6_1_4()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_7_3_13_11_9_1_12_14_2_5_4_15_6_10_0_8()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_9_5_2_10_0_7_4_15_14_11_6_3_1_12_8_13()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_2_6_0_8_12_10_11_3_4_7_15_1_13_5_14_9()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_12_1_14_4_5_15_13_10_0_6_9_8_7_3_2_11()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_13_7_12_3_11_14_1_9_5_15_8_2_0_4_6_10()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_6_14_11_0_15_9_3_8_12_13_1_10_2_7_4_5()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+	LOAD_MSG_AVX2_10_8_7_1_2_4_6_5_15_9_3_13_11_14_12_0()
+	ROUND_AVX2(Y12, Y13, Y14, Y15, Y10, Y4, Y5)
+
+	ROUND_AVX2(32(DX), 64(DX), 96(DX), 128(DX), Y10, Y4, Y5)
+	ROUND_AVX2(160(DX), 192(DX), 224(DX), 256(DX), Y10, Y4, Y5)
+
+	VPXOR Y0, Y8, Y8
+	VPXOR Y1, Y9, Y9
+	VPXOR Y2, Y8, Y8
+	VPXOR Y3, Y9, Y9
+
+	LEAQ 128(SI), SI
+	SUBQ $128, DI
+	JNE  loop
+
+	MOVQ R8, 0(BX)
+	MOVQ R9, 8(BX)
+
+	VMOVDQU Y8, 0(AX)
+	VMOVDQU Y9, 32(AX)
+	VZEROUPPER
+
+	RET
+
+#define VPUNPCKLQDQ_X2_X2_X15 BYTE $0xC5; BYTE $0x69; BYTE $0x6C; BYTE $0xFA
+#define VPUNPCKLQDQ_X3_X3_X15 BYTE $0xC5; BYTE $0x61; BYTE $0x6C; BYTE $0xFB
+#define VPUNPCKLQDQ_X7_X7_X15 BYTE $0xC5; BYTE $0x41; BYTE $0x6C; BYTE $0xFF
+#define VPUNPCKLQDQ_X13_X13_X15 BYTE $0xC4; BYTE $0x41; BYTE $0x11; BYTE $0x6C; BYTE $0xFD
+#define VPUNPCKLQDQ_X14_X14_X15 BYTE $0xC4; BYTE $0x41; BYTE $0x09; BYTE $0x6C; BYTE $0xFE
+
+#define VPUNPCKHQDQ_X15_X2_X2 BYTE $0xC4; BYTE $0xC1; BYTE $0x69; BYTE $0x6D; BYTE $0xD7
+#define VPUNPCKHQDQ_X15_X3_X3 BYTE $0xC4; BYTE $0xC1; BYTE $0x61; BYTE $0x6D; BYTE $0xDF
+#define VPUNPCKHQDQ_X15_X6_X6 BYTE $0xC4; BYTE $0xC1; BYTE $0x49; BYTE $0x6D; BYTE $0xF7
+#define VPUNPCKHQDQ_X15_X7_X7 BYTE $0xC4; BYTE $0xC1; BYTE $0x41; BYTE $0x6D; BYTE $0xFF
+#define VPUNPCKHQDQ_X15_X3_X2 BYTE $0xC4; BYTE $0xC1; BYTE $0x61; BYTE $0x6D; BYTE $0xD7
+#define VPUNPCKHQDQ_X15_X7_X6 BYTE $0xC4; BYTE $0xC1; BYTE $0x41; BYTE $0x6D; BYTE $0xF7
+#define VPUNPCKHQDQ_X15_X13_X3 BYTE $0xC4; BYTE $0xC1; BYTE $0x11; BYTE $0x6D; BYTE $0xDF
+#define VPUNPCKHQDQ_X15_X13_X7 BYTE $0xC4; BYTE $0xC1; BYTE $0x11; BYTE $0x6D; BYTE $0xFF
+
+#define SHUFFLE_AVX() \
+	VMOVDQA X6, X13;         \
+	VMOVDQA X2, X14;         \
+	VMOVDQA X4, X6;          \
+	VPUNPCKLQDQ_X13_X13_X15; \
+	VMOVDQA X5, X4;          \
+	VMOVDQA X6, X5;          \
+	VPUNPCKHQDQ_X15_X7_X6;   \
+	VPUNPCKLQDQ_X7_X7_X15;   \
+	VPUNPCKHQDQ_X15_X13_X7;  \
+	VPUNPCKLQDQ_X3_X3_X15;   \
+	VPUNPCKHQDQ_X15_X2_X2;   \
+	VPUNPCKLQDQ_X14_X14_X15; \
+	VPUNPCKHQDQ_X15_X3_X3;   \
+
+#define SHUFFLE_AVX_INV() \
+	VMOVDQA X2, X13;         \
+	VMOVDQA X4, X14;         \
+	VPUNPCKLQDQ_X2_X2_X15;   \
+	VMOVDQA X5, X4;          \
+	VPUNPCKHQDQ_X15_X3_X2;   \
+	VMOVDQA X14, X5;         \
+	VPUNPCKLQDQ_X3_X3_X15;   \
+	VMOVDQA X6, X14;         \
+	VPUNPCKHQDQ_X15_X13_X3;  \
+	VPUNPCKLQDQ_X7_X7_X15;   \
+	VPUNPCKHQDQ_X15_X6_X6;   \
+	VPUNPCKLQDQ_X14_X14_X15; \
+	VPUNPCKHQDQ_X15_X7_X7;   \
+
+#define HALF_ROUND_AVX(v0, v1, v2, v3, v4, v5, v6, v7, m0, m1, m2, m3, t0, c40, c48) \
+	VPADDQ  m0, v0, v0;   \
+	VPADDQ  v2, v0, v0;   \
+	VPADDQ  m1, v1, v1;   \
+	VPADDQ  v3, v1, v1;   \
+	VPXOR   v0, v6, v6;   \
+	VPXOR   v1, v7, v7;   \
+	VPSHUFD $-79, v6, v6; \
+	VPSHUFD $-79, v7, v7; \
+	VPADDQ  v6, v4, v4;   \
+	VPADDQ  v7, v5, v5;   \
+	VPXOR   v4, v2, v2;   \
+	VPXOR   v5, v3, v3;   \
+	VPSHUFB c40, v2, v2;  \
+	VPSHUFB c40, v3, v3;  \
+	VPADDQ  m2, v0, v0;   \
+	VPADDQ  v2, v0, v0;   \
+	VPADDQ  m3, v1, v1;   \
+	VPADDQ  v3, v1, v1;   \
+	VPXOR   v0, v6, v6;   \
+	VPXOR   v1, v7, v7;   \
+	VPSHUFB c48, v6, v6;  \
+	VPSHUFB c48, v7, v7;  \
+	VPADDQ  v6, v4, v4;   \
+	VPADDQ  v7, v5, v5;   \
+	VPXOR   v4, v2, v2;   \
+	VPXOR   v5, v3, v3;   \
+	VPADDQ  v2, v2, t0;   \
+	VPSRLQ  $63, v2, v2;  \
+	VPXOR   t0, v2, v2;   \
+	VPADDQ  v3, v3, t0;   \
+	VPSRLQ  $63, v3, v3;  \
+	VPXOR   t0, v3, v3
+
+// load msg: X12 = (i0, i1), X13 = (i2, i3), X14 = (i4, i5), X15 = (i6, i7)
+// i0, i1, i2, i3, i4, i5, i6, i7 must not be 0
+#define LOAD_MSG_AVX(i0, i1, i2, i3, i4, i5, i6, i7) \
+	VMOVQ_SI_X12(i0*8);     \
+	VMOVQ_SI_X13(i2*8);     \
+	VMOVQ_SI_X14(i4*8);     \
+	VMOVQ_SI_X15(i6*8);     \
+	VPINSRQ_1_SI_X12(i1*8); \
+	VPINSRQ_1_SI_X13(i3*8); \
+	VPINSRQ_1_SI_X14(i5*8); \
+	VPINSRQ_1_SI_X15(i7*8)
+
+// load msg: X12 = (0, 2), X13 = (4, 6), X14 = (1, 3), X15 = (5, 7)
+#define LOAD_MSG_AVX_0_2_4_6_1_3_5_7() \
+	VMOVQ_SI_X12_0;        \
+	VMOVQ_SI_X13(4*8);     \
+	VMOVQ_SI_X14(1*8);     \
+	VMOVQ_SI_X15(5*8);     \
+	VPINSRQ_1_SI_X12(2*8); \
+	VPINSRQ_1_SI_X13(6*8); \
+	VPINSRQ_1_SI_X14(3*8); \
+	VPINSRQ_1_SI_X15(7*8)
+
+// load msg: X12 = (1, 0), X13 = (11, 5), X14 = (12, 2), X15 = (7, 3)
+#define LOAD_MSG_AVX_1_0_11_5_12_2_7_3() \
+	VPSHUFD $0x4E, 0*8(SI), X12; \
+	VMOVQ_SI_X13(11*8);          \
+	VMOVQ_SI_X14(12*8);          \
+	VMOVQ_SI_X15(7*8);           \
+	VPINSRQ_1_SI_X13(5*8);       \
+	VPINSRQ_1_SI_X14(2*8);       \
+	VPINSRQ_1_SI_X15(3*8)
+
+// load msg: X12 = (11, 12), X13 = (5, 15), X14 = (8, 0), X15 = (2, 13)
+#define LOAD_MSG_AVX_11_12_5_15_8_0_2_13() \
+	VMOVDQU 11*8(SI), X12;  \
+	VMOVQ_SI_X13(5*8);      \
+	VMOVQ_SI_X14(8*8);      \
+	VMOVQ_SI_X15(2*8);      \
+	VPINSRQ_1_SI_X13(15*8); \
+	VPINSRQ_1_SI_X14_0;     \
+	VPINSRQ_1_SI_X15(13*8)
+
+// load msg: X12 = (2, 5), X13 = (4, 15), X14 = (6, 10), X15 = (0, 8)
+#define LOAD_MSG_AVX_2_5_4_15_6_10_0_8() \
+	VMOVQ_SI_X12(2*8);      \
+	VMOVQ_SI_X13(4*8);      \
+	VMOVQ_SI_X14(6*8);      \
+	VMOVQ_SI_X15_0;         \
+	VPINSRQ_1_SI_X12(5*8);  \
+	VPINSRQ_1_SI_X13(15*8); \
+	VPINSRQ_1_SI_X14(10*8); \
+	VPINSRQ_1_SI_X15(8*8)
+
+// load msg: X12 = (9, 5), X13 = (2, 10), X14 = (0, 7), X15 = (4, 15)
+#define LOAD_MSG_AVX_9_5_2_10_0_7_4_15() \
+	VMOVQ_SI_X12(9*8);      \
+	VMOVQ_SI_X13(2*8);      \
+	VMOVQ_SI_X14_0;         \
+	VMOVQ_SI_X15(4*8);      \
+	VPINSRQ_1_SI_X12(5*8);  \
+	VPINSRQ_1_SI_X13(10*8); \
+	VPINSRQ_1_SI_X14(7*8);  \
+	VPINSRQ_1_SI_X15(15*8)
+
+// load msg: X12 = (2, 6), X13 = (0, 8), X14 = (12, 10), X15 = (11, 3)
+#define LOAD_MSG_AVX_2_6_0_8_12_10_11_3() \
+	VMOVQ_SI_X12(2*8);      \
+	VMOVQ_SI_X13_0;         \
+	VMOVQ_SI_X14(12*8);     \
+	VMOVQ_SI_X15(11*8);     \
+	VPINSRQ_1_SI_X12(6*8);  \
+	VPINSRQ_1_SI_X13(8*8);  \
+	VPINSRQ_1_SI_X14(10*8); \
+	VPINSRQ_1_SI_X15(3*8)
+
+// load msg: X12 = (0, 6), X13 = (9, 8), X14 = (7, 3), X15 = (2, 11)
+#define LOAD_MSG_AVX_0_6_9_8_7_3_2_11() \
+	MOVQ    0*8(SI), X12;        \
+	VPSHUFD $0x4E, 8*8(SI), X13; \
+	MOVQ    7*8(SI), X14;        \
+	MOVQ    2*8(SI), X15;        \
+	VPINSRQ_1_SI_X12(6*8);       \
+	VPINSRQ_1_SI_X14(3*8);       \
+	VPINSRQ_1_SI_X15(11*8)
+
+// load msg: X12 = (6, 14), X13 = (11, 0), X14 = (15, 9), X15 = (3, 8)
+#define LOAD_MSG_AVX_6_14_11_0_15_9_3_8() \
+	MOVQ 6*8(SI), X12;      \
+	MOVQ 11*8(SI), X13;     \
+	MOVQ 15*8(SI), X14;     \
+	MOVQ 3*8(SI), X15;      \
+	VPINSRQ_1_SI_X12(14*8); \
+	VPINSRQ_1_SI_X13_0;     \
+	VPINSRQ_1_SI_X14(9*8);  \
+	VPINSRQ_1_SI_X15(8*8)
+
+// load msg: X12 = (5, 15), X13 = (8, 2), X14 = (0, 4), X15 = (6, 10)
+#define LOAD_MSG_AVX_5_15_8_2_0_4_6_10() \
+	MOVQ 5*8(SI), X12;      \
+	MOVQ 8*8(SI), X13;      \
+	MOVQ 0*8(SI), X14;      \
+	MOVQ 6*8(SI), X15;      \
+	VPINSRQ_1_SI_X12(15*8); \
+	VPINSRQ_1_SI_X13(2*8);  \
+	VPINSRQ_1_SI_X14(4*8);  \
+	VPINSRQ_1_SI_X15(10*8)
+
+// load msg: X12 = (12, 13), X13 = (1, 10), X14 = (2, 7), X15 = (4, 5)
+#define LOAD_MSG_AVX_12_13_1_10_2_7_4_5() \
+	VMOVDQU 12*8(SI), X12;  \
+	MOVQ    1*8(SI), X13;   \
+	MOVQ    2*8(SI), X14;   \
+	VPINSRQ_1_SI_X13(10*8); \
+	VPINSRQ_1_SI_X14(7*8);  \
+	VMOVDQU 4*8(SI), X15
+
+// load msg: X12 = (15, 9), X13 = (3, 13), X14 = (11, 14), X15 = (12, 0)
+#define LOAD_MSG_AVX_15_9_3_13_11_14_12_0() \
+	MOVQ 15*8(SI), X12;     \
+	MOVQ 3*8(SI), X13;      \
+	MOVQ 11*8(SI), X14;     \
+	MOVQ 12*8(SI), X15;     \
+	VPINSRQ_1_SI_X12(9*8);  \
+	VPINSRQ_1_SI_X13(13*8); \
+	VPINSRQ_1_SI_X14(14*8); \
+	VPINSRQ_1_SI_X15_0
+
+// func hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
+TEXT ·hashBlocksAVX(SB), 4, $288-48 // frame size = 272 + 16 byte alignment
+	MOVQ h+0(FP), AX
+	MOVQ c+8(FP), BX
+	MOVQ flag+16(FP), CX
+	MOVQ blocks_base+24(FP), SI
+	MOVQ blocks_len+32(FP), DI
+
+	MOVQ SP, R10
+	ADDQ $15, R10
+	ANDQ $~15, R10
+
+	VMOVDQU ·AVX_c40<>(SB), X0
+	VMOVDQU ·AVX_c48<>(SB), X1
+	VMOVDQA X0, X8
+	VMOVDQA X1, X9
+
+	VMOVDQU ·AVX_iv3<>(SB), X0
+	VMOVDQA X0, 0(R10)
+	XORQ    CX, 0(R10)          // 0(R10) = ·AVX_iv3 ^ (CX || 0)
+
+	VMOVDQU 0(AX), X10
+	VMOVDQU 16(AX), X11
+	VMOVDQU 32(AX), X2
+	VMOVDQU 48(AX), X3
+
+	MOVQ 0(BX), R8
+	MOVQ 8(BX), R9
+
+loop:
+	ADDQ $128, R8
+	CMPQ R8, $128
+	JGE  noinc
+	INCQ R9
+
+noinc:
+	VMOVQ_R8_X15
+	VPINSRQ_1_R9_X15
+
+	VMOVDQA X10, X0
+	VMOVDQA X11, X1
+	VMOVDQU ·AVX_iv0<>(SB), X4
+	VMOVDQU ·AVX_iv1<>(SB), X5
+	VMOVDQU ·AVX_iv2<>(SB), X6
+
+	VPXOR   X15, X6, X6
+	VMOVDQA 0(R10), X7
+
+	LOAD_MSG_AVX_0_2_4_6_1_3_5_7()
+	VMOVDQA X12, 16(R10)
+	VMOVDQA X13, 32(R10)
+	VMOVDQA X14, 48(R10)
+	VMOVDQA X15, 64(R10)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX(8, 10, 12, 14, 9, 11, 13, 15)
+	VMOVDQA X12, 80(R10)
+	VMOVDQA X13, 96(R10)
+	VMOVDQA X14, 112(R10)
+	VMOVDQA X15, 128(R10)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX(14, 4, 9, 13, 10, 8, 15, 6)
+	VMOVDQA X12, 144(R10)
+	VMOVDQA X13, 160(R10)
+	VMOVDQA X14, 176(R10)
+	VMOVDQA X15, 192(R10)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX_1_0_11_5_12_2_7_3()
+	VMOVDQA X12, 208(R10)
+	VMOVDQA X13, 224(R10)
+	VMOVDQA X14, 240(R10)
+	VMOVDQA X15, 256(R10)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX_11_12_5_15_8_0_2_13()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX(10, 3, 7, 9, 14, 6, 1, 4)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX(7, 3, 13, 11, 9, 1, 12, 14)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX_2_5_4_15_6_10_0_8()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX_9_5_2_10_0_7_4_15()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX(14, 11, 6, 3, 1, 12, 8, 13)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX_2_6_0_8_12_10_11_3()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX(4, 7, 15, 1, 13, 5, 14, 9)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX(12, 1, 14, 4, 5, 15, 13, 10)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX_0_6_9_8_7_3_2_11()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX(13, 7, 12, 3, 11, 14, 1, 9)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX_5_15_8_2_0_4_6_10()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX_6_14_11_0_15_9_3_8()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX_12_13_1_10_2_7_4_5()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	LOAD_MSG_AVX(10, 8, 7, 1, 2, 4, 6, 5)
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX()
+	LOAD_MSG_AVX_15_9_3_13_11_14_12_0()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, X12, X13, X14, X15, X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 16(R10), 32(R10), 48(R10), 64(R10), X15, X8, X9)
+	SHUFFLE_AVX()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 80(R10), 96(R10), 112(R10), 128(R10), X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 144(R10), 160(R10), 176(R10), 192(R10), X15, X8, X9)
+	SHUFFLE_AVX()
+	HALF_ROUND_AVX(X0, X1, X2, X3, X4, X5, X6, X7, 208(R10), 224(R10), 240(R10), 256(R10), X15, X8, X9)
+	SHUFFLE_AVX_INV()
+
+	VMOVDQU 32(AX), X14
+	VMOVDQU 48(AX), X15
+	VPXOR   X0, X10, X10
+	VPXOR   X1, X11, X11
+	VPXOR   X2, X14, X14
+	VPXOR   X3, X15, X15
+	VPXOR   X4, X10, X10
+	VPXOR   X5, X11, X11
+	VPXOR   X6, X14, X2
+	VPXOR   X7, X15, X3
+	VMOVDQU X2, 32(AX)
+	VMOVDQU X3, 48(AX)
+
+	LEAQ 128(SI), SI
+	SUBQ $128, DI
+	JNE  loop
+
+	VMOVDQU X10, 0(AX)
+	VMOVDQU X11, 16(AX)
+
+	MOVQ R8, 0(BX)
+	MOVQ R9, 8(BX)
+	VZEROUPPER
+
+	RET
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s b/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s
new file mode 100644
index 00000000..adfac00c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s
@@ -0,0 +1,278 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && gc && !purego
+
+#include "textflag.h"
+
+DATA ·iv0<>+0x00(SB)/8, $0x6a09e667f3bcc908
+DATA ·iv0<>+0x08(SB)/8, $0xbb67ae8584caa73b
+GLOBL ·iv0<>(SB), (NOPTR+RODATA), $16
+
+DATA ·iv1<>+0x00(SB)/8, $0x3c6ef372fe94f82b
+DATA ·iv1<>+0x08(SB)/8, $0xa54ff53a5f1d36f1
+GLOBL ·iv1<>(SB), (NOPTR+RODATA), $16
+
+DATA ·iv2<>+0x00(SB)/8, $0x510e527fade682d1
+DATA ·iv2<>+0x08(SB)/8, $0x9b05688c2b3e6c1f
+GLOBL ·iv2<>(SB), (NOPTR+RODATA), $16
+
+DATA ·iv3<>+0x00(SB)/8, $0x1f83d9abfb41bd6b
+DATA ·iv3<>+0x08(SB)/8, $0x5be0cd19137e2179
+GLOBL ·iv3<>(SB), (NOPTR+RODATA), $16
+
+DATA ·c40<>+0x00(SB)/8, $0x0201000706050403
+DATA ·c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b
+GLOBL ·c40<>(SB), (NOPTR+RODATA), $16
+
+DATA ·c48<>+0x00(SB)/8, $0x0100070605040302
+DATA ·c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a
+GLOBL ·c48<>(SB), (NOPTR+RODATA), $16
+
+#define SHUFFLE(v2, v3, v4, v5, v6, v7, t1, t2) \
+	MOVO       v4, t1; \
+	MOVO       v5, v4; \
+	MOVO       t1, v5; \
+	MOVO       v6, t1; \
+	PUNPCKLQDQ v6, t2; \
+	PUNPCKHQDQ v7, v6; \
+	PUNPCKHQDQ t2, v6; \
+	PUNPCKLQDQ v7, t2; \
+	MOVO       t1, v7; \
+	MOVO       v2, t1; \
+	PUNPCKHQDQ t2, v7; \
+	PUNPCKLQDQ v3, t2; \
+	PUNPCKHQDQ t2, v2; \
+	PUNPCKLQDQ t1, t2; \
+	PUNPCKHQDQ t2, v3
+
+#define SHUFFLE_INV(v2, v3, v4, v5, v6, v7, t1, t2) \
+	MOVO       v4, t1; \
+	MOVO       v5, v4; \
+	MOVO       t1, v5; \
+	MOVO       v2, t1; \
+	PUNPCKLQDQ v2, t2; \
+	PUNPCKHQDQ v3, v2; \
+	PUNPCKHQDQ t2, v2; \
+	PUNPCKLQDQ v3, t2; \
+	MOVO       t1, v3; \
+	MOVO       v6, t1; \
+	PUNPCKHQDQ t2, v3; \
+	PUNPCKLQDQ v7, t2; \
+	PUNPCKHQDQ t2, v6; \
+	PUNPCKLQDQ t1, t2; \
+	PUNPCKHQDQ t2, v7
+
+#define HALF_ROUND(v0, v1, v2, v3, v4, v5, v6, v7, m0, m1, m2, m3, t0, c40, c48) \
+	PADDQ  m0, v0;        \
+	PADDQ  m1, v1;        \
+	PADDQ  v2, v0;        \
+	PADDQ  v3, v1;        \
+	PXOR   v0, v6;        \
+	PXOR   v1, v7;        \
+	PSHUFD $0xB1, v6, v6; \
+	PSHUFD $0xB1, v7, v7; \
+	PADDQ  v6, v4;        \
+	PADDQ  v7, v5;        \
+	PXOR   v4, v2;        \
+	PXOR   v5, v3;        \
+	PSHUFB c40, v2;       \
+	PSHUFB c40, v3;       \
+	PADDQ  m2, v0;        \
+	PADDQ  m3, v1;        \
+	PADDQ  v2, v0;        \
+	PADDQ  v3, v1;        \
+	PXOR   v0, v6;        \
+	PXOR   v1, v7;        \
+	PSHUFB c48, v6;       \
+	PSHUFB c48, v7;       \
+	PADDQ  v6, v4;        \
+	PADDQ  v7, v5;        \
+	PXOR   v4, v2;        \
+	PXOR   v5, v3;        \
+	MOVOU  v2, t0;        \
+	PADDQ  v2, t0;        \
+	PSRLQ  $63, v2;       \
+	PXOR   t0, v2;        \
+	MOVOU  v3, t0;        \
+	PADDQ  v3, t0;        \
+	PSRLQ  $63, v3;       \
+	PXOR   t0, v3
+
+#define LOAD_MSG(m0, m1, m2, m3, src, i0, i1, i2, i3, i4, i5, i6, i7) \
+	MOVQ   i0*8(src), m0;     \
+	PINSRQ $1, i1*8(src), m0; \
+	MOVQ   i2*8(src), m1;     \
+	PINSRQ $1, i3*8(src), m1; \
+	MOVQ   i4*8(src), m2;     \
+	PINSRQ $1, i5*8(src), m2; \
+	MOVQ   i6*8(src), m3;     \
+	PINSRQ $1, i7*8(src), m3
+
+// func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
+TEXT ·hashBlocksSSE4(SB), 4, $288-48 // frame size = 272 + 16 byte alignment
+	MOVQ h+0(FP), AX
+	MOVQ c+8(FP), BX
+	MOVQ flag+16(FP), CX
+	MOVQ blocks_base+24(FP), SI
+	MOVQ blocks_len+32(FP), DI
+
+	MOVQ SP, R10
+	ADDQ $15, R10
+	ANDQ $~15, R10
+
+	MOVOU ·iv3<>(SB), X0
+	MOVO  X0, 0(R10)
+	XORQ  CX, 0(R10)     // 0(R10) = ·iv3 ^ (CX || 0)
+
+	MOVOU ·c40<>(SB), X13
+	MOVOU ·c48<>(SB), X14
+
+	MOVOU 0(AX), X12
+	MOVOU 16(AX), X15
+
+	MOVQ 0(BX), R8
+	MOVQ 8(BX), R9
+
+loop:
+	ADDQ $128, R8
+	CMPQ R8, $128
+	JGE  noinc
+	INCQ R9
+
+noinc:
+	MOVQ R8, X8
+	PINSRQ $1, R9, X8
+
+	MOVO X12, X0
+	MOVO X15, X1
+	MOVOU 32(AX), X2
+	MOVOU 48(AX), X3
+	MOVOU ·iv0<>(SB), X4
+	MOVOU ·iv1<>(SB), X5
+	MOVOU ·iv2<>(SB), X6
+
+	PXOR X8, X6
+	MOVO 0(R10), X7
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 0, 2, 4, 6, 1, 3, 5, 7)
+	MOVO X8, 16(R10)
+	MOVO X9, 32(R10)
+	MOVO X10, 48(R10)
+	MOVO X11, 64(R10)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 8, 10, 12, 14, 9, 11, 13, 15)
+	MOVO X8, 80(R10)
+	MOVO X9, 96(R10)
+	MOVO X10, 112(R10)
+	MOVO X11, 128(R10)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 14, 4, 9, 13, 10, 8, 15, 6)
+	MOVO X8, 144(R10)
+	MOVO X9, 160(R10)
+	MOVO X10, 176(R10)
+	MOVO X11, 192(R10)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 1, 0, 11, 5, 12, 2, 7, 3)
+	MOVO X8, 208(R10)
+	MOVO X9, 224(R10)
+	MOVO X10, 240(R10)
+	MOVO X11, 256(R10)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 11, 12, 5, 15, 8, 0, 2, 13)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 10, 3, 7, 9, 14, 6, 1, 4)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 7, 3, 13, 11, 9, 1, 12, 14)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 2, 5, 4, 15, 6, 10, 0, 8)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 9, 5, 2, 10, 0, 7, 4, 15)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 14, 11, 6, 3, 1, 12, 8, 13)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 2, 6, 0, 8, 12, 10, 11, 3)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 4, 7, 15, 1, 13, 5, 14, 9)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 12, 1, 14, 4, 5, 15, 13, 10)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 0, 6, 9, 8, 7, 3, 2, 11)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 13, 7, 12, 3, 11, 14, 1, 9)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 5, 15, 8, 2, 0, 4, 6, 10)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 6, 14, 11, 0, 15, 9, 3, 8)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 12, 13, 1, 10, 2, 7, 4, 5)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	LOAD_MSG(X8, X9, X10, X11, SI, 10, 8, 7, 1, 2, 4, 6, 5)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	LOAD_MSG(X8, X9, X10, X11, SI, 15, 9, 3, 13, 11, 14, 12, 0)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 16(R10), 32(R10), 48(R10), 64(R10), X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 80(R10), 96(R10), 112(R10), 128(R10), X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 144(R10), 160(R10), 176(R10), 192(R10), X11, X13, X14)
+	SHUFFLE(X2, X3, X4, X5, X6, X7, X8, X9)
+	HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, 208(R10), 224(R10), 240(R10), 256(R10), X11, X13, X14)
+	SHUFFLE_INV(X2, X3, X4, X5, X6, X7, X8, X9)
+
+	MOVOU 32(AX), X10
+	MOVOU 48(AX), X11
+	PXOR  X0, X12
+	PXOR  X1, X15
+	PXOR  X2, X10
+	PXOR  X3, X11
+	PXOR  X4, X12
+	PXOR  X5, X15
+	PXOR  X6, X10
+	PXOR  X7, X11
+	MOVOU X10, 32(AX)
+	MOVOU X11, 48(AX)
+
+	LEAQ 128(SI), SI
+	SUBQ $128, DI
+	JNE  loop
+
+	MOVOU X12, 0(AX)
+	MOVOU X15, 16(AX)
+
+	MOVQ R8, 0(BX)
+	MOVQ R9, 8(BX)
+
+	RET
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b_generic.go b/vendor/golang.org/x/crypto/blake2b/blake2b_generic.go
new file mode 100644
index 00000000..3168a8aa
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2b_generic.go
@@ -0,0 +1,182 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package blake2b
+
+import (
+	"encoding/binary"
+	"math/bits"
+)
+
+// the precomputed values for BLAKE2b
+// there are 12 16-byte arrays - one for each round
+// the entries are calculated from the sigma constants.
+var precomputed = [12][16]byte{
+	{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15},
+	{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3},
+	{11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4},
+	{7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8},
+	{9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13},
+	{2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9},
+	{12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11},
+	{13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10},
+	{6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5},
+	{10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0},
+	{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15}, // equal to the first
+	{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3}, // equal to the second
+}
+
+func hashBlocksGeneric(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
+	var m [16]uint64
+	c0, c1 := c[0], c[1]
+
+	for i := 0; i < len(blocks); {
+		c0 += BlockSize
+		if c0 < BlockSize {
+			c1++
+		}
+
+		v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
+		v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]
+		v12 ^= c0
+		v13 ^= c1
+		v14 ^= flag
+
+		for j := range m {
+			m[j] = binary.LittleEndian.Uint64(blocks[i:])
+			i += 8
+		}
+
+		for j := range precomputed {
+			s := &(precomputed[j])
+
+			v0 += m[s[0]]
+			v0 += v4
+			v12 ^= v0
+			v12 = bits.RotateLeft64(v12, -32)
+			v8 += v12
+			v4 ^= v8
+			v4 = bits.RotateLeft64(v4, -24)
+			v1 += m[s[1]]
+			v1 += v5
+			v13 ^= v1
+			v13 = bits.RotateLeft64(v13, -32)
+			v9 += v13
+			v5 ^= v9
+			v5 = bits.RotateLeft64(v5, -24)
+			v2 += m[s[2]]
+			v2 += v6
+			v14 ^= v2
+			v14 = bits.RotateLeft64(v14, -32)
+			v10 += v14
+			v6 ^= v10
+			v6 = bits.RotateLeft64(v6, -24)
+			v3 += m[s[3]]
+			v3 += v7
+			v15 ^= v3
+			v15 = bits.RotateLeft64(v15, -32)
+			v11 += v15
+			v7 ^= v11
+			v7 = bits.RotateLeft64(v7, -24)
+
+			v0 += m[s[4]]
+			v0 += v4
+			v12 ^= v0
+			v12 = bits.RotateLeft64(v12, -16)
+			v8 += v12
+			v4 ^= v8
+			v4 = bits.RotateLeft64(v4, -63)
+			v1 += m[s[5]]
+			v1 += v5
+			v13 ^= v1
+			v13 = bits.RotateLeft64(v13, -16)
+			v9 += v13
+			v5 ^= v9
+			v5 = bits.RotateLeft64(v5, -63)
+			v2 += m[s[6]]
+			v2 += v6
+			v14 ^= v2
+			v14 = bits.RotateLeft64(v14, -16)
+			v10 += v14
+			v6 ^= v10
+			v6 = bits.RotateLeft64(v6, -63)
+			v3 += m[s[7]]
+			v3 += v7
+			v15 ^= v3
+			v15 = bits.RotateLeft64(v15, -16)
+			v11 += v15
+			v7 ^= v11
+			v7 = bits.RotateLeft64(v7, -63)
+
+			v0 += m[s[8]]
+			v0 += v5
+			v15 ^= v0
+			v15 = bits.RotateLeft64(v15, -32)
+			v10 += v15
+			v5 ^= v10
+			v5 = bits.RotateLeft64(v5, -24)
+			v1 += m[s[9]]
+			v1 += v6
+			v12 ^= v1
+			v12 = bits.RotateLeft64(v12, -32)
+			v11 += v12
+			v6 ^= v11
+			v6 = bits.RotateLeft64(v6, -24)
+			v2 += m[s[10]]
+			v2 += v7
+			v13 ^= v2
+			v13 = bits.RotateLeft64(v13, -32)
+			v8 += v13
+			v7 ^= v8
+			v7 = bits.RotateLeft64(v7, -24)
+			v3 += m[s[11]]
+			v3 += v4
+			v14 ^= v3
+			v14 = bits.RotateLeft64(v14, -32)
+			v9 += v14
+			v4 ^= v9
+			v4 = bits.RotateLeft64(v4, -24)
+
+			v0 += m[s[12]]
+			v0 += v5
+			v15 ^= v0
+			v15 = bits.RotateLeft64(v15, -16)
+			v10 += v15
+			v5 ^= v10
+			v5 = bits.RotateLeft64(v5, -63)
+			v1 += m[s[13]]
+			v1 += v6
+			v12 ^= v1
+			v12 = bits.RotateLeft64(v12, -16)
+			v11 += v12
+			v6 ^= v11
+			v6 = bits.RotateLeft64(v6, -63)
+			v2 += m[s[14]]
+			v2 += v7
+			v13 ^= v2
+			v13 = bits.RotateLeft64(v13, -16)
+			v8 += v13
+			v7 ^= v8
+			v7 = bits.RotateLeft64(v7, -63)
+			v3 += m[s[15]]
+			v3 += v4
+			v14 ^= v3
+			v14 = bits.RotateLeft64(v14, -16)
+			v9 += v14
+			v4 ^= v9
+			v4 = bits.RotateLeft64(v4, -63)
+
+		}
+
+		h[0] ^= v0 ^ v8
+		h[1] ^= v1 ^ v9
+		h[2] ^= v2 ^ v10
+		h[3] ^= v3 ^ v11
+		h[4] ^= v4 ^ v12
+		h[5] ^= v5 ^ v13
+		h[6] ^= v6 ^ v14
+		h[7] ^= v7 ^ v15
+	}
+	c[0], c[1] = c0, c1
+}
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b_ref.go b/vendor/golang.org/x/crypto/blake2b/blake2b_ref.go
new file mode 100644
index 00000000..6e28668c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2b_ref.go
@@ -0,0 +1,11 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 || purego || !gc
+
+package blake2b
+
+func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
+	hashBlocksGeneric(h, c, flag, blocks)
+}
diff --git a/vendor/golang.org/x/crypto/blake2b/blake2x.go b/vendor/golang.org/x/crypto/blake2b/blake2x.go
new file mode 100644
index 00000000..52c414db
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/blake2x.go
@@ -0,0 +1,177 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package blake2b
+
+import (
+	"encoding/binary"
+	"errors"
+	"io"
+)
+
+// XOF defines the interface to hash functions that
+// support arbitrary-length output.
+type XOF interface {
+	// Write absorbs more data into the hash's state. It panics if called
+	// after Read.
+	io.Writer
+
+	// Read reads more output from the hash. It returns io.EOF if the limit
+	// has been reached.
+	io.Reader
+
+	// Clone returns a copy of the XOF in its current state.
+	Clone() XOF
+
+	// Reset resets the XOF to its initial state.
+	Reset()
+}
+
+// OutputLengthUnknown can be used as the size argument to NewXOF to indicate
+// the length of the output is not known in advance.
+const OutputLengthUnknown = 0
+
+// magicUnknownOutputLength is a magic value for the output size that indicates
+// an unknown number of output bytes.
+const magicUnknownOutputLength = (1 << 32) - 1
+
+// maxOutputLength is the absolute maximum number of bytes to produce when the
+// number of output bytes is unknown.
+const maxOutputLength = (1 << 32) * 64
+
+// NewXOF creates a new variable-output-length hash. The hash either produce a
+// known number of bytes (1 <= size < 2**32-1), or an unknown number of bytes
+// (size == OutputLengthUnknown). In the latter case, an absolute limit of
+// 256GiB applies.
+//
+// A non-nil key turns the hash into a MAC. The key must between
+// zero and 32 bytes long.
+func NewXOF(size uint32, key []byte) (XOF, error) {
+	if len(key) > Size {
+		return nil, errKeySize
+	}
+	if size == magicUnknownOutputLength {
+		// 2^32-1 indicates an unknown number of bytes and thus isn't a
+		// valid length.
+		return nil, errors.New("blake2b: XOF length too large")
+	}
+	if size == OutputLengthUnknown {
+		size = magicUnknownOutputLength
+	}
+	x := &xof{
+		d: digest{
+			size:   Size,
+			keyLen: len(key),
+		},
+		length: size,
+	}
+	copy(x.d.key[:], key)
+	x.Reset()
+	return x, nil
+}
+
+type xof struct {
+	d                digest
+	length           uint32
+	remaining        uint64
+	cfg, root, block [Size]byte
+	offset           int
+	nodeOffset       uint32
+	readMode         bool
+}
+
+func (x *xof) Write(p []byte) (n int, err error) {
+	if x.readMode {
+		panic("blake2b: write to XOF after read")
+	}
+	return x.d.Write(p)
+}
+
+func (x *xof) Clone() XOF {
+	clone := *x
+	return &clone
+}
+
+func (x *xof) Reset() {
+	x.cfg[0] = byte(Size)
+	binary.LittleEndian.PutUint32(x.cfg[4:], uint32(Size)) // leaf length
+	binary.LittleEndian.PutUint32(x.cfg[12:], x.length)    // XOF length
+	x.cfg[17] = byte(Size)                                 // inner hash size
+
+	x.d.Reset()
+	x.d.h[1] ^= uint64(x.length) << 32
+
+	x.remaining = uint64(x.length)
+	if x.remaining == magicUnknownOutputLength {
+		x.remaining = maxOutputLength
+	}
+	x.offset, x.nodeOffset = 0, 0
+	x.readMode = false
+}
+
+func (x *xof) Read(p []byte) (n int, err error) {
+	if !x.readMode {
+		x.d.finalize(&x.root)
+		x.readMode = true
+	}
+
+	if x.remaining == 0 {
+		return 0, io.EOF
+	}
+
+	n = len(p)
+	if uint64(n) > x.remaining {
+		n = int(x.remaining)
+		p = p[:n]
+	}
+
+	if x.offset > 0 {
+		blockRemaining := Size - x.offset
+		if n < blockRemaining {
+			x.offset += copy(p, x.block[x.offset:])
+			x.remaining -= uint64(n)
+			return
+		}
+		copy(p, x.block[x.offset:])
+		p = p[blockRemaining:]
+		x.offset = 0
+		x.remaining -= uint64(blockRemaining)
+	}
+
+	for len(p) >= Size {
+		binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
+		x.nodeOffset++
+
+		x.d.initConfig(&x.cfg)
+		x.d.Write(x.root[:])
+		x.d.finalize(&x.block)
+
+		copy(p, x.block[:])
+		p = p[Size:]
+		x.remaining -= uint64(Size)
+	}
+
+	if todo := len(p); todo > 0 {
+		if x.remaining < uint64(Size) {
+			x.cfg[0] = byte(x.remaining)
+		}
+		binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
+		x.nodeOffset++
+
+		x.d.initConfig(&x.cfg)
+		x.d.Write(x.root[:])
+		x.d.finalize(&x.block)
+
+		x.offset = copy(p, x.block[:todo])
+		x.remaining -= uint64(todo)
+	}
+	return
+}
+
+func (d *digest) initConfig(cfg *[Size]byte) {
+	d.offset, d.c[0], d.c[1] = 0, 0, 0
+	for i := range d.h {
+		d.h[i] = iv[i] ^ binary.LittleEndian.Uint64(cfg[i*8:])
+	}
+}
diff --git a/vendor/golang.org/x/crypto/blake2b/register.go b/vendor/golang.org/x/crypto/blake2b/register.go
new file mode 100644
index 00000000..54e446e1
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2b/register.go
@@ -0,0 +1,30 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package blake2b
+
+import (
+	"crypto"
+	"hash"
+)
+
+func init() {
+	newHash256 := func() hash.Hash {
+		h, _ := New256(nil)
+		return h
+	}
+	newHash384 := func() hash.Hash {
+		h, _ := New384(nil)
+		return h
+	}
+
+	newHash512 := func() hash.Hash {
+		h, _ := New512(nil)
+		return h
+	}
+
+	crypto.RegisterHash(crypto.BLAKE2b_256, newHash256)
+	crypto.RegisterHash(crypto.BLAKE2b_384, newHash384)
+	crypto.RegisterHash(crypto.BLAKE2b_512, newHash512)
+}
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s.go b/vendor/golang.org/x/crypto/blake2s/blake2s.go
new file mode 100644
index 00000000..c25d07d4
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s.go
@@ -0,0 +1,254 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package blake2s implements the BLAKE2s hash algorithm defined by RFC 7693
+// and the extendable output function (XOF) BLAKE2Xs.
+//
+// BLAKE2s is optimized for 8- to 32-bit platforms and produces digests of any
+// size between 1 and 32 bytes.
+// For a detailed specification of BLAKE2s see https://blake2.net/blake2.pdf
+// and for BLAKE2Xs see https://blake2.net/blake2x.pdf
+//
+// If you aren't sure which function you need, use BLAKE2s (Sum256 or New256).
+// If you need a secret-key MAC (message authentication code), use the New256
+// function with a non-nil key.
+//
+// BLAKE2X is a construction to compute hash values larger than 32 bytes. It
+// can produce hash values between 0 and 65535 bytes.
+package blake2s
+
+import (
+	"crypto"
+	"encoding/binary"
+	"errors"
+	"hash"
+)
+
+const (
+	// The blocksize of BLAKE2s in bytes.
+	BlockSize = 64
+
+	// The hash size of BLAKE2s-256 in bytes.
+	Size = 32
+
+	// The hash size of BLAKE2s-128 in bytes.
+	Size128 = 16
+)
+
+var errKeySize = errors.New("blake2s: invalid key size")
+
+var iv = [8]uint32{
+	0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+	0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
+}
+
+// Sum256 returns the BLAKE2s-256 checksum of the data.
+func Sum256(data []byte) [Size]byte {
+	var sum [Size]byte
+	checkSum(&sum, Size, data)
+	return sum
+}
+
+// New256 returns a new hash.Hash computing the BLAKE2s-256 checksum. A non-nil
+// key turns the hash into a MAC. The key must between zero and 32 bytes long.
+// When the key is nil, the returned hash.Hash implements BinaryMarshaler
+// and BinaryUnmarshaler for state (de)serialization as documented by hash.Hash.
+func New256(key []byte) (hash.Hash, error) { return newDigest(Size, key) }
+
+func init() {
+	crypto.RegisterHash(crypto.BLAKE2s_256, func() hash.Hash {
+		h, _ := New256(nil)
+		return h
+	})
+}
+
+// New128 returns a new hash.Hash computing the BLAKE2s-128 checksum given a
+// non-empty key. Note that a 128-bit digest is too small to be secure as a
+// cryptographic hash and should only be used as a MAC, thus the key argument
+// is not optional.
+func New128(key []byte) (hash.Hash, error) {
+	if len(key) == 0 {
+		return nil, errors.New("blake2s: a key is required for a 128-bit hash")
+	}
+	return newDigest(Size128, key)
+}
+
+func newDigest(hashSize int, key []byte) (*digest, error) {
+	if len(key) > Size {
+		return nil, errKeySize
+	}
+	d := &digest{
+		size:   hashSize,
+		keyLen: len(key),
+	}
+	copy(d.key[:], key)
+	d.Reset()
+	return d, nil
+}
+
+func checkSum(sum *[Size]byte, hashSize int, data []byte) {
+	var (
+		h [8]uint32
+		c [2]uint32
+	)
+
+	h = iv
+	h[0] ^= uint32(hashSize) | (1 << 16) | (1 << 24)
+
+	if length := len(data); length > BlockSize {
+		n := length &^ (BlockSize - 1)
+		if length == n {
+			n -= BlockSize
+		}
+		hashBlocks(&h, &c, 0, data[:n])
+		data = data[n:]
+	}
+
+	var block [BlockSize]byte
+	offset := copy(block[:], data)
+	remaining := uint32(BlockSize - offset)
+
+	if c[0] < remaining {
+		c[1]--
+	}
+	c[0] -= remaining
+
+	hashBlocks(&h, &c, 0xFFFFFFFF, block[:])
+
+	for i, v := range h {
+		binary.LittleEndian.PutUint32(sum[4*i:], v)
+	}
+}
+
+type digest struct {
+	h      [8]uint32
+	c      [2]uint32
+	size   int
+	block  [BlockSize]byte
+	offset int
+
+	key    [BlockSize]byte
+	keyLen int
+}
+
+const (
+	magic         = "b2s"
+	marshaledSize = len(magic) + 8*4 + 2*4 + 1 + BlockSize + 1
+)
+
+func (d *digest) MarshalBinary() ([]byte, error) {
+	if d.keyLen != 0 {
+		return nil, errors.New("crypto/blake2s: cannot marshal MACs")
+	}
+	b := make([]byte, 0, marshaledSize)
+	b = append(b, magic...)
+	for i := 0; i < 8; i++ {
+		b = appendUint32(b, d.h[i])
+	}
+	b = appendUint32(b, d.c[0])
+	b = appendUint32(b, d.c[1])
+	// Maximum value for size is 32
+	b = append(b, byte(d.size))
+	b = append(b, d.block[:]...)
+	b = append(b, byte(d.offset))
+	return b, nil
+}
+
+func (d *digest) UnmarshalBinary(b []byte) error {
+	if len(b) < len(magic) || string(b[:len(magic)]) != magic {
+		return errors.New("crypto/blake2s: invalid hash state identifier")
+	}
+	if len(b) != marshaledSize {
+		return errors.New("crypto/blake2s: invalid hash state size")
+	}
+	b = b[len(magic):]
+	for i := 0; i < 8; i++ {
+		b, d.h[i] = consumeUint32(b)
+	}
+	b, d.c[0] = consumeUint32(b)
+	b, d.c[1] = consumeUint32(b)
+	d.size = int(b[0])
+	b = b[1:]
+	copy(d.block[:], b[:BlockSize])
+	b = b[BlockSize:]
+	d.offset = int(b[0])
+	return nil
+}
+
+func (d *digest) BlockSize() int { return BlockSize }
+
+func (d *digest) Size() int { return d.size }
+
+func (d *digest) Reset() {
+	d.h = iv
+	d.h[0] ^= uint32(d.size) | (uint32(d.keyLen) << 8) | (1 << 16) | (1 << 24)
+	d.offset, d.c[0], d.c[1] = 0, 0, 0
+	if d.keyLen > 0 {
+		d.block = d.key
+		d.offset = BlockSize
+	}
+}
+
+func (d *digest) Write(p []byte) (n int, err error) {
+	n = len(p)
+
+	if d.offset > 0 {
+		remaining := BlockSize - d.offset
+		if n <= remaining {
+			d.offset += copy(d.block[d.offset:], p)
+			return
+		}
+		copy(d.block[d.offset:], p[:remaining])
+		hashBlocks(&d.h, &d.c, 0, d.block[:])
+		d.offset = 0
+		p = p[remaining:]
+	}
+
+	if length := len(p); length > BlockSize {
+		nn := length &^ (BlockSize - 1)
+		if length == nn {
+			nn -= BlockSize
+		}
+		hashBlocks(&d.h, &d.c, 0, p[:nn])
+		p = p[nn:]
+	}
+
+	d.offset += copy(d.block[:], p)
+	return
+}
+
+func (d *digest) Sum(sum []byte) []byte {
+	var hash [Size]byte
+	d.finalize(&hash)
+	return append(sum, hash[:d.size]...)
+}
+
+func (d *digest) finalize(hash *[Size]byte) {
+	var block [BlockSize]byte
+	h := d.h
+	c := d.c
+
+	copy(block[:], d.block[:d.offset])
+	remaining := uint32(BlockSize - d.offset)
+	if c[0] < remaining {
+		c[1]--
+	}
+	c[0] -= remaining
+
+	hashBlocks(&h, &c, 0xFFFFFFFF, block[:])
+	for i, v := range h {
+		binary.LittleEndian.PutUint32(hash[4*i:], v)
+	}
+}
+
+func appendUint32(b []byte, x uint32) []byte {
+	var a [4]byte
+	binary.BigEndian.PutUint32(a[:], x)
+	return append(b, a[:]...)
+}
+
+func consumeUint32(b []byte) ([]byte, uint32) {
+	x := binary.BigEndian.Uint32(b)
+	return b[4:], x
+}
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s_386.go b/vendor/golang.org/x/crypto/blake2s/blake2s_386.go
new file mode 100644
index 00000000..97f62961
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s_386.go
@@ -0,0 +1,32 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build 386 && gc && !purego
+
+package blake2s
+
+import "golang.org/x/sys/cpu"
+
+var (
+	useSSE4  = false
+	useSSSE3 = cpu.X86.HasSSSE3
+	useSSE2  = cpu.X86.HasSSE2
+)
+
+//go:noescape
+func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+
+//go:noescape
+func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+
+func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
+	switch {
+	case useSSSE3:
+		hashBlocksSSSE3(h, c, flag, blocks)
+	case useSSE2:
+		hashBlocksSSE2(h, c, flag, blocks)
+	default:
+		hashBlocksGeneric(h, c, flag, blocks)
+	}
+}
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s_386.s b/vendor/golang.org/x/crypto/blake2s/blake2s_386.s
new file mode 100644
index 00000000..919c0265
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s_386.s
@@ -0,0 +1,429 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build 386 && gc && !purego
+
+#include "textflag.h"
+
+DATA iv0<>+0x00(SB)/4, $0x6a09e667
+DATA iv0<>+0x04(SB)/4, $0xbb67ae85
+DATA iv0<>+0x08(SB)/4, $0x3c6ef372
+DATA iv0<>+0x0c(SB)/4, $0xa54ff53a
+GLOBL iv0<>(SB), (NOPTR+RODATA), $16
+
+DATA iv1<>+0x00(SB)/4, $0x510e527f
+DATA iv1<>+0x04(SB)/4, $0x9b05688c
+DATA iv1<>+0x08(SB)/4, $0x1f83d9ab
+DATA iv1<>+0x0c(SB)/4, $0x5be0cd19
+GLOBL iv1<>(SB), (NOPTR+RODATA), $16
+
+DATA rol16<>+0x00(SB)/8, $0x0504070601000302
+DATA rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A
+GLOBL rol16<>(SB), (NOPTR+RODATA), $16
+
+DATA rol8<>+0x00(SB)/8, $0x0407060500030201
+DATA rol8<>+0x08(SB)/8, $0x0C0F0E0D080B0A09
+GLOBL rol8<>(SB), (NOPTR+RODATA), $16
+
+DATA counter<>+0x00(SB)/8, $0x40
+DATA counter<>+0x08(SB)/8, $0x0
+GLOBL counter<>(SB), (NOPTR+RODATA), $16
+
+#define ROTL_SSE2(n, t, v) \
+	MOVO  v, t;       \
+	PSLLL $n, t;      \
+	PSRLL $(32-n), v; \
+	PXOR  t, v
+
+#define ROTL_SSSE3(c, v) \
+	PSHUFB c, v
+
+#define ROUND_SSE2(v0, v1, v2, v3, m0, m1, m2, m3, t) \
+	PADDL  m0, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(16, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m1, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(24, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v1, v1; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v3, v3; \
+	PADDL  m2, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(16, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m3, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(24, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v3, v3; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v1, v1
+
+#define ROUND_SSSE3(v0, v1, v2, v3, m0, m1, m2, m3, t, c16, c8) \
+	PADDL  m0, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c16, v3);  \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m1, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c8, v3);   \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v1, v1; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v3, v3; \
+	PADDL  m2, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c16, v3);  \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m3, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c8, v3);   \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v3, v3; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v1, v1
+
+#define PRECOMPUTE(dst, off, src, t) \
+	MOVL 0*4(src), t;          \
+	MOVL t, 0*4+off+0(dst);    \
+	MOVL t, 9*4+off+64(dst);   \
+	MOVL t, 5*4+off+128(dst);  \
+	MOVL t, 14*4+off+192(dst); \
+	MOVL t, 4*4+off+256(dst);  \
+	MOVL t, 2*4+off+320(dst);  \
+	MOVL t, 8*4+off+384(dst);  \
+	MOVL t, 12*4+off+448(dst); \
+	MOVL t, 3*4+off+512(dst);  \
+	MOVL t, 15*4+off+576(dst); \
+	MOVL 1*4(src), t;          \
+	MOVL t, 4*4+off+0(dst);    \
+	MOVL t, 8*4+off+64(dst);   \
+	MOVL t, 14*4+off+128(dst); \
+	MOVL t, 5*4+off+192(dst);  \
+	MOVL t, 12*4+off+256(dst); \
+	MOVL t, 11*4+off+320(dst); \
+	MOVL t, 1*4+off+384(dst);  \
+	MOVL t, 6*4+off+448(dst);  \
+	MOVL t, 10*4+off+512(dst); \
+	MOVL t, 3*4+off+576(dst);  \
+	MOVL 2*4(src), t;          \
+	MOVL t, 1*4+off+0(dst);    \
+	MOVL t, 13*4+off+64(dst);  \
+	MOVL t, 6*4+off+128(dst);  \
+	MOVL t, 8*4+off+192(dst);  \
+	MOVL t, 2*4+off+256(dst);  \
+	MOVL t, 0*4+off+320(dst);  \
+	MOVL t, 14*4+off+384(dst); \
+	MOVL t, 11*4+off+448(dst); \
+	MOVL t, 12*4+off+512(dst); \
+	MOVL t, 4*4+off+576(dst);  \
+	MOVL 3*4(src), t;          \
+	MOVL t, 5*4+off+0(dst);    \
+	MOVL t, 15*4+off+64(dst);  \
+	MOVL t, 9*4+off+128(dst);  \
+	MOVL t, 1*4+off+192(dst);  \
+	MOVL t, 11*4+off+256(dst); \
+	MOVL t, 7*4+off+320(dst);  \
+	MOVL t, 13*4+off+384(dst); \
+	MOVL t, 3*4+off+448(dst);  \
+	MOVL t, 6*4+off+512(dst);  \
+	MOVL t, 10*4+off+576(dst); \
+	MOVL 4*4(src), t;          \
+	MOVL t, 2*4+off+0(dst);    \
+	MOVL t, 1*4+off+64(dst);   \
+	MOVL t, 15*4+off+128(dst); \
+	MOVL t, 10*4+off+192(dst); \
+	MOVL t, 6*4+off+256(dst);  \
+	MOVL t, 8*4+off+320(dst);  \
+	MOVL t, 3*4+off+384(dst);  \
+	MOVL t, 13*4+off+448(dst); \
+	MOVL t, 14*4+off+512(dst); \
+	MOVL t, 5*4+off+576(dst);  \
+	MOVL 5*4(src), t;          \
+	MOVL t, 6*4+off+0(dst);    \
+	MOVL t, 11*4+off+64(dst);  \
+	MOVL t, 2*4+off+128(dst);  \
+	MOVL t, 9*4+off+192(dst);  \
+	MOVL t, 1*4+off+256(dst);  \
+	MOVL t, 13*4+off+320(dst); \
+	MOVL t, 4*4+off+384(dst);  \
+	MOVL t, 8*4+off+448(dst);  \
+	MOVL t, 15*4+off+512(dst); \
+	MOVL t, 7*4+off+576(dst);  \
+	MOVL 6*4(src), t;          \
+	MOVL t, 3*4+off+0(dst);    \
+	MOVL t, 7*4+off+64(dst);   \
+	MOVL t, 13*4+off+128(dst); \
+	MOVL t, 12*4+off+192(dst); \
+	MOVL t, 10*4+off+256(dst); \
+	MOVL t, 1*4+off+320(dst);  \
+	MOVL t, 9*4+off+384(dst);  \
+	MOVL t, 14*4+off+448(dst); \
+	MOVL t, 0*4+off+512(dst);  \
+	MOVL t, 6*4+off+576(dst);  \
+	MOVL 7*4(src), t;          \
+	MOVL t, 7*4+off+0(dst);    \
+	MOVL t, 14*4+off+64(dst);  \
+	MOVL t, 10*4+off+128(dst); \
+	MOVL t, 0*4+off+192(dst);  \
+	MOVL t, 5*4+off+256(dst);  \
+	MOVL t, 9*4+off+320(dst);  \
+	MOVL t, 12*4+off+384(dst); \
+	MOVL t, 1*4+off+448(dst);  \
+	MOVL t, 13*4+off+512(dst); \
+	MOVL t, 2*4+off+576(dst);  \
+	MOVL 8*4(src), t;          \
+	MOVL t, 8*4+off+0(dst);    \
+	MOVL t, 5*4+off+64(dst);   \
+	MOVL t, 4*4+off+128(dst);  \
+	MOVL t, 15*4+off+192(dst); \
+	MOVL t, 14*4+off+256(dst); \
+	MOVL t, 3*4+off+320(dst);  \
+	MOVL t, 11*4+off+384(dst); \
+	MOVL t, 10*4+off+448(dst); \
+	MOVL t, 7*4+off+512(dst);  \
+	MOVL t, 1*4+off+576(dst);  \
+	MOVL 9*4(src), t;          \
+	MOVL t, 12*4+off+0(dst);   \
+	MOVL t, 2*4+off+64(dst);   \
+	MOVL t, 11*4+off+128(dst); \
+	MOVL t, 4*4+off+192(dst);  \
+	MOVL t, 0*4+off+256(dst);  \
+	MOVL t, 15*4+off+320(dst); \
+	MOVL t, 10*4+off+384(dst); \
+	MOVL t, 7*4+off+448(dst);  \
+	MOVL t, 5*4+off+512(dst);  \
+	MOVL t, 9*4+off+576(dst);  \
+	MOVL 10*4(src), t;         \
+	MOVL t, 9*4+off+0(dst);    \
+	MOVL t, 4*4+off+64(dst);   \
+	MOVL t, 8*4+off+128(dst);  \
+	MOVL t, 13*4+off+192(dst); \
+	MOVL t, 3*4+off+256(dst);  \
+	MOVL t, 5*4+off+320(dst);  \
+	MOVL t, 7*4+off+384(dst);  \
+	MOVL t, 15*4+off+448(dst); \
+	MOVL t, 11*4+off+512(dst); \
+	MOVL t, 0*4+off+576(dst);  \
+	MOVL 11*4(src), t;         \
+	MOVL t, 13*4+off+0(dst);   \
+	MOVL t, 10*4+off+64(dst);  \
+	MOVL t, 0*4+off+128(dst);  \
+	MOVL t, 3*4+off+192(dst);  \
+	MOVL t, 9*4+off+256(dst);  \
+	MOVL t, 6*4+off+320(dst);  \
+	MOVL t, 15*4+off+384(dst); \
+	MOVL t, 4*4+off+448(dst);  \
+	MOVL t, 2*4+off+512(dst);  \
+	MOVL t, 12*4+off+576(dst); \
+	MOVL 12*4(src), t;         \
+	MOVL t, 10*4+off+0(dst);   \
+	MOVL t, 12*4+off+64(dst);  \
+	MOVL t, 1*4+off+128(dst);  \
+	MOVL t, 6*4+off+192(dst);  \
+	MOVL t, 13*4+off+256(dst); \
+	MOVL t, 4*4+off+320(dst);  \
+	MOVL t, 0*4+off+384(dst);  \
+	MOVL t, 2*4+off+448(dst);  \
+	MOVL t, 8*4+off+512(dst);  \
+	MOVL t, 14*4+off+576(dst); \
+	MOVL 13*4(src), t;         \
+	MOVL t, 14*4+off+0(dst);   \
+	MOVL t, 3*4+off+64(dst);   \
+	MOVL t, 7*4+off+128(dst);  \
+	MOVL t, 2*4+off+192(dst);  \
+	MOVL t, 15*4+off+256(dst); \
+	MOVL t, 12*4+off+320(dst); \
+	MOVL t, 6*4+off+384(dst);  \
+	MOVL t, 0*4+off+448(dst);  \
+	MOVL t, 9*4+off+512(dst);  \
+	MOVL t, 11*4+off+576(dst); \
+	MOVL 14*4(src), t;         \
+	MOVL t, 11*4+off+0(dst);   \
+	MOVL t, 0*4+off+64(dst);   \
+	MOVL t, 12*4+off+128(dst); \
+	MOVL t, 7*4+off+192(dst);  \
+	MOVL t, 8*4+off+256(dst);  \
+	MOVL t, 14*4+off+320(dst); \
+	MOVL t, 2*4+off+384(dst);  \
+	MOVL t, 5*4+off+448(dst);  \
+	MOVL t, 1*4+off+512(dst);  \
+	MOVL t, 13*4+off+576(dst); \
+	MOVL 15*4(src), t;         \
+	MOVL t, 15*4+off+0(dst);   \
+	MOVL t, 6*4+off+64(dst);   \
+	MOVL t, 3*4+off+128(dst);  \
+	MOVL t, 11*4+off+192(dst); \
+	MOVL t, 7*4+off+256(dst);  \
+	MOVL t, 10*4+off+320(dst); \
+	MOVL t, 5*4+off+384(dst);  \
+	MOVL t, 9*4+off+448(dst);  \
+	MOVL t, 4*4+off+512(dst);  \
+	MOVL t, 8*4+off+576(dst)
+
+// func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+TEXT ·hashBlocksSSE2(SB), 0, $672-24 // frame = 656 + 16 byte alignment
+	MOVL h+0(FP), AX
+	MOVL c+4(FP), BX
+	MOVL flag+8(FP), CX
+	MOVL blocks_base+12(FP), SI
+	MOVL blocks_len+16(FP), DX
+
+	MOVL SP, DI
+	ADDL $15, DI
+	ANDL $~15, DI
+
+	MOVL CX, 8(DI)
+	MOVL 0(BX), CX
+	MOVL CX, 0(DI)
+	MOVL 4(BX), CX
+	MOVL CX, 4(DI)
+	XORL CX, CX
+	MOVL CX, 12(DI)
+
+	MOVOU 0(AX), X0
+	MOVOU 16(AX), X1
+	MOVOU counter<>(SB), X2
+
+loop:
+	MOVO  X0, X4
+	MOVO  X1, X5
+	MOVOU iv0<>(SB), X6
+	MOVOU iv1<>(SB), X7
+
+	MOVO  0(DI), X3
+	PADDQ X2, X3
+	PXOR  X3, X7
+	MOVO  X3, 0(DI)
+
+	PRECOMPUTE(DI, 16, SI, CX)
+	ROUND_SSE2(X4, X5, X6, X7, 16(DI), 32(DI), 48(DI), 64(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+64(DI), 32+64(DI), 48+64(DI), 64+64(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+128(DI), 32+128(DI), 48+128(DI), 64+128(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+192(DI), 32+192(DI), 48+192(DI), 64+192(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+256(DI), 32+256(DI), 48+256(DI), 64+256(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+320(DI), 32+320(DI), 48+320(DI), 64+320(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+384(DI), 32+384(DI), 48+384(DI), 64+384(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+448(DI), 32+448(DI), 48+448(DI), 64+448(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+512(DI), 32+512(DI), 48+512(DI), 64+512(DI), X3)
+	ROUND_SSE2(X4, X5, X6, X7, 16+576(DI), 32+576(DI), 48+576(DI), 64+576(DI), X3)
+
+	PXOR X4, X0
+	PXOR X5, X1
+	PXOR X6, X0
+	PXOR X7, X1
+
+	LEAL 64(SI), SI
+	SUBL $64, DX
+	JNE  loop
+
+	MOVL 0(DI), CX
+	MOVL CX, 0(BX)
+	MOVL 4(DI), CX
+	MOVL CX, 4(BX)
+
+	MOVOU X0, 0(AX)
+	MOVOU X1, 16(AX)
+
+	RET
+
+// func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+TEXT ·hashBlocksSSSE3(SB), 0, $704-24 // frame = 688 + 16 byte alignment
+	MOVL h+0(FP), AX
+	MOVL c+4(FP), BX
+	MOVL flag+8(FP), CX
+	MOVL blocks_base+12(FP), SI
+	MOVL blocks_len+16(FP), DX
+
+	MOVL SP, DI
+	ADDL $15, DI
+	ANDL $~15, DI
+
+	MOVL CX, 8(DI)
+	MOVL 0(BX), CX
+	MOVL CX, 0(DI)
+	MOVL 4(BX), CX
+	MOVL CX, 4(DI)
+	XORL CX, CX
+	MOVL CX, 12(DI)
+
+	MOVOU 0(AX), X0
+	MOVOU 16(AX), X1
+	MOVOU counter<>(SB), X2
+
+loop:
+	MOVO  X0, 656(DI)
+	MOVO  X1, 672(DI)
+	MOVO  X0, X4
+	MOVO  X1, X5
+	MOVOU iv0<>(SB), X6
+	MOVOU iv1<>(SB), X7
+
+	MOVO  0(DI), X3
+	PADDQ X2, X3
+	PXOR  X3, X7
+	MOVO  X3, 0(DI)
+
+	MOVOU rol16<>(SB), X0
+	MOVOU rol8<>(SB), X1
+
+	PRECOMPUTE(DI, 16, SI, CX)
+	ROUND_SSSE3(X4, X5, X6, X7, 16(DI), 32(DI), 48(DI), 64(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+64(DI), 32+64(DI), 48+64(DI), 64+64(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+128(DI), 32+128(DI), 48+128(DI), 64+128(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+192(DI), 32+192(DI), 48+192(DI), 64+192(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+256(DI), 32+256(DI), 48+256(DI), 64+256(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+320(DI), 32+320(DI), 48+320(DI), 64+320(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+384(DI), 32+384(DI), 48+384(DI), 64+384(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+448(DI), 32+448(DI), 48+448(DI), 64+448(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+512(DI), 32+512(DI), 48+512(DI), 64+512(DI), X3, X0, X1)
+	ROUND_SSSE3(X4, X5, X6, X7, 16+576(DI), 32+576(DI), 48+576(DI), 64+576(DI), X3, X0, X1)
+
+	MOVO 656(DI), X0
+	MOVO 672(DI), X1
+	PXOR X4, X0
+	PXOR X5, X1
+	PXOR X6, X0
+	PXOR X7, X1
+
+	LEAL 64(SI), SI
+	SUBL $64, DX
+	JNE  loop
+
+	MOVL 0(DI), CX
+	MOVL CX, 0(BX)
+	MOVL 4(DI), CX
+	MOVL CX, 4(BX)
+
+	MOVOU X0, 0(AX)
+	MOVOU X1, 16(AX)
+
+	RET
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go b/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go
new file mode 100644
index 00000000..8a731025
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go
@@ -0,0 +1,37 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && gc && !purego
+
+package blake2s
+
+import "golang.org/x/sys/cpu"
+
+var (
+	useSSE4  = cpu.X86.HasSSE41
+	useSSSE3 = cpu.X86.HasSSSE3
+	useSSE2  = cpu.X86.HasSSE2
+)
+
+//go:noescape
+func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+
+//go:noescape
+func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+
+//go:noescape
+func hashBlocksSSE4(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+
+func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
+	switch {
+	case useSSE4:
+		hashBlocksSSE4(h, c, flag, blocks)
+	case useSSSE3:
+		hashBlocksSSSE3(h, c, flag, blocks)
+	case useSSE2:
+		hashBlocksSSE2(h, c, flag, blocks)
+	default:
+		hashBlocksGeneric(h, c, flag, blocks)
+	}
+}
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s b/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s
new file mode 100644
index 00000000..fe4b818a
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s
@@ -0,0 +1,432 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && gc && !purego
+
+#include "textflag.h"
+
+DATA iv0<>+0x00(SB)/4, $0x6a09e667
+DATA iv0<>+0x04(SB)/4, $0xbb67ae85
+DATA iv0<>+0x08(SB)/4, $0x3c6ef372
+DATA iv0<>+0x0c(SB)/4, $0xa54ff53a
+GLOBL iv0<>(SB), (NOPTR+RODATA), $16
+
+DATA iv1<>+0x00(SB)/4, $0x510e527f
+DATA iv1<>+0x04(SB)/4, $0x9b05688c
+DATA iv1<>+0x08(SB)/4, $0x1f83d9ab
+DATA iv1<>+0x0c(SB)/4, $0x5be0cd19
+GLOBL iv1<>(SB), (NOPTR+RODATA), $16
+
+DATA rol16<>+0x00(SB)/8, $0x0504070601000302
+DATA rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A
+GLOBL rol16<>(SB), (NOPTR+RODATA), $16
+
+DATA rol8<>+0x00(SB)/8, $0x0407060500030201
+DATA rol8<>+0x08(SB)/8, $0x0C0F0E0D080B0A09
+GLOBL rol8<>(SB), (NOPTR+RODATA), $16
+
+DATA counter<>+0x00(SB)/8, $0x40
+DATA counter<>+0x08(SB)/8, $0x0
+GLOBL counter<>(SB), (NOPTR+RODATA), $16
+
+#define ROTL_SSE2(n, t, v) \
+	MOVO  v, t;       \
+	PSLLL $n, t;      \
+	PSRLL $(32-n), v; \
+	PXOR  t, v
+
+#define ROTL_SSSE3(c, v) \
+	PSHUFB c, v
+
+#define ROUND_SSE2(v0, v1, v2, v3, m0, m1, m2, m3, t) \
+	PADDL  m0, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(16, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m1, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(24, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v1, v1; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v3, v3; \
+	PADDL  m2, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(16, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m3, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSE2(24, t, v3); \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v3, v3; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v1, v1
+
+#define ROUND_SSSE3(v0, v1, v2, v3, m0, m1, m2, m3, t, c16, c8) \
+	PADDL  m0, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c16, v3);  \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m1, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c8, v3);   \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v1, v1; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v3, v3; \
+	PADDL  m2, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c16, v3);  \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(20, t, v1); \
+	PADDL  m3, v0;        \
+	PADDL  v1, v0;        \
+	PXOR   v0, v3;        \
+	ROTL_SSSE3(c8, v3);   \
+	PADDL  v3, v2;        \
+	PXOR   v2, v1;        \
+	ROTL_SSE2(25, t, v1); \
+	PSHUFL $0x39, v3, v3; \
+	PSHUFL $0x4E, v2, v2; \
+	PSHUFL $0x93, v1, v1
+
+
+#define LOAD_MSG_SSE4(m0, m1, m2, m3, src, i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15) \
+	MOVL   i0*4(src), m0;      \
+	PINSRD $1, i1*4(src), m0;  \
+	PINSRD $2, i2*4(src), m0;  \
+	PINSRD $3, i3*4(src), m0;  \
+	MOVL   i4*4(src), m1;      \
+	PINSRD $1, i5*4(src), m1;  \
+	PINSRD $2, i6*4(src), m1;  \
+	PINSRD $3, i7*4(src), m1;  \
+	MOVL   i8*4(src), m2;      \
+	PINSRD $1, i9*4(src), m2;  \
+	PINSRD $2, i10*4(src), m2; \
+	PINSRD $3, i11*4(src), m2; \
+	MOVL   i12*4(src), m3;     \
+	PINSRD $1, i13*4(src), m3; \
+	PINSRD $2, i14*4(src), m3; \
+	PINSRD $3, i15*4(src), m3
+
+#define PRECOMPUTE_MSG(dst, off, src, R8, R9, R10, R11, R12, R13, R14, R15) \
+	MOVQ 0*4(src), R8;           \
+	MOVQ 2*4(src), R9;           \
+	MOVQ 4*4(src), R10;          \
+	MOVQ 6*4(src), R11;          \
+	MOVQ 8*4(src), R12;          \
+	MOVQ 10*4(src), R13;         \
+	MOVQ 12*4(src), R14;         \
+	MOVQ 14*4(src), R15;         \
+	                             \
+	MOVL R8, 0*4+off+0(dst);     \
+	MOVL R8, 9*4+off+64(dst);    \
+	MOVL R8, 5*4+off+128(dst);   \
+	MOVL R8, 14*4+off+192(dst);  \
+	MOVL R8, 4*4+off+256(dst);   \
+	MOVL R8, 2*4+off+320(dst);   \
+	MOVL R8, 8*4+off+384(dst);   \
+	MOVL R8, 12*4+off+448(dst);  \
+	MOVL R8, 3*4+off+512(dst);   \
+	MOVL R8, 15*4+off+576(dst);  \
+	SHRQ $32, R8;                \
+	MOVL R8, 4*4+off+0(dst);     \
+	MOVL R8, 8*4+off+64(dst);    \
+	MOVL R8, 14*4+off+128(dst);  \
+	MOVL R8, 5*4+off+192(dst);   \
+	MOVL R8, 12*4+off+256(dst);  \
+	MOVL R8, 11*4+off+320(dst);  \
+	MOVL R8, 1*4+off+384(dst);   \
+	MOVL R8, 6*4+off+448(dst);   \
+	MOVL R8, 10*4+off+512(dst);  \
+	MOVL R8, 3*4+off+576(dst);   \
+	                             \
+	MOVL R9, 1*4+off+0(dst);     \
+	MOVL R9, 13*4+off+64(dst);   \
+	MOVL R9, 6*4+off+128(dst);   \
+	MOVL R9, 8*4+off+192(dst);   \
+	MOVL R9, 2*4+off+256(dst);   \
+	MOVL R9, 0*4+off+320(dst);   \
+	MOVL R9, 14*4+off+384(dst);  \
+	MOVL R9, 11*4+off+448(dst);  \
+	MOVL R9, 12*4+off+512(dst);  \
+	MOVL R9, 4*4+off+576(dst);   \
+	SHRQ $32, R9;                \
+	MOVL R9, 5*4+off+0(dst);     \
+	MOVL R9, 15*4+off+64(dst);   \
+	MOVL R9, 9*4+off+128(dst);   \
+	MOVL R9, 1*4+off+192(dst);   \
+	MOVL R9, 11*4+off+256(dst);  \
+	MOVL R9, 7*4+off+320(dst);   \
+	MOVL R9, 13*4+off+384(dst);  \
+	MOVL R9, 3*4+off+448(dst);   \
+	MOVL R9, 6*4+off+512(dst);   \
+	MOVL R9, 10*4+off+576(dst);  \
+	                             \
+	MOVL R10, 2*4+off+0(dst);    \
+	MOVL R10, 1*4+off+64(dst);   \
+	MOVL R10, 15*4+off+128(dst); \
+	MOVL R10, 10*4+off+192(dst); \
+	MOVL R10, 6*4+off+256(dst);  \
+	MOVL R10, 8*4+off+320(dst);  \
+	MOVL R10, 3*4+off+384(dst);  \
+	MOVL R10, 13*4+off+448(dst); \
+	MOVL R10, 14*4+off+512(dst); \
+	MOVL R10, 5*4+off+576(dst);  \
+	SHRQ $32, R10;               \
+	MOVL R10, 6*4+off+0(dst);    \
+	MOVL R10, 11*4+off+64(dst);  \
+	MOVL R10, 2*4+off+128(dst);  \
+	MOVL R10, 9*4+off+192(dst);  \
+	MOVL R10, 1*4+off+256(dst);  \
+	MOVL R10, 13*4+off+320(dst); \
+	MOVL R10, 4*4+off+384(dst);  \
+	MOVL R10, 8*4+off+448(dst);  \
+	MOVL R10, 15*4+off+512(dst); \
+	MOVL R10, 7*4+off+576(dst);  \
+	                             \
+	MOVL R11, 3*4+off+0(dst);    \
+	MOVL R11, 7*4+off+64(dst);   \
+	MOVL R11, 13*4+off+128(dst); \
+	MOVL R11, 12*4+off+192(dst); \
+	MOVL R11, 10*4+off+256(dst); \
+	MOVL R11, 1*4+off+320(dst);  \
+	MOVL R11, 9*4+off+384(dst);  \
+	MOVL R11, 14*4+off+448(dst); \
+	MOVL R11, 0*4+off+512(dst);  \
+	MOVL R11, 6*4+off+576(dst);  \
+	SHRQ $32, R11;               \
+	MOVL R11, 7*4+off+0(dst);    \
+	MOVL R11, 14*4+off+64(dst);  \
+	MOVL R11, 10*4+off+128(dst); \
+	MOVL R11, 0*4+off+192(dst);  \
+	MOVL R11, 5*4+off+256(dst);  \
+	MOVL R11, 9*4+off+320(dst);  \
+	MOVL R11, 12*4+off+384(dst); \
+	MOVL R11, 1*4+off+448(dst);  \
+	MOVL R11, 13*4+off+512(dst); \
+	MOVL R11, 2*4+off+576(dst);  \
+	                             \
+	MOVL R12, 8*4+off+0(dst);    \
+	MOVL R12, 5*4+off+64(dst);   \
+	MOVL R12, 4*4+off+128(dst);  \
+	MOVL R12, 15*4+off+192(dst); \
+	MOVL R12, 14*4+off+256(dst); \
+	MOVL R12, 3*4+off+320(dst);  \
+	MOVL R12, 11*4+off+384(dst); \
+	MOVL R12, 10*4+off+448(dst); \
+	MOVL R12, 7*4+off+512(dst);  \
+	MOVL R12, 1*4+off+576(dst);  \
+	SHRQ $32, R12;               \
+	MOVL R12, 12*4+off+0(dst);   \
+	MOVL R12, 2*4+off+64(dst);   \
+	MOVL R12, 11*4+off+128(dst); \
+	MOVL R12, 4*4+off+192(dst);  \
+	MOVL R12, 0*4+off+256(dst);  \
+	MOVL R12, 15*4+off+320(dst); \
+	MOVL R12, 10*4+off+384(dst); \
+	MOVL R12, 7*4+off+448(dst);  \
+	MOVL R12, 5*4+off+512(dst);  \
+	MOVL R12, 9*4+off+576(dst);  \
+	                             \
+	MOVL R13, 9*4+off+0(dst);    \
+	MOVL R13, 4*4+off+64(dst);   \
+	MOVL R13, 8*4+off+128(dst);  \
+	MOVL R13, 13*4+off+192(dst); \
+	MOVL R13, 3*4+off+256(dst);  \
+	MOVL R13, 5*4+off+320(dst);  \
+	MOVL R13, 7*4+off+384(dst);  \
+	MOVL R13, 15*4+off+448(dst); \
+	MOVL R13, 11*4+off+512(dst); \
+	MOVL R13, 0*4+off+576(dst);  \
+	SHRQ $32, R13;               \
+	MOVL R13, 13*4+off+0(dst);   \
+	MOVL R13, 10*4+off+64(dst);  \
+	MOVL R13, 0*4+off+128(dst);  \
+	MOVL R13, 3*4+off+192(dst);  \
+	MOVL R13, 9*4+off+256(dst);  \
+	MOVL R13, 6*4+off+320(dst);  \
+	MOVL R13, 15*4+off+384(dst); \
+	MOVL R13, 4*4+off+448(dst);  \
+	MOVL R13, 2*4+off+512(dst);  \
+	MOVL R13, 12*4+off+576(dst); \
+	                             \
+	MOVL R14, 10*4+off+0(dst);   \
+	MOVL R14, 12*4+off+64(dst);  \
+	MOVL R14, 1*4+off+128(dst);  \
+	MOVL R14, 6*4+off+192(dst);  \
+	MOVL R14, 13*4+off+256(dst); \
+	MOVL R14, 4*4+off+320(dst);  \
+	MOVL R14, 0*4+off+384(dst);  \
+	MOVL R14, 2*4+off+448(dst);  \
+	MOVL R14, 8*4+off+512(dst);  \
+	MOVL R14, 14*4+off+576(dst); \
+	SHRQ $32, R14;               \
+	MOVL R14, 14*4+off+0(dst);   \
+	MOVL R14, 3*4+off+64(dst);   \
+	MOVL R14, 7*4+off+128(dst);  \
+	MOVL R14, 2*4+off+192(dst);  \
+	MOVL R14, 15*4+off+256(dst); \
+	MOVL R14, 12*4+off+320(dst); \
+	MOVL R14, 6*4+off+384(dst);  \
+	MOVL R14, 0*4+off+448(dst);  \
+	MOVL R14, 9*4+off+512(dst);  \
+	MOVL R14, 11*4+off+576(dst); \
+	                             \
+	MOVL R15, 11*4+off+0(dst);   \
+	MOVL R15, 0*4+off+64(dst);   \
+	MOVL R15, 12*4+off+128(dst); \
+	MOVL R15, 7*4+off+192(dst);  \
+	MOVL R15, 8*4+off+256(dst);  \
+	MOVL R15, 14*4+off+320(dst); \
+	MOVL R15, 2*4+off+384(dst);  \
+	MOVL R15, 5*4+off+448(dst);  \
+	MOVL R15, 1*4+off+512(dst);  \
+	MOVL R15, 13*4+off+576(dst); \
+	SHRQ $32, R15;               \
+	MOVL R15, 15*4+off+0(dst);   \
+	MOVL R15, 6*4+off+64(dst);   \
+	MOVL R15, 3*4+off+128(dst);  \
+	MOVL R15, 11*4+off+192(dst); \
+	MOVL R15, 7*4+off+256(dst);  \
+	MOVL R15, 10*4+off+320(dst); \
+	MOVL R15, 5*4+off+384(dst);  \
+	MOVL R15, 9*4+off+448(dst);  \
+	MOVL R15, 4*4+off+512(dst);  \
+	MOVL R15, 8*4+off+576(dst)
+
+#define BLAKE2s_SSE2() \
+	PRECOMPUTE_MSG(BP, 16, SI, R8, R9, R10, R11, R12, R13, R14, R15);               \
+	ROUND_SSE2(X4, X5, X6, X7, 16(BP), 32(BP), 48(BP), 64(BP), X8);                 \
+	ROUND_SSE2(X4, X5, X6, X7, 16+64(BP), 32+64(BP), 48+64(BP), 64+64(BP), X8);     \
+	ROUND_SSE2(X4, X5, X6, X7, 16+128(BP), 32+128(BP), 48+128(BP), 64+128(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+192(BP), 32+192(BP), 48+192(BP), 64+192(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+256(BP), 32+256(BP), 48+256(BP), 64+256(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+320(BP), 32+320(BP), 48+320(BP), 64+320(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+384(BP), 32+384(BP), 48+384(BP), 64+384(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+448(BP), 32+448(BP), 48+448(BP), 64+448(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+512(BP), 32+512(BP), 48+512(BP), 64+512(BP), X8); \
+	ROUND_SSE2(X4, X5, X6, X7, 16+576(BP), 32+576(BP), 48+576(BP), 64+576(BP), X8)
+
+#define BLAKE2s_SSSE3() \
+	PRECOMPUTE_MSG(BP, 16, SI, R8, R9, R10, R11, R12, R13, R14, R15);                          \
+	ROUND_SSSE3(X4, X5, X6, X7, 16(BP), 32(BP), 48(BP), 64(BP), X8, X13, X14);                 \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+64(BP), 32+64(BP), 48+64(BP), 64+64(BP), X8, X13, X14);     \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+128(BP), 32+128(BP), 48+128(BP), 64+128(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+192(BP), 32+192(BP), 48+192(BP), 64+192(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+256(BP), 32+256(BP), 48+256(BP), 64+256(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+320(BP), 32+320(BP), 48+320(BP), 64+320(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+384(BP), 32+384(BP), 48+384(BP), 64+384(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+448(BP), 32+448(BP), 48+448(BP), 64+448(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+512(BP), 32+512(BP), 48+512(BP), 64+512(BP), X8, X13, X14); \
+	ROUND_SSSE3(X4, X5, X6, X7, 16+576(BP), 32+576(BP), 48+576(BP), 64+576(BP), X8, X13, X14)
+
+#define BLAKE2s_SSE4() \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14);                               \
+	LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0); \
+	ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14)
+
+#define HASH_BLOCKS(h, c, flag, blocks_base, blocks_len, BLAKE2s_FUNC) \
+	MOVQ  h, AX;                   \
+	MOVQ  c, BX;                   \
+	MOVL  flag, CX;                \
+	MOVQ  blocks_base, SI;         \
+	MOVQ  blocks_len, DX;          \
+	                               \
+	MOVQ  SP, BP;                  \
+	ADDQ  $15, BP;                 \
+	ANDQ  $~15, BP;                \
+	                               \
+	MOVQ  0(BX), R9;               \
+	MOVQ  R9, 0(BP);               \
+	MOVQ  CX, 8(BP);               \
+	                               \
+	MOVOU 0(AX), X0;               \
+	MOVOU 16(AX), X1;              \
+	MOVOU iv0<>(SB), X2;           \
+	MOVOU iv1<>(SB), X3            \
+	                               \
+	MOVOU counter<>(SB), X12;      \
+	MOVOU rol16<>(SB), X13;        \
+	MOVOU rol8<>(SB), X14;         \
+	MOVO  0(BP), X15;              \
+	                               \
+	loop:                          \
+	MOVO  X0, X4;                  \
+	MOVO  X1, X5;                  \
+	MOVO  X2, X6;                  \
+	MOVO  X3, X7;                  \
+	                               \
+	PADDQ X12, X15;                \
+	PXOR  X15, X7;                 \
+	                               \
+	BLAKE2s_FUNC();                \
+	                               \
+	PXOR  X4, X0;                  \
+	PXOR  X5, X1;                  \
+	PXOR  X6, X0;                  \
+	PXOR  X7, X1;                  \
+	                               \
+	LEAQ  64(SI), SI;              \
+	SUBQ  $64, DX;                 \
+	JNE   loop;                    \
+	                               \
+	MOVO  X15, 0(BP);              \
+	MOVQ  0(BP), R9;               \
+	MOVQ  R9, 0(BX);               \
+	                               \
+	MOVOU X0, 0(AX);               \
+	MOVOU X1, 16(AX)
+
+// func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+TEXT ·hashBlocksSSE2(SB), 0, $672-48 // frame = 656 + 16 byte alignment
+	HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSE2)
+	RET
+
+// func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+TEXT ·hashBlocksSSSE3(SB), 0, $672-48 // frame = 656 + 16 byte alignment
+	HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSSE3)
+	RET
+
+// func hashBlocksSSE4(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
+TEXT ·hashBlocksSSE4(SB), 0, $32-48 // frame = 16 + 16 byte alignment
+	HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSE4)
+	RET
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s_generic.go b/vendor/golang.org/x/crypto/blake2s/blake2s_generic.go
new file mode 100644
index 00000000..24a1ff22
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s_generic.go
@@ -0,0 +1,178 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package blake2s
+
+import (
+	"math/bits"
+)
+
+// the precomputed values for BLAKE2s
+// there are 10 16-byte arrays - one for each round
+// the entries are calculated from the sigma constants.
+var precomputed = [10][16]byte{
+	{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15},
+	{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3},
+	{11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4},
+	{7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8},
+	{9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13},
+	{2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9},
+	{12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11},
+	{13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10},
+	{6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5},
+	{10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0},
+}
+
+func hashBlocksGeneric(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
+	var m [16]uint32
+	c0, c1 := c[0], c[1]
+
+	for i := 0; i < len(blocks); {
+		c0 += BlockSize
+		if c0 < BlockSize {
+			c1++
+		}
+
+		v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
+		v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]
+		v12 ^= c0
+		v13 ^= c1
+		v14 ^= flag
+
+		for j := range m {
+			m[j] = uint32(blocks[i]) | uint32(blocks[i+1])<<8 | uint32(blocks[i+2])<<16 | uint32(blocks[i+3])<<24
+			i += 4
+		}
+
+		for k := range precomputed {
+			s := &(precomputed[k])
+
+			v0 += m[s[0]]
+			v0 += v4
+			v12 ^= v0
+			v12 = bits.RotateLeft32(v12, -16)
+			v8 += v12
+			v4 ^= v8
+			v4 = bits.RotateLeft32(v4, -12)
+			v1 += m[s[1]]
+			v1 += v5
+			v13 ^= v1
+			v13 = bits.RotateLeft32(v13, -16)
+			v9 += v13
+			v5 ^= v9
+			v5 = bits.RotateLeft32(v5, -12)
+			v2 += m[s[2]]
+			v2 += v6
+			v14 ^= v2
+			v14 = bits.RotateLeft32(v14, -16)
+			v10 += v14
+			v6 ^= v10
+			v6 = bits.RotateLeft32(v6, -12)
+			v3 += m[s[3]]
+			v3 += v7
+			v15 ^= v3
+			v15 = bits.RotateLeft32(v15, -16)
+			v11 += v15
+			v7 ^= v11
+			v7 = bits.RotateLeft32(v7, -12)
+
+			v0 += m[s[4]]
+			v0 += v4
+			v12 ^= v0
+			v12 = bits.RotateLeft32(v12, -8)
+			v8 += v12
+			v4 ^= v8
+			v4 = bits.RotateLeft32(v4, -7)
+			v1 += m[s[5]]
+			v1 += v5
+			v13 ^= v1
+			v13 = bits.RotateLeft32(v13, -8)
+			v9 += v13
+			v5 ^= v9
+			v5 = bits.RotateLeft32(v5, -7)
+			v2 += m[s[6]]
+			v2 += v6
+			v14 ^= v2
+			v14 = bits.RotateLeft32(v14, -8)
+			v10 += v14
+			v6 ^= v10
+			v6 = bits.RotateLeft32(v6, -7)
+			v3 += m[s[7]]
+			v3 += v7
+			v15 ^= v3
+			v15 = bits.RotateLeft32(v15, -8)
+			v11 += v15
+			v7 ^= v11
+			v7 = bits.RotateLeft32(v7, -7)
+
+			v0 += m[s[8]]
+			v0 += v5
+			v15 ^= v0
+			v15 = bits.RotateLeft32(v15, -16)
+			v10 += v15
+			v5 ^= v10
+			v5 = bits.RotateLeft32(v5, -12)
+			v1 += m[s[9]]
+			v1 += v6
+			v12 ^= v1
+			v12 = bits.RotateLeft32(v12, -16)
+			v11 += v12
+			v6 ^= v11
+			v6 = bits.RotateLeft32(v6, -12)
+			v2 += m[s[10]]
+			v2 += v7
+			v13 ^= v2
+			v13 = bits.RotateLeft32(v13, -16)
+			v8 += v13
+			v7 ^= v8
+			v7 = bits.RotateLeft32(v7, -12)
+			v3 += m[s[11]]
+			v3 += v4
+			v14 ^= v3
+			v14 = bits.RotateLeft32(v14, -16)
+			v9 += v14
+			v4 ^= v9
+			v4 = bits.RotateLeft32(v4, -12)
+
+			v0 += m[s[12]]
+			v0 += v5
+			v15 ^= v0
+			v15 = bits.RotateLeft32(v15, -8)
+			v10 += v15
+			v5 ^= v10
+			v5 = bits.RotateLeft32(v5, -7)
+			v1 += m[s[13]]
+			v1 += v6
+			v12 ^= v1
+			v12 = bits.RotateLeft32(v12, -8)
+			v11 += v12
+			v6 ^= v11
+			v6 = bits.RotateLeft32(v6, -7)
+			v2 += m[s[14]]
+			v2 += v7
+			v13 ^= v2
+			v13 = bits.RotateLeft32(v13, -8)
+			v8 += v13
+			v7 ^= v8
+			v7 = bits.RotateLeft32(v7, -7)
+			v3 += m[s[15]]
+			v3 += v4
+			v14 ^= v3
+			v14 = bits.RotateLeft32(v14, -8)
+			v9 += v14
+			v4 ^= v9
+			v4 = bits.RotateLeft32(v4, -7)
+		}
+
+		h[0] ^= v0 ^ v8
+		h[1] ^= v1 ^ v9
+		h[2] ^= v2 ^ v10
+		h[3] ^= v3 ^ v11
+		h[4] ^= v4 ^ v12
+		h[5] ^= v5 ^ v13
+		h[6] ^= v6 ^ v14
+		h[7] ^= v7 ^ v15
+	}
+	c[0], c[1] = c0, c1
+}
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2s_ref.go b/vendor/golang.org/x/crypto/blake2s/blake2s_ref.go
new file mode 100644
index 00000000..38ce8e28
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2s_ref.go
@@ -0,0 +1,17 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (!amd64 && !386) || !gc || purego
+
+package blake2s
+
+var (
+	useSSE4  = false
+	useSSSE3 = false
+	useSSE2  = false
+)
+
+func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
+	hashBlocksGeneric(h, c, flag, blocks)
+}
diff --git a/vendor/golang.org/x/crypto/blake2s/blake2x.go b/vendor/golang.org/x/crypto/blake2s/blake2x.go
new file mode 100644
index 00000000..828749ff
--- /dev/null
+++ b/vendor/golang.org/x/crypto/blake2s/blake2x.go
@@ -0,0 +1,178 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package blake2s
+
+import (
+	"encoding/binary"
+	"errors"
+	"io"
+)
+
+// XOF defines the interface to hash functions that
+// support arbitrary-length output.
+type XOF interface {
+	// Write absorbs more data into the hash's state. It panics if called
+	// after Read.
+	io.Writer
+
+	// Read reads more output from the hash. It returns io.EOF if the limit
+	// has been reached.
+	io.Reader
+
+	// Clone returns a copy of the XOF in its current state.
+	Clone() XOF
+
+	// Reset resets the XOF to its initial state.
+	Reset()
+}
+
+// OutputLengthUnknown can be used as the size argument to NewXOF to indicate
+// the length of the output is not known in advance.
+const OutputLengthUnknown = 0
+
+// magicUnknownOutputLength is a magic value for the output size that indicates
+// an unknown number of output bytes.
+const magicUnknownOutputLength = 65535
+
+// maxOutputLength is the absolute maximum number of bytes to produce when the
+// number of output bytes is unknown.
+const maxOutputLength = (1 << 32) * 32
+
+// NewXOF creates a new variable-output-length hash. The hash either produce a
+// known number of bytes (1 <= size < 65535), or an unknown number of bytes
+// (size == OutputLengthUnknown). In the latter case, an absolute limit of
+// 128GiB applies.
+//
+// A non-nil key turns the hash into a MAC. The key must between
+// zero and 32 bytes long.
+func NewXOF(size uint16, key []byte) (XOF, error) {
+	if len(key) > Size {
+		return nil, errKeySize
+	}
+	if size == magicUnknownOutputLength {
+		// 2^16-1 indicates an unknown number of bytes and thus isn't a
+		// valid length.
+		return nil, errors.New("blake2s: XOF length too large")
+	}
+	if size == OutputLengthUnknown {
+		size = magicUnknownOutputLength
+	}
+	x := &xof{
+		d: digest{
+			size:   Size,
+			keyLen: len(key),
+		},
+		length: size,
+	}
+	copy(x.d.key[:], key)
+	x.Reset()
+	return x, nil
+}
+
+type xof struct {
+	d                digest
+	length           uint16
+	remaining        uint64
+	cfg, root, block [Size]byte
+	offset           int
+	nodeOffset       uint32
+	readMode         bool
+}
+
+func (x *xof) Write(p []byte) (n int, err error) {
+	if x.readMode {
+		panic("blake2s: write to XOF after read")
+	}
+	return x.d.Write(p)
+}
+
+func (x *xof) Clone() XOF {
+	clone := *x
+	return &clone
+}
+
+func (x *xof) Reset() {
+	x.cfg[0] = byte(Size)
+	binary.LittleEndian.PutUint32(x.cfg[4:], uint32(Size)) // leaf length
+	binary.LittleEndian.PutUint16(x.cfg[12:], x.length)    // XOF length
+	x.cfg[15] = byte(Size)                                 // inner hash size
+
+	x.d.Reset()
+	x.d.h[3] ^= uint32(x.length)
+
+	x.remaining = uint64(x.length)
+	if x.remaining == magicUnknownOutputLength {
+		x.remaining = maxOutputLength
+	}
+	x.offset, x.nodeOffset = 0, 0
+	x.readMode = false
+}
+
+func (x *xof) Read(p []byte) (n int, err error) {
+	if !x.readMode {
+		x.d.finalize(&x.root)
+		x.readMode = true
+	}
+
+	if x.remaining == 0 {
+		return 0, io.EOF
+	}
+
+	n = len(p)
+	if uint64(n) > x.remaining {
+		n = int(x.remaining)
+		p = p[:n]
+	}
+
+	if x.offset > 0 {
+		blockRemaining := Size - x.offset
+		if n < blockRemaining {
+			x.offset += copy(p, x.block[x.offset:])
+			x.remaining -= uint64(n)
+			return
+		}
+		copy(p, x.block[x.offset:])
+		p = p[blockRemaining:]
+		x.offset = 0
+		x.remaining -= uint64(blockRemaining)
+	}
+
+	for len(p) >= Size {
+		binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
+		x.nodeOffset++
+
+		x.d.initConfig(&x.cfg)
+		x.d.Write(x.root[:])
+		x.d.finalize(&x.block)
+
+		copy(p, x.block[:])
+		p = p[Size:]
+		x.remaining -= uint64(Size)
+	}
+
+	if todo := len(p); todo > 0 {
+		if x.remaining < uint64(Size) {
+			x.cfg[0] = byte(x.remaining)
+		}
+		binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
+		x.nodeOffset++
+
+		x.d.initConfig(&x.cfg)
+		x.d.Write(x.root[:])
+		x.d.finalize(&x.block)
+
+		x.offset = copy(p, x.block[:todo])
+		x.remaining -= uint64(todo)
+	}
+
+	return
+}
+
+func (d *digest) initConfig(cfg *[Size]byte) {
+	d.offset, d.c[0], d.c[1] = 0, 0, 0
+	for i := range d.h {
+		d.h[i] = iv[i] ^ binary.LittleEndian.Uint32(cfg[i*4:])
+	}
+}
diff --git a/vendor/golang.org/x/crypto/blowfish/cipher.go b/vendor/golang.org/x/crypto/blowfish/cipher.go
index 213bf204..08989568 100644
--- a/vendor/golang.org/x/crypto/blowfish/cipher.go
+++ b/vendor/golang.org/x/crypto/blowfish/cipher.go
@@ -11,7 +11,7 @@
 // Deprecated: any new system should use AES (from crypto/aes, if necessary in
 // an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
 // golang.org/x/crypto/chacha20poly1305).
-package blowfish // import "golang.org/x/crypto/blowfish"
+package blowfish
 
 // The code is a port of Bruce Schneier's C implementation.
 // See https://www.schneier.com/blowfish.html.
diff --git a/vendor/golang.org/x/crypto/cast5/cast5.go b/vendor/golang.org/x/crypto/cast5/cast5.go
index 425e8eec..016e9021 100644
--- a/vendor/golang.org/x/crypto/cast5/cast5.go
+++ b/vendor/golang.org/x/crypto/cast5/cast5.go
@@ -11,7 +11,7 @@
 // Deprecated: any new system should use AES (from crypto/aes, if necessary in
 // an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
 // golang.org/x/crypto/chacha20poly1305).
-package cast5 // import "golang.org/x/crypto/cast5"
+package cast5
 
 import (
 	"errors"
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
index 66aebae2..c672ccf6 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
@@ -33,6 +33,9 @@
 #define CONSTBASE  R16
 #define BLOCKS R17
 
+// for VPERMXOR
+#define MASK  R18
+
 DATA consts<>+0x00(SB)/8, $0x3320646e61707865
 DATA consts<>+0x08(SB)/8, $0x6b20657479622d32
 DATA consts<>+0x10(SB)/8, $0x0000000000000001
@@ -53,7 +56,11 @@ DATA consts<>+0x80(SB)/8, $0x6b2065746b206574
 DATA consts<>+0x88(SB)/8, $0x6b2065746b206574
 DATA consts<>+0x90(SB)/8, $0x0000000100000000
 DATA consts<>+0x98(SB)/8, $0x0000000300000002
-GLOBL consts<>(SB), RODATA, $0xa0
+DATA consts<>+0xa0(SB)/8, $0x5566774411223300
+DATA consts<>+0xa8(SB)/8, $0xddeeffcc99aabb88
+DATA consts<>+0xb0(SB)/8, $0x6677445522330011
+DATA consts<>+0xb8(SB)/8, $0xeeffccddaabb8899
+GLOBL consts<>(SB), RODATA, $0xc0
 
 //func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32)
 TEXT ·chaCha20_ctr32_vsx(SB),NOSPLIT,$64-40
@@ -70,6 +77,9 @@ TEXT ·chaCha20_ctr32_vsx(SB),NOSPLIT,$64-40
 	MOVD $48, R10
 	MOVD $64, R11
 	SRD $6, LEN, BLOCKS
+	// for VPERMXOR
+	MOVD $consts<>+0xa0(SB), MASK
+	MOVD $16, R20
 	// V16
 	LXVW4X (CONSTBASE)(R0), VS48
 	ADD $80,CONSTBASE
@@ -87,6 +97,10 @@ TEXT ·chaCha20_ctr32_vsx(SB),NOSPLIT,$64-40
 	// V28
 	LXVW4X (CONSTBASE)(R11), VS60
 
+	// Load mask constants for VPERMXOR
+	LXVW4X (MASK)(R0), V20
+	LXVW4X (MASK)(R20), V21
+
 	// splat slot from V19 -> V26
 	VSPLTW $0, V19, V26
 
@@ -97,7 +111,7 @@ TEXT ·chaCha20_ctr32_vsx(SB),NOSPLIT,$64-40
 
 	MOVD $10, R14
 	MOVD R14, CTR
-
+	PCALIGN $16
 loop_outer_vsx:
 	// V0, V1, V2, V3
 	LXVW4X (R0)(CONSTBASE), VS32
@@ -128,22 +142,17 @@ loop_outer_vsx:
 	VSPLTISW $12, V28
 	VSPLTISW $8, V29
 	VSPLTISW $7, V30
-
+	PCALIGN $16
 loop_vsx:
 	VADDUWM V0, V4, V0
 	VADDUWM V1, V5, V1
 	VADDUWM V2, V6, V2
 	VADDUWM V3, V7, V3
 
-	VXOR V12, V0, V12
-	VXOR V13, V1, V13
-	VXOR V14, V2, V14
-	VXOR V15, V3, V15
-
-	VRLW V12, V27, V12
-	VRLW V13, V27, V13
-	VRLW V14, V27, V14
-	VRLW V15, V27, V15
+	VPERMXOR V12, V0, V21, V12
+	VPERMXOR V13, V1, V21, V13
+	VPERMXOR V14, V2, V21, V14
+	VPERMXOR V15, V3, V21, V15
 
 	VADDUWM V8, V12, V8
 	VADDUWM V9, V13, V9
@@ -165,15 +174,10 @@ loop_vsx:
 	VADDUWM V2, V6, V2
 	VADDUWM V3, V7, V3
 
-	VXOR V12, V0, V12
-	VXOR V13, V1, V13
-	VXOR V14, V2, V14
-	VXOR V15, V3, V15
-
-	VRLW V12, V29, V12
-	VRLW V13, V29, V13
-	VRLW V14, V29, V14
-	VRLW V15, V29, V15
+	VPERMXOR V12, V0, V20, V12
+	VPERMXOR V13, V1, V20, V13
+	VPERMXOR V14, V2, V20, V14
+	VPERMXOR V15, V3, V20, V15
 
 	VADDUWM V8, V12, V8
 	VADDUWM V9, V13, V9
@@ -195,15 +199,10 @@ loop_vsx:
 	VADDUWM V2, V7, V2
 	VADDUWM V3, V4, V3
 
-	VXOR V15, V0, V15
-	VXOR V12, V1, V12
-	VXOR V13, V2, V13
-	VXOR V14, V3, V14
-
-	VRLW V15, V27, V15
-	VRLW V12, V27, V12
-	VRLW V13, V27, V13
-	VRLW V14, V27, V14
+	VPERMXOR V15, V0, V21, V15
+	VPERMXOR V12, V1, V21, V12
+	VPERMXOR V13, V2, V21, V13
+	VPERMXOR V14, V3, V21, V14
 
 	VADDUWM V10, V15, V10
 	VADDUWM V11, V12, V11
@@ -225,15 +224,10 @@ loop_vsx:
 	VADDUWM V2, V7, V2
 	VADDUWM V3, V4, V3
 
-	VXOR V15, V0, V15
-	VXOR V12, V1, V12
-	VXOR V13, V2, V13
-	VXOR V14, V3, V14
-
-	VRLW V15, V29, V15
-	VRLW V12, V29, V12
-	VRLW V13, V29, V13
-	VRLW V14, V29, V14
+	VPERMXOR V15, V0, V20, V15
+	VPERMXOR V12, V1, V20, V12
+	VPERMXOR V13, V2, V20, V13
+	VPERMXOR V14, V3, V20, V14
 
 	VADDUWM V10, V15, V10
 	VADDUWM V11, V12, V11
@@ -249,48 +243,48 @@ loop_vsx:
 	VRLW V6, V30, V6
 	VRLW V7, V30, V7
 	VRLW V4, V30, V4
-	BC   16, LT, loop_vsx
+	BDNZ   loop_vsx
 
 	VADDUWM V12, V26, V12
 
-	WORD $0x13600F8C		// VMRGEW V0, V1, V27
-	WORD $0x13821F8C		// VMRGEW V2, V3, V28
+	VMRGEW V0, V1, V27
+	VMRGEW V2, V3, V28
 
-	WORD $0x10000E8C		// VMRGOW V0, V1, V0
-	WORD $0x10421E8C		// VMRGOW V2, V3, V2
+	VMRGOW V0, V1, V0
+	VMRGOW V2, V3, V2
 
-	WORD $0x13A42F8C		// VMRGEW V4, V5, V29
-	WORD $0x13C63F8C		// VMRGEW V6, V7, V30
+	VMRGEW V4, V5, V29
+	VMRGEW V6, V7, V30
 
 	XXPERMDI VS32, VS34, $0, VS33
 	XXPERMDI VS32, VS34, $3, VS35
 	XXPERMDI VS59, VS60, $0, VS32
 	XXPERMDI VS59, VS60, $3, VS34
 
-	WORD $0x10842E8C		// VMRGOW V4, V5, V4
-	WORD $0x10C63E8C		// VMRGOW V6, V7, V6
+	VMRGOW V4, V5, V4
+	VMRGOW V6, V7, V6
 
-	WORD $0x13684F8C		// VMRGEW V8, V9, V27
-	WORD $0x138A5F8C		// VMRGEW V10, V11, V28
+	VMRGEW V8, V9, V27
+	VMRGEW V10, V11, V28
 
 	XXPERMDI VS36, VS38, $0, VS37
 	XXPERMDI VS36, VS38, $3, VS39
 	XXPERMDI VS61, VS62, $0, VS36
 	XXPERMDI VS61, VS62, $3, VS38
 
-	WORD $0x11084E8C		// VMRGOW V8, V9, V8
-	WORD $0x114A5E8C		// VMRGOW V10, V11, V10
+	VMRGOW V8, V9, V8
+	VMRGOW V10, V11, V10
 
-	WORD $0x13AC6F8C		// VMRGEW V12, V13, V29
-	WORD $0x13CE7F8C		// VMRGEW V14, V15, V30
+	VMRGEW V12, V13, V29
+	VMRGEW V14, V15, V30
 
 	XXPERMDI VS40, VS42, $0, VS41
 	XXPERMDI VS40, VS42, $3, VS43
 	XXPERMDI VS59, VS60, $0, VS40
 	XXPERMDI VS59, VS60, $3, VS42
 
-	WORD $0x118C6E8C		// VMRGOW V12, V13, V12
-	WORD $0x11CE7E8C		// VMRGOW V14, V15, V14
+	VMRGOW V12, V13, V12
+	VMRGOW V14, V15, V14
 
 	VSPLTISW $4, V27
 	VADDUWM V26, V27, V26
@@ -431,7 +425,7 @@ tail_vsx:
 	ADD $-1, R11, R12
 	ADD $-1, INP
 	ADD $-1, OUT
-
+	PCALIGN $16
 looptail_vsx:
 	// Copying the result to OUT
 	// in bytes.
@@ -439,7 +433,7 @@ looptail_vsx:
 	MOVBZU 1(INP), TMP
 	XOR    KEY, TMP, KEY
 	MOVBU  KEY, 1(OUT)
-	BC     16, LT, looptail_vsx
+	BDNZ   looptail_vsx
 
 	// Clear the stack values
 	STXVW4X VS48, (R11)(R0)
diff --git a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
index 93da7322..8cf5d811 100644
--- a/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
+++ b/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
@@ -5,7 +5,7 @@
 // Package chacha20poly1305 implements the ChaCha20-Poly1305 AEAD and its
 // extended nonce variant XChaCha20-Poly1305, as specified in RFC 8439 and
 // draft-irtf-cfrg-xchacha-01.
-package chacha20poly1305 // import "golang.org/x/crypto/chacha20poly1305"
+package chacha20poly1305
 
 import (
 	"crypto/cipher"
diff --git a/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go b/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go
index cda8e3ed..90ef6a24 100644
--- a/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go
+++ b/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go
@@ -4,7 +4,7 @@
 
 // Package asn1 contains supporting types for parsing and building ASN.1
 // messages with the cryptobyte package.
-package asn1 // import "golang.org/x/crypto/cryptobyte/asn1"
+package asn1
 
 // Tag represents an ASN.1 identifier octet, consisting of a tag number
 // (indicating a type) and class (such as context-specific or constructed).
diff --git a/vendor/golang.org/x/crypto/cryptobyte/string.go b/vendor/golang.org/x/crypto/cryptobyte/string.go
index 10692a8a..4b0f8097 100644
--- a/vendor/golang.org/x/crypto/cryptobyte/string.go
+++ b/vendor/golang.org/x/crypto/cryptobyte/string.go
@@ -15,7 +15,7 @@
 //
 // See the documentation and examples for the Builder and String types to get
 // started.
-package cryptobyte // import "golang.org/x/crypto/cryptobyte"
+package cryptobyte
 
 // String represents a string of bytes. It provides methods for parsing
 // fixed-length and length-prefixed values from it.
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519.go b/vendor/golang.org/x/crypto/curve25519/curve25519.go
index 00f963ea..21ca3b2e 100644
--- a/vendor/golang.org/x/crypto/curve25519/curve25519.go
+++ b/vendor/golang.org/x/crypto/curve25519/curve25519.go
@@ -6,9 +6,11 @@
 // performs scalar multiplication on the elliptic curve known as Curve25519.
 // See RFC 7748.
 //
-// Starting in Go 1.20, this package is a wrapper for the X25519 implementation
+// This package is a wrapper for the X25519 implementation
 // in the crypto/ecdh package.
-package curve25519 // import "golang.org/x/crypto/curve25519"
+package curve25519
+
+import "crypto/ecdh"
 
 // ScalarMult sets dst to the product scalar * point.
 //
@@ -16,7 +18,13 @@ package curve25519 // import "golang.org/x/crypto/curve25519"
 // zeroes, irrespective of the scalar. Instead, use the X25519 function, which
 // will return an error.
 func ScalarMult(dst, scalar, point *[32]byte) {
-	scalarMult(dst, scalar, point)
+	if _, err := x25519(dst, scalar[:], point[:]); err != nil {
+		// The only error condition for x25519 when the inputs are 32 bytes long
+		// is if the output would have been the all-zero value.
+		for i := range dst {
+			dst[i] = 0
+		}
+	}
 }
 
 // ScalarBaseMult sets dst to the product scalar * base where base is the
@@ -25,7 +33,12 @@ func ScalarMult(dst, scalar, point *[32]byte) {
 // It is recommended to use the X25519 function with Basepoint instead, as
 // copying into fixed size arrays can lead to unexpected bugs.
 func ScalarBaseMult(dst, scalar *[32]byte) {
-	scalarBaseMult(dst, scalar)
+	curve := ecdh.X25519()
+	priv, err := curve.NewPrivateKey(scalar[:])
+	if err != nil {
+		panic("curve25519: internal error: scalarBaseMult was not 32 bytes")
+	}
+	copy(dst[:], priv.PublicKey().Bytes())
 }
 
 const (
@@ -57,3 +70,21 @@ func X25519(scalar, point []byte) ([]byte, error) {
 	var dst [32]byte
 	return x25519(&dst, scalar, point)
 }
+
+func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
+	curve := ecdh.X25519()
+	pub, err := curve.NewPublicKey(point)
+	if err != nil {
+		return nil, err
+	}
+	priv, err := curve.NewPrivateKey(scalar)
+	if err != nil {
+		return nil, err
+	}
+	out, err := priv.ECDH(pub)
+	if err != nil {
+		return nil, err
+	}
+	copy(dst[:], out)
+	return dst[:], nil
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_compat.go b/vendor/golang.org/x/crypto/curve25519/curve25519_compat.go
deleted file mode 100644
index ba647e8d..00000000
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_compat.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !go1.20
-
-package curve25519
-
-import (
-	"crypto/subtle"
-	"errors"
-	"strconv"
-
-	"golang.org/x/crypto/curve25519/internal/field"
-)
-
-func scalarMult(dst, scalar, point *[32]byte) {
-	var e [32]byte
-
-	copy(e[:], scalar[:])
-	e[0] &= 248
-	e[31] &= 127
-	e[31] |= 64
-
-	var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element
-	x1.SetBytes(point[:])
-	x2.One()
-	x3.Set(&x1)
-	z3.One()
-
-	swap := 0
-	for pos := 254; pos >= 0; pos-- {
-		b := e[pos/8] >> uint(pos&7)
-		b &= 1
-		swap ^= int(b)
-		x2.Swap(&x3, swap)
-		z2.Swap(&z3, swap)
-		swap = int(b)
-
-		tmp0.Subtract(&x3, &z3)
-		tmp1.Subtract(&x2, &z2)
-		x2.Add(&x2, &z2)
-		z2.Add(&x3, &z3)
-		z3.Multiply(&tmp0, &x2)
-		z2.Multiply(&z2, &tmp1)
-		tmp0.Square(&tmp1)
-		tmp1.Square(&x2)
-		x3.Add(&z3, &z2)
-		z2.Subtract(&z3, &z2)
-		x2.Multiply(&tmp1, &tmp0)
-		tmp1.Subtract(&tmp1, &tmp0)
-		z2.Square(&z2)
-
-		z3.Mult32(&tmp1, 121666)
-		x3.Square(&x3)
-		tmp0.Add(&tmp0, &z3)
-		z3.Multiply(&x1, &z2)
-		z2.Multiply(&tmp1, &tmp0)
-	}
-
-	x2.Swap(&x3, swap)
-	z2.Swap(&z3, swap)
-
-	z2.Invert(&z2)
-	x2.Multiply(&x2, &z2)
-	copy(dst[:], x2.Bytes())
-}
-
-func scalarBaseMult(dst, scalar *[32]byte) {
-	checkBasepoint()
-	scalarMult(dst, scalar, &basePoint)
-}
-
-func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
-	var in [32]byte
-	if l := len(scalar); l != 32 {
-		return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32")
-	}
-	if l := len(point); l != 32 {
-		return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32")
-	}
-	copy(in[:], scalar)
-	if &point[0] == &Basepoint[0] {
-		scalarBaseMult(dst, &in)
-	} else {
-		var base, zero [32]byte
-		copy(base[:], point)
-		scalarMult(dst, &in, &base)
-		if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
-			return nil, errors.New("bad input point: low order point")
-		}
-	}
-	return dst[:], nil
-}
-
-func checkBasepoint() {
-	if subtle.ConstantTimeCompare(Basepoint, []byte{
-		0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	}) != 1 {
-		panic("curve25519: global Basepoint value was modified")
-	}
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_go120.go b/vendor/golang.org/x/crypto/curve25519/curve25519_go120.go
deleted file mode 100644
index 627df497..00000000
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_go120.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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.20
-
-package curve25519
-
-import "crypto/ecdh"
-
-func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
-	curve := ecdh.X25519()
-	pub, err := curve.NewPublicKey(point)
-	if err != nil {
-		return nil, err
-	}
-	priv, err := curve.NewPrivateKey(scalar)
-	if err != nil {
-		return nil, err
-	}
-	out, err := priv.ECDH(pub)
-	if err != nil {
-		return nil, err
-	}
-	copy(dst[:], out)
-	return dst[:], nil
-}
-
-func scalarMult(dst, scalar, point *[32]byte) {
-	if _, err := x25519(dst, scalar[:], point[:]); err != nil {
-		// The only error condition for x25519 when the inputs are 32 bytes long
-		// is if the output would have been the all-zero value.
-		for i := range dst {
-			dst[i] = 0
-		}
-	}
-}
-
-func scalarBaseMult(dst, scalar *[32]byte) {
-	curve := ecdh.X25519()
-	priv, err := curve.NewPrivateKey(scalar[:])
-	if err != nil {
-		panic("curve25519: internal error: scalarBaseMult was not 32 bytes")
-	}
-	copy(dst[:], priv.PublicKey().Bytes())
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/README b/vendor/golang.org/x/crypto/curve25519/internal/field/README
deleted file mode 100644
index e25bca7d..00000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/README
+++ /dev/null
@@ -1,7 +0,0 @@
-This package is kept in sync with crypto/ed25519/internal/edwards25519/field in
-the standard library.
-
-If there are any changes in the standard library that need to be synced to this
-package, run sync.sh. It will not overwrite any local changes made since the
-previous sync, so it's ok to land changes in this package first, and then sync
-to the standard library later.
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go
deleted file mode 100644
index ca841ad9..00000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go
+++ /dev/null
@@ -1,416 +0,0 @@
-// Copyright (c) 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package field implements fast arithmetic modulo 2^255-19.
-package field
-
-import (
-	"crypto/subtle"
-	"encoding/binary"
-	"math/bits"
-)
-
-// Element represents an element of the field GF(2^255-19). Note that this
-// is not a cryptographically secure group, and should only be used to interact
-// with edwards25519.Point coordinates.
-//
-// This type works similarly to math/big.Int, and all arguments and receivers
-// are allowed to alias.
-//
-// The zero value is a valid zero element.
-type Element struct {
-	// An element t represents the integer
-	//     t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204
-	//
-	// Between operations, all limbs are expected to be lower than 2^52.
-	l0 uint64
-	l1 uint64
-	l2 uint64
-	l3 uint64
-	l4 uint64
-}
-
-const maskLow51Bits uint64 = (1 << 51) - 1
-
-var feZero = &Element{0, 0, 0, 0, 0}
-
-// Zero sets v = 0, and returns v.
-func (v *Element) Zero() *Element {
-	*v = *feZero
-	return v
-}
-
-var feOne = &Element{1, 0, 0, 0, 0}
-
-// One sets v = 1, and returns v.
-func (v *Element) One() *Element {
-	*v = *feOne
-	return v
-}
-
-// reduce reduces v modulo 2^255 - 19 and returns it.
-func (v *Element) reduce() *Element {
-	v.carryPropagate()
-
-	// After the light reduction we now have a field element representation
-	// v < 2^255 + 2^13 * 19, but need v < 2^255 - 19.
-
-	// If v >= 2^255 - 19, then v + 19 >= 2^255, which would overflow 2^255 - 1,
-	// generating a carry. That is, c will be 0 if v < 2^255 - 19, and 1 otherwise.
-	c := (v.l0 + 19) >> 51
-	c = (v.l1 + c) >> 51
-	c = (v.l2 + c) >> 51
-	c = (v.l3 + c) >> 51
-	c = (v.l4 + c) >> 51
-
-	// If v < 2^255 - 19 and c = 0, this will be a no-op. Otherwise, it's
-	// effectively applying the reduction identity to the carry.
-	v.l0 += 19 * c
-
-	v.l1 += v.l0 >> 51
-	v.l0 = v.l0 & maskLow51Bits
-	v.l2 += v.l1 >> 51
-	v.l1 = v.l1 & maskLow51Bits
-	v.l3 += v.l2 >> 51
-	v.l2 = v.l2 & maskLow51Bits
-	v.l4 += v.l3 >> 51
-	v.l3 = v.l3 & maskLow51Bits
-	// no additional carry
-	v.l4 = v.l4 & maskLow51Bits
-
-	return v
-}
-
-// Add sets v = a + b, and returns v.
-func (v *Element) Add(a, b *Element) *Element {
-	v.l0 = a.l0 + b.l0
-	v.l1 = a.l1 + b.l1
-	v.l2 = a.l2 + b.l2
-	v.l3 = a.l3 + b.l3
-	v.l4 = a.l4 + b.l4
-	// Using the generic implementation here is actually faster than the
-	// assembly. Probably because the body of this function is so simple that
-	// the compiler can figure out better optimizations by inlining the carry
-	// propagation. TODO
-	return v.carryPropagateGeneric()
-}
-
-// Subtract sets v = a - b, and returns v.
-func (v *Element) Subtract(a, b *Element) *Element {
-	// We first add 2 * p, to guarantee the subtraction won't underflow, and
-	// then subtract b (which can be up to 2^255 + 2^13 * 19).
-	v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0
-	v.l1 = (a.l1 + 0xFFFFFFFFFFFFE) - b.l1
-	v.l2 = (a.l2 + 0xFFFFFFFFFFFFE) - b.l2
-	v.l3 = (a.l3 + 0xFFFFFFFFFFFFE) - b.l3
-	v.l4 = (a.l4 + 0xFFFFFFFFFFFFE) - b.l4
-	return v.carryPropagate()
-}
-
-// Negate sets v = -a, and returns v.
-func (v *Element) Negate(a *Element) *Element {
-	return v.Subtract(feZero, a)
-}
-
-// Invert sets v = 1/z mod p, and returns v.
-//
-// If z == 0, Invert returns v = 0.
-func (v *Element) Invert(z *Element) *Element {
-	// Inversion is implemented as exponentiation with exponent p − 2. It uses the
-	// same sequence of 255 squarings and 11 multiplications as [Curve25519].
-	var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t Element
-
-	z2.Square(z)             // 2
-	t.Square(&z2)            // 4
-	t.Square(&t)             // 8
-	z9.Multiply(&t, z)       // 9
-	z11.Multiply(&z9, &z2)   // 11
-	t.Square(&z11)           // 22
-	z2_5_0.Multiply(&t, &z9) // 31 = 2^5 - 2^0
-
-	t.Square(&z2_5_0) // 2^6 - 2^1
-	for i := 0; i < 4; i++ {
-		t.Square(&t) // 2^10 - 2^5
-	}
-	z2_10_0.Multiply(&t, &z2_5_0) // 2^10 - 2^0
-
-	t.Square(&z2_10_0) // 2^11 - 2^1
-	for i := 0; i < 9; i++ {
-		t.Square(&t) // 2^20 - 2^10
-	}
-	z2_20_0.Multiply(&t, &z2_10_0) // 2^20 - 2^0
-
-	t.Square(&z2_20_0) // 2^21 - 2^1
-	for i := 0; i < 19; i++ {
-		t.Square(&t) // 2^40 - 2^20
-	}
-	t.Multiply(&t, &z2_20_0) // 2^40 - 2^0
-
-	t.Square(&t) // 2^41 - 2^1
-	for i := 0; i < 9; i++ {
-		t.Square(&t) // 2^50 - 2^10
-	}
-	z2_50_0.Multiply(&t, &z2_10_0) // 2^50 - 2^0
-
-	t.Square(&z2_50_0) // 2^51 - 2^1
-	for i := 0; i < 49; i++ {
-		t.Square(&t) // 2^100 - 2^50
-	}
-	z2_100_0.Multiply(&t, &z2_50_0) // 2^100 - 2^0
-
-	t.Square(&z2_100_0) // 2^101 - 2^1
-	for i := 0; i < 99; i++ {
-		t.Square(&t) // 2^200 - 2^100
-	}
-	t.Multiply(&t, &z2_100_0) // 2^200 - 2^0
-
-	t.Square(&t) // 2^201 - 2^1
-	for i := 0; i < 49; i++ {
-		t.Square(&t) // 2^250 - 2^50
-	}
-	t.Multiply(&t, &z2_50_0) // 2^250 - 2^0
-
-	t.Square(&t) // 2^251 - 2^1
-	t.Square(&t) // 2^252 - 2^2
-	t.Square(&t) // 2^253 - 2^3
-	t.Square(&t) // 2^254 - 2^4
-	t.Square(&t) // 2^255 - 2^5
-
-	return v.Multiply(&t, &z11) // 2^255 - 21
-}
-
-// Set sets v = a, and returns v.
-func (v *Element) Set(a *Element) *Element {
-	*v = *a
-	return v
-}
-
-// SetBytes sets v to x, which must be a 32-byte little-endian encoding.
-//
-// Consistent with RFC 7748, the most significant bit (the high bit of the
-// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1)
-// are accepted. Note that this is laxer than specified by RFC 8032.
-func (v *Element) SetBytes(x []byte) *Element {
-	if len(x) != 32 {
-		panic("edwards25519: invalid field element input size")
-	}
-
-	// Bits 0:51 (bytes 0:8, bits 0:64, shift 0, mask 51).
-	v.l0 = binary.LittleEndian.Uint64(x[0:8])
-	v.l0 &= maskLow51Bits
-	// Bits 51:102 (bytes 6:14, bits 48:112, shift 3, mask 51).
-	v.l1 = binary.LittleEndian.Uint64(x[6:14]) >> 3
-	v.l1 &= maskLow51Bits
-	// Bits 102:153 (bytes 12:20, bits 96:160, shift 6, mask 51).
-	v.l2 = binary.LittleEndian.Uint64(x[12:20]) >> 6
-	v.l2 &= maskLow51Bits
-	// Bits 153:204 (bytes 19:27, bits 152:216, shift 1, mask 51).
-	v.l3 = binary.LittleEndian.Uint64(x[19:27]) >> 1
-	v.l3 &= maskLow51Bits
-	// Bits 204:251 (bytes 24:32, bits 192:256, shift 12, mask 51).
-	// Note: not bytes 25:33, shift 4, to avoid overread.
-	v.l4 = binary.LittleEndian.Uint64(x[24:32]) >> 12
-	v.l4 &= maskLow51Bits
-
-	return v
-}
-
-// Bytes returns the canonical 32-byte little-endian encoding of v.
-func (v *Element) Bytes() []byte {
-	// This function is outlined to make the allocations inline in the caller
-	// rather than happen on the heap.
-	var out [32]byte
-	return v.bytes(&out)
-}
-
-func (v *Element) bytes(out *[32]byte) []byte {
-	t := *v
-	t.reduce()
-
-	var buf [8]byte
-	for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} {
-		bitsOffset := i * 51
-		binary.LittleEndian.PutUint64(buf[:], l<<uint(bitsOffset%8))
-		for i, bb := range buf {
-			off := bitsOffset/8 + i
-			if off >= len(out) {
-				break
-			}
-			out[off] |= bb
-		}
-	}
-
-	return out[:]
-}
-
-// Equal returns 1 if v and u are equal, and 0 otherwise.
-func (v *Element) Equal(u *Element) int {
-	sa, sv := u.Bytes(), v.Bytes()
-	return subtle.ConstantTimeCompare(sa, sv)
-}
-
-// mask64Bits returns 0xffffffff if cond is 1, and 0 otherwise.
-func mask64Bits(cond int) uint64 { return ^(uint64(cond) - 1) }
-
-// Select sets v to a if cond == 1, and to b if cond == 0.
-func (v *Element) Select(a, b *Element, cond int) *Element {
-	m := mask64Bits(cond)
-	v.l0 = (m & a.l0) | (^m & b.l0)
-	v.l1 = (m & a.l1) | (^m & b.l1)
-	v.l2 = (m & a.l2) | (^m & b.l2)
-	v.l3 = (m & a.l3) | (^m & b.l3)
-	v.l4 = (m & a.l4) | (^m & b.l4)
-	return v
-}
-
-// Swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v.
-func (v *Element) Swap(u *Element, cond int) {
-	m := mask64Bits(cond)
-	t := m & (v.l0 ^ u.l0)
-	v.l0 ^= t
-	u.l0 ^= t
-	t = m & (v.l1 ^ u.l1)
-	v.l1 ^= t
-	u.l1 ^= t
-	t = m & (v.l2 ^ u.l2)
-	v.l2 ^= t
-	u.l2 ^= t
-	t = m & (v.l3 ^ u.l3)
-	v.l3 ^= t
-	u.l3 ^= t
-	t = m & (v.l4 ^ u.l4)
-	v.l4 ^= t
-	u.l4 ^= t
-}
-
-// IsNegative returns 1 if v is negative, and 0 otherwise.
-func (v *Element) IsNegative() int {
-	return int(v.Bytes()[0] & 1)
-}
-
-// Absolute sets v to |u|, and returns v.
-func (v *Element) Absolute(u *Element) *Element {
-	return v.Select(new(Element).Negate(u), u, u.IsNegative())
-}
-
-// Multiply sets v = x * y, and returns v.
-func (v *Element) Multiply(x, y *Element) *Element {
-	feMul(v, x, y)
-	return v
-}
-
-// Square sets v = x * x, and returns v.
-func (v *Element) Square(x *Element) *Element {
-	feSquare(v, x)
-	return v
-}
-
-// Mult32 sets v = x * y, and returns v.
-func (v *Element) Mult32(x *Element, y uint32) *Element {
-	x0lo, x0hi := mul51(x.l0, y)
-	x1lo, x1hi := mul51(x.l1, y)
-	x2lo, x2hi := mul51(x.l2, y)
-	x3lo, x3hi := mul51(x.l3, y)
-	x4lo, x4hi := mul51(x.l4, y)
-	v.l0 = x0lo + 19*x4hi // carried over per the reduction identity
-	v.l1 = x1lo + x0hi
-	v.l2 = x2lo + x1hi
-	v.l3 = x3lo + x2hi
-	v.l4 = x4lo + x3hi
-	// The hi portions are going to be only 32 bits, plus any previous excess,
-	// so we can skip the carry propagation.
-	return v
-}
-
-// mul51 returns lo + hi * 2⁵¹ = a * b.
-func mul51(a uint64, b uint32) (lo uint64, hi uint64) {
-	mh, ml := bits.Mul64(a, uint64(b))
-	lo = ml & maskLow51Bits
-	hi = (mh << 13) | (ml >> 51)
-	return
-}
-
-// Pow22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3.
-func (v *Element) Pow22523(x *Element) *Element {
-	var t0, t1, t2 Element
-
-	t0.Square(x)             // x^2
-	t1.Square(&t0)           // x^4
-	t1.Square(&t1)           // x^8
-	t1.Multiply(x, &t1)      // x^9
-	t0.Multiply(&t0, &t1)    // x^11
-	t0.Square(&t0)           // x^22
-	t0.Multiply(&t1, &t0)    // x^31
-	t1.Square(&t0)           // x^62
-	for i := 1; i < 5; i++ { // x^992
-		t1.Square(&t1)
-	}
-	t0.Multiply(&t1, &t0)     // x^1023 -> 1023 = 2^10 - 1
-	t1.Square(&t0)            // 2^11 - 2
-	for i := 1; i < 10; i++ { // 2^20 - 2^10
-		t1.Square(&t1)
-	}
-	t1.Multiply(&t1, &t0)     // 2^20 - 1
-	t2.Square(&t1)            // 2^21 - 2
-	for i := 1; i < 20; i++ { // 2^40 - 2^20
-		t2.Square(&t2)
-	}
-	t1.Multiply(&t2, &t1)     // 2^40 - 1
-	t1.Square(&t1)            // 2^41 - 2
-	for i := 1; i < 10; i++ { // 2^50 - 2^10
-		t1.Square(&t1)
-	}
-	t0.Multiply(&t1, &t0)     // 2^50 - 1
-	t1.Square(&t0)            // 2^51 - 2
-	for i := 1; i < 50; i++ { // 2^100 - 2^50
-		t1.Square(&t1)
-	}
-	t1.Multiply(&t1, &t0)      // 2^100 - 1
-	t2.Square(&t1)             // 2^101 - 2
-	for i := 1; i < 100; i++ { // 2^200 - 2^100
-		t2.Square(&t2)
-	}
-	t1.Multiply(&t2, &t1)     // 2^200 - 1
-	t1.Square(&t1)            // 2^201 - 2
-	for i := 1; i < 50; i++ { // 2^250 - 2^50
-		t1.Square(&t1)
-	}
-	t0.Multiply(&t1, &t0)     // 2^250 - 1
-	t0.Square(&t0)            // 2^251 - 2
-	t0.Square(&t0)            // 2^252 - 4
-	return v.Multiply(&t0, x) // 2^252 - 3 -> x^(2^252-3)
-}
-
-// sqrtM1 is 2^((p-1)/4), which squared is equal to -1 by Euler's Criterion.
-var sqrtM1 = &Element{1718705420411056, 234908883556509,
-	2233514472574048, 2117202627021982, 765476049583133}
-
-// SqrtRatio sets r to the non-negative square root of the ratio of u and v.
-//
-// If u/v is square, SqrtRatio returns r and 1. If u/v is not square, SqrtRatio
-// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00,
-// and returns r and 0.
-func (r *Element) SqrtRatio(u, v *Element) (rr *Element, wasSquare int) {
-	var a, b Element
-
-	// r = (u * v3) * (u * v7)^((p-5)/8)
-	v2 := a.Square(v)
-	uv3 := b.Multiply(u, b.Multiply(v2, v))
-	uv7 := a.Multiply(uv3, a.Square(v2))
-	r.Multiply(uv3, r.Pow22523(uv7))
-
-	check := a.Multiply(v, a.Square(r)) // check = v * r^2
-
-	uNeg := b.Negate(u)
-	correctSignSqrt := check.Equal(u)
-	flippedSignSqrt := check.Equal(uNeg)
-	flippedSignSqrtI := check.Equal(uNeg.Multiply(uNeg, sqrtM1))
-
-	rPrime := b.Multiply(r, sqrtM1) // r_prime = SQRT_M1 * r
-	// r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r)
-	r.Select(rPrime, r, flippedSignSqrt|flippedSignSqrtI)
-
-	r.Absolute(r) // Choose the nonnegative square root.
-	return r, correctSignSqrt | flippedSignSqrt
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
deleted file mode 100644
index 70c54169..00000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
-
-//go:build amd64 && gc && !purego
-
-package field
-
-// feMul sets out = a * b. It works like feMulGeneric.
-//
-//go:noescape
-func feMul(out *Element, a *Element, b *Element)
-
-// feSquare sets out = a * a. It works like feSquareGeneric.
-//
-//go:noescape
-func feSquare(out *Element, a *Element)
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
deleted file mode 100644
index 60817acc..00000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
+++ /dev/null
@@ -1,378 +0,0 @@
-// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
-
-//go:build amd64 && gc && !purego
-
-#include "textflag.h"
-
-// func feMul(out *Element, a *Element, b *Element)
-TEXT ·feMul(SB), NOSPLIT, $0-24
-	MOVQ a+8(FP), CX
-	MOVQ b+16(FP), BX
-
-	// r0 = a0×b0
-	MOVQ (CX), AX
-	MULQ (BX)
-	MOVQ AX, DI
-	MOVQ DX, SI
-
-	// r0 += 19×a1×b4
-	MOVQ   8(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   32(BX)
-	ADDQ   AX, DI
-	ADCQ   DX, SI
-
-	// r0 += 19×a2×b3
-	MOVQ   16(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   24(BX)
-	ADDQ   AX, DI
-	ADCQ   DX, SI
-
-	// r0 += 19×a3×b2
-	MOVQ   24(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   16(BX)
-	ADDQ   AX, DI
-	ADCQ   DX, SI
-
-	// r0 += 19×a4×b1
-	MOVQ   32(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   8(BX)
-	ADDQ   AX, DI
-	ADCQ   DX, SI
-
-	// r1 = a0×b1
-	MOVQ (CX), AX
-	MULQ 8(BX)
-	MOVQ AX, R9
-	MOVQ DX, R8
-
-	// r1 += a1×b0
-	MOVQ 8(CX), AX
-	MULQ (BX)
-	ADDQ AX, R9
-	ADCQ DX, R8
-
-	// r1 += 19×a2×b4
-	MOVQ   16(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   32(BX)
-	ADDQ   AX, R9
-	ADCQ   DX, R8
-
-	// r1 += 19×a3×b3
-	MOVQ   24(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   24(BX)
-	ADDQ   AX, R9
-	ADCQ   DX, R8
-
-	// r1 += 19×a4×b2
-	MOVQ   32(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   16(BX)
-	ADDQ   AX, R9
-	ADCQ   DX, R8
-
-	// r2 = a0×b2
-	MOVQ (CX), AX
-	MULQ 16(BX)
-	MOVQ AX, R11
-	MOVQ DX, R10
-
-	// r2 += a1×b1
-	MOVQ 8(CX), AX
-	MULQ 8(BX)
-	ADDQ AX, R11
-	ADCQ DX, R10
-
-	// r2 += a2×b0
-	MOVQ 16(CX), AX
-	MULQ (BX)
-	ADDQ AX, R11
-	ADCQ DX, R10
-
-	// r2 += 19×a3×b4
-	MOVQ   24(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   32(BX)
-	ADDQ   AX, R11
-	ADCQ   DX, R10
-
-	// r2 += 19×a4×b3
-	MOVQ   32(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   24(BX)
-	ADDQ   AX, R11
-	ADCQ   DX, R10
-
-	// r3 = a0×b3
-	MOVQ (CX), AX
-	MULQ 24(BX)
-	MOVQ AX, R13
-	MOVQ DX, R12
-
-	// r3 += a1×b2
-	MOVQ 8(CX), AX
-	MULQ 16(BX)
-	ADDQ AX, R13
-	ADCQ DX, R12
-
-	// r3 += a2×b1
-	MOVQ 16(CX), AX
-	MULQ 8(BX)
-	ADDQ AX, R13
-	ADCQ DX, R12
-
-	// r3 += a3×b0
-	MOVQ 24(CX), AX
-	MULQ (BX)
-	ADDQ AX, R13
-	ADCQ DX, R12
-
-	// r3 += 19×a4×b4
-	MOVQ   32(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   32(BX)
-	ADDQ   AX, R13
-	ADCQ   DX, R12
-
-	// r4 = a0×b4
-	MOVQ (CX), AX
-	MULQ 32(BX)
-	MOVQ AX, R15
-	MOVQ DX, R14
-
-	// r4 += a1×b3
-	MOVQ 8(CX), AX
-	MULQ 24(BX)
-	ADDQ AX, R15
-	ADCQ DX, R14
-
-	// r4 += a2×b2
-	MOVQ 16(CX), AX
-	MULQ 16(BX)
-	ADDQ AX, R15
-	ADCQ DX, R14
-
-	// r4 += a3×b1
-	MOVQ 24(CX), AX
-	MULQ 8(BX)
-	ADDQ AX, R15
-	ADCQ DX, R14
-
-	// r4 += a4×b0
-	MOVQ 32(CX), AX
-	MULQ (BX)
-	ADDQ AX, R15
-	ADCQ DX, R14
-
-	// First reduction chain
-	MOVQ   $0x0007ffffffffffff, AX
-	SHLQ   $0x0d, DI, SI
-	SHLQ   $0x0d, R9, R8
-	SHLQ   $0x0d, R11, R10
-	SHLQ   $0x0d, R13, R12
-	SHLQ   $0x0d, R15, R14
-	ANDQ   AX, DI
-	IMUL3Q $0x13, R14, R14
-	ADDQ   R14, DI
-	ANDQ   AX, R9
-	ADDQ   SI, R9
-	ANDQ   AX, R11
-	ADDQ   R8, R11
-	ANDQ   AX, R13
-	ADDQ   R10, R13
-	ANDQ   AX, R15
-	ADDQ   R12, R15
-
-	// Second reduction chain (carryPropagate)
-	MOVQ   DI, SI
-	SHRQ   $0x33, SI
-	MOVQ   R9, R8
-	SHRQ   $0x33, R8
-	MOVQ   R11, R10
-	SHRQ   $0x33, R10
-	MOVQ   R13, R12
-	SHRQ   $0x33, R12
-	MOVQ   R15, R14
-	SHRQ   $0x33, R14
-	ANDQ   AX, DI
-	IMUL3Q $0x13, R14, R14
-	ADDQ   R14, DI
-	ANDQ   AX, R9
-	ADDQ   SI, R9
-	ANDQ   AX, R11
-	ADDQ   R8, R11
-	ANDQ   AX, R13
-	ADDQ   R10, R13
-	ANDQ   AX, R15
-	ADDQ   R12, R15
-
-	// Store output
-	MOVQ out+0(FP), AX
-	MOVQ DI, (AX)
-	MOVQ R9, 8(AX)
-	MOVQ R11, 16(AX)
-	MOVQ R13, 24(AX)
-	MOVQ R15, 32(AX)
-	RET
-
-// func feSquare(out *Element, a *Element)
-TEXT ·feSquare(SB), NOSPLIT, $0-16
-	MOVQ a+8(FP), CX
-
-	// r0 = l0×l0
-	MOVQ (CX), AX
-	MULQ (CX)
-	MOVQ AX, SI
-	MOVQ DX, BX
-
-	// r0 += 38×l1×l4
-	MOVQ   8(CX), AX
-	IMUL3Q $0x26, AX, AX
-	MULQ   32(CX)
-	ADDQ   AX, SI
-	ADCQ   DX, BX
-
-	// r0 += 38×l2×l3
-	MOVQ   16(CX), AX
-	IMUL3Q $0x26, AX, AX
-	MULQ   24(CX)
-	ADDQ   AX, SI
-	ADCQ   DX, BX
-
-	// r1 = 2×l0×l1
-	MOVQ (CX), AX
-	SHLQ $0x01, AX
-	MULQ 8(CX)
-	MOVQ AX, R8
-	MOVQ DX, DI
-
-	// r1 += 38×l2×l4
-	MOVQ   16(CX), AX
-	IMUL3Q $0x26, AX, AX
-	MULQ   32(CX)
-	ADDQ   AX, R8
-	ADCQ   DX, DI
-
-	// r1 += 19×l3×l3
-	MOVQ   24(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   24(CX)
-	ADDQ   AX, R8
-	ADCQ   DX, DI
-
-	// r2 = 2×l0×l2
-	MOVQ (CX), AX
-	SHLQ $0x01, AX
-	MULQ 16(CX)
-	MOVQ AX, R10
-	MOVQ DX, R9
-
-	// r2 += l1×l1
-	MOVQ 8(CX), AX
-	MULQ 8(CX)
-	ADDQ AX, R10
-	ADCQ DX, R9
-
-	// r2 += 38×l3×l4
-	MOVQ   24(CX), AX
-	IMUL3Q $0x26, AX, AX
-	MULQ   32(CX)
-	ADDQ   AX, R10
-	ADCQ   DX, R9
-
-	// r3 = 2×l0×l3
-	MOVQ (CX), AX
-	SHLQ $0x01, AX
-	MULQ 24(CX)
-	MOVQ AX, R12
-	MOVQ DX, R11
-
-	// r3 += 2×l1×l2
-	MOVQ   8(CX), AX
-	IMUL3Q $0x02, AX, AX
-	MULQ   16(CX)
-	ADDQ   AX, R12
-	ADCQ   DX, R11
-
-	// r3 += 19×l4×l4
-	MOVQ   32(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   32(CX)
-	ADDQ   AX, R12
-	ADCQ   DX, R11
-
-	// r4 = 2×l0×l4
-	MOVQ (CX), AX
-	SHLQ $0x01, AX
-	MULQ 32(CX)
-	MOVQ AX, R14
-	MOVQ DX, R13
-
-	// r4 += 2×l1×l3
-	MOVQ   8(CX), AX
-	IMUL3Q $0x02, AX, AX
-	MULQ   24(CX)
-	ADDQ   AX, R14
-	ADCQ   DX, R13
-
-	// r4 += l2×l2
-	MOVQ 16(CX), AX
-	MULQ 16(CX)
-	ADDQ AX, R14
-	ADCQ DX, R13
-
-	// First reduction chain
-	MOVQ   $0x0007ffffffffffff, AX
-	SHLQ   $0x0d, SI, BX
-	SHLQ   $0x0d, R8, DI
-	SHLQ   $0x0d, R10, R9
-	SHLQ   $0x0d, R12, R11
-	SHLQ   $0x0d, R14, R13
-	ANDQ   AX, SI
-	IMUL3Q $0x13, R13, R13
-	ADDQ   R13, SI
-	ANDQ   AX, R8
-	ADDQ   BX, R8
-	ANDQ   AX, R10
-	ADDQ   DI, R10
-	ANDQ   AX, R12
-	ADDQ   R9, R12
-	ANDQ   AX, R14
-	ADDQ   R11, R14
-
-	// Second reduction chain (carryPropagate)
-	MOVQ   SI, BX
-	SHRQ   $0x33, BX
-	MOVQ   R8, DI
-	SHRQ   $0x33, DI
-	MOVQ   R10, R9
-	SHRQ   $0x33, R9
-	MOVQ   R12, R11
-	SHRQ   $0x33, R11
-	MOVQ   R14, R13
-	SHRQ   $0x33, R13
-	ANDQ   AX, SI
-	IMUL3Q $0x13, R13, R13
-	ADDQ   R13, SI
-	ANDQ   AX, R8
-	ADDQ   BX, R8
-	ANDQ   AX, R10
-	ADDQ   DI, R10
-	ANDQ   AX, R12
-	ADDQ   R9, R12
-	ANDQ   AX, R14
-	ADDQ   R11, R14
-
-	// Store output
-	MOVQ out+0(FP), AX
-	MOVQ SI, (AX)
-	MOVQ R8, 8(AX)
-	MOVQ R10, 16(AX)
-	MOVQ R12, 24(AX)
-	MOVQ R14, 32(AX)
-	RET
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
deleted file mode 100644
index 9da280d1..00000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !amd64 || !gc || purego
-
-package field
-
-func feMul(v, x, y *Element) { feMulGeneric(v, x, y) }
-
-func feSquare(v, x *Element) { feSquareGeneric(v, x) }
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
deleted file mode 100644
index 075fe9b9..00000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build arm64 && gc && !purego
-
-package field
-
-//go:noescape
-func carryPropagate(v *Element)
-
-func (v *Element) carryPropagate() *Element {
-	carryPropagate(v)
-	return v
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
deleted file mode 100644
index 3126a434..00000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build arm64 && gc && !purego
-
-#include "textflag.h"
-
-// carryPropagate works exactly like carryPropagateGeneric and uses the
-// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but
-// avoids loading R0-R4 twice and uses LDP and STP.
-//
-// See https://golang.org/issues/43145 for the main compiler issue.
-//
-// func carryPropagate(v *Element)
-TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8
-	MOVD v+0(FP), R20
-
-	LDP 0(R20), (R0, R1)
-	LDP 16(R20), (R2, R3)
-	MOVD 32(R20), R4
-
-	AND $0x7ffffffffffff, R0, R10
-	AND $0x7ffffffffffff, R1, R11
-	AND $0x7ffffffffffff, R2, R12
-	AND $0x7ffffffffffff, R3, R13
-	AND $0x7ffffffffffff, R4, R14
-
-	ADD R0>>51, R11, R11
-	ADD R1>>51, R12, R12
-	ADD R2>>51, R13, R13
-	ADD R3>>51, R14, R14
-	// R4>>51 * 19 + R10 -> R10
-	LSR $51, R4, R21
-	MOVD $19, R22
-	MADD R22, R10, R21, R10
-
-	STP (R10, R11), 0(R20)
-	STP (R12, R13), 16(R20)
-	MOVD R14, 32(R20)
-
-	RET
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
deleted file mode 100644
index fc029ac1..00000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !arm64 || !gc || purego
-
-package field
-
-func (v *Element) carryPropagate() *Element {
-	return v.carryPropagateGeneric()
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
deleted file mode 100644
index 2671217d..00000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright (c) 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package field
-
-import "math/bits"
-
-// uint128 holds a 128-bit number as two 64-bit limbs, for use with the
-// bits.Mul64 and bits.Add64 intrinsics.
-type uint128 struct {
-	lo, hi uint64
-}
-
-// mul64 returns a * b.
-func mul64(a, b uint64) uint128 {
-	hi, lo := bits.Mul64(a, b)
-	return uint128{lo, hi}
-}
-
-// addMul64 returns v + a * b.
-func addMul64(v uint128, a, b uint64) uint128 {
-	hi, lo := bits.Mul64(a, b)
-	lo, c := bits.Add64(lo, v.lo, 0)
-	hi, _ = bits.Add64(hi, v.hi, c)
-	return uint128{lo, hi}
-}
-
-// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits.
-func shiftRightBy51(a uint128) uint64 {
-	return (a.hi << (64 - 51)) | (a.lo >> 51)
-}
-
-func feMulGeneric(v, a, b *Element) {
-	a0 := a.l0
-	a1 := a.l1
-	a2 := a.l2
-	a3 := a.l3
-	a4 := a.l4
-
-	b0 := b.l0
-	b1 := b.l1
-	b2 := b.l2
-	b3 := b.l3
-	b4 := b.l4
-
-	// Limb multiplication works like pen-and-paper columnar multiplication, but
-	// with 51-bit limbs instead of digits.
-	//
-	//                          a4   a3   a2   a1   a0  x
-	//                          b4   b3   b2   b1   b0  =
-	//                         ------------------------
-	//                        a4b0 a3b0 a2b0 a1b0 a0b0  +
-	//                   a4b1 a3b1 a2b1 a1b1 a0b1       +
-	//              a4b2 a3b2 a2b2 a1b2 a0b2            +
-	//         a4b3 a3b3 a2b3 a1b3 a0b3                 +
-	//    a4b4 a3b4 a2b4 a1b4 a0b4                      =
-	//   ----------------------------------------------
-	//      r8   r7   r6   r5   r4   r3   r2   r1   r0
-	//
-	// We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to
-	// reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5,
-	// r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc.
-	//
-	// Reduction can be carried out simultaneously to multiplication. For
-	// example, we do not compute r5: whenever the result of a multiplication
-	// belongs to r5, like a1b4, we multiply it by 19 and add the result to r0.
-	//
-	//            a4b0    a3b0    a2b0    a1b0    a0b0  +
-	//            a3b1    a2b1    a1b1    a0b1 19×a4b1  +
-	//            a2b2    a1b2    a0b2 19×a4b2 19×a3b2  +
-	//            a1b3    a0b3 19×a4b3 19×a3b3 19×a2b3  +
-	//            a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4  =
-	//           --------------------------------------
-	//              r4      r3      r2      r1      r0
-	//
-	// Finally we add up the columns into wide, overlapping limbs.
-
-	a1_19 := a1 * 19
-	a2_19 := a2 * 19
-	a3_19 := a3 * 19
-	a4_19 := a4 * 19
-
-	// r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
-	r0 := mul64(a0, b0)
-	r0 = addMul64(r0, a1_19, b4)
-	r0 = addMul64(r0, a2_19, b3)
-	r0 = addMul64(r0, a3_19, b2)
-	r0 = addMul64(r0, a4_19, b1)
-
-	// r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
-	r1 := mul64(a0, b1)
-	r1 = addMul64(r1, a1, b0)
-	r1 = addMul64(r1, a2_19, b4)
-	r1 = addMul64(r1, a3_19, b3)
-	r1 = addMul64(r1, a4_19, b2)
-
-	// r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
-	r2 := mul64(a0, b2)
-	r2 = addMul64(r2, a1, b1)
-	r2 = addMul64(r2, a2, b0)
-	r2 = addMul64(r2, a3_19, b4)
-	r2 = addMul64(r2, a4_19, b3)
-
-	// r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
-	r3 := mul64(a0, b3)
-	r3 = addMul64(r3, a1, b2)
-	r3 = addMul64(r3, a2, b1)
-	r3 = addMul64(r3, a3, b0)
-	r3 = addMul64(r3, a4_19, b4)
-
-	// r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
-	r4 := mul64(a0, b4)
-	r4 = addMul64(r4, a1, b3)
-	r4 = addMul64(r4, a2, b2)
-	r4 = addMul64(r4, a3, b1)
-	r4 = addMul64(r4, a4, b0)
-
-	// After the multiplication, we need to reduce (carry) the five coefficients
-	// to obtain a result with limbs that are at most slightly larger than 2⁵¹,
-	// to respect the Element invariant.
-	//
-	// Overall, the reduction works the same as carryPropagate, except with
-	// wider inputs: we take the carry for each coefficient by shifting it right
-	// by 51, and add it to the limb above it. The top carry is multiplied by 19
-	// according to the reduction identity and added to the lowest limb.
-	//
-	// The largest coefficient (r0) will be at most 111 bits, which guarantees
-	// that all carries are at most 111 - 51 = 60 bits, which fits in a uint64.
-	//
-	//     r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
-	//     r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²)
-	//     r0 < (1 + 19 × 4) × 2⁵² × 2⁵²
-	//     r0 < 2⁷ × 2⁵² × 2⁵²
-	//     r0 < 2¹¹¹
-	//
-	// Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most
-	// 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and
-	// allows us to easily apply the reduction identity.
-	//
-	//     r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
-	//     r4 < 5 × 2⁵² × 2⁵²
-	//     r4 < 2¹⁰⁷
-	//
-
-	c0 := shiftRightBy51(r0)
-	c1 := shiftRightBy51(r1)
-	c2 := shiftRightBy51(r2)
-	c3 := shiftRightBy51(r3)
-	c4 := shiftRightBy51(r4)
-
-	rr0 := r0.lo&maskLow51Bits + c4*19
-	rr1 := r1.lo&maskLow51Bits + c0
-	rr2 := r2.lo&maskLow51Bits + c1
-	rr3 := r3.lo&maskLow51Bits + c2
-	rr4 := r4.lo&maskLow51Bits + c3
-
-	// Now all coefficients fit into 64-bit registers but are still too large to
-	// be passed around as a Element. We therefore do one last carry chain,
-	// where the carries will be small enough to fit in the wiggle room above 2⁵¹.
-	*v = Element{rr0, rr1, rr2, rr3, rr4}
-	v.carryPropagate()
-}
-
-func feSquareGeneric(v, a *Element) {
-	l0 := a.l0
-	l1 := a.l1
-	l2 := a.l2
-	l3 := a.l3
-	l4 := a.l4
-
-	// Squaring works precisely like multiplication above, but thanks to its
-	// symmetry we get to group a few terms together.
-	//
-	//                          l4   l3   l2   l1   l0  x
-	//                          l4   l3   l2   l1   l0  =
-	//                         ------------------------
-	//                        l4l0 l3l0 l2l0 l1l0 l0l0  +
-	//                   l4l1 l3l1 l2l1 l1l1 l0l1       +
-	//              l4l2 l3l2 l2l2 l1l2 l0l2            +
-	//         l4l3 l3l3 l2l3 l1l3 l0l3                 +
-	//    l4l4 l3l4 l2l4 l1l4 l0l4                      =
-	//   ----------------------------------------------
-	//      r8   r7   r6   r5   r4   r3   r2   r1   r0
-	//
-	//            l4l0    l3l0    l2l0    l1l0    l0l0  +
-	//            l3l1    l2l1    l1l1    l0l1 19×l4l1  +
-	//            l2l2    l1l2    l0l2 19×l4l2 19×l3l2  +
-	//            l1l3    l0l3 19×l4l3 19×l3l3 19×l2l3  +
-	//            l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4  =
-	//           --------------------------------------
-	//              r4      r3      r2      r1      r0
-	//
-	// With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with
-	// only three Mul64 and four Add64, instead of five and eight.
-
-	l0_2 := l0 * 2
-	l1_2 := l1 * 2
-
-	l1_38 := l1 * 38
-	l2_38 := l2 * 38
-	l3_38 := l3 * 38
-
-	l3_19 := l3 * 19
-	l4_19 := l4 * 19
-
-	// r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3)
-	r0 := mul64(l0, l0)
-	r0 = addMul64(r0, l1_38, l4)
-	r0 = addMul64(r0, l2_38, l3)
-
-	// r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
-	r1 := mul64(l0_2, l1)
-	r1 = addMul64(r1, l2_38, l4)
-	r1 = addMul64(r1, l3_19, l3)
-
-	// r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4
-	r2 := mul64(l0_2, l2)
-	r2 = addMul64(r2, l1, l1)
-	r2 = addMul64(r2, l3_38, l4)
-
-	// r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
-	r3 := mul64(l0_2, l3)
-	r3 = addMul64(r3, l1_2, l2)
-	r3 = addMul64(r3, l4_19, l4)
-
-	// r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2
-	r4 := mul64(l0_2, l4)
-	r4 = addMul64(r4, l1_2, l3)
-	r4 = addMul64(r4, l2, l2)
-
-	c0 := shiftRightBy51(r0)
-	c1 := shiftRightBy51(r1)
-	c2 := shiftRightBy51(r2)
-	c3 := shiftRightBy51(r3)
-	c4 := shiftRightBy51(r4)
-
-	rr0 := r0.lo&maskLow51Bits + c4*19
-	rr1 := r1.lo&maskLow51Bits + c0
-	rr2 := r2.lo&maskLow51Bits + c1
-	rr3 := r3.lo&maskLow51Bits + c2
-	rr4 := r4.lo&maskLow51Bits + c3
-
-	*v = Element{rr0, rr1, rr2, rr3, rr4}
-	v.carryPropagate()
-}
-
-// carryPropagateGeneric brings the limbs below 52 bits by applying the reduction
-// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry. TODO inline
-func (v *Element) carryPropagateGeneric() *Element {
-	c0 := v.l0 >> 51
-	c1 := v.l1 >> 51
-	c2 := v.l2 >> 51
-	c3 := v.l3 >> 51
-	c4 := v.l4 >> 51
-
-	v.l0 = v.l0&maskLow51Bits + c4*19
-	v.l1 = v.l1&maskLow51Bits + c0
-	v.l2 = v.l2&maskLow51Bits + c1
-	v.l3 = v.l3&maskLow51Bits + c2
-	v.l4 = v.l4&maskLow51Bits + c3
-
-	return v
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
deleted file mode 100644
index e3685f95..00000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
+++ /dev/null
@@ -1 +0,0 @@
-b0c49ae9f59d233526f8934262c5bbbe14d4358d
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
deleted file mode 100644
index 1ba22a8b..00000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#! /bin/bash
-set -euo pipefail
-
-cd "$(git rev-parse --show-toplevel)"
-
-STD_PATH=src/crypto/ed25519/internal/edwards25519/field
-LOCAL_PATH=curve25519/internal/field
-LAST_SYNC_REF=$(cat $LOCAL_PATH/sync.checkpoint)
-
-git fetch https://go.googlesource.com/go master
-
-if git diff --quiet $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH; then
-    echo "No changes."
-else
-    NEW_REF=$(git rev-parse FETCH_HEAD | tee $LOCAL_PATH/sync.checkpoint)
-    echo "Applying changes from $LAST_SYNC_REF to $NEW_REF..."
-    git diff $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH | \
-        git apply -3 --directory=$LOCAL_PATH
-fi
diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519.go b/vendor/golang.org/x/crypto/ed25519/ed25519.go
index a7828345..59b3a95a 100644
--- a/vendor/golang.org/x/crypto/ed25519/ed25519.go
+++ b/vendor/golang.org/x/crypto/ed25519/ed25519.go
@@ -11,9 +11,7 @@
 // operations with the same key more efficient. This package refers to the RFC
 // 8032 private key as the “seed”.
 //
-// Beginning with Go 1.13, the functionality of this package was moved to the
-// standard library as crypto/ed25519. This package only acts as a compatibility
-// wrapper.
+// This package is a wrapper around the standard library crypto/ed25519 package.
 package ed25519
 
 import (
diff --git a/vendor/golang.org/x/crypto/hkdf/hkdf.go b/vendor/golang.org/x/crypto/hkdf/hkdf.go
index f4ded5fe..3bee6629 100644
--- a/vendor/golang.org/x/crypto/hkdf/hkdf.go
+++ b/vendor/golang.org/x/crypto/hkdf/hkdf.go
@@ -8,7 +8,7 @@
 // HKDF is a cryptographic key derivation function (KDF) with the goal of
 // expanding limited input keying material into one or more cryptographically
 // strong secret keys.
-package hkdf // import "golang.org/x/crypto/hkdf"
+package hkdf
 
 import (
 	"crypto/hmac"
diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s
index d2ca5dee..b3c1699b 100644
--- a/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s
+++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s
@@ -19,15 +19,14 @@
 
 #define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \
 	MULLD  r0, h0, t0;  \
-	MULLD  r0, h1, t4;  \
 	MULHDU r0, h0, t1;  \
+	MULLD  r0, h1, t4;  \
 	MULHDU r0, h1, t5;  \
 	ADDC   t4, t1, t1;  \
 	MULLD  r0, h2, t2;  \
-	ADDZE  t5;          \
 	MULHDU r1, h0, t4;  \
 	MULLD  r1, h0, h0;  \
-	ADD    t5, t2, t2;  \
+	ADDE   t5, t2, t2;  \
 	ADDC   h0, t1, t1;  \
 	MULLD  h2, r1, t3;  \
 	ADDZE  t4, h0;      \
@@ -37,13 +36,11 @@
 	ADDE   t5, t3, t3;  \
 	ADDC   h0, t2, t2;  \
 	MOVD   $-4, t4;     \
-	MOVD   t0, h0;      \
-	MOVD   t1, h1;      \
 	ADDZE  t3;          \
-	ANDCC  $3, t2, h2;  \
-	AND    t2, t4, t0;  \
+	RLDICL $0, t2, $62, h2; \
+	AND    t2, t4, h0;  \
 	ADDC   t0, h0, h0;  \
-	ADDE   t3, h1, h1;  \
+	ADDE   t3, t1, h1;  \
 	SLD    $62, t3, t4; \
 	SRD    $2, t2;      \
 	ADDZE  h2;          \
@@ -75,6 +72,7 @@ TEXT ·update(SB), $0-32
 loop:
 	POLY1305_ADD(R4, R8, R9, R10, R20, R21, R22)
 
+	PCALIGN $16
 multiply:
 	POLY1305_MUL(R8, R9, R10, R11, R12, R16, R17, R18, R14, R20, R21)
 	ADD $-16, R5
diff --git a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go b/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
index f3c3242a..1fe600ad 100644
--- a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
+++ b/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
@@ -32,7 +32,7 @@ chunk size.
 
 This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
 */
-package secretbox // import "golang.org/x/crypto/nacl/secretbox"
+package secretbox
 
 import (
 	"golang.org/x/crypto/internal/alias"
diff --git a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
index 904b57e0..28cd99c7 100644
--- a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
+++ b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
@@ -16,7 +16,7 @@ Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To
 choose, you can pass the `New` functions from the different SHA packages to
 pbkdf2.Key.
 */
-package pbkdf2 // import "golang.org/x/crypto/pbkdf2"
+package pbkdf2
 
 import (
 	"crypto/hmac"
diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
index 3fd05b27..3685b344 100644
--- a/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
+++ b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // Package salsa provides low-level access to functions in the Salsa family.
-package salsa // import "golang.org/x/crypto/salsa20/salsa"
+package salsa
 
 import "math/bits"
 
diff --git a/vendor/golang.org/x/crypto/salsa20/salsa20.go b/vendor/golang.org/x/crypto/salsa20/salsa20.go
index 8f4f896c..e75c9342 100644
--- a/vendor/golang.org/x/crypto/salsa20/salsa20.go
+++ b/vendor/golang.org/x/crypto/salsa20/salsa20.go
@@ -19,7 +19,7 @@ This package also implements XSalsa20: a version of Salsa20 with a 24-byte
 nonce as specified in https://cr.yp.to/snuffle/xsalsa-20081128.pdf. Simply
 passing a 24-byte slice as the nonce triggers XSalsa20.
 */
-package salsa20 // import "golang.org/x/crypto/salsa20"
+package salsa20
 
 // TODO(agl): implement XORKeyStream12 and XORKeyStream8 - the reduced round variants of Salsa20.
 
diff --git a/vendor/golang.org/x/crypto/sha3/doc.go b/vendor/golang.org/x/crypto/sha3/doc.go
index decd8cf9..7e023090 100644
--- a/vendor/golang.org/x/crypto/sha3/doc.go
+++ b/vendor/golang.org/x/crypto/sha3/doc.go
@@ -59,4 +59,4 @@
 // They produce output of the same length, with the same security strengths
 // against all attacks. This means, in particular, that SHA3-256 only has
 // 128-bit collision resistance, because its output length is 32 bytes.
-package sha3 // import "golang.org/x/crypto/sha3"
+package sha3
diff --git a/vendor/golang.org/x/crypto/sha3/hashes.go b/vendor/golang.org/x/crypto/sha3/hashes.go
index 0d8043fd..c544b29e 100644
--- a/vendor/golang.org/x/crypto/sha3/hashes.go
+++ b/vendor/golang.org/x/crypto/sha3/hashes.go
@@ -9,6 +9,7 @@ package sha3
 // bytes.
 
 import (
+	"crypto"
 	"hash"
 )
 
@@ -16,39 +17,50 @@ import (
 // Its generic security strength is 224 bits against preimage attacks,
 // and 112 bits against collision attacks.
 func New224() hash.Hash {
-	if h := new224Asm(); h != nil {
-		return h
-	}
-	return &state{rate: 144, outputLen: 28, dsbyte: 0x06}
+	return new224()
 }
 
 // New256 creates a new SHA3-256 hash.
 // Its generic security strength is 256 bits against preimage attacks,
 // and 128 bits against collision attacks.
 func New256() hash.Hash {
-	if h := new256Asm(); h != nil {
-		return h
-	}
-	return &state{rate: 136, outputLen: 32, dsbyte: 0x06}
+	return new256()
 }
 
 // New384 creates a new SHA3-384 hash.
 // Its generic security strength is 384 bits against preimage attacks,
 // and 192 bits against collision attacks.
 func New384() hash.Hash {
-	if h := new384Asm(); h != nil {
-		return h
-	}
-	return &state{rate: 104, outputLen: 48, dsbyte: 0x06}
+	return new384()
 }
 
 // New512 creates a new SHA3-512 hash.
 // Its generic security strength is 512 bits against preimage attacks,
 // and 256 bits against collision attacks.
 func New512() hash.Hash {
-	if h := new512Asm(); h != nil {
-		return h
-	}
+	return new512()
+}
+
+func init() {
+	crypto.RegisterHash(crypto.SHA3_224, New224)
+	crypto.RegisterHash(crypto.SHA3_256, New256)
+	crypto.RegisterHash(crypto.SHA3_384, New384)
+	crypto.RegisterHash(crypto.SHA3_512, New512)
+}
+
+func new224Generic() *state {
+	return &state{rate: 144, outputLen: 28, dsbyte: 0x06}
+}
+
+func new256Generic() *state {
+	return &state{rate: 136, outputLen: 32, dsbyte: 0x06}
+}
+
+func new384Generic() *state {
+	return &state{rate: 104, outputLen: 48, dsbyte: 0x06}
+}
+
+func new512Generic() *state {
 	return &state{rate: 72, outputLen: 64, dsbyte: 0x06}
 }
 
diff --git a/vendor/golang.org/x/crypto/sha3/hashes_generic.go b/vendor/golang.org/x/crypto/sha3/hashes_generic.go
deleted file mode 100644
index fe8c8479..00000000
--- a/vendor/golang.org/x/crypto/sha3/hashes_generic.go
+++ /dev/null
@@ -1,27 +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.
-
-//go:build !gc || purego || !s390x
-
-package sha3
-
-import (
-	"hash"
-)
-
-// new224Asm returns an assembly implementation of SHA3-224 if available,
-// otherwise it returns nil.
-func new224Asm() hash.Hash { return nil }
-
-// new256Asm returns an assembly implementation of SHA3-256 if available,
-// otherwise it returns nil.
-func new256Asm() hash.Hash { return nil }
-
-// new384Asm returns an assembly implementation of SHA3-384 if available,
-// otherwise it returns nil.
-func new384Asm() hash.Hash { return nil }
-
-// new512Asm returns an assembly implementation of SHA3-512 if available,
-// otherwise it returns nil.
-func new512Asm() hash.Hash { return nil }
diff --git a/vendor/golang.org/x/crypto/sha3/hashes_noasm.go b/vendor/golang.org/x/crypto/sha3/hashes_noasm.go
new file mode 100644
index 00000000..9d85fb62
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/hashes_noasm.go
@@ -0,0 +1,23 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !gc || purego || !s390x
+
+package sha3
+
+func new224() *state {
+	return new224Generic()
+}
+
+func new256() *state {
+	return new256Generic()
+}
+
+func new384() *state {
+	return new384Generic()
+}
+
+func new512() *state {
+	return new512Generic()
+}
diff --git a/vendor/golang.org/x/crypto/sha3/register.go b/vendor/golang.org/x/crypto/sha3/register.go
deleted file mode 100644
index addfd504..00000000
--- a/vendor/golang.org/x/crypto/sha3/register.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.4
-
-package sha3
-
-import (
-	"crypto"
-)
-
-func init() {
-	crypto.RegisterHash(crypto.SHA3_224, New224)
-	crypto.RegisterHash(crypto.SHA3_256, New256)
-	crypto.RegisterHash(crypto.SHA3_384, New384)
-	crypto.RegisterHash(crypto.SHA3_512, New512)
-}
diff --git a/vendor/golang.org/x/crypto/sha3/sha3.go b/vendor/golang.org/x/crypto/sha3/sha3.go
index 4884d172..afedde5a 100644
--- a/vendor/golang.org/x/crypto/sha3/sha3.go
+++ b/vendor/golang.org/x/crypto/sha3/sha3.go
@@ -23,7 +23,6 @@ const (
 type state struct {
 	// Generic sponge components.
 	a    [25]uint64 // main state of the hash
-	buf  []byte     // points into storage
 	rate int        // the number of bytes of state to use
 
 	// dsbyte contains the "domain separation" bits and the first bit of
@@ -40,7 +39,8 @@ type state struct {
 	//      Extendable-Output Functions (May 2014)"
 	dsbyte byte
 
-	storage storageBuf
+	i, n    int // storage[i:n] is the buffer, i is only used while squeezing
+	storage [maxRate]byte
 
 	// Specific to SHA-3 and SHAKE.
 	outputLen int             // the default output size in bytes
@@ -54,24 +54,18 @@ func (d *state) BlockSize() int { return d.rate }
 func (d *state) Size() int { return d.outputLen }
 
 // Reset clears the internal state by zeroing the sponge state and
-// the byte buffer, and setting Sponge.state to absorbing.
+// the buffer indexes, and setting Sponge.state to absorbing.
 func (d *state) Reset() {
 	// Zero the permutation's state.
 	for i := range d.a {
 		d.a[i] = 0
 	}
 	d.state = spongeAbsorbing
-	d.buf = d.storage.asBytes()[:0]
+	d.i, d.n = 0, 0
 }
 
 func (d *state) clone() *state {
 	ret := *d
-	if ret.state == spongeAbsorbing {
-		ret.buf = ret.storage.asBytes()[:len(ret.buf)]
-	} else {
-		ret.buf = ret.storage.asBytes()[d.rate-cap(d.buf) : d.rate]
-	}
-
 	return &ret
 }
 
@@ -82,43 +76,40 @@ func (d *state) permute() {
 	case spongeAbsorbing:
 		// If we're absorbing, we need to xor the input into the state
 		// before applying the permutation.
-		xorIn(d, d.buf)
-		d.buf = d.storage.asBytes()[:0]
+		xorIn(d, d.storage[:d.rate])
+		d.n = 0
 		keccakF1600(&d.a)
 	case spongeSqueezing:
 		// If we're squeezing, we need to apply the permutation before
 		// copying more output.
 		keccakF1600(&d.a)
-		d.buf = d.storage.asBytes()[:d.rate]
-		copyOut(d, d.buf)
+		d.i = 0
+		copyOut(d, d.storage[:d.rate])
 	}
 }
 
 // pads appends the domain separation bits in dsbyte, applies
 // the multi-bitrate 10..1 padding rule, and permutes the state.
-func (d *state) padAndPermute(dsbyte byte) {
-	if d.buf == nil {
-		d.buf = d.storage.asBytes()[:0]
-	}
+func (d *state) padAndPermute() {
 	// Pad with this instance's domain-separator bits. We know that there's
 	// at least one byte of space in d.buf because, if it were full,
 	// permute would have been called to empty it. dsbyte also contains the
 	// first one bit for the padding. See the comment in the state struct.
-	d.buf = append(d.buf, dsbyte)
-	zerosStart := len(d.buf)
-	d.buf = d.storage.asBytes()[:d.rate]
-	for i := zerosStart; i < d.rate; i++ {
-		d.buf[i] = 0
+	d.storage[d.n] = d.dsbyte
+	d.n++
+	for d.n < d.rate {
+		d.storage[d.n] = 0
+		d.n++
 	}
 	// This adds the final one bit for the padding. Because of the way that
 	// bits are numbered from the LSB upwards, the final bit is the MSB of
 	// the last byte.
-	d.buf[d.rate-1] ^= 0x80
+	d.storage[d.rate-1] ^= 0x80
 	// Apply the permutation
 	d.permute()
 	d.state = spongeSqueezing
-	d.buf = d.storage.asBytes()[:d.rate]
-	copyOut(d, d.buf)
+	d.n = d.rate
+	copyOut(d, d.storage[:d.rate])
 }
 
 // Write absorbs more data into the hash's state. It panics if any
@@ -127,28 +118,25 @@ func (d *state) Write(p []byte) (written int, err error) {
 	if d.state != spongeAbsorbing {
 		panic("sha3: Write after Read")
 	}
-	if d.buf == nil {
-		d.buf = d.storage.asBytes()[:0]
-	}
 	written = len(p)
 
 	for len(p) > 0 {
-		if len(d.buf) == 0 && len(p) >= d.rate {
+		if d.n == 0 && len(p) >= d.rate {
 			// The fast path; absorb a full "rate" bytes of input and apply the permutation.
 			xorIn(d, p[:d.rate])
 			p = p[d.rate:]
 			keccakF1600(&d.a)
 		} else {
 			// The slow path; buffer the input until we can fill the sponge, and then xor it in.
-			todo := d.rate - len(d.buf)
+			todo := d.rate - d.n
 			if todo > len(p) {
 				todo = len(p)
 			}
-			d.buf = append(d.buf, p[:todo]...)
+			d.n += copy(d.storage[d.n:], p[:todo])
 			p = p[todo:]
 
 			// If the sponge is full, apply the permutation.
-			if len(d.buf) == d.rate {
+			if d.n == d.rate {
 				d.permute()
 			}
 		}
@@ -161,19 +149,19 @@ func (d *state) Write(p []byte) (written int, err error) {
 func (d *state) Read(out []byte) (n int, err error) {
 	// If we're still absorbing, pad and apply the permutation.
 	if d.state == spongeAbsorbing {
-		d.padAndPermute(d.dsbyte)
+		d.padAndPermute()
 	}
 
 	n = len(out)
 
 	// Now, do the squeezing.
 	for len(out) > 0 {
-		n := copy(out, d.buf)
-		d.buf = d.buf[n:]
+		n := copy(out, d.storage[d.i:d.n])
+		d.i += n
 		out = out[n:]
 
 		// Apply the permutation if we've squeezed the sponge dry.
-		if len(d.buf) == 0 {
+		if d.i == d.rate {
 			d.permute()
 		}
 	}
diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.go b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go
index d861bca5..00d8034a 100644
--- a/vendor/golang.org/x/crypto/sha3/sha3_s390x.go
+++ b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go
@@ -143,6 +143,12 @@ func (s *asmState) Write(b []byte) (int, error) {
 
 // Read squeezes an arbitrary number of bytes from the sponge.
 func (s *asmState) Read(out []byte) (n int, err error) {
+	// The 'compute last message digest' instruction only stores the digest
+	// at the first operand (dst) for SHAKE functions.
+	if s.function != shake_128 && s.function != shake_256 {
+		panic("sha3: can only call Read for SHAKE functions")
+	}
+
 	n = len(out)
 
 	// need to pad if we were absorbing
@@ -202,8 +208,17 @@ func (s *asmState) Sum(b []byte) []byte {
 
 	// Hash the buffer. Note that we don't clear it because we
 	// aren't updating the state.
-	klmd(s.function, &a, nil, s.buf)
-	return append(b, a[:s.outputLen]...)
+	switch s.function {
+	case sha3_224, sha3_256, sha3_384, sha3_512:
+		klmd(s.function, &a, nil, s.buf)
+		return append(b, a[:s.outputLen]...)
+	case shake_128, shake_256:
+		d := make([]byte, s.outputLen, 64)
+		klmd(s.function, &a, d, s.buf)
+		return append(b, d[:s.outputLen]...)
+	default:
+		panic("sha3: unknown function")
+	}
 }
 
 // Reset resets the Hash to its initial state.
@@ -233,56 +248,56 @@ func (s *asmState) Clone() ShakeHash {
 	return s.clone()
 }
 
-// new224Asm returns an assembly implementation of SHA3-224 if available,
-// otherwise it returns nil.
-func new224Asm() hash.Hash {
+// new224 returns an assembly implementation of SHA3-224 if available,
+// otherwise it returns a generic implementation.
+func new224() hash.Hash {
 	if cpu.S390X.HasSHA3 {
 		return newAsmState(sha3_224)
 	}
-	return nil
+	return new224Generic()
 }
 
-// new256Asm returns an assembly implementation of SHA3-256 if available,
-// otherwise it returns nil.
-func new256Asm() hash.Hash {
+// new256 returns an assembly implementation of SHA3-256 if available,
+// otherwise it returns a generic implementation.
+func new256() hash.Hash {
 	if cpu.S390X.HasSHA3 {
 		return newAsmState(sha3_256)
 	}
-	return nil
+	return new256Generic()
 }
 
-// new384Asm returns an assembly implementation of SHA3-384 if available,
-// otherwise it returns nil.
-func new384Asm() hash.Hash {
+// new384 returns an assembly implementation of SHA3-384 if available,
+// otherwise it returns a generic implementation.
+func new384() hash.Hash {
 	if cpu.S390X.HasSHA3 {
 		return newAsmState(sha3_384)
 	}
-	return nil
+	return new384Generic()
 }
 
-// new512Asm returns an assembly implementation of SHA3-512 if available,
-// otherwise it returns nil.
-func new512Asm() hash.Hash {
+// new512 returns an assembly implementation of SHA3-512 if available,
+// otherwise it returns a generic implementation.
+func new512() hash.Hash {
 	if cpu.S390X.HasSHA3 {
 		return newAsmState(sha3_512)
 	}
-	return nil
+	return new512Generic()
 }
 
-// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
-// otherwise it returns nil.
-func newShake128Asm() ShakeHash {
+// newShake128 returns an assembly implementation of SHAKE-128 if available,
+// otherwise it returns a generic implementation.
+func newShake128() ShakeHash {
 	if cpu.S390X.HasSHA3 {
 		return newAsmState(shake_128)
 	}
-	return nil
+	return newShake128Generic()
 }
 
-// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
-// otherwise it returns nil.
-func newShake256Asm() ShakeHash {
+// newShake256 returns an assembly implementation of SHAKE-256 if available,
+// otherwise it returns a generic implementation.
+func newShake256() ShakeHash {
 	if cpu.S390X.HasSHA3 {
 		return newAsmState(shake_256)
 	}
-	return nil
+	return newShake256Generic()
 }
diff --git a/vendor/golang.org/x/crypto/sha3/shake.go b/vendor/golang.org/x/crypto/sha3/shake.go
index bb699840..1ea9275b 100644
--- a/vendor/golang.org/x/crypto/sha3/shake.go
+++ b/vendor/golang.org/x/crypto/sha3/shake.go
@@ -115,19 +115,21 @@ func (c *state) Clone() ShakeHash {
 // Its generic security strength is 128 bits against all attacks if at
 // least 32 bytes of its output are used.
 func NewShake128() ShakeHash {
-	if h := newShake128Asm(); h != nil {
-		return h
-	}
-	return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake}
+	return newShake128()
 }
 
 // NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
 // Its generic security strength is 256 bits against all attacks if
 // at least 64 bytes of its output are used.
 func NewShake256() ShakeHash {
-	if h := newShake256Asm(); h != nil {
-		return h
-	}
+	return newShake256()
+}
+
+func newShake128Generic() *state {
+	return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake}
+}
+
+func newShake256Generic() *state {
 	return &state{rate: rate256, outputLen: 64, dsbyte: dsbyteShake}
 }
 
diff --git a/vendor/golang.org/x/crypto/sha3/shake_generic.go b/vendor/golang.org/x/crypto/sha3/shake_generic.go
deleted file mode 100644
index 8d31cf5b..00000000
--- a/vendor/golang.org/x/crypto/sha3/shake_generic.go
+++ /dev/null
@@ -1,19 +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.
-
-//go:build !gc || purego || !s390x
-
-package sha3
-
-// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
-// otherwise it returns nil.
-func newShake128Asm() ShakeHash {
-	return nil
-}
-
-// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
-// otherwise it returns nil.
-func newShake256Asm() ShakeHash {
-	return nil
-}
diff --git a/vendor/golang.org/x/crypto/sha3/shake_noasm.go b/vendor/golang.org/x/crypto/sha3/shake_noasm.go
new file mode 100644
index 00000000..4276ba4a
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/shake_noasm.go
@@ -0,0 +1,15 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !gc || purego || !s390x
+
+package sha3
+
+func newShake128() *state {
+	return newShake128Generic()
+}
+
+func newShake256() *state {
+	return newShake256Generic()
+}
diff --git a/vendor/golang.org/x/crypto/sha3/xor.go b/vendor/golang.org/x/crypto/sha3/xor.go
index 7337cca8..6ada5c95 100644
--- a/vendor/golang.org/x/crypto/sha3/xor.go
+++ b/vendor/golang.org/x/crypto/sha3/xor.go
@@ -2,22 +2,39 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (!amd64 && !386 && !ppc64le) || purego
-
 package sha3
 
-// A storageBuf is an aligned array of maxRate bytes.
-type storageBuf [maxRate]byte
-
-func (b *storageBuf) asBytes() *[maxRate]byte {
-	return (*[maxRate]byte)(b)
-}
+import (
+	"crypto/subtle"
+	"encoding/binary"
+	"unsafe"
 
-var (
-	xorIn            = xorInGeneric
-	copyOut          = copyOutGeneric
-	xorInUnaligned   = xorInGeneric
-	copyOutUnaligned = copyOutGeneric
+	"golang.org/x/sys/cpu"
 )
 
-const xorImplementationUnaligned = "generic"
+// xorIn xors the bytes in buf into the state.
+func xorIn(d *state, buf []byte) {
+	if cpu.IsBigEndian {
+		for i := 0; len(buf) >= 8; i++ {
+			a := binary.LittleEndian.Uint64(buf)
+			d.a[i] ^= a
+			buf = buf[8:]
+		}
+	} else {
+		ab := (*[25 * 64 / 8]byte)(unsafe.Pointer(&d.a))
+		subtle.XORBytes(ab[:], ab[:], buf)
+	}
+}
+
+// copyOut copies uint64s to a byte buffer.
+func copyOut(d *state, b []byte) {
+	if cpu.IsBigEndian {
+		for i := 0; len(b) >= 8; i++ {
+			binary.LittleEndian.PutUint64(b, d.a[i])
+			b = b[8:]
+		}
+	} else {
+		ab := (*[25 * 64 / 8]byte)(unsafe.Pointer(&d.a))
+		copy(b, ab[:])
+	}
+}
diff --git a/vendor/golang.org/x/crypto/twofish/twofish.go b/vendor/golang.org/x/crypto/twofish/twofish.go
index e4eeae17..6d0a3028 100644
--- a/vendor/golang.org/x/crypto/twofish/twofish.go
+++ b/vendor/golang.org/x/crypto/twofish/twofish.go
@@ -9,7 +9,7 @@
 // implementation. Instead, use AES (from crypto/aes, if necessary in an AEAD
 // mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
 // golang.org/x/crypto/chacha20poly1305).
-package twofish // import "golang.org/x/crypto/twofish"
+package twofish
 
 // Twofish is defined in https://www.schneier.com/paper-twofish-paper.pdf [TWOFISH]
 
diff --git a/vendor/golang.org/x/crypto/xtea/cipher.go b/vendor/golang.org/x/crypto/xtea/cipher.go
index a4c2fd02..7b4f8aaa 100644
--- a/vendor/golang.org/x/crypto/xtea/cipher.go
+++ b/vendor/golang.org/x/crypto/xtea/cipher.go
@@ -12,7 +12,7 @@
 // Deprecated: any new system should use AES (from crypto/aes, if necessary in
 // an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
 // golang.org/x/crypto/chacha20poly1305).
-package xtea // import "golang.org/x/crypto/xtea"
+package xtea
 
 // For details, see http://www.cix.co.uk/~klockstone/xtea.pdf
 
diff --git a/vendor/golang.org/x/net/http/httpguts/httplex.go b/vendor/golang.org/x/net/http/httpguts/httplex.go
index 6e071e85..9b4de940 100644
--- a/vendor/golang.org/x/net/http/httpguts/httplex.go
+++ b/vendor/golang.org/x/net/http/httpguts/httplex.go
@@ -12,7 +12,7 @@ import (
 	"golang.org/x/net/idna"
 )
 
-var isTokenTable = [127]bool{
+var isTokenTable = [256]bool{
 	'!':  true,
 	'#':  true,
 	'$':  true,
@@ -93,12 +93,7 @@ var isTokenTable = [127]bool{
 }
 
 func IsTokenRune(r rune) bool {
-	i := int(r)
-	return i < len(isTokenTable) && isTokenTable[i]
-}
-
-func isNotToken(r rune) bool {
-	return !IsTokenRune(r)
+	return r < utf8.RuneSelf && isTokenTable[byte(r)]
 }
 
 // HeaderValuesContainsToken reports whether any string in values
@@ -202,8 +197,8 @@ func ValidHeaderFieldName(v string) bool {
 	if len(v) == 0 {
 		return false
 	}
-	for _, r := range v {
-		if !IsTokenRune(r) {
+	for i := 0; i < len(v); i++ {
+		if !isTokenTable[v[i]] {
 			return false
 		}
 	}
diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go
index e2b298d8..105c3b27 100644
--- a/vendor/golang.org/x/net/http2/frame.go
+++ b/vendor/golang.org/x/net/http2/frame.go
@@ -490,6 +490,9 @@ func terminalReadFrameError(err error) bool {
 // returned error is ErrFrameTooLarge. Other errors may be of type
 // ConnectionError, StreamError, or anything else from the underlying
 // reader.
+//
+// If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID
+// indicates the stream responsible for the error.
 func (fr *Framer) ReadFrame() (Frame, error) {
 	fr.errDetail = nil
 	if fr.lastFrame != nil {
@@ -1521,7 +1524,7 @@ func (fr *Framer) maxHeaderStringLen() int {
 // readMetaFrame returns 0 or more CONTINUATION frames from fr and
 // merge them into the provided hf and returns a MetaHeadersFrame
 // with the decoded hpack values.
-func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
+func (fr *Framer) readMetaFrame(hf *HeadersFrame) (Frame, error) {
 	if fr.AllowIllegalReads {
 		return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders")
 	}
@@ -1564,6 +1567,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
 		if size > remainSize {
 			hdec.SetEmitEnabled(false)
 			mh.Truncated = true
+			remainSize = 0
 			return
 		}
 		remainSize -= size
@@ -1576,8 +1580,38 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
 	var hc headersOrContinuation = hf
 	for {
 		frag := hc.HeaderBlockFragment()
+
+		// Avoid parsing large amounts of headers that we will then discard.
+		// If the sender exceeds the max header list size by too much,
+		// skip parsing the fragment and close the connection.
+		//
+		// "Too much" is either any CONTINUATION frame after we've already
+		// exceeded the max header list size (in which case remainSize is 0),
+		// or a frame whose encoded size is more than twice the remaining
+		// header list bytes we're willing to accept.
+		if int64(len(frag)) > int64(2*remainSize) {
+			if VerboseLogs {
+				log.Printf("http2: header list too large")
+			}
+			// It would be nice to send a RST_STREAM before sending the GOAWAY,
+			// but the structure of the server's frame writer makes this difficult.
+			return mh, ConnectionError(ErrCodeProtocol)
+		}
+
+		// Also close the connection after any CONTINUATION frame following an
+		// invalid header, since we stop tracking the size of the headers after
+		// an invalid one.
+		if invalid != nil {
+			if VerboseLogs {
+				log.Printf("http2: invalid header: %v", invalid)
+			}
+			// It would be nice to send a RST_STREAM before sending the GOAWAY,
+			// but the structure of the server's frame writer makes this difficult.
+			return mh, ConnectionError(ErrCodeProtocol)
+		}
+
 		if _, err := hdec.Write(frag); err != nil {
-			return nil, ConnectionError(ErrCodeCompression)
+			return mh, ConnectionError(ErrCodeCompression)
 		}
 
 		if hc.HeadersEnded() {
@@ -1594,7 +1628,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
 	mh.HeadersFrame.invalidate()
 
 	if err := hdec.Close(); err != nil {
-		return nil, ConnectionError(ErrCodeCompression)
+		return mh, ConnectionError(ErrCodeCompression)
 	}
 	if invalid != nil {
 		fr.errDetail = invalid
diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go
index 6f2df281..003e649f 100644
--- a/vendor/golang.org/x/net/http2/http2.go
+++ b/vendor/golang.org/x/net/http2/http2.go
@@ -17,6 +17,7 @@ package http2 // import "golang.org/x/net/http2"
 
 import (
 	"bufio"
+	"context"
 	"crypto/tls"
 	"fmt"
 	"io"
@@ -26,6 +27,7 @@ import (
 	"strconv"
 	"strings"
 	"sync"
+	"time"
 
 	"golang.org/x/net/http/httpguts"
 )
@@ -210,12 +212,6 @@ type stringWriter interface {
 	WriteString(s string) (n int, err error)
 }
 
-// A gate lets two goroutines coordinate their activities.
-type gate chan struct{}
-
-func (g gate) Done() { g <- struct{}{} }
-func (g gate) Wait() { <-g }
-
 // A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed).
 type closeWaiter chan struct{}
 
@@ -383,3 +379,14 @@ func validPseudoPath(v string) bool {
 // makes that struct also non-comparable, and generally doesn't add
 // any size (as long as it's first).
 type incomparable [0]func()
+
+// synctestGroupInterface is the methods of synctestGroup used by Server and Transport.
+// It's defined as an interface here to let us keep synctestGroup entirely test-only
+// and not a part of non-test builds.
+type synctestGroupInterface interface {
+	Join()
+	Now() time.Time
+	NewTimer(d time.Duration) timer
+	AfterFunc(d time.Duration, f func()) timer
+	ContextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc)
+}
diff --git a/vendor/golang.org/x/net/http2/pipe.go b/vendor/golang.org/x/net/http2/pipe.go
index 684d984f..3b9f06b9 100644
--- a/vendor/golang.org/x/net/http2/pipe.go
+++ b/vendor/golang.org/x/net/http2/pipe.go
@@ -77,7 +77,10 @@ func (p *pipe) Read(d []byte) (n int, err error) {
 	}
 }
 
-var errClosedPipeWrite = errors.New("write on closed buffer")
+var (
+	errClosedPipeWrite        = errors.New("write on closed buffer")
+	errUninitializedPipeWrite = errors.New("write on uninitialized buffer")
+)
 
 // Write copies bytes from p into the buffer and wakes a reader.
 // It is an error to write more data than the buffer can hold.
@@ -91,6 +94,12 @@ func (p *pipe) Write(d []byte) (n int, err error) {
 	if p.err != nil || p.breakErr != nil {
 		return 0, errClosedPipeWrite
 	}
+	// pipe.setBuffer is never invoked, leaving the buffer uninitialized.
+	// We shouldn't try to write to an uninitialized pipe,
+	// but returning an error is better than panicking.
+	if p.b == nil {
+		return 0, errUninitializedPipeWrite
+	}
 	return p.b.Write(d)
 }
 
diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go
index ae94c640..6c349f3e 100644
--- a/vendor/golang.org/x/net/http2/server.go
+++ b/vendor/golang.org/x/net/http2/server.go
@@ -124,6 +124,7 @@ type Server struct {
 	// IdleTimeout specifies how long until idle clients should be
 	// closed with a GOAWAY frame. PING frames are not considered
 	// activity for the purposes of IdleTimeout.
+	// If zero or negative, there is no timeout.
 	IdleTimeout time.Duration
 
 	// MaxUploadBufferPerConnection is the size of the initial flow
@@ -153,6 +154,39 @@ type Server struct {
 	// so that we don't embed a Mutex in this struct, which will make the
 	// struct non-copyable, which might break some callers.
 	state *serverInternalState
+
+	// Synchronization group used for testing.
+	// Outside of tests, this is nil.
+	group synctestGroupInterface
+}
+
+func (s *Server) markNewGoroutine() {
+	if s.group != nil {
+		s.group.Join()
+	}
+}
+
+func (s *Server) now() time.Time {
+	if s.group != nil {
+		return s.group.Now()
+	}
+	return time.Now()
+}
+
+// newTimer creates a new time.Timer, or a synthetic timer in tests.
+func (s *Server) newTimer(d time.Duration) timer {
+	if s.group != nil {
+		return s.group.NewTimer(d)
+	}
+	return timeTimer{time.NewTimer(d)}
+}
+
+// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests.
+func (s *Server) afterFunc(d time.Duration, f func()) timer {
+	if s.group != nil {
+		return s.group.AfterFunc(d, f)
+	}
+	return timeTimer{time.AfterFunc(d, f)}
 }
 
 func (s *Server) initialConnRecvWindowSize() int32 {
@@ -399,6 +433,10 @@ func (o *ServeConnOpts) handler() http.Handler {
 //
 // The opts parameter is optional. If nil, default values are used.
 func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
+	s.serveConn(c, opts, nil)
+}
+
+func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverConn)) {
 	baseCtx, cancel := serverConnBaseContext(c, opts)
 	defer cancel()
 
@@ -425,6 +463,9 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
 		pushEnabled:                 true,
 		sawClientPreface:            opts.SawClientPreface,
 	}
+	if newf != nil {
+		newf(sc)
+	}
 
 	s.state.registerConn(sc)
 	defer s.state.unregisterConn(sc)
@@ -434,7 +475,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
 	// passes the connection off to us with the deadline already set.
 	// Write deadlines are set per stream in serverConn.newStream.
 	// Disarm the net.Conn write deadline here.
-	if sc.hs.WriteTimeout != 0 {
+	if sc.hs.WriteTimeout > 0 {
 		sc.conn.SetWriteDeadline(time.Time{})
 	}
 
@@ -598,8 +639,8 @@ type serverConn struct {
 	inFrameScheduleLoop         bool              // whether we're in the scheduleFrameWrite loop
 	needToSendGoAway            bool              // we need to schedule a GOAWAY frame write
 	goAwayCode                  ErrCode
-	shutdownTimer               *time.Timer // nil until used
-	idleTimer                   *time.Timer // nil if unused
+	shutdownTimer               timer // nil until used
+	idleTimer                   timer // nil if unused
 
 	// Owned by the writeFrameAsync goroutine:
 	headerWriteBuf bytes.Buffer
@@ -648,12 +689,12 @@ type stream struct {
 	flow             outflow // limits writing from Handler to client
 	inflow           inflow  // what the client is allowed to POST/etc to us
 	state            streamState
-	resetQueued      bool        // RST_STREAM queued for write; set by sc.resetStream
-	gotTrailerHeader bool        // HEADER frame for trailers was seen
-	wroteHeaders     bool        // whether we wrote headers (not status 100)
-	readDeadline     *time.Timer // nil if unused
-	writeDeadline    *time.Timer // nil if unused
-	closeErr         error       // set before cw is closed
+	resetQueued      bool  // RST_STREAM queued for write; set by sc.resetStream
+	gotTrailerHeader bool  // HEADER frame for trailers was seen
+	wroteHeaders     bool  // whether we wrote headers (not status 100)
+	readDeadline     timer // nil if unused
+	writeDeadline    timer // nil if unused
+	closeErr         error // set before cw is closed
 
 	trailer    http.Header // accumulated trailers
 	reqTrailer http.Header // handler's Request.Trailer
@@ -731,11 +772,7 @@ func isClosedConnError(err error) bool {
 		return false
 	}
 
-	// TODO: remove this string search and be more like the Windows
-	// case below. That might involve modifying the standard library
-	// to return better error types.
-	str := err.Error()
-	if strings.Contains(str, "use of closed network connection") {
+	if errors.Is(err, net.ErrClosed) {
 		return true
 	}
 
@@ -814,8 +851,9 @@ type readFrameResult struct {
 // consumer is done with the frame.
 // It's run on its own goroutine.
 func (sc *serverConn) readFrames() {
-	gate := make(gate)
-	gateDone := gate.Done
+	sc.srv.markNewGoroutine()
+	gate := make(chan struct{})
+	gateDone := func() { gate <- struct{}{} }
 	for {
 		f, err := sc.framer.ReadFrame()
 		select {
@@ -846,6 +884,7 @@ type frameWriteResult struct {
 // At most one goroutine can be running writeFrameAsync at a time per
 // serverConn.
 func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest, wd *writeData) {
+	sc.srv.markNewGoroutine()
 	var err error
 	if wd == nil {
 		err = wr.write.writeFrame(sc)
@@ -924,14 +963,14 @@ func (sc *serverConn) serve() {
 	sc.setConnState(http.StateActive)
 	sc.setConnState(http.StateIdle)
 
-	if sc.srv.IdleTimeout != 0 {
-		sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
+	if sc.srv.IdleTimeout > 0 {
+		sc.idleTimer = sc.srv.afterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
 		defer sc.idleTimer.Stop()
 	}
 
 	go sc.readFrames() // closed by defer sc.conn.Close above
 
-	settingsTimer := time.AfterFunc(firstSettingsTimeout, sc.onSettingsTimer)
+	settingsTimer := sc.srv.afterFunc(firstSettingsTimeout, sc.onSettingsTimer)
 	defer settingsTimer.Stop()
 
 	loopNum := 0
@@ -1060,10 +1099,10 @@ func (sc *serverConn) readPreface() error {
 			errc <- nil
 		}
 	}()
-	timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server?
+	timer := sc.srv.newTimer(prefaceTimeout) // TODO: configurable on *Server?
 	defer timer.Stop()
 	select {
-	case <-timer.C:
+	case <-timer.C():
 		return errPrefaceTimeout
 	case err := <-errc:
 		if err == nil {
@@ -1428,7 +1467,7 @@ func (sc *serverConn) goAway(code ErrCode) {
 
 func (sc *serverConn) shutDownIn(d time.Duration) {
 	sc.serveG.check()
-	sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer)
+	sc.shutdownTimer = sc.srv.afterFunc(d, sc.onShutdownTimer)
 }
 
 func (sc *serverConn) resetStream(se StreamError) {
@@ -1481,6 +1520,11 @@ func (sc *serverConn) processFrameFromReader(res readFrameResult) bool {
 		sc.goAway(ErrCodeFlowControl)
 		return true
 	case ConnectionError:
+		if res.f != nil {
+			if id := res.f.Header().StreamID; id > sc.maxClientStreamID {
+				sc.maxClientStreamID = id
+			}
+		}
 		sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev)
 		sc.goAway(ErrCode(ev))
 		return true // goAway will handle shutdown
@@ -1637,7 +1681,7 @@ func (sc *serverConn) closeStream(st *stream, err error) {
 	delete(sc.streams, st.id)
 	if len(sc.streams) == 0 {
 		sc.setConnState(http.StateIdle)
-		if sc.srv.IdleTimeout != 0 {
+		if sc.srv.IdleTimeout > 0 && sc.idleTimer != nil {
 			sc.idleTimer.Reset(sc.srv.IdleTimeout)
 		}
 		if h1ServerKeepAlivesDisabled(sc.hs) {
@@ -1659,6 +1703,7 @@ func (sc *serverConn) closeStream(st *stream, err error) {
 		}
 	}
 	st.closeErr = err
+	st.cancelCtx()
 	st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
 	sc.writeSched.CloseStream(st.id)
 }
@@ -2017,9 +2062,9 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
 	// similar to how the http1 server works. Here it's
 	// technically more like the http1 Server's ReadHeaderTimeout
 	// (in Go 1.8), though. That's a more sane option anyway.
-	if sc.hs.ReadTimeout != 0 {
+	if sc.hs.ReadTimeout > 0 {
 		sc.conn.SetReadDeadline(time.Time{})
-		st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
+		st.readDeadline = sc.srv.afterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
 	}
 
 	return sc.scheduleHandler(id, rw, req, handler)
@@ -2038,7 +2083,7 @@ func (sc *serverConn) upgradeRequest(req *http.Request) {
 
 	// Disable any read deadline set by the net/http package
 	// prior to the upgrade.
-	if sc.hs.ReadTimeout != 0 {
+	if sc.hs.ReadTimeout > 0 {
 		sc.conn.SetReadDeadline(time.Time{})
 	}
 
@@ -2116,8 +2161,8 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream
 	st.flow.conn = &sc.flow // link to conn-level counter
 	st.flow.add(sc.initialStreamSendWindowSize)
 	st.inflow.init(sc.srv.initialStreamRecvWindowSize())
-	if sc.hs.WriteTimeout != 0 {
-		st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
+	if sc.hs.WriteTimeout > 0 {
+		st.writeDeadline = sc.srv.afterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
 	}
 
 	sc.streams[id] = st
@@ -2341,6 +2386,7 @@ func (sc *serverConn) handlerDone() {
 
 // Run on its own goroutine.
 func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) {
+	sc.srv.markNewGoroutine()
 	defer sc.sendServeMsg(handlerDoneMsg)
 	didPanic := true
 	defer func() {
@@ -2637,7 +2683,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
 		var date string
 		if _, ok := rws.snapHeader["Date"]; !ok {
 			// TODO(bradfitz): be faster here, like net/http? measure.
-			date = time.Now().UTC().Format(http.TimeFormat)
+			date = rws.conn.srv.now().UTC().Format(http.TimeFormat)
 		}
 
 		for _, v := range rws.snapHeader["Trailer"] {
@@ -2759,7 +2805,7 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() {
 
 func (w *responseWriter) SetReadDeadline(deadline time.Time) error {
 	st := w.rws.stream
-	if !deadline.IsZero() && deadline.Before(time.Now()) {
+	if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) {
 		// If we're setting a deadline in the past, reset the stream immediately
 		// so writes after SetWriteDeadline returns will fail.
 		st.onReadTimeout()
@@ -2775,9 +2821,9 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error {
 		if deadline.IsZero() {
 			st.readDeadline = nil
 		} else if st.readDeadline == nil {
-			st.readDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onReadTimeout)
+			st.readDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onReadTimeout)
 		} else {
-			st.readDeadline.Reset(deadline.Sub(time.Now()))
+			st.readDeadline.Reset(deadline.Sub(sc.srv.now()))
 		}
 	})
 	return nil
@@ -2785,7 +2831,7 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error {
 
 func (w *responseWriter) SetWriteDeadline(deadline time.Time) error {
 	st := w.rws.stream
-	if !deadline.IsZero() && deadline.Before(time.Now()) {
+	if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) {
 		// If we're setting a deadline in the past, reset the stream immediately
 		// so writes after SetWriteDeadline returns will fail.
 		st.onWriteTimeout()
@@ -2801,9 +2847,9 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error {
 		if deadline.IsZero() {
 			st.writeDeadline = nil
 		} else if st.writeDeadline == nil {
-			st.writeDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onWriteTimeout)
+			st.writeDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onWriteTimeout)
 		} else {
-			st.writeDeadline.Reset(deadline.Sub(time.Now()))
+			st.writeDeadline.Reset(deadline.Sub(sc.srv.now()))
 		}
 	})
 	return nil
diff --git a/vendor/golang.org/x/net/http2/timer.go b/vendor/golang.org/x/net/http2/timer.go
new file mode 100644
index 00000000..0b1c17b8
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/timer.go
@@ -0,0 +1,20 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+package http2
+
+import "time"
+
+// A timer is a time.Timer, as an interface which can be replaced in tests.
+type timer = interface {
+	C() <-chan time.Time
+	Reset(d time.Duration) bool
+	Stop() bool
+}
+
+// timeTimer adapts a time.Timer to the timer interface.
+type timeTimer struct {
+	*time.Timer
+}
+
+func (t timeTimer) C() <-chan time.Time { return t.Timer.C }
diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go
index df578b86..61f511f9 100644
--- a/vendor/golang.org/x/net/http2/transport.go
+++ b/vendor/golang.org/x/net/http2/transport.go
@@ -147,6 +147,12 @@ type Transport struct {
 	// waiting for their turn.
 	StrictMaxConcurrentStreams bool
 
+	// IdleConnTimeout is the maximum amount of time an idle
+	// (keep-alive) connection will remain idle before closing
+	// itself.
+	// Zero means no limit.
+	IdleConnTimeout time.Duration
+
 	// ReadIdleTimeout is the timeout after which a health check using ping
 	// frame will be carried out if no frame is received on the connection.
 	// Note that a ping response will is considered a received frame, so if
@@ -178,6 +184,46 @@ type Transport struct {
 
 	connPoolOnce  sync.Once
 	connPoolOrDef ClientConnPool // non-nil version of ConnPool
+
+	*transportTestHooks
+}
+
+// Hook points used for testing.
+// Outside of tests, t.transportTestHooks is nil and these all have minimal implementations.
+// Inside tests, see the testSyncHooks function docs.
+
+type transportTestHooks struct {
+	newclientconn func(*ClientConn)
+	group         synctestGroupInterface
+}
+
+func (t *Transport) markNewGoroutine() {
+	if t != nil && t.transportTestHooks != nil {
+		t.transportTestHooks.group.Join()
+	}
+}
+
+// newTimer creates a new time.Timer, or a synthetic timer in tests.
+func (t *Transport) newTimer(d time.Duration) timer {
+	if t.transportTestHooks != nil {
+		return t.transportTestHooks.group.NewTimer(d)
+	}
+	return timeTimer{time.NewTimer(d)}
+}
+
+// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests.
+func (t *Transport) afterFunc(d time.Duration, f func()) timer {
+	if t.transportTestHooks != nil {
+		return t.transportTestHooks.group.AfterFunc(d, f)
+	}
+	return timeTimer{time.AfterFunc(d, f)}
+}
+
+func (t *Transport) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) {
+	if t.transportTestHooks != nil {
+		return t.transportTestHooks.group.ContextWithTimeout(ctx, d)
+	}
+	return context.WithTimeout(ctx, d)
 }
 
 func (t *Transport) maxHeaderListSize() uint32 {
@@ -302,7 +348,7 @@ type ClientConn struct {
 	readerErr  error         // set before readerDone is closed
 
 	idleTimeout time.Duration // or 0 for never
-	idleTimer   *time.Timer
+	idleTimer   timer
 
 	mu              sync.Mutex // guards following
 	cond            *sync.Cond // hold mu; broadcast on flow/closed changes
@@ -446,6 +492,7 @@ func (cs *clientStream) closeReqBodyLocked() {
 	cs.reqBodyClosed = make(chan struct{})
 	reqBodyClosed := cs.reqBodyClosed
 	go func() {
+		cs.cc.t.markNewGoroutine()
 		cs.reqBody.Close()
 		close(reqBodyClosed)
 	}()
@@ -537,15 +584,6 @@ func authorityAddr(scheme string, authority string) (addr string) {
 	return net.JoinHostPort(host, port)
 }
 
-var retryBackoffHook func(time.Duration) *time.Timer
-
-func backoffNewTimer(d time.Duration) *time.Timer {
-	if retryBackoffHook != nil {
-		return retryBackoffHook(d)
-	}
-	return time.NewTimer(d)
-}
-
 // RoundTripOpt is like RoundTrip, but takes options.
 func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {
 	if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) {
@@ -573,13 +611,13 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res
 				backoff := float64(uint(1) << (uint(retry) - 1))
 				backoff += backoff * (0.1 * mathrand.Float64())
 				d := time.Second * time.Duration(backoff)
-				timer := backoffNewTimer(d)
+				tm := t.newTimer(d)
 				select {
-				case <-timer.C:
+				case <-tm.C():
 					t.vlogf("RoundTrip retrying after failure: %v", roundTripErr)
 					continue
 				case <-req.Context().Done():
-					timer.Stop()
+					tm.Stop()
 					err = req.Context().Err()
 				}
 			}
@@ -658,6 +696,9 @@ func canRetryError(err error) bool {
 }
 
 func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) {
+	if t.transportTestHooks != nil {
+		return t.newClientConn(nil, singleUse)
+	}
 	host, _, err := net.SplitHostPort(addr)
 	if err != nil {
 		return nil, err
@@ -751,9 +792,10 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
 		pings:                 make(map[[8]byte]chan struct{}),
 		reqHeaderMu:           make(chan struct{}, 1),
 	}
-	if d := t.idleConnTimeout(); d != 0 {
-		cc.idleTimeout = d
-		cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout)
+	if t.transportTestHooks != nil {
+		t.markNewGoroutine()
+		t.transportTestHooks.newclientconn(cc)
+		c = cc.tconn
 	}
 	if VerboseLogs {
 		t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr())
@@ -785,10 +827,6 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
 	cc.henc.SetMaxDynamicTableSizeLimit(t.maxEncoderHeaderTableSize())
 	cc.peerMaxHeaderTableSize = initialHeaderTableSize
 
-	if t.AllowHTTP {
-		cc.nextStreamID = 3
-	}
-
 	if cs, ok := c.(connectionStater); ok {
 		state := cs.ConnectionState()
 		cc.tlsState = &state
@@ -818,6 +856,12 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
 		return nil, cc.werr
 	}
 
+	// Start the idle timer after the connection is fully initialized.
+	if d := t.idleConnTimeout(); d != 0 {
+		cc.idleTimeout = d
+		cc.idleTimer = t.afterFunc(d, cc.onIdleTimeout)
+	}
+
 	go cc.readLoop()
 	return cc, nil
 }
@@ -826,7 +870,7 @@ func (cc *ClientConn) healthCheck() {
 	pingTimeout := cc.t.pingTimeout()
 	// We don't need to periodically ping in the health check, because the readLoop of ClientConn will
 	// trigger the healthCheck again if there is no frame received.
-	ctx, cancel := context.WithTimeout(context.Background(), pingTimeout)
+	ctx, cancel := cc.t.contextWithTimeout(context.Background(), pingTimeout)
 	defer cancel()
 	cc.vlogf("http2: Transport sending health check")
 	err := cc.Ping(ctx)
@@ -861,7 +905,20 @@ func (cc *ClientConn) setGoAway(f *GoAwayFrame) {
 	}
 	last := f.LastStreamID
 	for streamID, cs := range cc.streams {
-		if streamID > last {
+		if streamID <= last {
+			// The server's GOAWAY indicates that it received this stream.
+			// It will either finish processing it, or close the connection
+			// without doing so. Either way, leave the stream alone for now.
+			continue
+		}
+		if streamID == 1 && cc.goAway.ErrCode != ErrCodeNo {
+			// Don't retry the first stream on a connection if we get a non-NO error.
+			// If the server is sending an error on a new connection,
+			// retrying the request on a new one probably isn't going to work.
+			cs.abortStreamLocked(fmt.Errorf("http2: Transport received GOAWAY from server ErrCode:%v", cc.goAway.ErrCode))
+		} else {
+			// Aborting the stream with errClentConnGotGoAway indicates that
+			// the request should be retried on a new connection.
 			cs.abortStreamLocked(errClientConnGotGoAway)
 		}
 	}
@@ -1057,6 +1114,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error {
 	done := make(chan struct{})
 	cancelled := false // guarded by cc.mu
 	go func() {
+		cc.t.markNewGoroutine()
 		cc.mu.Lock()
 		defer cc.mu.Unlock()
 		for {
@@ -1215,6 +1273,10 @@ func (cc *ClientConn) decrStreamReservationsLocked() {
 }
 
 func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
+	return cc.roundTrip(req, nil)
+}
+
+func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) (*http.Response, error) {
 	ctx := req.Context()
 	cs := &clientStream{
 		cc:                   cc,
@@ -1229,7 +1291,28 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
 		respHeaderRecv:       make(chan struct{}),
 		donec:                make(chan struct{}),
 	}
-	go cs.doRequest(req)
+
+	// TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
+	if !cc.t.disableCompression() &&
+		req.Header.Get("Accept-Encoding") == "" &&
+		req.Header.Get("Range") == "" &&
+		!cs.isHead {
+		// Request gzip only, not deflate. Deflate is ambiguous and
+		// not as universally supported anyway.
+		// See: https://zlib.net/zlib_faq.html#faq39
+		//
+		// Note that we don't request this for HEAD requests,
+		// due to a bug in nginx:
+		//   http://trac.nginx.org/nginx/ticket/358
+		//   https://golang.org/issue/5522
+		//
+		// We don't request gzip if the request is for a range, since
+		// auto-decoding a portion of a gzipped document will just fail
+		// anyway. See https://golang.org/issue/8923
+		cs.requestedGzip = true
+	}
+
+	go cs.doRequest(req, streamf)
 
 	waitDone := func() error {
 		select {
@@ -1322,8 +1405,9 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
 // doRequest runs for the duration of the request lifetime.
 //
 // It sends the request and performs post-request cleanup (closing Request.Body, etc.).
-func (cs *clientStream) doRequest(req *http.Request) {
-	err := cs.writeRequest(req)
+func (cs *clientStream) doRequest(req *http.Request, streamf func(*clientStream)) {
+	cs.cc.t.markNewGoroutine()
+	err := cs.writeRequest(req, streamf)
 	cs.cleanupWriteRequest(err)
 }
 
@@ -1334,7 +1418,7 @@ func (cs *clientStream) doRequest(req *http.Request) {
 //
 // It returns non-nil if the request ends otherwise.
 // If the returned error is StreamError, the error Code may be used in resetting the stream.
-func (cs *clientStream) writeRequest(req *http.Request) (err error) {
+func (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStream)) (err error) {
 	cc := cs.cc
 	ctx := cs.ctx
 
@@ -1372,24 +1456,8 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) {
 	}
 	cc.mu.Unlock()
 
-	// TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
-	if !cc.t.disableCompression() &&
-		req.Header.Get("Accept-Encoding") == "" &&
-		req.Header.Get("Range") == "" &&
-		!cs.isHead {
-		// Request gzip only, not deflate. Deflate is ambiguous and
-		// not as universally supported anyway.
-		// See: https://zlib.net/zlib_faq.html#faq39
-		//
-		// Note that we don't request this for HEAD requests,
-		// due to a bug in nginx:
-		//   http://trac.nginx.org/nginx/ticket/358
-		//   https://golang.org/issue/5522
-		//
-		// We don't request gzip if the request is for a range, since
-		// auto-decoding a portion of a gzipped document will just fail
-		// anyway. See https://golang.org/issue/8923
-		cs.requestedGzip = true
+	if streamf != nil {
+		streamf(cs)
 	}
 
 	continueTimeout := cc.t.expectContinueTimeout()
@@ -1452,9 +1520,9 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) {
 	var respHeaderTimer <-chan time.Time
 	var respHeaderRecv chan struct{}
 	if d := cc.responseHeaderTimeout(); d != 0 {
-		timer := time.NewTimer(d)
+		timer := cc.t.newTimer(d)
 		defer timer.Stop()
-		respHeaderTimer = timer.C
+		respHeaderTimer = timer.C()
 		respHeaderRecv = cs.respHeaderRecv
 	}
 	// Wait until the peer half-closes its end of the stream,
@@ -1875,6 +1943,22 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error)
 	}
 }
 
+func validateHeaders(hdrs http.Header) string {
+	for k, vv := range hdrs {
+		if !httpguts.ValidHeaderFieldName(k) {
+			return fmt.Sprintf("name %q", k)
+		}
+		for _, v := range vv {
+			if !httpguts.ValidHeaderFieldValue(v) {
+				// Don't include the value in the error,
+				// because it may be sensitive.
+				return fmt.Sprintf("value for header %q", k)
+			}
+		}
+	}
+	return ""
+}
+
 var errNilRequestURL = errors.New("http2: Request.URI is nil")
 
 // requires cc.wmu be held.
@@ -1912,19 +1996,14 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
 		}
 	}
 
-	// Check for any invalid headers and return an error before we
+	// Check for any invalid headers+trailers and return an error before we
 	// potentially pollute our hpack state. (We want to be able to
 	// continue to reuse the hpack encoder for future requests)
-	for k, vv := range req.Header {
-		if !httpguts.ValidHeaderFieldName(k) {
-			return nil, fmt.Errorf("invalid HTTP header name %q", k)
-		}
-		for _, v := range vv {
-			if !httpguts.ValidHeaderFieldValue(v) {
-				// Don't include the value in the error, because it may be sensitive.
-				return nil, fmt.Errorf("invalid HTTP header value for header %q", k)
-			}
-		}
+	if err := validateHeaders(req.Header); err != "" {
+		return nil, fmt.Errorf("invalid HTTP header %s", err)
+	}
+	if err := validateHeaders(req.Trailer); err != "" {
+		return nil, fmt.Errorf("invalid HTTP trailer %s", err)
 	}
 
 	enumerateHeaders := func(f func(name, value string)) {
@@ -2165,6 +2244,7 @@ type clientConnReadLoop struct {
 
 // readLoop runs in its own goroutine and reads and dispatches frames.
 func (cc *ClientConn) readLoop() {
+	cc.t.markNewGoroutine()
 	rl := &clientConnReadLoop{cc: cc}
 	defer rl.cleanup()
 	cc.readerErr = rl.run()
@@ -2266,10 +2346,9 @@ func (rl *clientConnReadLoop) run() error {
 	cc := rl.cc
 	gotSettings := false
 	readIdleTimeout := cc.t.ReadIdleTimeout
-	var t *time.Timer
+	var t timer
 	if readIdleTimeout != 0 {
-		t = time.AfterFunc(readIdleTimeout, cc.healthCheck)
-		defer t.Stop()
+		t = cc.t.afterFunc(readIdleTimeout, cc.healthCheck)
 	}
 	for {
 		f, err := cc.fr.ReadFrame()
@@ -2684,7 +2763,7 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error {
 		})
 		return nil
 	}
-	if !cs.firstByte {
+	if !cs.pastHeaders {
 		cc.logf("protocol error: received DATA before a HEADERS frame")
 		rl.endStreamError(cs, StreamError{
 			StreamID: f.StreamID,
@@ -2911,6 +2990,15 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error {
 		fl = &cs.flow
 	}
 	if !fl.add(int32(f.Increment)) {
+		// For stream, the sender sends RST_STREAM with an error code of FLOW_CONTROL_ERROR
+		if cs != nil {
+			rl.endStreamError(cs, StreamError{
+				StreamID: f.StreamID,
+				Code:     ErrCodeFlowControl,
+			})
+			return nil
+		}
+
 		return ConnectionError(ErrCodeFlowControl)
 	}
 	cc.cond.Broadcast()
@@ -2955,24 +3043,26 @@ func (cc *ClientConn) Ping(ctx context.Context) error {
 		}
 		cc.mu.Unlock()
 	}
-	errc := make(chan error, 1)
+	var pingError error
+	errc := make(chan struct{})
 	go func() {
+		cc.t.markNewGoroutine()
 		cc.wmu.Lock()
 		defer cc.wmu.Unlock()
-		if err := cc.fr.WritePing(false, p); err != nil {
-			errc <- err
+		if pingError = cc.fr.WritePing(false, p); pingError != nil {
+			close(errc)
 			return
 		}
-		if err := cc.bw.Flush(); err != nil {
-			errc <- err
+		if pingError = cc.bw.Flush(); pingError != nil {
+			close(errc)
 			return
 		}
 	}()
 	select {
 	case <-c:
 		return nil
-	case err := <-errc:
-		return err
+	case <-errc:
+		return pingError
 	case <-ctx.Done():
 		return ctx.Err()
 	case <-cc.readerDone:
@@ -3141,9 +3231,17 @@ func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, err
 }
 
 func (t *Transport) idleConnTimeout() time.Duration {
+	// to keep things backwards compatible, we use non-zero values of
+	// IdleConnTimeout, followed by using the IdleConnTimeout on the underlying
+	// http1 transport, followed by 0
+	if t.IdleConnTimeout != 0 {
+		return t.IdleConnTimeout
+	}
+
 	if t.t1 != nil {
 		return t.t1.IdleConnTimeout
 	}
+
 	return 0
 }
 
diff --git a/vendor/golang.org/x/net/http2/writesched_priority.go b/vendor/golang.org/x/net/http2/writesched_priority.go
index 0a242c66..f6783339 100644
--- a/vendor/golang.org/x/net/http2/writesched_priority.go
+++ b/vendor/golang.org/x/net/http2/writesched_priority.go
@@ -443,8 +443,8 @@ func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, max
 }
 
 func (ws *priorityWriteScheduler) removeNode(n *priorityNode) {
-	for k := n.kids; k != nil; k = k.next {
-		k.setParent(n.parent)
+	for n.kids != nil {
+		n.kids.setParent(n.parent)
 	}
 	n.setParent(nil)
 	delete(ws.nodes, n.id)
diff --git a/vendor/golang.org/x/net/proxy/per_host.go b/vendor/golang.org/x/net/proxy/per_host.go
index 573fe79e..d7d4b8b6 100644
--- a/vendor/golang.org/x/net/proxy/per_host.go
+++ b/vendor/golang.org/x/net/proxy/per_host.go
@@ -137,9 +137,7 @@ func (p *PerHost) AddNetwork(net *net.IPNet) {
 // AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
 // "example.com" matches "example.com" and all of its subdomains.
 func (p *PerHost) AddZone(zone string) {
-	if strings.HasSuffix(zone, ".") {
-		zone = zone[:len(zone)-1]
-	}
+	zone = strings.TrimSuffix(zone, ".")
 	if !strings.HasPrefix(zone, ".") {
 		zone = "." + zone
 	}
@@ -148,8 +146,6 @@ func (p *PerHost) AddZone(zone string) {
 
 // AddHost specifies a host name that will use the bypass proxy.
 func (p *PerHost) AddHost(host string) {
-	if strings.HasSuffix(host, ".") {
-		host = host[:len(host)-1]
-	}
+	host = strings.TrimSuffix(host, ".")
 	p.bypassHosts = append(p.bypassHosts, host)
 }
diff --git a/vendor/golang.org/x/sys/cpu/cpu.go b/vendor/golang.org/x/sys/cpu/cpu.go
index 4756ad5f..8fa707aa 100644
--- a/vendor/golang.org/x/sys/cpu/cpu.go
+++ b/vendor/golang.org/x/sys/cpu/cpu.go
@@ -103,6 +103,7 @@ var ARM64 struct {
 	HasASIMDDP  bool // Advanced SIMD double precision instruction set
 	HasSHA512   bool // SHA512 hardware implementation
 	HasSVE      bool // Scalable Vector Extensions
+	HasSVE2     bool // Scalable Vector Extensions 2
 	HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
 	_           CacheLinePad
 }
diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_arm64.go
index f3eb993b..0e27a21e 100644
--- a/vendor/golang.org/x/sys/cpu/cpu_arm64.go
+++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.go
@@ -28,6 +28,7 @@ func initOptions() {
 		{Name: "sm3", Feature: &ARM64.HasSM3},
 		{Name: "sm4", Feature: &ARM64.HasSM4},
 		{Name: "sve", Feature: &ARM64.HasSVE},
+		{Name: "sve2", Feature: &ARM64.HasSVE2},
 		{Name: "crc32", Feature: &ARM64.HasCRC32},
 		{Name: "atomics", Feature: &ARM64.HasATOMICS},
 		{Name: "asimdhp", Feature: &ARM64.HasASIMDHP},
@@ -164,6 +165,15 @@ func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) {
 	switch extractBits(pfr0, 32, 35) {
 	case 1:
 		ARM64.HasSVE = true
+
+		parseARM64SVERegister(getzfr0())
+	}
+}
+
+func parseARM64SVERegister(zfr0 uint64) {
+	switch extractBits(zfr0, 0, 3) {
+	case 1:
+		ARM64.HasSVE2 = true
 	}
 }
 
diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.s b/vendor/golang.org/x/sys/cpu/cpu_arm64.s
index fcb9a388..22cc9984 100644
--- a/vendor/golang.org/x/sys/cpu/cpu_arm64.s
+++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.s
@@ -29,3 +29,11 @@ TEXT ·getpfr0(SB),NOSPLIT,$0-8
 	WORD	$0xd5380400
 	MOVD	R0, ret+0(FP)
 	RET
+
+// func getzfr0() uint64
+TEXT ·getzfr0(SB),NOSPLIT,$0-8
+	// get SVE Feature Register 0 into x0
+	// mrs	x0, ID_AA64ZFR0_EL1 = d5380480
+	WORD $0xd5380480
+	MOVD	R0, ret+0(FP)
+	RET
diff --git a/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
index a8acd3e3..6ac6e1ef 100644
--- a/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
+++ b/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
@@ -9,3 +9,4 @@ package cpu
 func getisar0() uint64
 func getisar1() uint64
 func getpfr0() uint64
+func getzfr0() uint64
diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
index a968b80f..3d386d0f 100644
--- a/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
+++ b/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
@@ -35,6 +35,8 @@ const (
 	hwcap_SHA512   = 1 << 21
 	hwcap_SVE      = 1 << 22
 	hwcap_ASIMDFHM = 1 << 23
+
+	hwcap2_SVE2 = 1 << 1
 )
 
 // linuxKernelCanEmulateCPUID reports whether we're running
@@ -104,6 +106,9 @@ func doinit() {
 	ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512)
 	ARM64.HasSVE = isSet(hwCap, hwcap_SVE)
 	ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM)
+
+	// HWCAP2 feature bits
+	ARM64.HasSVE2 = isSet(hwCap2, hwcap2_SVE2)
 }
 
 func isSet(hwc uint, value uint) bool {
diff --git a/vendor/golang.org/x/sys/unix/aliases.go b/vendor/golang.org/x/sys/unix/aliases.go
index e7d3df4b..b0e41985 100644
--- a/vendor/golang.org/x/sys/unix/aliases.go
+++ b/vendor/golang.org/x/sys/unix/aliases.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
 
 package unix
 
diff --git a/vendor/golang.org/x/sys/unix/asm_zos_s390x.s b/vendor/golang.org/x/sys/unix/asm_zos_s390x.s
index 2f67ba86..813dfad7 100644
--- a/vendor/golang.org/x/sys/unix/asm_zos_s390x.s
+++ b/vendor/golang.org/x/sys/unix/asm_zos_s390x.s
@@ -9,9 +9,11 @@
 #define PSALAA            1208(R0)
 #define GTAB64(x)           80(x)
 #define LCA64(x)            88(x)
+#define SAVSTACK_ASYNC(x)  336(x) // in the LCA
 #define CAA(x)               8(x)
-#define EDCHPXV(x)        1016(x)       // in the CAA
-#define SAVSTACK_ASYNC(x)  336(x)       // in the LCA
+#define CEECAATHDID(x)     976(x) // in the CAA
+#define EDCHPXV(x)        1016(x) // in the CAA
+#define GOCB(x)           1104(x) // in the CAA
 
 // SS_*, where x=SAVSTACK_ASYNC
 #define SS_LE(x)             0(x)
@@ -19,405 +21,362 @@
 #define SS_ERRNO(x)         16(x)
 #define SS_ERRNOJR(x)       20(x)
 
-#define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6
+// Function Descriptor Offsets
+#define __errno  0x156*16
+#define __err2ad 0x16C*16
 
-TEXT ·clearErrno(SB),NOSPLIT,$0-0
-	BL	addrerrno<>(SB)
-	MOVD	$0, 0(R3)
+// Call Instructions
+#define LE_CALL    BYTE $0x0D; BYTE $0x76 // BL R7, R6
+#define SVC_LOAD   BYTE $0x0A; BYTE $0x08 // SVC 08 LOAD
+#define SVC_DELETE BYTE $0x0A; BYTE $0x09 // SVC 09 DELETE
+
+DATA zosLibVec<>(SB)/8, $0
+GLOBL zosLibVec<>(SB), NOPTR, $8
+
+TEXT ·initZosLibVec(SB), NOSPLIT|NOFRAME, $0-0
+	MOVW PSALAA, R8
+	MOVD LCA64(R8), R8
+	MOVD CAA(R8), R8
+	MOVD EDCHPXV(R8), R8
+	MOVD R8, zosLibVec<>(SB)
+	RET
+
+TEXT ·GetZosLibVec(SB), NOSPLIT|NOFRAME, $0-0
+	MOVD zosLibVec<>(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+TEXT ·clearErrno(SB), NOSPLIT, $0-0
+	BL   addrerrno<>(SB)
+	MOVD $0, 0(R3)
 	RET
 
 // Returns the address of errno in R3.
-TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0
+TEXT addrerrno<>(SB), NOSPLIT|NOFRAME, $0-0
 	// Get library control area (LCA).
-	MOVW	PSALAA, R8
-	MOVD	LCA64(R8), R8
+	MOVW PSALAA, R8
+	MOVD LCA64(R8), R8
 
 	// Get __errno FuncDesc.
-	MOVD	CAA(R8), R9
-	MOVD	EDCHPXV(R9), R9
-	ADD	$(0x156*16), R9
-	LMG	0(R9), R5, R6
+	MOVD CAA(R8), R9
+	MOVD EDCHPXV(R9), R9
+	ADD  $(__errno), R9
+	LMG  0(R9), R5, R6
 
 	// Switch to saved LE stack.
-	MOVD	SAVSTACK_ASYNC(R8), R9
-	MOVD	0(R9), R4
-	MOVD	$0, 0(R9)
+	MOVD SAVSTACK_ASYNC(R8), R9
+	MOVD 0(R9), R4
+	MOVD $0, 0(R9)
 
 	// Call __errno function.
 	LE_CALL
 	NOPH
 
 	// Switch back to Go stack.
-	XOR	R0, R0      // Restore R0 to $0.
-	MOVD	R4, 0(R9)   // Save stack pointer.
+	XOR  R0, R0    // Restore R0 to $0.
+	MOVD R4, 0(R9) // Save stack pointer.
 	RET
 
-TEXT ·syscall_syscall(SB),NOSPLIT,$0-56
-	BL	runtime·entersyscall(SB)
-	MOVD	a1+8(FP), R1
-	MOVD	a2+16(FP), R2
-	MOVD	a3+24(FP), R3
+// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
+TEXT ·svcCall(SB), NOSPLIT, $0
+	BL   runtime·save_g(SB)     // Save g and stack pointer
+	MOVW PSALAA, R8
+	MOVD LCA64(R8), R8
+	MOVD SAVSTACK_ASYNC(R8), R9
+	MOVD R15, 0(R9)
 
-	// Get library control area (LCA).
-	MOVW	PSALAA, R8
-	MOVD	LCA64(R8), R8
+	MOVD argv+8(FP), R1   // Move function arguments into registers
+	MOVD dsa+16(FP), g
+	MOVD fnptr+0(FP), R15
 
-	// Get function.
-	MOVD	CAA(R8), R9
-	MOVD	EDCHPXV(R9), R9
-	MOVD	trap+0(FP), R5
-	SLD	$4, R5
-	ADD	R5, R9
-	LMG	0(R9), R5, R6
+	BYTE $0x0D // Branch to function
+	BYTE $0xEF
 
-	// Restore LE stack.
-	MOVD	SAVSTACK_ASYNC(R8), R9
-	MOVD	0(R9), R4
-	MOVD	$0, 0(R9)
+	BL   runtime·load_g(SB)     // Restore g and stack pointer
+	MOVW PSALAA, R8
+	MOVD LCA64(R8), R8
+	MOVD SAVSTACK_ASYNC(R8), R9
+	MOVD 0(R9), R15
 
-	// Call function.
-	LE_CALL
-	NOPH
-	XOR	R0, R0      // Restore R0 to $0.
-	MOVD	R4, 0(R9)   // Save stack pointer.
-
-	MOVD	R3, r1+32(FP)
-	MOVD	R0, r2+40(FP)
-	MOVD	R0, err+48(FP)
-	MOVW	R3, R4
-	CMP	R4, $-1
-	BNE	done
-	BL	addrerrno<>(SB)
-	MOVWZ	0(R3), R3
-	MOVD	R3, err+48(FP)
-done:
-	BL	runtime·exitsyscall(SB)
 	RET
 
-TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56
-	MOVD	a1+8(FP), R1
-	MOVD	a2+16(FP), R2
-	MOVD	a3+24(FP), R3
-
-	// Get library control area (LCA).
-	MOVW	PSALAA, R8
-	MOVD	LCA64(R8), R8
-
-	// Get function.
-	MOVD	CAA(R8), R9
-	MOVD	EDCHPXV(R9), R9
-	MOVD	trap+0(FP), R5
-	SLD	$4, R5
-	ADD	R5, R9
-	LMG	0(R9), R5, R6
+// func svcLoad(name *byte) unsafe.Pointer
+TEXT ·svcLoad(SB), NOSPLIT, $0
+	MOVD R15, R2         // Save go stack pointer
+	MOVD name+0(FP), R0  // Move SVC args into registers
+	MOVD $0x80000000, R1
+	MOVD $0, R15
+	SVC_LOAD
+	MOVW R15, R3         // Save return code from SVC
+	MOVD R2, R15         // Restore go stack pointer
+	CMP  R3, $0          // Check SVC return code
+	BNE  error
+
+	MOVD $-2, R3       // Reset last bit of entry point to zero
+	AND  R0, R3
+	MOVD R3, ret+8(FP) // Return entry point returned by SVC
+	CMP  R0, R3        // Check if last bit of entry point was set
+	BNE  done
+
+	MOVD R15, R2 // Save go stack pointer
+	MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)
+	SVC_DELETE
+	MOVD R2, R15 // Restore go stack pointer
 
-	// Restore LE stack.
-	MOVD	SAVSTACK_ASYNC(R8), R9
-	MOVD	0(R9), R4
-	MOVD	$0, 0(R9)
+error:
+	MOVD $0, ret+8(FP) // Return 0 on failure
 
-	// Call function.
-	LE_CALL
-	NOPH
-	XOR	R0, R0      // Restore R0 to $0.
-	MOVD	R4, 0(R9)   // Save stack pointer.
-
-	MOVD	R3, r1+32(FP)
-	MOVD	R0, r2+40(FP)
-	MOVD	R0, err+48(FP)
-	MOVW	R3, R4
-	CMP	R4, $-1
-	BNE	done
-	BL	addrerrno<>(SB)
-	MOVWZ	0(R3), R3
-	MOVD	R3, err+48(FP)
 done:
+	XOR R0, R0 // Reset r0 to 0
 	RET
 
-TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80
-	BL	runtime·entersyscall(SB)
-	MOVD	a1+8(FP), R1
-	MOVD	a2+16(FP), R2
-	MOVD	a3+24(FP), R3
+// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
+TEXT ·svcUnload(SB), NOSPLIT, $0
+	MOVD R15, R2          // Save go stack pointer
+	MOVD name+0(FP), R0   // Move SVC args into registers
+	MOVD fnptr+8(FP), R15
+	SVC_DELETE
+	XOR  R0, R0           // Reset r0 to 0
+	MOVD R15, R1          // Save SVC return code
+	MOVD R2, R15          // Restore go stack pointer
+	MOVD R1, ret+16(FP)   // Return SVC return code
+	RET
 
+// func gettid() uint64
+TEXT ·gettid(SB), NOSPLIT, $0
 	// Get library control area (LCA).
-	MOVW	PSALAA, R8
-	MOVD	LCA64(R8), R8
+	MOVW PSALAA, R8
+	MOVD LCA64(R8), R8
 
-	// Get function.
-	MOVD	CAA(R8), R9
-	MOVD	EDCHPXV(R9), R9
-	MOVD	trap+0(FP), R5
-	SLD	$4, R5
-	ADD	R5, R9
-	LMG	0(R9), R5, R6
+	// Get CEECAATHDID
+	MOVD CAA(R8), R9
+	MOVD CEECAATHDID(R9), R9
+	MOVD R9, ret+0(FP)
 
-	// Restore LE stack.
-	MOVD	SAVSTACK_ASYNC(R8), R9
-	MOVD	0(R9), R4
-	MOVD	$0, 0(R9)
-
-	// Fill in parameter list.
-	MOVD	a4+32(FP), R12
-	MOVD	R12, (2176+24)(R4)
-	MOVD	a5+40(FP), R12
-	MOVD	R12, (2176+32)(R4)
-	MOVD	a6+48(FP), R12
-	MOVD	R12, (2176+40)(R4)
-
-	// Call function.
-	LE_CALL
-	NOPH
-	XOR	R0, R0      // Restore R0 to $0.
-	MOVD	R4, 0(R9)   // Save stack pointer.
-
-	MOVD	R3, r1+56(FP)
-	MOVD	R0, r2+64(FP)
-	MOVD	R0, err+72(FP)
-	MOVW	R3, R4
-	CMP	R4, $-1
-	BNE	done
-	BL	addrerrno<>(SB)
-	MOVWZ	0(R3), R3
-	MOVD	R3, err+72(FP)
-done:
-	BL	runtime·exitsyscall(SB)
 	RET
 
-TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80
-	MOVD	a1+8(FP), R1
-	MOVD	a2+16(FP), R2
-	MOVD	a3+24(FP), R3
-
-	// Get library control area (LCA).
-	MOVW	PSALAA, R8
-	MOVD	LCA64(R8), R8
-
-	// Get function.
-	MOVD	CAA(R8), R9
-	MOVD	EDCHPXV(R9), R9
-	MOVD	trap+0(FP), R5
-	SLD	$4, R5
-	ADD	R5, R9
-	LMG	0(R9), R5, R6
+//
+// Call LE function, if the return is -1
+// errno and errno2 is retrieved
+//
+TEXT ·CallLeFuncWithErr(SB), NOSPLIT, $0
+	MOVW PSALAA, R8
+	MOVD LCA64(R8), R8
+	MOVD CAA(R8), R9
+	MOVD g, GOCB(R9)
 
 	// Restore LE stack.
-	MOVD	SAVSTACK_ASYNC(R8), R9
-	MOVD	0(R9), R4
-	MOVD	$0, 0(R9)
-
-	// Fill in parameter list.
-	MOVD	a4+32(FP), R12
-	MOVD	R12, (2176+24)(R4)
-	MOVD	a5+40(FP), R12
-	MOVD	R12, (2176+32)(R4)
-	MOVD	a6+48(FP), R12
-	MOVD	R12, (2176+40)(R4)
-
-	// Call function.
-	LE_CALL
+	MOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address
+	MOVD 0(R9), R4              // R4-> restore previously saved stack frame pointer
+
+	MOVD parms_base+8(FP), R7 // R7 -> argument array
+	MOVD parms_len+16(FP), R8 // R8 number of arguments
+
+	//  arg 1 ---> R1
+	CMP  R8, $0
+	BEQ  docall
+	SUB  $1, R8
+	MOVD 0(R7), R1
+
+	//  arg 2 ---> R2
+	CMP  R8, $0
+	BEQ  docall
+	SUB  $1, R8
+	ADD  $8, R7
+	MOVD 0(R7), R2
+
+	//  arg 3 --> R3
+	CMP  R8, $0
+	BEQ  docall
+	SUB  $1, R8
+	ADD  $8, R7
+	MOVD 0(R7), R3
+
+	CMP  R8, $0
+	BEQ  docall
+	MOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument
+
+repeat:
+	ADD  $8, R7
+	MOVD 0(R7), R0      // advance arg pointer by 8 byte
+	ADD  $8, R6         // advance LE argument address by 8 byte
+	MOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame
+	SUB  $1, R8
+	CMP  R8, $0
+	BNE  repeat
+
+docall:
+	MOVD funcdesc+0(FP), R8 // R8-> function descriptor
+	LMG  0(R8), R5, R6
+	MOVD $0, 0(R9)          // R9 address of SAVSTACK_ASYNC
+	LE_CALL                 // balr R7, R6 (return #1)
+	NOPH
+	MOVD R3, ret+32(FP)
+	CMP  R3, $-1            // compare result to -1
+	BNE  done
+
+	// retrieve errno and errno2
+	MOVD  zosLibVec<>(SB), R8
+	ADD   $(__errno), R8
+	LMG   0(R8), R5, R6
+	LE_CALL                   // balr R7, R6 __errno (return #3)
 	NOPH
-	XOR	R0, R0      // Restore R0 to $0.
-	MOVD	R4, 0(R9)   // Save stack pointer.
-
-	MOVD	R3, r1+56(FP)
-	MOVD	R0, r2+64(FP)
-	MOVD	R0, err+72(FP)
-	MOVW	R3, R4
-	CMP	R4, $-1
-	BNE	done
-	BL	·rrno<>(SB)
-	MOVWZ	0(R3), R3
-	MOVD	R3, err+72(FP)
+	MOVWZ 0(R3), R3
+	MOVD  R3, err+48(FP)
+	MOVD  zosLibVec<>(SB), R8
+	ADD   $(__err2ad), R8
+	LMG   0(R8), R5, R6
+	LE_CALL                   // balr R7, R6 __err2ad (return #2)
+	NOPH
+	MOVW  (R3), R2            // retrieve errno2
+	MOVD  R2, errno2+40(FP)   // store in return area
+
 done:
+	MOVD R4, 0(R9)            // Save stack pointer.
 	RET
 
-TEXT ·syscall_syscall9(SB),NOSPLIT,$0
-	BL	runtime·entersyscall(SB)
-	MOVD	a1+8(FP), R1
-	MOVD	a2+16(FP), R2
-	MOVD	a3+24(FP), R3
-
-	// Get library control area (LCA).
-	MOVW	PSALAA, R8
-	MOVD	LCA64(R8), R8
-
-	// Get function.
-	MOVD	CAA(R8), R9
-	MOVD	EDCHPXV(R9), R9
-	MOVD	trap+0(FP), R5
-	SLD	$4, R5
-	ADD	R5, R9
-	LMG	0(R9), R5, R6
+//
+// Call LE function, if the return is 0
+// errno and errno2 is retrieved
+//
+TEXT ·CallLeFuncWithPtrReturn(SB), NOSPLIT, $0
+	MOVW PSALAA, R8
+	MOVD LCA64(R8), R8
+	MOVD CAA(R8), R9
+	MOVD g, GOCB(R9)
 
 	// Restore LE stack.
-	MOVD	SAVSTACK_ASYNC(R8), R9
-	MOVD	0(R9), R4
-	MOVD	$0, 0(R9)
-
-	// Fill in parameter list.
-	MOVD	a4+32(FP), R12
-	MOVD	R12, (2176+24)(R4)
-	MOVD	a5+40(FP), R12
-	MOVD	R12, (2176+32)(R4)
-	MOVD	a6+48(FP), R12
-	MOVD	R12, (2176+40)(R4)
-	MOVD	a7+56(FP), R12
-	MOVD	R12, (2176+48)(R4)
-	MOVD	a8+64(FP), R12
-	MOVD	R12, (2176+56)(R4)
-	MOVD	a9+72(FP), R12
-	MOVD	R12, (2176+64)(R4)
-
-	// Call function.
-	LE_CALL
+	MOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address
+	MOVD 0(R9), R4              // R4-> restore previously saved stack frame pointer
+
+	MOVD parms_base+8(FP), R7 // R7 -> argument array
+	MOVD parms_len+16(FP), R8 // R8 number of arguments
+
+	//  arg 1 ---> R1
+	CMP  R8, $0
+	BEQ  docall
+	SUB  $1, R8
+	MOVD 0(R7), R1
+
+	//  arg 2 ---> R2
+	CMP  R8, $0
+	BEQ  docall
+	SUB  $1, R8
+	ADD  $8, R7
+	MOVD 0(R7), R2
+
+	//  arg 3 --> R3
+	CMP  R8, $0
+	BEQ  docall
+	SUB  $1, R8
+	ADD  $8, R7
+	MOVD 0(R7), R3
+
+	CMP  R8, $0
+	BEQ  docall
+	MOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument
+
+repeat:
+	ADD  $8, R7
+	MOVD 0(R7), R0      // advance arg pointer by 8 byte
+	ADD  $8, R6         // advance LE argument address by 8 byte
+	MOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame
+	SUB  $1, R8
+	CMP  R8, $0
+	BNE  repeat
+
+docall:
+	MOVD funcdesc+0(FP), R8 // R8-> function descriptor
+	LMG  0(R8), R5, R6
+	MOVD $0, 0(R9)          // R9 address of SAVSTACK_ASYNC
+	LE_CALL                 // balr R7, R6 (return #1)
 	NOPH
-	XOR	R0, R0      // Restore R0 to $0.
-	MOVD	R4, 0(R9)   // Save stack pointer.
-
-	MOVD	R3, r1+80(FP)
-	MOVD	R0, r2+88(FP)
-	MOVD	R0, err+96(FP)
-	MOVW	R3, R4
-	CMP	R4, $-1
-	BNE	done
-	BL	addrerrno<>(SB)
-	MOVWZ	0(R3), R3
-	MOVD	R3, err+96(FP)
-done:
-        BL	runtime·exitsyscall(SB)
-        RET
-
-TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0
-	MOVD	a1+8(FP), R1
-	MOVD	a2+16(FP), R2
-	MOVD	a3+24(FP), R3
-
-	// Get library control area (LCA).
-	MOVW	PSALAA, R8
-	MOVD	LCA64(R8), R8
-
-	// Get function.
-	MOVD	CAA(R8), R9
-	MOVD	EDCHPXV(R9), R9
-	MOVD	trap+0(FP), R5
-	SLD	$4, R5
-	ADD	R5, R9
-	LMG	0(R9), R5, R6
-
-	// Restore LE stack.
-	MOVD	SAVSTACK_ASYNC(R8), R9
-	MOVD	0(R9), R4
-	MOVD	$0, 0(R9)
-
-	// Fill in parameter list.
-	MOVD	a4+32(FP), R12
-	MOVD	R12, (2176+24)(R4)
-	MOVD	a5+40(FP), R12
-	MOVD	R12, (2176+32)(R4)
-	MOVD	a6+48(FP), R12
-	MOVD	R12, (2176+40)(R4)
-	MOVD	a7+56(FP), R12
-	MOVD	R12, (2176+48)(R4)
-	MOVD	a8+64(FP), R12
-	MOVD	R12, (2176+56)(R4)
-	MOVD	a9+72(FP), R12
-	MOVD	R12, (2176+64)(R4)
-
-	// Call function.
-	LE_CALL
+	MOVD R3, ret+32(FP)
+	CMP  R3, $0             // compare result to 0
+	BNE  done
+
+	// retrieve errno and errno2
+	MOVD  zosLibVec<>(SB), R8
+	ADD   $(__errno), R8
+	LMG   0(R8), R5, R6
+	LE_CALL                   // balr R7, R6 __errno (return #3)
 	NOPH
-	XOR	R0, R0      // Restore R0 to $0.
-	MOVD	R4, 0(R9)   // Save stack pointer.
-
-	MOVD	R3, r1+80(FP)
-	MOVD	R0, r2+88(FP)
-	MOVD	R0, err+96(FP)
-	MOVW	R3, R4
-	CMP	R4, $-1
-	BNE	done
-	BL	addrerrno<>(SB)
-	MOVWZ	0(R3), R3
-	MOVD	R3, err+96(FP)
-done:
-	RET
-
-// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
-TEXT ·svcCall(SB),NOSPLIT,$0
-	BL	runtime·save_g(SB)   // Save g and stack pointer
-	MOVW	PSALAA, R8
-	MOVD	LCA64(R8), R8
-	MOVD	SAVSTACK_ASYNC(R8), R9
-	MOVD	R15, 0(R9)
-
-	MOVD	argv+8(FP), R1       // Move function arguments into registers
-	MOVD	dsa+16(FP), g
-	MOVD	fnptr+0(FP), R15
-
-	BYTE	$0x0D                // Branch to function
-	BYTE	$0xEF
-
-	BL	runtime·load_g(SB)   // Restore g and stack pointer
-	MOVW	PSALAA, R8
-	MOVD	LCA64(R8), R8
-	MOVD	SAVSTACK_ASYNC(R8), R9
-	MOVD	0(R9), R15
-
-	RET
-
-// func svcLoad(name *byte) unsafe.Pointer
-TEXT ·svcLoad(SB),NOSPLIT,$0
-	MOVD	R15, R2          // Save go stack pointer
-	MOVD	name+0(FP), R0   // Move SVC args into registers
-	MOVD	$0x80000000, R1
-	MOVD	$0, R15
-	BYTE	$0x0A            // SVC 08 LOAD
-	BYTE	$0x08
-	MOVW	R15, R3          // Save return code from SVC
-	MOVD	R2, R15          // Restore go stack pointer
-	CMP	R3, $0           // Check SVC return code
-	BNE	error
-
-	MOVD	$-2, R3          // Reset last bit of entry point to zero
-	AND	R0, R3
-	MOVD	R3, addr+8(FP)   // Return entry point returned by SVC
-	CMP	R0, R3           // Check if last bit of entry point was set
-	BNE	done
-
-	MOVD	R15, R2          // Save go stack pointer
-	MOVD	$0, R15          // Move SVC args into registers (entry point still in r0 from SVC 08)
-	BYTE	$0x0A            // SVC 09 DELETE
-	BYTE	$0x09
-	MOVD	R2, R15          // Restore go stack pointer
+	MOVWZ 0(R3), R3
+	MOVD  R3, err+48(FP)
+	MOVD  zosLibVec<>(SB), R8
+	ADD   $(__err2ad), R8
+	LMG   0(R8), R5, R6
+	LE_CALL                   // balr R7, R6 __err2ad (return #2)
+	NOPH
+	MOVW  (R3), R2            // retrieve errno2
+	MOVD  R2, errno2+40(FP)   // store in return area
+	XOR   R2, R2
+	MOVWZ R2, (R3)            // clear errno2
 
-error:
-	MOVD	$0, addr+8(FP)   // Return 0 on failure
 done:
-	XOR	R0, R0           // Reset r0 to 0
+	MOVD R4, 0(R9)            // Save stack pointer.
 	RET
 
-// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
-TEXT ·svcUnload(SB),NOSPLIT,$0
-	MOVD	R15, R2          // Save go stack pointer
-	MOVD	name+0(FP), R0   // Move SVC args into registers
-	MOVD	addr+8(FP), R15
-	BYTE	$0x0A            // SVC 09
-	BYTE	$0x09
-	XOR	R0, R0           // Reset r0 to 0
-	MOVD	R15, R1          // Save SVC return code
-	MOVD	R2, R15          // Restore go stack pointer
-	MOVD	R1, rc+0(FP)     // Return SVC return code
+//
+// function to test if a pointer can be safely dereferenced (content read)
+// return 0 for succces
+//
+TEXT ·ptrtest(SB), NOSPLIT, $0-16
+	MOVD arg+0(FP), R10 // test pointer in R10
+
+	// set up R2 to point to CEECAADMC
+	BYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt  2,1208
+	BYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22                         // llgtr 2,2
+	BYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF                         // nilh  2,32767
+	BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg    2,88(2)
+	BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg    2,8(2)
+	BYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68                         // la    2,872(2)
+
+	// set up R5 to point to the "shunt" path which set 1 to R3 (failure)
+	BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33 // xgr   3,3
+	BYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04 // bras  5,lbl1
+	BYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01 // lghi  3,1
+
+	// if r3 is not zero (failed) then branch to finish
+	BYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33 // lbl1     ltgr  3,3
+	BYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08 // brc   b'0111',lbl2
+
+	// stomic store shunt address in R5 into CEECAADMC
+	BYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg   5,0(2)
+
+	// now try reading from the test pointer in R10, if it fails it branches to the "lghi" instruction above
+	BYTE $0xE3; BYTE $0x9A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg    9,0(10)
+
+	// finish here, restore 0 into CEECAADMC
+	BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99                         // lbl2     xgr   9,9
+	BYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg   9,0(2)
+	MOVD R3, ret+8(FP)                                                     // result in R3
 	RET
 
-// func gettid() uint64
-TEXT ·gettid(SB), NOSPLIT, $0
-	// Get library control area (LCA).
-	MOVW PSALAA, R8
-	MOVD LCA64(R8), R8
-
-	// Get CEECAATHDID
-	MOVD CAA(R8), R9
-	MOVD 0x3D0(R9), R9
-	MOVD R9, ret+0(FP)
-
+//
+// function to test if a untptr can be loaded from a pointer
+// return 1: the 8-byte content
+//        2: 0 for success, 1 for failure
+//
+// func safeload(ptr uintptr) ( value uintptr, error uintptr)
+TEXT ·safeload(SB), NOSPLIT, $0-24
+	MOVD ptr+0(FP), R10                                                    // test pointer in R10
+	MOVD $0x0, R6
+	BYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt  2,1208
+	BYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22                         // llgtr 2,2
+	BYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF                         // nilh  2,32767
+	BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg    2,88(2)
+	BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg    2,8(2)
+	BYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68                         // la    2,872(2)
+	BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33                         // xgr   3,3
+	BYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04                         // bras  5,lbl1
+	BYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01                         // lghi  3,1
+	BYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33                         // lbl1     ltgr  3,3
+	BYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08                         // brc   b'0111',lbl2
+	BYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 5,0(2)
+	BYTE $0xE3; BYTE $0x6A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg    6,0(10)
+	BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99                         // lbl2     xgr   9,9
+	BYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg   9,0(2)
+	MOVD R6, value+8(FP)                                                   // result in R6
+	MOVD R3, error+16(FP)                                                  // error in R3
 	RET
diff --git a/vendor/golang.org/x/sys/unix/bpxsvc_zos.go b/vendor/golang.org/x/sys/unix/bpxsvc_zos.go
new file mode 100644
index 00000000..39d647d8
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/bpxsvc_zos.go
@@ -0,0 +1,657 @@
+// Copyright 2024 The Go 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 zos
+
+package unix
+
+import (
+	"bytes"
+	"fmt"
+	"unsafe"
+)
+
+//go:noescape
+func bpxcall(plist []unsafe.Pointer, bpx_offset int64)
+
+//go:noescape
+func A2e([]byte)
+
+//go:noescape
+func E2a([]byte)
+
+const (
+	BPX4STA = 192  // stat
+	BPX4FST = 104  // fstat
+	BPX4LST = 132  // lstat
+	BPX4OPN = 156  // open
+	BPX4CLO = 72   // close
+	BPX4CHR = 500  // chattr
+	BPX4FCR = 504  // fchattr
+	BPX4LCR = 1180 // lchattr
+	BPX4CTW = 492  // cond_timed_wait
+	BPX4GTH = 1056 // __getthent
+	BPX4PTQ = 412  // pthread_quiesc
+	BPX4PTR = 320  // ptrace
+)
+
+const (
+	//options
+	//byte1
+	BPX_OPNFHIGH = 0x80
+	//byte2
+	BPX_OPNFEXEC = 0x80
+	//byte3
+	BPX_O_NOLARGEFILE = 0x08
+	BPX_O_LARGEFILE   = 0x04
+	BPX_O_ASYNCSIG    = 0x02
+	BPX_O_SYNC        = 0x01
+	//byte4
+	BPX_O_CREXCL   = 0xc0
+	BPX_O_CREAT    = 0x80
+	BPX_O_EXCL     = 0x40
+	BPX_O_NOCTTY   = 0x20
+	BPX_O_TRUNC    = 0x10
+	BPX_O_APPEND   = 0x08
+	BPX_O_NONBLOCK = 0x04
+	BPX_FNDELAY    = 0x04
+	BPX_O_RDWR     = 0x03
+	BPX_O_RDONLY   = 0x02
+	BPX_O_WRONLY   = 0x01
+	BPX_O_ACCMODE  = 0x03
+	BPX_O_GETFL    = 0x0f
+
+	//mode
+	// byte1 (file type)
+	BPX_FT_DIR      = 1
+	BPX_FT_CHARSPEC = 2
+	BPX_FT_REGFILE  = 3
+	BPX_FT_FIFO     = 4
+	BPX_FT_SYMLINK  = 5
+	BPX_FT_SOCKET   = 6
+	//byte3
+	BPX_S_ISUID  = 0x08
+	BPX_S_ISGID  = 0x04
+	BPX_S_ISVTX  = 0x02
+	BPX_S_IRWXU1 = 0x01
+	BPX_S_IRUSR  = 0x01
+	//byte4
+	BPX_S_IRWXU2 = 0xc0
+	BPX_S_IWUSR  = 0x80
+	BPX_S_IXUSR  = 0x40
+	BPX_S_IRWXG  = 0x38
+	BPX_S_IRGRP  = 0x20
+	BPX_S_IWGRP  = 0x10
+	BPX_S_IXGRP  = 0x08
+	BPX_S_IRWXOX = 0x07
+	BPX_S_IROTH  = 0x04
+	BPX_S_IWOTH  = 0x02
+	BPX_S_IXOTH  = 0x01
+
+	CW_INTRPT  = 1
+	CW_CONDVAR = 32
+	CW_TIMEOUT = 64
+
+	PGTHA_NEXT        = 2
+	PGTHA_CURRENT     = 1
+	PGTHA_FIRST       = 0
+	PGTHA_LAST        = 3
+	PGTHA_PROCESS     = 0x80
+	PGTHA_CONTTY      = 0x40
+	PGTHA_PATH        = 0x20
+	PGTHA_COMMAND     = 0x10
+	PGTHA_FILEDATA    = 0x08
+	PGTHA_THREAD      = 0x04
+	PGTHA_PTAG        = 0x02
+	PGTHA_COMMANDLONG = 0x01
+	PGTHA_THREADFAST  = 0x80
+	PGTHA_FILEPATH    = 0x40
+	PGTHA_THDSIGMASK  = 0x20
+	// thread quiece mode
+	QUIESCE_TERM       int32 = 1
+	QUIESCE_FORCE      int32 = 2
+	QUIESCE_QUERY      int32 = 3
+	QUIESCE_FREEZE     int32 = 4
+	QUIESCE_UNFREEZE   int32 = 5
+	FREEZE_THIS_THREAD int32 = 6
+	FREEZE_EXIT        int32 = 8
+	QUIESCE_SRB        int32 = 9
+)
+
+type Pgtha struct {
+	Pid        uint32 // 0
+	Tid0       uint32 // 4
+	Tid1       uint32
+	Accesspid  byte    // C
+	Accesstid  byte    // D
+	Accessasid uint16  // E
+	Loginname  [8]byte // 10
+	Flag1      byte    // 18
+	Flag1b2    byte    // 19
+}
+
+type Bpxystat_t struct { // DSECT BPXYSTAT
+	St_id           [4]uint8  // 0
+	St_length       uint16    // 0x4
+	St_version      uint16    // 0x6
+	St_mode         uint32    // 0x8
+	St_ino          uint32    // 0xc
+	St_dev          uint32    // 0x10
+	St_nlink        uint32    // 0x14
+	St_uid          uint32    // 0x18
+	St_gid          uint32    // 0x1c
+	St_size         uint64    // 0x20
+	St_atime        uint32    // 0x28
+	St_mtime        uint32    // 0x2c
+	St_ctime        uint32    // 0x30
+	St_rdev         uint32    // 0x34
+	St_auditoraudit uint32    // 0x38
+	St_useraudit    uint32    // 0x3c
+	St_blksize      uint32    // 0x40
+	St_createtime   uint32    // 0x44
+	St_auditid      [4]uint32 // 0x48
+	St_res01        uint32    // 0x58
+	Ft_ccsid        uint16    // 0x5c
+	Ft_flags        uint16    // 0x5e
+	St_res01a       [2]uint32 // 0x60
+	St_res02        uint32    // 0x68
+	St_blocks       uint32    // 0x6c
+	St_opaque       [3]uint8  // 0x70
+	St_visible      uint8     // 0x73
+	St_reftime      uint32    // 0x74
+	St_fid          uint64    // 0x78
+	St_filefmt      uint8     // 0x80
+	St_fspflag2     uint8     // 0x81
+	St_res03        [2]uint8  // 0x82
+	St_ctimemsec    uint32    // 0x84
+	St_seclabel     [8]uint8  // 0x88
+	St_res04        [4]uint8  // 0x90
+	// end of version 1
+	_               uint32    // 0x94
+	St_atime64      uint64    // 0x98
+	St_mtime64      uint64    // 0xa0
+	St_ctime64      uint64    // 0xa8
+	St_createtime64 uint64    // 0xb0
+	St_reftime64    uint64    // 0xb8
+	_               uint64    // 0xc0
+	St_res05        [16]uint8 // 0xc8
+	// end of version 2
+}
+
+type BpxFilestatus struct {
+	Oflag1 byte
+	Oflag2 byte
+	Oflag3 byte
+	Oflag4 byte
+}
+
+type BpxMode struct {
+	Ftype byte
+	Mode1 byte
+	Mode2 byte
+	Mode3 byte
+}
+
+// Thr attribute structure for extended attributes
+type Bpxyatt_t struct { // DSECT BPXYATT
+	Att_id           [4]uint8
+	Att_version      uint16
+	Att_res01        [2]uint8
+	Att_setflags1    uint8
+	Att_setflags2    uint8
+	Att_setflags3    uint8
+	Att_setflags4    uint8
+	Att_mode         uint32
+	Att_uid          uint32
+	Att_gid          uint32
+	Att_opaquemask   [3]uint8
+	Att_visblmaskres uint8
+	Att_opaque       [3]uint8
+	Att_visibleres   uint8
+	Att_size_h       uint32
+	Att_size_l       uint32
+	Att_atime        uint32
+	Att_mtime        uint32
+	Att_auditoraudit uint32
+	Att_useraudit    uint32
+	Att_ctime        uint32
+	Att_reftime      uint32
+	// end of version 1
+	Att_filefmt uint8
+	Att_res02   [3]uint8
+	Att_filetag uint32
+	Att_res03   [8]uint8
+	// end of version 2
+	Att_atime64   uint64
+	Att_mtime64   uint64
+	Att_ctime64   uint64
+	Att_reftime64 uint64
+	Att_seclabel  [8]uint8
+	Att_ver3res02 [8]uint8
+	// end of version 3
+}
+
+func BpxOpen(name string, options *BpxFilestatus, mode *BpxMode) (rv int32, rc int32, rn int32) {
+	if len(name) < 1024 {
+		var namebuf [1024]byte
+		sz := int32(copy(namebuf[:], name))
+		A2e(namebuf[:sz])
+		var parms [7]unsafe.Pointer
+		parms[0] = unsafe.Pointer(&sz)
+		parms[1] = unsafe.Pointer(&namebuf[0])
+		parms[2] = unsafe.Pointer(options)
+		parms[3] = unsafe.Pointer(mode)
+		parms[4] = unsafe.Pointer(&rv)
+		parms[5] = unsafe.Pointer(&rc)
+		parms[6] = unsafe.Pointer(&rn)
+		bpxcall(parms[:], BPX4OPN)
+		return rv, rc, rn
+	}
+	return -1, -1, -1
+}
+
+func BpxClose(fd int32) (rv int32, rc int32, rn int32) {
+	var parms [4]unsafe.Pointer
+	parms[0] = unsafe.Pointer(&fd)
+	parms[1] = unsafe.Pointer(&rv)
+	parms[2] = unsafe.Pointer(&rc)
+	parms[3] = unsafe.Pointer(&rn)
+	bpxcall(parms[:], BPX4CLO)
+	return rv, rc, rn
+}
+
+func BpxFileFStat(fd int32, st *Bpxystat_t) (rv int32, rc int32, rn int32) {
+	st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}
+	st.St_version = 2
+	stat_sz := uint32(unsafe.Sizeof(*st))
+	var parms [6]unsafe.Pointer
+	parms[0] = unsafe.Pointer(&fd)
+	parms[1] = unsafe.Pointer(&stat_sz)
+	parms[2] = unsafe.Pointer(st)
+	parms[3] = unsafe.Pointer(&rv)
+	parms[4] = unsafe.Pointer(&rc)
+	parms[5] = unsafe.Pointer(&rn)
+	bpxcall(parms[:], BPX4FST)
+	return rv, rc, rn
+}
+
+func BpxFileStat(name string, st *Bpxystat_t) (rv int32, rc int32, rn int32) {
+	if len(name) < 1024 {
+		var namebuf [1024]byte
+		sz := int32(copy(namebuf[:], name))
+		A2e(namebuf[:sz])
+		st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}
+		st.St_version = 2
+		stat_sz := uint32(unsafe.Sizeof(*st))
+		var parms [7]unsafe.Pointer
+		parms[0] = unsafe.Pointer(&sz)
+		parms[1] = unsafe.Pointer(&namebuf[0])
+		parms[2] = unsafe.Pointer(&stat_sz)
+		parms[3] = unsafe.Pointer(st)
+		parms[4] = unsafe.Pointer(&rv)
+		parms[5] = unsafe.Pointer(&rc)
+		parms[6] = unsafe.Pointer(&rn)
+		bpxcall(parms[:], BPX4STA)
+		return rv, rc, rn
+	}
+	return -1, -1, -1
+}
+
+func BpxFileLStat(name string, st *Bpxystat_t) (rv int32, rc int32, rn int32) {
+	if len(name) < 1024 {
+		var namebuf [1024]byte
+		sz := int32(copy(namebuf[:], name))
+		A2e(namebuf[:sz])
+		st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}
+		st.St_version = 2
+		stat_sz := uint32(unsafe.Sizeof(*st))
+		var parms [7]unsafe.Pointer
+		parms[0] = unsafe.Pointer(&sz)
+		parms[1] = unsafe.Pointer(&namebuf[0])
+		parms[2] = unsafe.Pointer(&stat_sz)
+		parms[3] = unsafe.Pointer(st)
+		parms[4] = unsafe.Pointer(&rv)
+		parms[5] = unsafe.Pointer(&rc)
+		parms[6] = unsafe.Pointer(&rn)
+		bpxcall(parms[:], BPX4LST)
+		return rv, rc, rn
+	}
+	return -1, -1, -1
+}
+
+func BpxChattr(path string, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {
+	if len(path) >= 1024 {
+		return -1, -1, -1
+	}
+	var namebuf [1024]byte
+	sz := int32(copy(namebuf[:], path))
+	A2e(namebuf[:sz])
+	attr_sz := uint32(unsafe.Sizeof(*attr))
+	var parms [7]unsafe.Pointer
+	parms[0] = unsafe.Pointer(&sz)
+	parms[1] = unsafe.Pointer(&namebuf[0])
+	parms[2] = unsafe.Pointer(&attr_sz)
+	parms[3] = unsafe.Pointer(attr)
+	parms[4] = unsafe.Pointer(&rv)
+	parms[5] = unsafe.Pointer(&rc)
+	parms[6] = unsafe.Pointer(&rn)
+	bpxcall(parms[:], BPX4CHR)
+	return rv, rc, rn
+}
+
+func BpxLchattr(path string, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {
+	if len(path) >= 1024 {
+		return -1, -1, -1
+	}
+	var namebuf [1024]byte
+	sz := int32(copy(namebuf[:], path))
+	A2e(namebuf[:sz])
+	attr_sz := uint32(unsafe.Sizeof(*attr))
+	var parms [7]unsafe.Pointer
+	parms[0] = unsafe.Pointer(&sz)
+	parms[1] = unsafe.Pointer(&namebuf[0])
+	parms[2] = unsafe.Pointer(&attr_sz)
+	parms[3] = unsafe.Pointer(attr)
+	parms[4] = unsafe.Pointer(&rv)
+	parms[5] = unsafe.Pointer(&rc)
+	parms[6] = unsafe.Pointer(&rn)
+	bpxcall(parms[:], BPX4LCR)
+	return rv, rc, rn
+}
+
+func BpxFchattr(fd int32, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {
+	attr_sz := uint32(unsafe.Sizeof(*attr))
+	var parms [6]unsafe.Pointer
+	parms[0] = unsafe.Pointer(&fd)
+	parms[1] = unsafe.Pointer(&attr_sz)
+	parms[2] = unsafe.Pointer(attr)
+	parms[3] = unsafe.Pointer(&rv)
+	parms[4] = unsafe.Pointer(&rc)
+	parms[5] = unsafe.Pointer(&rn)
+	bpxcall(parms[:], BPX4FCR)
+	return rv, rc, rn
+}
+
+func BpxCondTimedWait(sec uint32, nsec uint32, events uint32, secrem *uint32, nsecrem *uint32) (rv int32, rc int32, rn int32) {
+	var parms [8]unsafe.Pointer
+	parms[0] = unsafe.Pointer(&sec)
+	parms[1] = unsafe.Pointer(&nsec)
+	parms[2] = unsafe.Pointer(&events)
+	parms[3] = unsafe.Pointer(secrem)
+	parms[4] = unsafe.Pointer(nsecrem)
+	parms[5] = unsafe.Pointer(&rv)
+	parms[6] = unsafe.Pointer(&rc)
+	parms[7] = unsafe.Pointer(&rn)
+	bpxcall(parms[:], BPX4CTW)
+	return rv, rc, rn
+}
+func BpxGetthent(in *Pgtha, outlen *uint32, out unsafe.Pointer) (rv int32, rc int32, rn int32) {
+	var parms [7]unsafe.Pointer
+	inlen := uint32(26) // nothing else will work. Go says Pgtha is 28-byte because of alignment, but Pgtha is "packed" and must be 26-byte
+	parms[0] = unsafe.Pointer(&inlen)
+	parms[1] = unsafe.Pointer(&in)
+	parms[2] = unsafe.Pointer(outlen)
+	parms[3] = unsafe.Pointer(&out)
+	parms[4] = unsafe.Pointer(&rv)
+	parms[5] = unsafe.Pointer(&rc)
+	parms[6] = unsafe.Pointer(&rn)
+	bpxcall(parms[:], BPX4GTH)
+	return rv, rc, rn
+}
+func ZosJobname() (jobname string, err error) {
+	var pgtha Pgtha
+	pgtha.Pid = uint32(Getpid())
+	pgtha.Accesspid = PGTHA_CURRENT
+	pgtha.Flag1 = PGTHA_PROCESS
+	var out [256]byte
+	var outlen uint32
+	outlen = 256
+	rv, rc, rn := BpxGetthent(&pgtha, &outlen, unsafe.Pointer(&out[0]))
+	if rv == 0 {
+		gthc := []byte{0x87, 0xa3, 0x88, 0x83} // 'gthc' in ebcdic
+		ix := bytes.Index(out[:], gthc)
+		if ix == -1 {
+			err = fmt.Errorf("BPX4GTH: gthc return data not found")
+			return
+		}
+		jn := out[ix+80 : ix+88] // we didn't declare Pgthc, but jobname is 8-byte at offset 80
+		E2a(jn)
+		jobname = string(bytes.TrimRight(jn, " "))
+
+	} else {
+		err = fmt.Errorf("BPX4GTH: rc=%d errno=%d reason=code=0x%x", rv, rc, rn)
+	}
+	return
+}
+func Bpx4ptq(code int32, data string) (rv int32, rc int32, rn int32) {
+	var userdata [8]byte
+	var parms [5]unsafe.Pointer
+	copy(userdata[:], data+"        ")
+	A2e(userdata[:])
+	parms[0] = unsafe.Pointer(&code)
+	parms[1] = unsafe.Pointer(&userdata[0])
+	parms[2] = unsafe.Pointer(&rv)
+	parms[3] = unsafe.Pointer(&rc)
+	parms[4] = unsafe.Pointer(&rn)
+	bpxcall(parms[:], BPX4PTQ)
+	return rv, rc, rn
+}
+
+const (
+	PT_TRACE_ME             = 0  // Debug this process
+	PT_READ_I               = 1  // Read a full word
+	PT_READ_D               = 2  // Read a full word
+	PT_READ_U               = 3  // Read control info
+	PT_WRITE_I              = 4  //Write a full word
+	PT_WRITE_D              = 5  //Write a full word
+	PT_CONTINUE             = 7  //Continue the process
+	PT_KILL                 = 8  //Terminate the process
+	PT_READ_GPR             = 11 // Read GPR, CR, PSW
+	PT_READ_FPR             = 12 // Read FPR
+	PT_READ_VR              = 13 // Read VR
+	PT_WRITE_GPR            = 14 // Write GPR, CR, PSW
+	PT_WRITE_FPR            = 15 // Write FPR
+	PT_WRITE_VR             = 16 // Write VR
+	PT_READ_BLOCK           = 17 // Read storage
+	PT_WRITE_BLOCK          = 19 // Write storage
+	PT_READ_GPRH            = 20 // Read GPRH
+	PT_WRITE_GPRH           = 21 // Write GPRH
+	PT_REGHSET              = 22 // Read all GPRHs
+	PT_ATTACH               = 30 // Attach to a process
+	PT_DETACH               = 31 // Detach from a process
+	PT_REGSET               = 32 // Read all GPRs
+	PT_REATTACH             = 33 // Reattach to a process
+	PT_LDINFO               = 34 // Read loader info
+	PT_MULTI                = 35 // Multi process mode
+	PT_LD64INFO             = 36 // RMODE64 Info Area
+	PT_BLOCKREQ             = 40 // Block request
+	PT_THREAD_INFO          = 60 // Read thread info
+	PT_THREAD_MODIFY        = 61
+	PT_THREAD_READ_FOCUS    = 62
+	PT_THREAD_WRITE_FOCUS   = 63
+	PT_THREAD_HOLD          = 64
+	PT_THREAD_SIGNAL        = 65
+	PT_EXPLAIN              = 66
+	PT_EVENTS               = 67
+	PT_THREAD_INFO_EXTENDED = 68
+	PT_REATTACH2            = 71
+	PT_CAPTURE              = 72
+	PT_UNCAPTURE            = 73
+	PT_GET_THREAD_TCB       = 74
+	PT_GET_ALET             = 75
+	PT_SWAPIN               = 76
+	PT_EXTENDED_EVENT       = 98
+	PT_RECOVER              = 99  // Debug a program check
+	PT_GPR0                 = 0   // General purpose register 0
+	PT_GPR1                 = 1   // General purpose register 1
+	PT_GPR2                 = 2   // General purpose register 2
+	PT_GPR3                 = 3   // General purpose register 3
+	PT_GPR4                 = 4   // General purpose register 4
+	PT_GPR5                 = 5   // General purpose register 5
+	PT_GPR6                 = 6   // General purpose register 6
+	PT_GPR7                 = 7   // General purpose register 7
+	PT_GPR8                 = 8   // General purpose register 8
+	PT_GPR9                 = 9   // General purpose register 9
+	PT_GPR10                = 10  // General purpose register 10
+	PT_GPR11                = 11  // General purpose register 11
+	PT_GPR12                = 12  // General purpose register 12
+	PT_GPR13                = 13  // General purpose register 13
+	PT_GPR14                = 14  // General purpose register 14
+	PT_GPR15                = 15  // General purpose register 15
+	PT_FPR0                 = 16  // Floating point register 0
+	PT_FPR1                 = 17  // Floating point register 1
+	PT_FPR2                 = 18  // Floating point register 2
+	PT_FPR3                 = 19  // Floating point register 3
+	PT_FPR4                 = 20  // Floating point register 4
+	PT_FPR5                 = 21  // Floating point register 5
+	PT_FPR6                 = 22  // Floating point register 6
+	PT_FPR7                 = 23  // Floating point register 7
+	PT_FPR8                 = 24  // Floating point register 8
+	PT_FPR9                 = 25  // Floating point register 9
+	PT_FPR10                = 26  // Floating point register 10
+	PT_FPR11                = 27  // Floating point register 11
+	PT_FPR12                = 28  // Floating point register 12
+	PT_FPR13                = 29  // Floating point register 13
+	PT_FPR14                = 30  // Floating point register 14
+	PT_FPR15                = 31  // Floating point register 15
+	PT_FPC                  = 32  // Floating point control register
+	PT_PSW                  = 40  // PSW
+	PT_PSW0                 = 40  // Left half of the PSW
+	PT_PSW1                 = 41  // Right half of the PSW
+	PT_CR0                  = 42  // Control register 0
+	PT_CR1                  = 43  // Control register 1
+	PT_CR2                  = 44  // Control register 2
+	PT_CR3                  = 45  // Control register 3
+	PT_CR4                  = 46  // Control register 4
+	PT_CR5                  = 47  // Control register 5
+	PT_CR6                  = 48  // Control register 6
+	PT_CR7                  = 49  // Control register 7
+	PT_CR8                  = 50  // Control register 8
+	PT_CR9                  = 51  // Control register 9
+	PT_CR10                 = 52  // Control register 10
+	PT_CR11                 = 53  // Control register 11
+	PT_CR12                 = 54  // Control register 12
+	PT_CR13                 = 55  // Control register 13
+	PT_CR14                 = 56  // Control register 14
+	PT_CR15                 = 57  // Control register 15
+	PT_GPRH0                = 58  // GP High register 0
+	PT_GPRH1                = 59  // GP High register 1
+	PT_GPRH2                = 60  // GP High register 2
+	PT_GPRH3                = 61  // GP High register 3
+	PT_GPRH4                = 62  // GP High register 4
+	PT_GPRH5                = 63  // GP High register 5
+	PT_GPRH6                = 64  // GP High register 6
+	PT_GPRH7                = 65  // GP High register 7
+	PT_GPRH8                = 66  // GP High register 8
+	PT_GPRH9                = 67  // GP High register 9
+	PT_GPRH10               = 68  // GP High register 10
+	PT_GPRH11               = 69  // GP High register 11
+	PT_GPRH12               = 70  // GP High register 12
+	PT_GPRH13               = 71  // GP High register 13
+	PT_GPRH14               = 72  // GP High register 14
+	PT_GPRH15               = 73  // GP High register 15
+	PT_VR0                  = 74  // Vector register 0
+	PT_VR1                  = 75  // Vector register 1
+	PT_VR2                  = 76  // Vector register 2
+	PT_VR3                  = 77  // Vector register 3
+	PT_VR4                  = 78  // Vector register 4
+	PT_VR5                  = 79  // Vector register 5
+	PT_VR6                  = 80  // Vector register 6
+	PT_VR7                  = 81  // Vector register 7
+	PT_VR8                  = 82  // Vector register 8
+	PT_VR9                  = 83  // Vector register 9
+	PT_VR10                 = 84  // Vector register 10
+	PT_VR11                 = 85  // Vector register 11
+	PT_VR12                 = 86  // Vector register 12
+	PT_VR13                 = 87  // Vector register 13
+	PT_VR14                 = 88  // Vector register 14
+	PT_VR15                 = 89  // Vector register 15
+	PT_VR16                 = 90  // Vector register 16
+	PT_VR17                 = 91  // Vector register 17
+	PT_VR18                 = 92  // Vector register 18
+	PT_VR19                 = 93  // Vector register 19
+	PT_VR20                 = 94  // Vector register 20
+	PT_VR21                 = 95  // Vector register 21
+	PT_VR22                 = 96  // Vector register 22
+	PT_VR23                 = 97  // Vector register 23
+	PT_VR24                 = 98  // Vector register 24
+	PT_VR25                 = 99  // Vector register 25
+	PT_VR26                 = 100 // Vector register 26
+	PT_VR27                 = 101 // Vector register 27
+	PT_VR28                 = 102 // Vector register 28
+	PT_VR29                 = 103 // Vector register 29
+	PT_VR30                 = 104 // Vector register 30
+	PT_VR31                 = 105 // Vector register 31
+	PT_PSWG                 = 106 // PSWG
+	PT_PSWG0                = 106 // Bytes 0-3
+	PT_PSWG1                = 107 // Bytes 4-7
+	PT_PSWG2                = 108 // Bytes 8-11 (IA high word)
+	PT_PSWG3                = 109 // Bytes 12-15 (IA low word)
+)
+
+func Bpx4ptr(request int32, pid int32, addr unsafe.Pointer, data unsafe.Pointer, buffer unsafe.Pointer) (rv int32, rc int32, rn int32) {
+	var parms [8]unsafe.Pointer
+	parms[0] = unsafe.Pointer(&request)
+	parms[1] = unsafe.Pointer(&pid)
+	parms[2] = unsafe.Pointer(&addr)
+	parms[3] = unsafe.Pointer(&data)
+	parms[4] = unsafe.Pointer(&buffer)
+	parms[5] = unsafe.Pointer(&rv)
+	parms[6] = unsafe.Pointer(&rc)
+	parms[7] = unsafe.Pointer(&rn)
+	bpxcall(parms[:], BPX4PTR)
+	return rv, rc, rn
+}
+
+func copyU8(val uint8, dest []uint8) int {
+	if len(dest) < 1 {
+		return 0
+	}
+	dest[0] = val
+	return 1
+}
+
+func copyU8Arr(src, dest []uint8) int {
+	if len(dest) < len(src) {
+		return 0
+	}
+	for i, v := range src {
+		dest[i] = v
+	}
+	return len(src)
+}
+
+func copyU16(val uint16, dest []uint16) int {
+	if len(dest) < 1 {
+		return 0
+	}
+	dest[0] = val
+	return 1
+}
+
+func copyU32(val uint32, dest []uint32) int {
+	if len(dest) < 1 {
+		return 0
+	}
+	dest[0] = val
+	return 1
+}
+
+func copyU32Arr(src, dest []uint32) int {
+	if len(dest) < len(src) {
+		return 0
+	}
+	for i, v := range src {
+		dest[i] = v
+	}
+	return len(src)
+}
+
+func copyU64(val uint64, dest []uint64) int {
+	if len(dest) < 1 {
+		return 0
+	}
+	dest[0] = val
+	return 1
+}
diff --git a/vendor/golang.org/x/sys/unix/bpxsvc_zos.s b/vendor/golang.org/x/sys/unix/bpxsvc_zos.s
new file mode 100644
index 00000000..4bd4a179
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/bpxsvc_zos.s
@@ -0,0 +1,192 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "go_asm.h"
+#include "textflag.h"
+
+// function to call USS assembly language services
+//
+// doc: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_3.1.0/com.ibm.zos.v3r1.bpxb100/bit64env.htm
+//
+//   arg1 unsafe.Pointer array that ressembles an OS PLIST
+//
+//   arg2 function offset as in
+//       doc: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_3.1.0/com.ibm.zos.v3r1.bpxb100/bpx2cr_List_of_offsets.htm
+//
+// func bpxcall(plist []unsafe.Pointer, bpx_offset int64)
+
+TEXT ·bpxcall(SB), NOSPLIT|NOFRAME, $0
+	MOVD  plist_base+0(FP), R1  // r1 points to plist
+	MOVD  bpx_offset+24(FP), R2 // r2 offset to BPX vector table
+	MOVD  R14, R7               // save r14
+	MOVD  R15, R8               // save r15
+	MOVWZ 16(R0), R9
+	MOVWZ 544(R9), R9
+	MOVWZ 24(R9), R9            // call vector in r9
+	ADD   R2, R9                // add offset to vector table
+	MOVWZ (R9), R9              // r9 points to entry point
+	BYTE  $0x0D                 // BL R14,R9 --> basr r14,r9
+	BYTE  $0xE9                 // clobbers 0,1,14,15
+	MOVD  R8, R15               // restore 15
+	JMP   R7                    // return via saved return address
+
+//   func A2e(arr [] byte)
+//   code page conversion from  819 to 1047
+TEXT ·A2e(SB), NOSPLIT|NOFRAME, $0
+	MOVD arg_base+0(FP), R2                        // pointer to arry of characters
+	MOVD arg_len+8(FP), R3                         // count
+	XOR  R0, R0
+	XOR  R1, R1
+	BYTE $0xA7; BYTE $0x15; BYTE $0x00; BYTE $0x82 // BRAS 1,(2+(256/2))
+
+	// ASCII -> EBCDIC conversion table:
+	BYTE $0x00; BYTE $0x01; BYTE $0x02; BYTE $0x03
+	BYTE $0x37; BYTE $0x2d; BYTE $0x2e; BYTE $0x2f
+	BYTE $0x16; BYTE $0x05; BYTE $0x15; BYTE $0x0b
+	BYTE $0x0c; BYTE $0x0d; BYTE $0x0e; BYTE $0x0f
+	BYTE $0x10; BYTE $0x11; BYTE $0x12; BYTE $0x13
+	BYTE $0x3c; BYTE $0x3d; BYTE $0x32; BYTE $0x26
+	BYTE $0x18; BYTE $0x19; BYTE $0x3f; BYTE $0x27
+	BYTE $0x1c; BYTE $0x1d; BYTE $0x1e; BYTE $0x1f
+	BYTE $0x40; BYTE $0x5a; BYTE $0x7f; BYTE $0x7b
+	BYTE $0x5b; BYTE $0x6c; BYTE $0x50; BYTE $0x7d
+	BYTE $0x4d; BYTE $0x5d; BYTE $0x5c; BYTE $0x4e
+	BYTE $0x6b; BYTE $0x60; BYTE $0x4b; BYTE $0x61
+	BYTE $0xf0; BYTE $0xf1; BYTE $0xf2; BYTE $0xf3
+	BYTE $0xf4; BYTE $0xf5; BYTE $0xf6; BYTE $0xf7
+	BYTE $0xf8; BYTE $0xf9; BYTE $0x7a; BYTE $0x5e
+	BYTE $0x4c; BYTE $0x7e; BYTE $0x6e; BYTE $0x6f
+	BYTE $0x7c; BYTE $0xc1; BYTE $0xc2; BYTE $0xc3
+	BYTE $0xc4; BYTE $0xc5; BYTE $0xc6; BYTE $0xc7
+	BYTE $0xc8; BYTE $0xc9; BYTE $0xd1; BYTE $0xd2
+	BYTE $0xd3; BYTE $0xd4; BYTE $0xd5; BYTE $0xd6
+	BYTE $0xd7; BYTE $0xd8; BYTE $0xd9; BYTE $0xe2
+	BYTE $0xe3; BYTE $0xe4; BYTE $0xe5; BYTE $0xe6
+	BYTE $0xe7; BYTE $0xe8; BYTE $0xe9; BYTE $0xad
+	BYTE $0xe0; BYTE $0xbd; BYTE $0x5f; BYTE $0x6d
+	BYTE $0x79; BYTE $0x81; BYTE $0x82; BYTE $0x83
+	BYTE $0x84; BYTE $0x85; BYTE $0x86; BYTE $0x87
+	BYTE $0x88; BYTE $0x89; BYTE $0x91; BYTE $0x92
+	BYTE $0x93; BYTE $0x94; BYTE $0x95; BYTE $0x96
+	BYTE $0x97; BYTE $0x98; BYTE $0x99; BYTE $0xa2
+	BYTE $0xa3; BYTE $0xa4; BYTE $0xa5; BYTE $0xa6
+	BYTE $0xa7; BYTE $0xa8; BYTE $0xa9; BYTE $0xc0
+	BYTE $0x4f; BYTE $0xd0; BYTE $0xa1; BYTE $0x07
+	BYTE $0x20; BYTE $0x21; BYTE $0x22; BYTE $0x23
+	BYTE $0x24; BYTE $0x25; BYTE $0x06; BYTE $0x17
+	BYTE $0x28; BYTE $0x29; BYTE $0x2a; BYTE $0x2b
+	BYTE $0x2c; BYTE $0x09; BYTE $0x0a; BYTE $0x1b
+	BYTE $0x30; BYTE $0x31; BYTE $0x1a; BYTE $0x33
+	BYTE $0x34; BYTE $0x35; BYTE $0x36; BYTE $0x08
+	BYTE $0x38; BYTE $0x39; BYTE $0x3a; BYTE $0x3b
+	BYTE $0x04; BYTE $0x14; BYTE $0x3e; BYTE $0xff
+	BYTE $0x41; BYTE $0xaa; BYTE $0x4a; BYTE $0xb1
+	BYTE $0x9f; BYTE $0xb2; BYTE $0x6a; BYTE $0xb5
+	BYTE $0xbb; BYTE $0xb4; BYTE $0x9a; BYTE $0x8a
+	BYTE $0xb0; BYTE $0xca; BYTE $0xaf; BYTE $0xbc
+	BYTE $0x90; BYTE $0x8f; BYTE $0xea; BYTE $0xfa
+	BYTE $0xbe; BYTE $0xa0; BYTE $0xb6; BYTE $0xb3
+	BYTE $0x9d; BYTE $0xda; BYTE $0x9b; BYTE $0x8b
+	BYTE $0xb7; BYTE $0xb8; BYTE $0xb9; BYTE $0xab
+	BYTE $0x64; BYTE $0x65; BYTE $0x62; BYTE $0x66
+	BYTE $0x63; BYTE $0x67; BYTE $0x9e; BYTE $0x68
+	BYTE $0x74; BYTE $0x71; BYTE $0x72; BYTE $0x73
+	BYTE $0x78; BYTE $0x75; BYTE $0x76; BYTE $0x77
+	BYTE $0xac; BYTE $0x69; BYTE $0xed; BYTE $0xee
+	BYTE $0xeb; BYTE $0xef; BYTE $0xec; BYTE $0xbf
+	BYTE $0x80; BYTE $0xfd; BYTE $0xfe; BYTE $0xfb
+	BYTE $0xfc; BYTE $0xba; BYTE $0xae; BYTE $0x59
+	BYTE $0x44; BYTE $0x45; BYTE $0x42; BYTE $0x46
+	BYTE $0x43; BYTE $0x47; BYTE $0x9c; BYTE $0x48
+	BYTE $0x54; BYTE $0x51; BYTE $0x52; BYTE $0x53
+	BYTE $0x58; BYTE $0x55; BYTE $0x56; BYTE $0x57
+	BYTE $0x8c; BYTE $0x49; BYTE $0xcd; BYTE $0xce
+	BYTE $0xcb; BYTE $0xcf; BYTE $0xcc; BYTE $0xe1
+	BYTE $0x70; BYTE $0xdd; BYTE $0xde; BYTE $0xdb
+	BYTE $0xdc; BYTE $0x8d; BYTE $0x8e; BYTE $0xdf
+
+retry:
+	WORD $0xB9931022 // TROO 2,2,b'0001'
+	BVS  retry
+	RET
+
+//   func e2a(arr [] byte)
+//   code page conversion from  1047 to 819
+TEXT ·E2a(SB), NOSPLIT|NOFRAME, $0
+	MOVD arg_base+0(FP), R2                        // pointer to arry of characters
+	MOVD arg_len+8(FP), R3                         // count
+	XOR  R0, R0
+	XOR  R1, R1
+	BYTE $0xA7; BYTE $0x15; BYTE $0x00; BYTE $0x82 // BRAS 1,(2+(256/2))
+
+	// EBCDIC -> ASCII conversion table:
+	BYTE $0x00; BYTE $0x01; BYTE $0x02; BYTE $0x03
+	BYTE $0x9c; BYTE $0x09; BYTE $0x86; BYTE $0x7f
+	BYTE $0x97; BYTE $0x8d; BYTE $0x8e; BYTE $0x0b
+	BYTE $0x0c; BYTE $0x0d; BYTE $0x0e; BYTE $0x0f
+	BYTE $0x10; BYTE $0x11; BYTE $0x12; BYTE $0x13
+	BYTE $0x9d; BYTE $0x0a; BYTE $0x08; BYTE $0x87
+	BYTE $0x18; BYTE $0x19; BYTE $0x92; BYTE $0x8f
+	BYTE $0x1c; BYTE $0x1d; BYTE $0x1e; BYTE $0x1f
+	BYTE $0x80; BYTE $0x81; BYTE $0x82; BYTE $0x83
+	BYTE $0x84; BYTE $0x85; BYTE $0x17; BYTE $0x1b
+	BYTE $0x88; BYTE $0x89; BYTE $0x8a; BYTE $0x8b
+	BYTE $0x8c; BYTE $0x05; BYTE $0x06; BYTE $0x07
+	BYTE $0x90; BYTE $0x91; BYTE $0x16; BYTE $0x93
+	BYTE $0x94; BYTE $0x95; BYTE $0x96; BYTE $0x04
+	BYTE $0x98; BYTE $0x99; BYTE $0x9a; BYTE $0x9b
+	BYTE $0x14; BYTE $0x15; BYTE $0x9e; BYTE $0x1a
+	BYTE $0x20; BYTE $0xa0; BYTE $0xe2; BYTE $0xe4
+	BYTE $0xe0; BYTE $0xe1; BYTE $0xe3; BYTE $0xe5
+	BYTE $0xe7; BYTE $0xf1; BYTE $0xa2; BYTE $0x2e
+	BYTE $0x3c; BYTE $0x28; BYTE $0x2b; BYTE $0x7c
+	BYTE $0x26; BYTE $0xe9; BYTE $0xea; BYTE $0xeb
+	BYTE $0xe8; BYTE $0xed; BYTE $0xee; BYTE $0xef
+	BYTE $0xec; BYTE $0xdf; BYTE $0x21; BYTE $0x24
+	BYTE $0x2a; BYTE $0x29; BYTE $0x3b; BYTE $0x5e
+	BYTE $0x2d; BYTE $0x2f; BYTE $0xc2; BYTE $0xc4
+	BYTE $0xc0; BYTE $0xc1; BYTE $0xc3; BYTE $0xc5
+	BYTE $0xc7; BYTE $0xd1; BYTE $0xa6; BYTE $0x2c
+	BYTE $0x25; BYTE $0x5f; BYTE $0x3e; BYTE $0x3f
+	BYTE $0xf8; BYTE $0xc9; BYTE $0xca; BYTE $0xcb
+	BYTE $0xc8; BYTE $0xcd; BYTE $0xce; BYTE $0xcf
+	BYTE $0xcc; BYTE $0x60; BYTE $0x3a; BYTE $0x23
+	BYTE $0x40; BYTE $0x27; BYTE $0x3d; BYTE $0x22
+	BYTE $0xd8; BYTE $0x61; BYTE $0x62; BYTE $0x63
+	BYTE $0x64; BYTE $0x65; BYTE $0x66; BYTE $0x67
+	BYTE $0x68; BYTE $0x69; BYTE $0xab; BYTE $0xbb
+	BYTE $0xf0; BYTE $0xfd; BYTE $0xfe; BYTE $0xb1
+	BYTE $0xb0; BYTE $0x6a; BYTE $0x6b; BYTE $0x6c
+	BYTE $0x6d; BYTE $0x6e; BYTE $0x6f; BYTE $0x70
+	BYTE $0x71; BYTE $0x72; BYTE $0xaa; BYTE $0xba
+	BYTE $0xe6; BYTE $0xb8; BYTE $0xc6; BYTE $0xa4
+	BYTE $0xb5; BYTE $0x7e; BYTE $0x73; BYTE $0x74
+	BYTE $0x75; BYTE $0x76; BYTE $0x77; BYTE $0x78
+	BYTE $0x79; BYTE $0x7a; BYTE $0xa1; BYTE $0xbf
+	BYTE $0xd0; BYTE $0x5b; BYTE $0xde; BYTE $0xae
+	BYTE $0xac; BYTE $0xa3; BYTE $0xa5; BYTE $0xb7
+	BYTE $0xa9; BYTE $0xa7; BYTE $0xb6; BYTE $0xbc
+	BYTE $0xbd; BYTE $0xbe; BYTE $0xdd; BYTE $0xa8
+	BYTE $0xaf; BYTE $0x5d; BYTE $0xb4; BYTE $0xd7
+	BYTE $0x7b; BYTE $0x41; BYTE $0x42; BYTE $0x43
+	BYTE $0x44; BYTE $0x45; BYTE $0x46; BYTE $0x47
+	BYTE $0x48; BYTE $0x49; BYTE $0xad; BYTE $0xf4
+	BYTE $0xf6; BYTE $0xf2; BYTE $0xf3; BYTE $0xf5
+	BYTE $0x7d; BYTE $0x4a; BYTE $0x4b; BYTE $0x4c
+	BYTE $0x4d; BYTE $0x4e; BYTE $0x4f; BYTE $0x50
+	BYTE $0x51; BYTE $0x52; BYTE $0xb9; BYTE $0xfb
+	BYTE $0xfc; BYTE $0xf9; BYTE $0xfa; BYTE $0xff
+	BYTE $0x5c; BYTE $0xf7; BYTE $0x53; BYTE $0x54
+	BYTE $0x55; BYTE $0x56; BYTE $0x57; BYTE $0x58
+	BYTE $0x59; BYTE $0x5a; BYTE $0xb2; BYTE $0xd4
+	BYTE $0xd6; BYTE $0xd2; BYTE $0xd3; BYTE $0xd5
+	BYTE $0x30; BYTE $0x31; BYTE $0x32; BYTE $0x33
+	BYTE $0x34; BYTE $0x35; BYTE $0x36; BYTE $0x37
+	BYTE $0x38; BYTE $0x39; BYTE $0xb3; BYTE $0xdb
+	BYTE $0xdc; BYTE $0xd9; BYTE $0xda; BYTE $0x9f
+
+retry:
+	WORD $0xB9931022 // TROO 2,2,b'0001'
+	BVS  retry
+	RET
diff --git a/vendor/golang.org/x/sys/unix/epoll_zos.go b/vendor/golang.org/x/sys/unix/epoll_zos.go
deleted file mode 100644
index 7753fdde..00000000
--- a/vendor/golang.org/x/sys/unix/epoll_zos.go
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build zos && s390x
-
-package unix
-
-import (
-	"sync"
-)
-
-// This file simulates epoll on z/OS using poll.
-
-// Analogous to epoll_event on Linux.
-// TODO(neeilan): Pad is because the Linux kernel expects a 96-bit struct. We never pass this to the kernel; remove?
-type EpollEvent struct {
-	Events uint32
-	Fd     int32
-	Pad    int32
-}
-
-const (
-	EPOLLERR      = 0x8
-	EPOLLHUP      = 0x10
-	EPOLLIN       = 0x1
-	EPOLLMSG      = 0x400
-	EPOLLOUT      = 0x4
-	EPOLLPRI      = 0x2
-	EPOLLRDBAND   = 0x80
-	EPOLLRDNORM   = 0x40
-	EPOLLWRBAND   = 0x200
-	EPOLLWRNORM   = 0x100
-	EPOLL_CTL_ADD = 0x1
-	EPOLL_CTL_DEL = 0x2
-	EPOLL_CTL_MOD = 0x3
-	// The following constants are part of the epoll API, but represent
-	// currently unsupported functionality on z/OS.
-	// EPOLL_CLOEXEC  = 0x80000
-	// EPOLLET        = 0x80000000
-	// EPOLLONESHOT   = 0x40000000
-	// EPOLLRDHUP     = 0x2000     // Typically used with edge-triggered notis
-	// EPOLLEXCLUSIVE = 0x10000000 // Exclusive wake-up mode
-	// EPOLLWAKEUP    = 0x20000000 // Relies on Linux's BLOCK_SUSPEND capability
-)
-
-// TODO(neeilan): We can eliminate these epToPoll / pToEpoll calls by using identical mask values for POLL/EPOLL
-// constants where possible The lower 16 bits of epoll events (uint32) can fit any system poll event (int16).
-
-// epToPollEvt converts epoll event field to poll equivalent.
-// In epoll, Events is a 32-bit field, while poll uses 16 bits.
-func epToPollEvt(events uint32) int16 {
-	var ep2p = map[uint32]int16{
-		EPOLLIN:  POLLIN,
-		EPOLLOUT: POLLOUT,
-		EPOLLHUP: POLLHUP,
-		EPOLLPRI: POLLPRI,
-		EPOLLERR: POLLERR,
-	}
-
-	var pollEvts int16 = 0
-	for epEvt, pEvt := range ep2p {
-		if (events & epEvt) != 0 {
-			pollEvts |= pEvt
-		}
-	}
-
-	return pollEvts
-}
-
-// pToEpollEvt converts 16 bit poll event bitfields to 32-bit epoll event fields.
-func pToEpollEvt(revents int16) uint32 {
-	var p2ep = map[int16]uint32{
-		POLLIN:  EPOLLIN,
-		POLLOUT: EPOLLOUT,
-		POLLHUP: EPOLLHUP,
-		POLLPRI: EPOLLPRI,
-		POLLERR: EPOLLERR,
-	}
-
-	var epollEvts uint32 = 0
-	for pEvt, epEvt := range p2ep {
-		if (revents & pEvt) != 0 {
-			epollEvts |= epEvt
-		}
-	}
-
-	return epollEvts
-}
-
-// Per-process epoll implementation.
-type epollImpl struct {
-	mu       sync.Mutex
-	epfd2ep  map[int]*eventPoll
-	nextEpfd int
-}
-
-// eventPoll holds a set of file descriptors being watched by the process. A process can have multiple epoll instances.
-// On Linux, this is an in-kernel data structure accessed through a fd.
-type eventPoll struct {
-	mu  sync.Mutex
-	fds map[int]*EpollEvent
-}
-
-// epoll impl for this process.
-var impl epollImpl = epollImpl{
-	epfd2ep:  make(map[int]*eventPoll),
-	nextEpfd: 0,
-}
-
-func (e *epollImpl) epollcreate(size int) (epfd int, err error) {
-	e.mu.Lock()
-	defer e.mu.Unlock()
-	epfd = e.nextEpfd
-	e.nextEpfd++
-
-	e.epfd2ep[epfd] = &eventPoll{
-		fds: make(map[int]*EpollEvent),
-	}
-	return epfd, nil
-}
-
-func (e *epollImpl) epollcreate1(flag int) (fd int, err error) {
-	return e.epollcreate(4)
-}
-
-func (e *epollImpl) epollctl(epfd int, op int, fd int, event *EpollEvent) (err error) {
-	e.mu.Lock()
-	defer e.mu.Unlock()
-
-	ep, ok := e.epfd2ep[epfd]
-	if !ok {
-
-		return EBADF
-	}
-
-	switch op {
-	case EPOLL_CTL_ADD:
-		// TODO(neeilan): When we make epfds and fds disjoint, detect epoll
-		// loops here (instances watching each other) and return ELOOP.
-		if _, ok := ep.fds[fd]; ok {
-			return EEXIST
-		}
-		ep.fds[fd] = event
-	case EPOLL_CTL_MOD:
-		if _, ok := ep.fds[fd]; !ok {
-			return ENOENT
-		}
-		ep.fds[fd] = event
-	case EPOLL_CTL_DEL:
-		if _, ok := ep.fds[fd]; !ok {
-			return ENOENT
-		}
-		delete(ep.fds, fd)
-
-	}
-	return nil
-}
-
-// Must be called while holding ep.mu
-func (ep *eventPoll) getFds() []int {
-	fds := make([]int, len(ep.fds))
-	for fd := range ep.fds {
-		fds = append(fds, fd)
-	}
-	return fds
-}
-
-func (e *epollImpl) epollwait(epfd int, events []EpollEvent, msec int) (n int, err error) {
-	e.mu.Lock() // in [rare] case of concurrent epollcreate + epollwait
-	ep, ok := e.epfd2ep[epfd]
-
-	if !ok {
-		e.mu.Unlock()
-		return 0, EBADF
-	}
-
-	pollfds := make([]PollFd, 4)
-	for fd, epollevt := range ep.fds {
-		pollfds = append(pollfds, PollFd{Fd: int32(fd), Events: epToPollEvt(epollevt.Events)})
-	}
-	e.mu.Unlock()
-
-	n, err = Poll(pollfds, msec)
-	if err != nil {
-		return n, err
-	}
-
-	i := 0
-	for _, pFd := range pollfds {
-		if pFd.Revents != 0 {
-			events[i] = EpollEvent{Fd: pFd.Fd, Events: pToEpollEvt(pFd.Revents)}
-			i++
-		}
-
-		if i == n {
-			break
-		}
-	}
-
-	return n, nil
-}
-
-func EpollCreate(size int) (fd int, err error) {
-	return impl.epollcreate(size)
-}
-
-func EpollCreate1(flag int) (fd int, err error) {
-	return impl.epollcreate1(flag)
-}
-
-func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
-	return impl.epollctl(epfd, op, fd, event)
-}
-
-// Because EpollWait mutates events, the caller is expected to coordinate
-// concurrent access if calling with the same epfd from multiple goroutines.
-func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
-	return impl.epollwait(epfd, events, msec)
-}
diff --git a/vendor/golang.org/x/sys/unix/fstatfs_zos.go b/vendor/golang.org/x/sys/unix/fstatfs_zos.go
deleted file mode 100644
index c8bde601..00000000
--- a/vendor/golang.org/x/sys/unix/fstatfs_zos.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build zos && s390x
-
-package unix
-
-import (
-	"unsafe"
-)
-
-// This file simulates fstatfs on z/OS using fstatvfs and w_getmntent.
-
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	var stat_v Statvfs_t
-	err = Fstatvfs(fd, &stat_v)
-	if err == nil {
-		// populate stat
-		stat.Type = 0
-		stat.Bsize = stat_v.Bsize
-		stat.Blocks = stat_v.Blocks
-		stat.Bfree = stat_v.Bfree
-		stat.Bavail = stat_v.Bavail
-		stat.Files = stat_v.Files
-		stat.Ffree = stat_v.Ffree
-		stat.Fsid = stat_v.Fsid
-		stat.Namelen = stat_v.Namemax
-		stat.Frsize = stat_v.Frsize
-		stat.Flags = stat_v.Flag
-		for passn := 0; passn < 5; passn++ {
-			switch passn {
-			case 0:
-				err = tryGetmntent64(stat)
-				break
-			case 1:
-				err = tryGetmntent128(stat)
-				break
-			case 2:
-				err = tryGetmntent256(stat)
-				break
-			case 3:
-				err = tryGetmntent512(stat)
-				break
-			case 4:
-				err = tryGetmntent1024(stat)
-				break
-			default:
-				break
-			}
-			//proceed to return if: err is nil (found), err is nonnil but not ERANGE (another error occurred)
-			if err == nil || err != nil && err != ERANGE {
-				break
-			}
-		}
-	}
-	return err
-}
-
-func tryGetmntent64(stat *Statfs_t) (err error) {
-	var mnt_ent_buffer struct {
-		header       W_Mnth
-		filesys_info [64]W_Mntent
-	}
-	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
-	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
-	if err != nil {
-		return err
-	}
-	err = ERANGE //return ERANGE if no match is found in this batch
-	for i := 0; i < fs_count; i++ {
-		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
-			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
-			err = nil
-			break
-		}
-	}
-	return err
-}
-
-func tryGetmntent128(stat *Statfs_t) (err error) {
-	var mnt_ent_buffer struct {
-		header       W_Mnth
-		filesys_info [128]W_Mntent
-	}
-	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
-	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
-	if err != nil {
-		return err
-	}
-	err = ERANGE //return ERANGE if no match is found in this batch
-	for i := 0; i < fs_count; i++ {
-		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
-			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
-			err = nil
-			break
-		}
-	}
-	return err
-}
-
-func tryGetmntent256(stat *Statfs_t) (err error) {
-	var mnt_ent_buffer struct {
-		header       W_Mnth
-		filesys_info [256]W_Mntent
-	}
-	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
-	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
-	if err != nil {
-		return err
-	}
-	err = ERANGE //return ERANGE if no match is found in this batch
-	for i := 0; i < fs_count; i++ {
-		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
-			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
-			err = nil
-			break
-		}
-	}
-	return err
-}
-
-func tryGetmntent512(stat *Statfs_t) (err error) {
-	var mnt_ent_buffer struct {
-		header       W_Mnth
-		filesys_info [512]W_Mntent
-	}
-	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
-	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
-	if err != nil {
-		return err
-	}
-	err = ERANGE //return ERANGE if no match is found in this batch
-	for i := 0; i < fs_count; i++ {
-		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
-			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
-			err = nil
-			break
-		}
-	}
-	return err
-}
-
-func tryGetmntent1024(stat *Statfs_t) (err error) {
-	var mnt_ent_buffer struct {
-		header       W_Mnth
-		filesys_info [1024]W_Mntent
-	}
-	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
-	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
-	if err != nil {
-		return err
-	}
-	err = ERANGE //return ERANGE if no match is found in this batch
-	for i := 0; i < fs_count; i++ {
-		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
-			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
-			err = nil
-			break
-		}
-	}
-	return err
-}
diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh
index fdcaa974..4ed2e488 100644
--- a/vendor/golang.org/x/sys/unix/mkerrors.sh
+++ b/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -263,6 +263,7 @@ struct ltchars {
 #include <linux/sched.h>
 #include <linux/seccomp.h>
 #include <linux/serial.h>
+#include <linux/sock_diag.h>
 #include <linux/sockios.h>
 #include <linux/taskstats.h>
 #include <linux/tipc.h>
@@ -549,6 +550,7 @@ ccflags="$@"
 		$2 !~ "NLA_TYPE_MASK" &&
 		$2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ &&
 		$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ ||
+		$2 ~ /^SOCK_|SK_DIAG_|SKNLGRP_$/ ||
 		$2 ~ /^FIORDCHK$/ ||
 		$2 ~ /^SIOC/ ||
 		$2 ~ /^TIOC/ ||
diff --git a/vendor/golang.org/x/sys/unix/mmap_nomremap.go b/vendor/golang.org/x/sys/unix/mmap_nomremap.go
index 4b68e597..7f602ffd 100644
--- a/vendor/golang.org/x/sys/unix/mmap_nomremap.go
+++ b/vendor/golang.org/x/sys/unix/mmap_nomremap.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris
+//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris || zos
 
 package unix
 
diff --git a/vendor/golang.org/x/sys/unix/mremap.go b/vendor/golang.org/x/sys/unix/mremap.go
index fd45fe52..3a5e776f 100644
--- a/vendor/golang.org/x/sys/unix/mremap.go
+++ b/vendor/golang.org/x/sys/unix/mremap.go
@@ -50,3 +50,8 @@ func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data [
 func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
 	return mapper.Mremap(oldData, newLength, flags)
 }
+
+func MremapPtr(oldAddr unsafe.Pointer, oldSize uintptr, newAddr unsafe.Pointer, newSize uintptr, flags int) (ret unsafe.Pointer, err error) {
+	xaddr, err := mapper.mremap(uintptr(oldAddr), oldSize, newSize, flags, uintptr(newAddr))
+	return unsafe.Pointer(xaddr), err
+}
diff --git a/vendor/golang.org/x/sys/unix/pagesize_unix.go b/vendor/golang.org/x/sys/unix/pagesize_unix.go
index 4d0a3430..0482408d 100644
--- a/vendor/golang.org/x/sys/unix/pagesize_unix.go
+++ b/vendor/golang.org/x/sys/unix/pagesize_unix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
 
 // For Unix, get the pagesize from the runtime.
 
diff --git a/vendor/golang.org/x/sys/unix/readdirent_getdirentries.go b/vendor/golang.org/x/sys/unix/readdirent_getdirentries.go
index 130398b6..b903c006 100644
--- a/vendor/golang.org/x/sys/unix/readdirent_getdirentries.go
+++ b/vendor/golang.org/x/sys/unix/readdirent_getdirentries.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build darwin
+//go:build darwin || zos
 
 package unix
 
diff --git a/vendor/golang.org/x/sys/unix/sockcmsg_zos.go b/vendor/golang.org/x/sys/unix/sockcmsg_zos.go
new file mode 100644
index 00000000..3e53dbc0
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/sockcmsg_zos.go
@@ -0,0 +1,58 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Socket control messages
+
+package unix
+
+import "unsafe"
+
+// UnixCredentials encodes credentials into a socket control message
+// for sending to another process. This can be used for
+// authentication.
+func UnixCredentials(ucred *Ucred) []byte {
+	b := make([]byte, CmsgSpace(SizeofUcred))
+	h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
+	h.Level = SOL_SOCKET
+	h.Type = SCM_CREDENTIALS
+	h.SetLen(CmsgLen(SizeofUcred))
+	*(*Ucred)(h.data(0)) = *ucred
+	return b
+}
+
+// ParseUnixCredentials decodes a socket control message that contains
+// credentials in a Ucred structure. To receive such a message, the
+// SO_PASSCRED option must be enabled on the socket.
+func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) {
+	if m.Header.Level != SOL_SOCKET {
+		return nil, EINVAL
+	}
+	if m.Header.Type != SCM_CREDENTIALS {
+		return nil, EINVAL
+	}
+	ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
+	return &ucred, nil
+}
+
+// PktInfo4 encodes Inet4Pktinfo into a socket control message of type IP_PKTINFO.
+func PktInfo4(info *Inet4Pktinfo) []byte {
+	b := make([]byte, CmsgSpace(SizeofInet4Pktinfo))
+	h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
+	h.Level = SOL_IP
+	h.Type = IP_PKTINFO
+	h.SetLen(CmsgLen(SizeofInet4Pktinfo))
+	*(*Inet4Pktinfo)(h.data(0)) = *info
+	return b
+}
+
+// PktInfo6 encodes Inet6Pktinfo into a socket control message of type IPV6_PKTINFO.
+func PktInfo6(info *Inet6Pktinfo) []byte {
+	b := make([]byte, CmsgSpace(SizeofInet6Pktinfo))
+	h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
+	h.Level = SOL_IPV6
+	h.Type = IPV6_PKTINFO
+	h.SetLen(CmsgLen(SizeofInet6Pktinfo))
+	*(*Inet6Pktinfo)(h.data(0)) = *info
+	return b
+}
diff --git a/vendor/golang.org/x/sys/unix/symaddr_zos_s390x.s b/vendor/golang.org/x/sys/unix/symaddr_zos_s390x.s
new file mode 100644
index 00000000..3c4f33cb
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/symaddr_zos_s390x.s
@@ -0,0 +1,75 @@
+// Copyright 2024 The Go 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 zos && s390x && gc
+
+#include "textflag.h"
+
+//  provide the address of function variable to be fixed up.
+
+TEXT ·getPipe2Addr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Pipe2(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+TEXT ·get_FlockAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Flock(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+TEXT ·get_GetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Getxattr(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+TEXT ·get_NanosleepAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Nanosleep(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+TEXT ·get_SetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Setxattr(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+TEXT ·get_Wait4Addr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Wait4(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+TEXT ·get_MountAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Mount(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+TEXT ·get_UnmountAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Unmount(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+TEXT ·get_UtimesNanoAtAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·UtimesNanoAt(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+TEXT ·get_UtimesNanoAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·UtimesNano(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+TEXT ·get_MkfifoatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Mkfifoat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+TEXT ·get_ChtagAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Chtag(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+TEXT ·get_ReadlinkatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Readlinkat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+	
diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go
index 59542a89..4cc7b005 100644
--- a/vendor/golang.org/x/sys/unix/syscall_darwin.go
+++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go
@@ -542,6 +542,18 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
 	}
 }
 
+//sys	pthread_chdir_np(path string) (err error)
+
+func PthreadChdir(path string) (err error) {
+	return pthread_chdir_np(path)
+}
+
+//sys	pthread_fchdir_np(fd int) (err error)
+
+func PthreadFchdir(fd int) (err error) {
+	return pthread_fchdir_np(fd)
+}
+
 //sys	sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
 
 //sys	shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go b/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go
index 16dc6993..2f0fa76e 100644
--- a/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go
+++ b/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build darwin && go1.12
+//go:build darwin
 
 package unix
 
diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go
index 64d1bb4d..2b57e0f7 100644
--- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go
@@ -13,6 +13,7 @@
 package unix
 
 import (
+	"errors"
 	"sync"
 	"unsafe"
 )
@@ -169,25 +170,26 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
 func Uname(uname *Utsname) error {
 	mib := []_C_int{CTL_KERN, KERN_OSTYPE}
 	n := unsafe.Sizeof(uname.Sysname)
-	if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
+	// Suppress ENOMEM errors to be compatible with the C library __xuname() implementation.
+	if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
 		return err
 	}
 
 	mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
 	n = unsafe.Sizeof(uname.Nodename)
-	if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
+	if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
 		return err
 	}
 
 	mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
 	n = unsafe.Sizeof(uname.Release)
-	if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
+	if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
 		return err
 	}
 
 	mib = []_C_int{CTL_KERN, KERN_VERSION}
 	n = unsafe.Sizeof(uname.Version)
-	if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
+	if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
 		return err
 	}
 
@@ -205,7 +207,7 @@ func Uname(uname *Utsname) error {
 
 	mib = []_C_int{CTL_HW, HW_MACHINE}
 	n = unsafe.Sizeof(uname.Machine)
-	if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
+	if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
 		return err
 	}
 
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go
index 0f85e29e..5682e262 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -1849,6 +1849,105 @@ func Dup2(oldfd, newfd int) error {
 //sys	Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error)
 //sys	Fsopen(fsName string, flags int) (fd int, err error)
 //sys	Fspick(dirfd int, pathName string, flags int) (fd int, err error)
+
+//sys	fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error)
+
+func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) {
+	var keyp *byte
+	if keyp, err = BytePtrFromString(key); err != nil {
+		return
+	}
+	return fsconfig(fd, cmd, keyp, value, aux)
+}
+
+// FsconfigSetFlag is equivalent to fsconfig(2) called
+// with cmd == FSCONFIG_SET_FLAG.
+//
+// fd is the filesystem context to act upon.
+// key the parameter key to set.
+func FsconfigSetFlag(fd int, key string) (err error) {
+	return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0)
+}
+
+// FsconfigSetString is equivalent to fsconfig(2) called
+// with cmd == FSCONFIG_SET_STRING.
+//
+// fd is the filesystem context to act upon.
+// key the parameter key to set.
+// value is the parameter value to set.
+func FsconfigSetString(fd int, key string, value string) (err error) {
+	var valuep *byte
+	if valuep, err = BytePtrFromString(value); err != nil {
+		return
+	}
+	return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0)
+}
+
+// FsconfigSetBinary is equivalent to fsconfig(2) called
+// with cmd == FSCONFIG_SET_BINARY.
+//
+// fd is the filesystem context to act upon.
+// key the parameter key to set.
+// value is the parameter value to set.
+func FsconfigSetBinary(fd int, key string, value []byte) (err error) {
+	if len(value) == 0 {
+		return EINVAL
+	}
+	return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value))
+}
+
+// FsconfigSetPath is equivalent to fsconfig(2) called
+// with cmd == FSCONFIG_SET_PATH.
+//
+// fd is the filesystem context to act upon.
+// key the parameter key to set.
+// path is a non-empty path for specified key.
+// atfd is a file descriptor at which to start lookup from or AT_FDCWD.
+func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) {
+	var valuep *byte
+	if valuep, err = BytePtrFromString(path); err != nil {
+		return
+	}
+	return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd)
+}
+
+// FsconfigSetPathEmpty is equivalent to fsconfig(2) called
+// with cmd == FSCONFIG_SET_PATH_EMPTY. The same as
+// FconfigSetPath but with AT_PATH_EMPTY implied.
+func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) {
+	var valuep *byte
+	if valuep, err = BytePtrFromString(path); err != nil {
+		return
+	}
+	return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd)
+}
+
+// FsconfigSetFd is equivalent to fsconfig(2) called
+// with cmd == FSCONFIG_SET_FD.
+//
+// fd is the filesystem context to act upon.
+// key the parameter key to set.
+// value is a file descriptor to be assigned to specified key.
+func FsconfigSetFd(fd int, key string, value int) (err error) {
+	return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value)
+}
+
+// FsconfigCreate is equivalent to fsconfig(2) called
+// with cmd == FSCONFIG_CMD_CREATE.
+//
+// fd is the filesystem context to act upon.
+func FsconfigCreate(fd int) (err error) {
+	return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0)
+}
+
+// FsconfigReconfigure is equivalent to fsconfig(2) called
+// with cmd == FSCONFIG_CMD_RECONFIGURE.
+//
+// fd is the filesystem context to act upon.
+func FsconfigReconfigure(fd int) (err error) {
+	return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0)
+}
+
 //sys	Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
 //sysnb	Getpgid(pid int) (pgid int, err error)
 
diff --git a/vendor/golang.org/x/sys/unix/syscall_unix.go b/vendor/golang.org/x/sys/unix/syscall_unix.go
index 77081de8..4e92e5aa 100644
--- a/vendor/golang.org/x/sys/unix/syscall_unix.go
+++ b/vendor/golang.org/x/sys/unix/syscall_unix.go
@@ -154,6 +154,15 @@ func Munmap(b []byte) (err error) {
 	return mapper.Munmap(b)
 }
 
+func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) {
+	xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset)
+	return unsafe.Pointer(xaddr), err
+}
+
+func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) {
+	return mapper.munmap(uintptr(addr), length)
+}
+
 func Read(fd int, p []byte) (n int, err error) {
 	n, err = read(fd, p)
 	if raceenabled {
diff --git a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
index b473038c..312ae6ac 100644
--- a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
+++ b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
@@ -4,11 +4,21 @@
 
 //go:build zos && s390x
 
+// Many of the following syscalls are not available on all versions of z/OS.
+// Some missing calls have legacy implementations/simulations but others
+// will be missing completely. To achieve consistent failing behaviour on
+// legacy systems, we first test the function pointer via a safeloading
+// mechanism to see if the function exists on a given system. Then execution
+// is branched to either continue the function call, or return an error.
+
 package unix
 
 import (
 	"bytes"
 	"fmt"
+	"os"
+	"reflect"
+	"regexp"
 	"runtime"
 	"sort"
 	"strings"
@@ -17,17 +27,205 @@ import (
 	"unsafe"
 )
 
+//go:noescape
+func initZosLibVec()
+
+//go:noescape
+func GetZosLibVec() uintptr
+
+func init() {
+	initZosLibVec()
+	r0, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS_____GETENV_A<<4, uintptr(unsafe.Pointer(&([]byte("__ZOS_XSYSTRACE\x00"))[0])))
+	if r0 != 0 {
+		n, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___ATOI_A<<4, r0)
+		ZosTraceLevel = int(n)
+		r0, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS_____GETENV_A<<4, uintptr(unsafe.Pointer(&([]byte("__ZOS_XSYSTRACEFD\x00"))[0])))
+		if r0 != 0 {
+			fd, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___ATOI_A<<4, r0)
+			f := os.NewFile(fd, "zostracefile")
+			if f != nil {
+				ZosTracefile = f
+			}
+		}
+
+	}
+}
+
+//go:noescape
+func CallLeFuncWithErr(funcdesc uintptr, parms ...uintptr) (ret, errno2 uintptr, err Errno)
+
+//go:noescape
+func CallLeFuncWithPtrReturn(funcdesc uintptr, parms ...uintptr) (ret, errno2 uintptr, err Errno)
+
+// -------------------------------
+// pointer validity test
+// good pointer returns 0
+// bad pointer returns 1
+//
+//go:nosplit
+func ptrtest(uintptr) uint64
+
+// Load memory at ptr location with error handling if the location is invalid
+//
+//go:noescape
+func safeload(ptr uintptr) (value uintptr, error uintptr)
+
 const (
-	O_CLOEXEC = 0       // Dummy value (not supported).
-	AF_LOCAL  = AF_UNIX // AF_LOCAL is an alias for AF_UNIX
+	entrypointLocationOffset = 8 // From function descriptor
+
+	xplinkEyecatcher   = 0x00c300c500c500f1 // ".C.E.E.1"
+	eyecatcherOffset   = 16                 // From function entrypoint (negative)
+	ppa1LocationOffset = 8                  // From function entrypoint (negative)
+
+	nameLenOffset = 0x14 // From PPA1 start
+	nameOffset    = 0x16 // From PPA1 start
 )
 
-func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
-func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
-func syscall_syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
-func syscall_rawsyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
-func syscall_syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
-func syscall_rawsyscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
+func getPpaOffset(funcptr uintptr) int64 {
+	entrypoint, err := safeload(funcptr + entrypointLocationOffset)
+	if err != 0 {
+		return -1
+	}
+
+	// XPLink functions have ".C.E.E.1" as the first 8 bytes (EBCDIC)
+	val, err := safeload(entrypoint - eyecatcherOffset)
+	if err != 0 {
+		return -1
+	}
+	if val != xplinkEyecatcher {
+		return -1
+	}
+
+	ppaoff, err := safeload(entrypoint - ppa1LocationOffset)
+	if err != 0 {
+		return -1
+	}
+
+	ppaoff >>= 32
+	return int64(ppaoff)
+}
+
+//-------------------------------
+// function descriptor pointer validity test
+// good pointer returns 0
+// bad pointer returns 1
+
+// TODO: currently mksyscall_zos_s390x.go generate empty string for funcName
+// have correct funcName pass to the funcptrtest function
+func funcptrtest(funcptr uintptr, funcName string) uint64 {
+	entrypoint, err := safeload(funcptr + entrypointLocationOffset)
+	if err != 0 {
+		return 1
+	}
+
+	ppaoff := getPpaOffset(funcptr)
+	if ppaoff == -1 {
+		return 1
+	}
+
+	// PPA1 offset value is from the start of the entire function block, not the entrypoint
+	ppa1 := (entrypoint - eyecatcherOffset) + uintptr(ppaoff)
+
+	nameLen, err := safeload(ppa1 + nameLenOffset)
+	if err != 0 {
+		return 1
+	}
+
+	nameLen >>= 48
+	if nameLen > 128 {
+		return 1
+	}
+
+	// no function name input to argument end here
+	if funcName == "" {
+		return 0
+	}
+
+	var funcname [128]byte
+	for i := 0; i < int(nameLen); i += 8 {
+		v, err := safeload(ppa1 + nameOffset + uintptr(i))
+		if err != 0 {
+			return 1
+		}
+		funcname[i] = byte(v >> 56)
+		funcname[i+1] = byte(v >> 48)
+		funcname[i+2] = byte(v >> 40)
+		funcname[i+3] = byte(v >> 32)
+		funcname[i+4] = byte(v >> 24)
+		funcname[i+5] = byte(v >> 16)
+		funcname[i+6] = byte(v >> 8)
+		funcname[i+7] = byte(v)
+	}
+
+	runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4, // __e2a_l
+		[]uintptr{uintptr(unsafe.Pointer(&funcname[0])), nameLen})
+
+	name := string(funcname[:nameLen])
+	if name != funcName {
+		return 1
+	}
+
+	return 0
+}
+
+// For detection of capabilities on a system.
+// Is function descriptor f a valid function?
+func isValidLeFunc(f uintptr) error {
+	ret := funcptrtest(f, "")
+	if ret != 0 {
+		return fmt.Errorf("Bad pointer, not an LE function ")
+	}
+	return nil
+}
+
+// Retrieve function name from descriptor
+func getLeFuncName(f uintptr) (string, error) {
+	// assume it has been checked, only check ppa1 validity here
+	entry := ((*[2]uintptr)(unsafe.Pointer(f)))[1]
+	preamp := ((*[4]uint32)(unsafe.Pointer(entry - eyecatcherOffset)))
+
+	offsetPpa1 := preamp[2]
+	if offsetPpa1 > 0x0ffff {
+		return "", fmt.Errorf("PPA1 offset seems too big 0x%x\n", offsetPpa1)
+	}
+
+	ppa1 := uintptr(unsafe.Pointer(preamp)) + uintptr(offsetPpa1)
+	res := ptrtest(ppa1)
+	if res != 0 {
+		return "", fmt.Errorf("PPA1 address not valid")
+	}
+
+	size := *(*uint16)(unsafe.Pointer(ppa1 + nameLenOffset))
+	if size > 128 {
+		return "", fmt.Errorf("Function name seems too long, length=%d\n", size)
+	}
+
+	var name [128]byte
+	funcname := (*[128]byte)(unsafe.Pointer(ppa1 + nameOffset))
+	copy(name[0:size], funcname[0:size])
+
+	runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4, // __e2a_l
+		[]uintptr{uintptr(unsafe.Pointer(&name[0])), uintptr(size)})
+
+	return string(name[:size]), nil
+}
+
+// Check z/OS version
+func zosLeVersion() (version, release uint32) {
+	p1 := (*(*uintptr)(unsafe.Pointer(uintptr(1208)))) >> 32
+	p1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 88)))
+	p1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 8)))
+	p1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 984)))
+	vrm := *(*uint32)(unsafe.Pointer(p1 + 80))
+	version = (vrm & 0x00ff0000) >> 16
+	release = (vrm & 0x0000ff00) >> 8
+	return
+}
+
+// returns a zos C FILE * for stdio fd 0, 1, 2
+func ZosStdioFilep(fd int32) uintptr {
+	return uintptr(*(*uint64)(unsafe.Pointer(uintptr(*(*uint64)(unsafe.Pointer(uintptr(*(*uint64)(unsafe.Pointer(uintptr(uint64(*(*uint32)(unsafe.Pointer(uintptr(1208)))) + 80))) + uint64((fd+2)<<3))))))))
+}
 
 func copyStat(stat *Stat_t, statLE *Stat_LE_t) {
 	stat.Dev = uint64(statLE.Dev)
@@ -65,6 +263,21 @@ func (d *Dirent) NameString() string {
 	}
 }
 
+func DecodeData(dest []byte, sz int, val uint64) {
+	for i := 0; i < sz; i++ {
+		dest[sz-1-i] = byte((val >> (uint64(i * 8))) & 0xff)
+	}
+}
+
+func EncodeData(data []byte) uint64 {
+	var value uint64
+	sz := len(data)
+	for i := 0; i < sz; i++ {
+		value |= uint64(data[i]) << uint64(((sz - i - 1) * 8))
+	}
+	return value
+}
+
 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
 	if sa.Port < 0 || sa.Port > 0xFFFF {
 		return nil, 0, EINVAL
@@ -74,7 +287,9 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
 	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
 	p[0] = byte(sa.Port >> 8)
 	p[1] = byte(sa.Port)
-	sa.raw.Addr = sa.Addr
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
 	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
 }
 
@@ -88,7 +303,9 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
 	p[0] = byte(sa.Port >> 8)
 	p[1] = byte(sa.Port)
 	sa.raw.Scope_id = sa.ZoneId
-	sa.raw.Addr = sa.Addr
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
 	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
 }
 
@@ -146,7 +363,9 @@ func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
 		sa := new(SockaddrInet4)
 		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
 		sa.Port = int(p[0])<<8 + int(p[1])
-		sa.Addr = pp.Addr
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
 		return sa, nil
 
 	case AF_INET6:
@@ -155,7 +374,9 @@ func anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {
 		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
 		sa.Port = int(p[0])<<8 + int(p[1])
 		sa.ZoneId = pp.Scope_id
-		sa.Addr = pp.Addr
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
 		return sa, nil
 	}
 	return nil, EAFNOSUPPORT
@@ -177,6 +398,43 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
 	return
 }
 
+func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	nfd, err = accept4(fd, &rsa, &len, flags)
+	if err != nil {
+		return
+	}
+	if len > SizeofSockaddrAny {
+		panic("RawSockaddrAny too small")
+	}
+	// TODO(neeilan): Remove 0 in call
+	sa, err = anyToSockaddr(0, &rsa)
+	if err != nil {
+		Close(nfd)
+		nfd = 0
+	}
+	return
+}
+
+func Ctermid() (tty string, err error) {
+	var termdev [1025]byte
+	runtime.EnterSyscall()
+	r0, err2, err1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___CTERMID_A<<4, uintptr(unsafe.Pointer(&termdev[0])))
+	runtime.ExitSyscall()
+	if r0 == 0 {
+		return "", fmt.Errorf("%s (errno2=0x%x)\n", err1.Error(), err2)
+	}
+	s := string(termdev[:])
+	idx := strings.Index(s, string(rune(0)))
+	if idx == -1 {
+		tty = s
+	} else {
+		tty = s[:idx]
+	}
+	return
+}
+
 func (iov *Iovec) SetLen(length int) {
 	iov.Len = uint64(length)
 }
@@ -190,10 +448,16 @@ func (cmsg *Cmsghdr) SetLen(length int) {
 }
 
 //sys   fcntl(fd int, cmd int, arg int) (val int, err error)
+//sys   Flistxattr(fd int, dest []byte) (sz int, err error) = SYS___FLISTXATTR_A
+//sys   Fremovexattr(fd int, attr string) (err error) = SYS___FREMOVEXATTR_A
 //sys	read(fd int, p []byte) (n int, err error)
 //sys	write(fd int, p []byte) (n int, err error)
 
+//sys   Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) = SYS___FGETXATTR_A
+//sys   Fsetxattr(fd int, attr string, data []byte, flag int) (err error) = SYS___FSETXATTR_A
+
 //sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = SYS___ACCEPT_A
+//sys	accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) = SYS___ACCEPT4_A
 //sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___BIND_A
 //sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___CONNECT_A
 //sysnb	getgroups(n int, list *_Gid_t) (nn int, err error)
@@ -204,6 +468,7 @@ func (cmsg *Cmsghdr) SetLen(length int) {
 //sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
 //sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETPEERNAME_A
 //sysnb	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETSOCKNAME_A
+//sys   Removexattr(path string, attr string) (err error) = SYS___REMOVEXATTR_A
 //sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = SYS___RECVFROM_A
 //sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = SYS___SENDTO_A
 //sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___RECVMSG_A
@@ -212,6 +477,10 @@ func (cmsg *Cmsghdr) SetLen(length int) {
 //sys   munmap(addr uintptr, length uintptr) (err error) = SYS_MUNMAP
 //sys   ioctl(fd int, req int, arg uintptr) (err error) = SYS_IOCTL
 //sys   ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) = SYS_IOCTL
+//sys	shmat(id int, addr uintptr, flag int) (ret uintptr, err error) = SYS_SHMAT
+//sys	shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) = SYS_SHMCTL64
+//sys	shmdt(addr uintptr) (err error) = SYS_SHMDT
+//sys	shmget(key int, size int, flag int) (id int, err error) = SYS_SHMGET
 
 //sys   Access(path string, mode uint32) (err error) = SYS___ACCESS_A
 //sys   Chdir(path string) (err error) = SYS___CHDIR_A
@@ -220,14 +489,31 @@ func (cmsg *Cmsghdr) SetLen(length int) {
 //sys   Creat(path string, mode uint32) (fd int, err error) = SYS___CREAT_A
 //sys	Dup(oldfd int) (fd int, err error)
 //sys	Dup2(oldfd int, newfd int) (err error)
+//sys	Dup3(oldfd int, newfd int, flags int) (err error) = SYS_DUP3
+//sys	Dirfd(dirp uintptr) (fd int, err error) = SYS_DIRFD
+//sys	EpollCreate(size int) (fd int, err error) = SYS_EPOLL_CREATE
+//sys	EpollCreate1(flags int) (fd int, err error) = SYS_EPOLL_CREATE1
+//sys	EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) = SYS_EPOLL_CTL
+//sys	EpollPwait(epfd int, events []EpollEvent, msec int, sigmask *int) (n int, err error) = SYS_EPOLL_PWAIT
+//sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_WAIT
 //sys	Errno2() (er2 int) = SYS___ERRNO2
-//sys	Err2ad() (eadd *int) = SYS___ERR2AD
+//sys	Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD
 //sys	Exit(code int)
+//sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error) = SYS___FACCESSAT_A
+
+func Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	return Faccessat(dirfd, path, mode, flags)
+}
+
 //sys	Fchdir(fd int) (err error)
 //sys	Fchmod(fd int, mode uint32) (err error)
+//sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) = SYS___FCHMODAT_A
 //sys	Fchown(fd int, uid int, gid int) (err error)
+//sys	Fchownat(fd int, path string, uid int, gid int, flags int) (err error) = SYS___FCHOWNAT_A
 //sys	FcntlInt(fd uintptr, cmd int, arg int) (retval int, err error) = SYS_FCNTL
+//sys	Fdatasync(fd int) (err error) = SYS_FDATASYNC
 //sys	fstat(fd int, stat *Stat_LE_t) (err error)
+//sys	fstatat(dirfd int, path string, stat *Stat_LE_t, flags int) (err error) = SYS___FSTATAT_A
 
 func Fstat(fd int, stat *Stat_t) (err error) {
 	var statLE Stat_LE_t
@@ -236,28 +522,208 @@ func Fstat(fd int, stat *Stat_t) (err error) {
 	return
 }
 
+func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
+	var statLE Stat_LE_t
+	err = fstatat(dirfd, path, &statLE, flags)
+	copyStat(stat, &statLE)
+	return
+}
+
+func impl_Getxattr(path string, attr string, dest []byte) (sz int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	var _p2 unsafe.Pointer
+	if len(dest) > 0 {
+		_p2 = unsafe.Pointer(&dest[0])
+	} else {
+		_p2 = unsafe.Pointer(&_zero)
+	}
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___GETXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)))
+	sz = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_GetxattrAddr() *(func(path string, attr string, dest []byte) (sz int, err error))
+
+var Getxattr = enter_Getxattr
+
+func enter_Getxattr(path string, attr string, dest []byte) (sz int, err error) {
+	funcref := get_GetxattrAddr()
+	if validGetxattr() {
+		*funcref = impl_Getxattr
+	} else {
+		*funcref = error_Getxattr
+	}
+	return (*funcref)(path, attr, dest)
+}
+
+func error_Getxattr(path string, attr string, dest []byte) (sz int, err error) {
+	return -1, ENOSYS
+}
+
+func validGetxattr() bool {
+	if funcptrtest(GetZosLibVec()+SYS___GETXATTR_A<<4, "") == 0 {
+		if name, err := getLeFuncName(GetZosLibVec() + SYS___GETXATTR_A<<4); err == nil {
+			return name == "__getxattr_a"
+		}
+	}
+	return false
+}
+
+//sys   Lgetxattr(link string, attr string, dest []byte) (sz int, err error) = SYS___LGETXATTR_A
+//sys   Lsetxattr(path string, attr string, data []byte, flags int) (err error) = SYS___LSETXATTR_A
+
+func impl_Setxattr(path string, attr string, data []byte, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	var _p2 unsafe.Pointer
+	if len(data) > 0 {
+		_p2 = unsafe.Pointer(&data[0])
+	} else {
+		_p2 = unsafe.Pointer(&_zero)
+	}
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___SETXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_SetxattrAddr() *(func(path string, attr string, data []byte, flags int) (err error))
+
+var Setxattr = enter_Setxattr
+
+func enter_Setxattr(path string, attr string, data []byte, flags int) (err error) {
+	funcref := get_SetxattrAddr()
+	if validSetxattr() {
+		*funcref = impl_Setxattr
+	} else {
+		*funcref = error_Setxattr
+	}
+	return (*funcref)(path, attr, data, flags)
+}
+
+func error_Setxattr(path string, attr string, data []byte, flags int) (err error) {
+	return ENOSYS
+}
+
+func validSetxattr() bool {
+	if funcptrtest(GetZosLibVec()+SYS___SETXATTR_A<<4, "") == 0 {
+		if name, err := getLeFuncName(GetZosLibVec() + SYS___SETXATTR_A<<4); err == nil {
+			return name == "__setxattr_a"
+		}
+	}
+	return false
+}
+
+//sys	Fstatfs(fd int, buf *Statfs_t) (err error) = SYS_FSTATFS
 //sys	Fstatvfs(fd int, stat *Statvfs_t) (err error) = SYS_FSTATVFS
 //sys	Fsync(fd int) (err error)
+//sys	Futimes(fd int, tv []Timeval) (err error) = SYS_FUTIMES
+//sys	Futimesat(dirfd int, path string, tv []Timeval) (err error) = SYS___FUTIMESAT_A
 //sys	Ftruncate(fd int, length int64) (err error)
-//sys   Getpagesize() (pgsize int) = SYS_GETPAGESIZE
+//sys	Getrandom(buf []byte, flags int) (n int, err error) = SYS_GETRANDOM
+//sys	InotifyInit() (fd int, err error) = SYS_INOTIFY_INIT
+//sys	InotifyInit1(flags int) (fd int, err error) = SYS_INOTIFY_INIT1
+//sys	InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) = SYS___INOTIFY_ADD_WATCH_A
+//sys	InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) = SYS_INOTIFY_RM_WATCH
+//sys   Listxattr(path string, dest []byte) (sz int, err error) = SYS___LISTXATTR_A
+//sys   Llistxattr(path string, dest []byte) (sz int, err error) = SYS___LLISTXATTR_A
+//sys   Lremovexattr(path string, attr string) (err error) = SYS___LREMOVEXATTR_A
+//sys	Lutimes(path string, tv []Timeval) (err error) = SYS___LUTIMES_A
 //sys   Mprotect(b []byte, prot int) (err error) = SYS_MPROTECT
 //sys   Msync(b []byte, flags int) (err error) = SYS_MSYNC
+//sys   Console2(cmsg *ConsMsg2, modstr *byte, concmd *uint32) (err error) = SYS___CONSOLE2
+
+// Pipe2 begin
+
+//go:nosplit
+func getPipe2Addr() *(func([]int, int) error)
+
+var Pipe2 = pipe2Enter
+
+func pipe2Enter(p []int, flags int) (err error) {
+	if funcptrtest(GetZosLibVec()+SYS_PIPE2<<4, "") == 0 {
+		*getPipe2Addr() = pipe2Impl
+	} else {
+		*getPipe2Addr() = pipe2Error
+	}
+	return (*getPipe2Addr())(p, flags)
+}
+
+func pipe2Impl(p []int, flags int) (err error) {
+	var pp [2]_C_int
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_PIPE2<<4, uintptr(unsafe.Pointer(&pp[0])), uintptr(flags))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	} else {
+		p[0] = int(pp[0])
+		p[1] = int(pp[1])
+	}
+	return
+}
+func pipe2Error(p []int, flags int) (err error) {
+	return fmt.Errorf("Pipe2 is not available on this system")
+}
+
+// Pipe2 end
+
 //sys   Poll(fds []PollFd, timeout int) (n int, err error) = SYS_POLL
+
+func Readdir(dir uintptr) (dirent *Dirent, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___READDIR_A<<4, uintptr(dir))
+	runtime.ExitSyscall()
+	dirent = (*Dirent)(unsafe.Pointer(r0))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//sys	Readdir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) = SYS___READDIR_R_A
+//sys	Statfs(path string, buf *Statfs_t) (err error) = SYS___STATFS_A
+//sys	Syncfs(fd int) (err error) = SYS_SYNCFS
 //sys   Times(tms *Tms) (ticks uintptr, err error) = SYS_TIMES
 //sys   W_Getmntent(buff *byte, size int) (lastsys int, err error) = SYS_W_GETMNTENT
 //sys   W_Getmntent_A(buff *byte, size int) (lastsys int, err error) = SYS___W_GETMNTENT_A
 
 //sys   mount_LE(path string, filesystem string, fstype string, mtm uint32, parmlen int32, parm string) (err error) = SYS___MOUNT_A
-//sys   unmount(filesystem string, mtm int) (err error) = SYS___UMOUNT_A
+//sys   unmount_LE(filesystem string, mtm int) (err error) = SYS___UMOUNT_A
 //sys   Chroot(path string) (err error) = SYS___CHROOT_A
 //sys   Select(nmsgsfds int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (ret int, err error) = SYS_SELECT
-//sysnb Uname(buf *Utsname) (err error) = SYS___UNAME_A
+//sysnb Uname(buf *Utsname) (err error) = SYS_____OSNAME_A
+//sys   Unshare(flags int) (err error) = SYS_UNSHARE
 
 func Ptsname(fd int) (name string, err error) {
-	r0, _, e1 := syscall_syscall(SYS___PTSNAME_A, uintptr(fd), 0, 0)
-	name = u2s(unsafe.Pointer(r0))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___PTSNAME_A<<4, uintptr(fd))
+	runtime.ExitSyscall()
+	if r0 == 0 {
+		err = errnoErr2(e1, e2)
+	} else {
+		name = u2s(unsafe.Pointer(r0))
 	}
 	return
 }
@@ -272,13 +738,19 @@ func u2s(cstr unsafe.Pointer) string {
 }
 
 func Close(fd int) (err error) {
-	_, _, e1 := syscall_syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSE<<4, uintptr(fd))
+	runtime.ExitSyscall()
 	for i := 0; e1 == EAGAIN && i < 10; i++ {
-		_, _, _ = syscall_syscall(SYS_USLEEP, uintptr(10), 0, 0)
-		_, _, e1 = syscall_syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+		runtime.EnterSyscall()
+		CallLeFuncWithErr(GetZosLibVec()+SYS_USLEEP<<4, uintptr(10))
+		runtime.ExitSyscall()
+		runtime.EnterSyscall()
+		r0, e2, e1 = CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSE<<4, uintptr(fd))
+		runtime.ExitSyscall()
 	}
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if r0 != 0 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -288,9 +760,15 @@ func Madvise(b []byte, advice int) (err error) {
 	return
 }
 
+func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
+	return mapper.Mmap(fd, offset, length, prot, flags)
+}
+
+func Munmap(b []byte) (err error) {
+	return mapper.Munmap(b)
+}
+
 //sys   Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A
-//sysnb	Getegid() (egid int)
-//sysnb	Geteuid() (uid int)
 //sysnb	Getgid() (gid int)
 //sysnb	Getpid() (pid int)
 //sysnb	Getpgid(pid int) (pgid int, err error) = SYS_GETPGID
@@ -317,11 +795,14 @@ func Getrusage(who int, rusage *Rusage) (err error) {
 	return
 }
 
+//sys	Getegid() (egid int) = SYS_GETEGID
+//sys	Geteuid() (euid int) = SYS_GETEUID
 //sysnb Getsid(pid int) (sid int, err error) = SYS_GETSID
 //sysnb	Getuid() (uid int)
 //sysnb	Kill(pid int, sig Signal) (err error)
 //sys	Lchown(path string, uid int, gid int) (err error) = SYS___LCHOWN_A
 //sys	Link(path string, link string) (err error) = SYS___LINK_A
+//sys	Linkat(oldDirFd int, oldPath string, newDirFd int, newPath string, flags int) (err error) = SYS___LINKAT_A
 //sys	Listen(s int, n int) (err error)
 //sys	lstat(path string, stat *Stat_LE_t) (err error) = SYS___LSTAT_A
 
@@ -332,15 +813,150 @@ func Lstat(path string, stat *Stat_t) (err error) {
 	return
 }
 
+// for checking symlinks begins with $VERSION/ $SYSNAME/ $SYSSYMR/ $SYSSYMA/
+func isSpecialPath(path []byte) (v bool) {
+	var special = [4][8]byte{
+		[8]byte{'V', 'E', 'R', 'S', 'I', 'O', 'N', '/'},
+		[8]byte{'S', 'Y', 'S', 'N', 'A', 'M', 'E', '/'},
+		[8]byte{'S', 'Y', 'S', 'S', 'Y', 'M', 'R', '/'},
+		[8]byte{'S', 'Y', 'S', 'S', 'Y', 'M', 'A', '/'}}
+
+	var i, j int
+	for i = 0; i < len(special); i++ {
+		for j = 0; j < len(special[i]); j++ {
+			if path[j] != special[i][j] {
+				break
+			}
+		}
+		if j == len(special[i]) {
+			return true
+		}
+	}
+	return false
+}
+
+func realpath(srcpath string, abspath []byte) (pathlen int, errno int) {
+	var source [1024]byte
+	copy(source[:], srcpath)
+	source[len(srcpath)] = 0
+	ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___REALPATH_A<<4, //__realpath_a()
+		[]uintptr{uintptr(unsafe.Pointer(&source[0])),
+			uintptr(unsafe.Pointer(&abspath[0]))})
+	if ret != 0 {
+		index := bytes.IndexByte(abspath[:], byte(0))
+		if index != -1 {
+			return index, 0
+		}
+	} else {
+		errptr := (*int)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{}))) //__errno()
+		return 0, *errptr
+	}
+	return 0, 245 // EBADDATA   245
+}
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	n = int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___READLINK_A<<4,
+		[]uintptr{uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))}))
+	runtime.KeepAlive(unsafe.Pointer(_p0))
+	if n == -1 {
+		value := *(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{})))
+		err = errnoErr(Errno(value))
+	} else {
+		if buf[0] == '$' {
+			if isSpecialPath(buf[1:9]) {
+				cnt, err1 := realpath(path, buf)
+				if err1 == 0 {
+					n = cnt
+				}
+			}
+		}
+	}
+	return
+}
+
+func impl_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___READLINKAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	runtime.ExitSyscall()
+	n = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+		return n, err
+	} else {
+		if buf[0] == '$' {
+			if isSpecialPath(buf[1:9]) {
+				cnt, err1 := realpath(path, buf)
+				if err1 == 0 {
+					n = cnt
+				}
+			}
+		}
+	}
+	return
+}
+
+//go:nosplit
+func get_ReadlinkatAddr() *(func(dirfd int, path string, buf []byte) (n int, err error))
+
+var Readlinkat = enter_Readlinkat
+
+func enter_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+	funcref := get_ReadlinkatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___READLINKAT_A<<4, "") == 0 {
+		*funcref = impl_Readlinkat
+	} else {
+		*funcref = error_Readlinkat
+	}
+	return (*funcref)(dirfd, path, buf)
+}
+
+func error_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+	n = -1
+	err = ENOSYS
+	return
+}
+
 //sys	Mkdir(path string, mode uint32) (err error) = SYS___MKDIR_A
+//sys	Mkdirat(dirfd int, path string, mode uint32) (err error) = SYS___MKDIRAT_A
 //sys   Mkfifo(path string, mode uint32) (err error) = SYS___MKFIFO_A
 //sys	Mknod(path string, mode uint32, dev int) (err error) = SYS___MKNOD_A
+//sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error) = SYS___MKNODAT_A
+//sys	PivotRoot(newroot string, oldroot string) (err error) = SYS___PIVOT_ROOT_A
 //sys	Pread(fd int, p []byte, offset int64) (n int, err error)
 //sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
-//sys	Readlink(path string, buf []byte) (n int, err error) = SYS___READLINK_A
+//sys	Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) = SYS___PRCTL_A
+//sysnb	Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT
 //sys	Rename(from string, to string) (err error) = SYS___RENAME_A
+//sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) = SYS___RENAMEAT_A
+//sys	Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) = SYS___RENAMEAT2_A
 //sys	Rmdir(path string) (err error) = SYS___RMDIR_A
 //sys   Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
+//sys	Setegid(egid int) (err error) = SYS_SETEGID
+//sys	Seteuid(euid int) (err error) = SYS_SETEUID
+//sys	Sethostname(p []byte) (err error) = SYS___SETHOSTNAME_A
+//sys   Setns(fd int, nstype int) (err error) = SYS_SETNS
 //sys	Setpriority(which int, who int, prio int) (err error)
 //sysnb	Setpgid(pid int, pgid int) (err error) = SYS_SETPGID
 //sysnb	Setrlimit(resource int, lim *Rlimit) (err error)
@@ -360,32 +976,57 @@ func Stat(path string, sta *Stat_t) (err error) {
 }
 
 //sys	Symlink(path string, link string) (err error) = SYS___SYMLINK_A
+//sys	Symlinkat(oldPath string, dirfd int, newPath string) (err error) = SYS___SYMLINKAT_A
 //sys	Sync() = SYS_SYNC
 //sys	Truncate(path string, length int64) (err error) = SYS___TRUNCATE_A
 //sys	Tcgetattr(fildes int, termptr *Termios) (err error) = SYS_TCGETATTR
 //sys	Tcsetattr(fildes int, when int, termptr *Termios) (err error) = SYS_TCSETATTR
 //sys	Umask(mask int) (oldmask int)
 //sys	Unlink(path string) (err error) = SYS___UNLINK_A
+//sys	Unlinkat(dirfd int, path string, flags int) (err error) = SYS___UNLINKAT_A
 //sys	Utime(path string, utim *Utimbuf) (err error) = SYS___UTIME_A
 
 //sys	open(path string, mode int, perm uint32) (fd int, err error) = SYS___OPEN_A
 
 func Open(path string, mode int, perm uint32) (fd int, err error) {
+	if mode&O_ACCMODE == 0 {
+		mode |= O_RDONLY
+	}
 	return open(path, mode, perm)
 }
 
-func Mkfifoat(dirfd int, path string, mode uint32) (err error) {
-	wd, err := Getwd()
-	if err != nil {
-		return err
+//sys	openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) = SYS___OPENAT_A
+
+func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
+	if flags&O_ACCMODE == 0 {
+		flags |= O_RDONLY
 	}
+	return openat(dirfd, path, flags, mode)
+}
 
-	if err := Fchdir(dirfd); err != nil {
-		return err
+//sys	openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) = SYS___OPENAT2_A
+
+func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {
+	if how.Flags&O_ACCMODE == 0 {
+		how.Flags |= O_RDONLY
 	}
-	defer Chdir(wd)
+	return openat2(dirfd, path, how, SizeofOpenHow)
+}
 
-	return Mkfifo(path, mode)
+func ZosFdToPath(dirfd int) (path string, err error) {
+	var buffer [1024]byte
+	runtime.EnterSyscall()
+	ret, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_W_IOCTL<<4, uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0])))
+	runtime.ExitSyscall()
+	if ret == 0 {
+		zb := bytes.IndexByte(buffer[:], 0)
+		if zb == -1 {
+			zb = len(buffer)
+		}
+		CallLeFuncWithErr(GetZosLibVec()+SYS___E2A_L<<4, uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb))
+		return string(buffer[:zb]), nil
+	}
+	return "", errnoErr2(e1, e2)
 }
 
 //sys	remove(path string) (err error)
@@ -403,10 +1044,12 @@ func Getcwd(buf []byte) (n int, err error) {
 	} else {
 		p = unsafe.Pointer(&_zero)
 	}
-	_, _, e := syscall_syscall(SYS___GETCWD_A, uintptr(p), uintptr(len(buf)), 0)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___GETCWD_A<<4, uintptr(p), uintptr(len(buf)))
+	runtime.ExitSyscall()
 	n = clen(buf) + 1
-	if e != 0 {
-		err = errnoErr(e)
+	if r0 == 0 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -520,9 +1163,41 @@ func (w WaitStatus) StopSignal() Signal {
 
 func (w WaitStatus) TrapCause() int { return -1 }
 
+//sys	waitid(idType int, id int, info *Siginfo, options int) (err error)
+
+func Waitid(idType int, id int, info *Siginfo, options int, rusage *Rusage) (err error) {
+	return waitid(idType, id, info, options)
+}
+
 //sys	waitpid(pid int, wstatus *_C_int, options int) (wpid int, err error)
 
-func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
+func impl_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_WAIT4<<4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)))
+	runtime.ExitSyscall()
+	wpid = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_Wait4Addr() *(func(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error))
+
+var Wait4 = enter_Wait4
+
+func enter_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
+	funcref := get_Wait4Addr()
+	if funcptrtest(GetZosLibVec()+SYS_WAIT4<<4, "") == 0 {
+		*funcref = impl_Wait4
+	} else {
+		*funcref = legacyWait4
+	}
+	return (*funcref)(pid, wstatus, options, rusage)
+}
+
+func legacyWait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
 	// TODO(mundaym): z/OS doesn't have wait4. I don't think getrusage does what we want.
 	// At the moment rusage will not be touched.
 	var status _C_int
@@ -571,23 +1246,62 @@ func Pipe(p []int) (err error) {
 	}
 	var pp [2]_C_int
 	err = pipe(&pp)
-	if err == nil {
-		p[0] = int(pp[0])
-		p[1] = int(pp[1])
-	}
+	p[0] = int(pp[0])
+	p[1] = int(pp[1])
 	return
 }
 
 //sys	utimes(path string, timeval *[2]Timeval) (err error) = SYS___UTIMES_A
 
 func Utimes(path string, tv []Timeval) (err error) {
+	if tv == nil {
+		return utimes(path, nil)
+	}
 	if len(tv) != 2 {
 		return EINVAL
 	}
 	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
 }
 
-func UtimesNano(path string, ts []Timespec) error {
+//sys	utimensat(dirfd int, path string, ts *[2]Timespec, flags int) (err error) = SYS___UTIMENSAT_A
+
+func validUtimensat() bool {
+	if funcptrtest(GetZosLibVec()+SYS___UTIMENSAT_A<<4, "") == 0 {
+		if name, err := getLeFuncName(GetZosLibVec() + SYS___UTIMENSAT_A<<4); err == nil {
+			return name == "__utimensat_a"
+		}
+	}
+	return false
+}
+
+// Begin UtimesNano
+
+//go:nosplit
+func get_UtimesNanoAddr() *(func(path string, ts []Timespec) (err error))
+
+var UtimesNano = enter_UtimesNano
+
+func enter_UtimesNano(path string, ts []Timespec) (err error) {
+	funcref := get_UtimesNanoAddr()
+	if validUtimensat() {
+		*funcref = utimesNanoImpl
+	} else {
+		*funcref = legacyUtimesNano
+	}
+	return (*funcref)(path, ts)
+}
+
+func utimesNanoImpl(path string, ts []Timespec) (err error) {
+	if ts == nil {
+		return utimensat(AT_FDCWD, path, nil, 0)
+	}
+	if len(ts) != 2 {
+		return EINVAL
+	}
+	return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
+}
+
+func legacyUtimesNano(path string, ts []Timespec) (err error) {
 	if len(ts) != 2 {
 		return EINVAL
 	}
@@ -600,6 +1314,70 @@ func UtimesNano(path string, ts []Timespec) error {
 	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
 }
 
+// End UtimesNano
+
+// Begin UtimesNanoAt
+
+//go:nosplit
+func get_UtimesNanoAtAddr() *(func(dirfd int, path string, ts []Timespec, flags int) (err error))
+
+var UtimesNanoAt = enter_UtimesNanoAt
+
+func enter_UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {
+	funcref := get_UtimesNanoAtAddr()
+	if validUtimensat() {
+		*funcref = utimesNanoAtImpl
+	} else {
+		*funcref = legacyUtimesNanoAt
+	}
+	return (*funcref)(dirfd, path, ts, flags)
+}
+
+func utimesNanoAtImpl(dirfd int, path string, ts []Timespec, flags int) (err error) {
+	if ts == nil {
+		return utimensat(dirfd, path, nil, flags)
+	}
+	if len(ts) != 2 {
+		return EINVAL
+	}
+	return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
+}
+
+func legacyUtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {
+	if path[0] != '/' {
+		dirPath, err := ZosFdToPath(dirfd)
+		if err != nil {
+			return err
+		}
+		path = dirPath + "/" + path
+	}
+	if flags == AT_SYMLINK_NOFOLLOW {
+		if len(ts) != 2 {
+			return EINVAL
+		}
+
+		if ts[0].Nsec >= 5e8 {
+			ts[0].Sec++
+		}
+		ts[0].Nsec = 0
+		if ts[1].Nsec >= 5e8 {
+			ts[1].Sec++
+		}
+		ts[1].Nsec = 0
+
+		// Not as efficient as it could be because Timespec and
+		// Timeval have different types in the different OSes
+		tv := []Timeval{
+			NsecToTimeval(TimespecToNsec(ts[0])),
+			NsecToTimeval(TimespecToNsec(ts[1])),
+		}
+		return Lutimes(path, tv)
+	}
+	return UtimesNano(path, ts)
+}
+
+// End UtimesNanoAt
+
 func Getsockname(fd int) (sa Sockaddr, err error) {
 	var rsa RawSockaddrAny
 	var len _Socklen = SizeofSockaddrAny
@@ -1186,67 +1964,46 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error)
 	return n, nil
 }
 
-func Opendir(name string) (uintptr, error) {
-	p, err := BytePtrFromString(name)
-	if err != nil {
-		return 0, err
-	}
-	dir, _, e := syscall_syscall(SYS___OPENDIR_A, uintptr(unsafe.Pointer(p)), 0, 0)
-	runtime.KeepAlive(unsafe.Pointer(p))
-	if e != 0 {
-		err = errnoErr(e)
-	}
-	return dir, err
-}
-
-// clearsyscall.Errno resets the errno value to 0.
-func clearErrno()
-
-func Readdir(dir uintptr) (*Dirent, error) {
-	var ent Dirent
-	var res uintptr
-	// __readdir_r_a returns errno at the end of the directory stream, rather than 0.
-	// Therefore to avoid false positives we clear errno before calling it.
-
-	// TODO(neeilan): Commented this out to get sys/unix compiling on z/OS. Uncomment and fix. Error: "undefined: clearsyscall"
-	//clearsyscall.Errno() // TODO(mundaym): check pre-emption rules.
-
-	e, _, _ := syscall_syscall(SYS___READDIR_R_A, dir, uintptr(unsafe.Pointer(&ent)), uintptr(unsafe.Pointer(&res)))
-	var err error
-	if e != 0 {
-		err = errnoErr(Errno(e))
-	}
-	if res == 0 {
-		return nil, err
-	}
-	return &ent, err
-}
-
-func readdir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) {
-	r0, _, e1 := syscall_syscall(SYS___READDIR_R_A, dirp, uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
-	if int64(r0) == -1 {
-		err = errnoErr(Errno(e1))
+func Opendir(name string) (uintptr, error) {
+	p, err := BytePtrFromString(name)
+	if err != nil {
+		return 0, err
 	}
-	return
+	err = nil
+	runtime.EnterSyscall()
+	dir, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___OPENDIR_A<<4, uintptr(unsafe.Pointer(p)))
+	runtime.ExitSyscall()
+	runtime.KeepAlive(unsafe.Pointer(p))
+	if dir == 0 {
+		err = errnoErr2(e1, e2)
+	}
+	return dir, err
 }
 
+// clearsyscall.Errno resets the errno value to 0.
+func clearErrno()
+
 func Closedir(dir uintptr) error {
-	_, _, e := syscall_syscall(SYS_CLOSEDIR, dir, 0, 0)
-	if e != 0 {
-		return errnoErr(e)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSEDIR<<4, dir)
+	runtime.ExitSyscall()
+	if r0 != 0 {
+		return errnoErr2(e1, e2)
 	}
 	return nil
 }
 
 func Seekdir(dir uintptr, pos int) {
-	_, _, _ = syscall_syscall(SYS_SEEKDIR, dir, uintptr(pos), 0)
+	runtime.EnterSyscall()
+	CallLeFuncWithErr(GetZosLibVec()+SYS_SEEKDIR<<4, dir, uintptr(pos))
+	runtime.ExitSyscall()
 }
 
 func Telldir(dir uintptr) (int, error) {
-	p, _, e := syscall_syscall(SYS_TELLDIR, dir, 0, 0)
+	p, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_TELLDIR<<4, dir)
 	pos := int(p)
-	if pos == -1 {
-		return pos, errnoErr(e)
+	if int64(p) == -1 {
+		return pos, errnoErr2(e1, e2)
 	}
 	return pos, nil
 }
@@ -1261,19 +2018,55 @@ func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
 	*(*int64)(unsafe.Pointer(&flock[4])) = lk.Start
 	*(*int64)(unsafe.Pointer(&flock[12])) = lk.Len
 	*(*int32)(unsafe.Pointer(&flock[20])) = lk.Pid
-	_, _, errno := syscall_syscall(SYS_FCNTL, fd, uintptr(cmd), uintptr(unsafe.Pointer(&flock)))
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, fd, uintptr(cmd), uintptr(unsafe.Pointer(&flock)))
+	runtime.ExitSyscall()
 	lk.Type = *(*int16)(unsafe.Pointer(&flock[0]))
 	lk.Whence = *(*int16)(unsafe.Pointer(&flock[2]))
 	lk.Start = *(*int64)(unsafe.Pointer(&flock[4]))
 	lk.Len = *(*int64)(unsafe.Pointer(&flock[12]))
 	lk.Pid = *(*int32)(unsafe.Pointer(&flock[20]))
-	if errno == 0 {
+	if r0 == 0 {
 		return nil
 	}
-	return errno
+	return errnoErr2(e1, e2)
+}
+
+func impl_Flock(fd int, how int) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FLOCK<<4, uintptr(fd), uintptr(how))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_FlockAddr() *(func(fd int, how int) (err error))
+
+var Flock = enter_Flock
+
+func validFlock(fp uintptr) bool {
+	if funcptrtest(GetZosLibVec()+SYS_FLOCK<<4, "") == 0 {
+		if name, err := getLeFuncName(GetZosLibVec() + SYS_FLOCK<<4); err == nil {
+			return name == "flock"
+		}
+	}
+	return false
+}
+
+func enter_Flock(fd int, how int) (err error) {
+	funcref := get_FlockAddr()
+	if validFlock(GetZosLibVec() + SYS_FLOCK<<4) {
+		*funcref = impl_Flock
+	} else {
+		*funcref = legacyFlock
+	}
+	return (*funcref)(fd, how)
 }
 
-func Flock(fd int, how int) error {
+func legacyFlock(fd int, how int) error {
 
 	var flock_type int16
 	var fcntl_cmd int
@@ -1307,41 +2100,51 @@ func Flock(fd int, how int) error {
 }
 
 func Mlock(b []byte) (err error) {
-	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
+	runtime.ExitSyscall()
+	if r0 != 0 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
 func Mlock2(b []byte, flags int) (err error) {
-	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
+	runtime.ExitSyscall()
+	if r0 != 0 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
 func Mlockall(flags int) (err error) {
-	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_NONSWAP, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)
+	runtime.ExitSyscall()
+	if r0 != 0 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
 func Munlock(b []byte) (err error) {
-	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_SWAP, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)
+	runtime.ExitSyscall()
+	if r0 != 0 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
 func Munlockall() (err error) {
-	_, _, e1 := syscall_syscall(SYS___MLOCKALL, _BPX_SWAP, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)
+	runtime.ExitSyscall()
+	if r0 != 0 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1372,15 +2175,104 @@ func ClockGettime(clockid int32, ts *Timespec) error {
 	return nil
 }
 
-func Statfs(path string, stat *Statfs_t) (err error) {
-	fd, err := open(path, O_RDONLY, 0)
-	defer Close(fd)
-	if err != nil {
-		return err
+// Chtag
+
+//go:nosplit
+func get_ChtagAddr() *(func(path string, ccsid uint64, textbit uint64) error)
+
+var Chtag = enter_Chtag
+
+func enter_Chtag(path string, ccsid uint64, textbit uint64) error {
+	funcref := get_ChtagAddr()
+	if validSetxattr() {
+		*funcref = impl_Chtag
+	} else {
+		*funcref = legacy_Chtag
+	}
+	return (*funcref)(path, ccsid, textbit)
+}
+
+func legacy_Chtag(path string, ccsid uint64, textbit uint64) error {
+	tag := ccsid<<16 | textbit<<15
+	var tag_buff [8]byte
+	DecodeData(tag_buff[:], 8, tag)
+	return Setxattr(path, "filetag", tag_buff[:], XATTR_REPLACE)
+}
+
+func impl_Chtag(path string, ccsid uint64, textbit uint64) error {
+	tag := ccsid<<16 | textbit<<15
+	var tag_buff [4]byte
+	DecodeData(tag_buff[:], 4, tag)
+	return Setxattr(path, "system.filetag", tag_buff[:], XATTR_REPLACE)
+}
+
+// End of Chtag
+
+// Nanosleep
+
+//go:nosplit
+func get_NanosleepAddr() *(func(time *Timespec, leftover *Timespec) error)
+
+var Nanosleep = enter_Nanosleep
+
+func enter_Nanosleep(time *Timespec, leftover *Timespec) error {
+	funcref := get_NanosleepAddr()
+	if funcptrtest(GetZosLibVec()+SYS_NANOSLEEP<<4, "") == 0 {
+		*funcref = impl_Nanosleep
+	} else {
+		*funcref = legacyNanosleep
+	}
+	return (*funcref)(time, leftover)
+}
+
+func impl_Nanosleep(time *Timespec, leftover *Timespec) error {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_NANOSLEEP<<4, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		return errnoErr2(e1, e2)
+	}
+	return nil
+}
+
+func legacyNanosleep(time *Timespec, leftover *Timespec) error {
+	t0 := runtime.Nanotime1()
+	var secrem uint32
+	var nsecrem uint32
+	total := time.Sec*1000000000 + time.Nsec
+	elapsed := runtime.Nanotime1() - t0
+	var rv int32
+	var rc int32
+	var err error
+	// repeatedly sleep for 1 second until less than 1 second left
+	for total-elapsed > 1000000000 {
+		rv, rc, _ = BpxCondTimedWait(uint32(1), uint32(0), uint32(CW_CONDVAR), &secrem, &nsecrem)
+		if rv != 0 && rc != 112 { // 112 is EAGAIN
+			if leftover != nil && rc == 120 { // 120 is EINTR
+				leftover.Sec = int64(secrem)
+				leftover.Nsec = int64(nsecrem)
+			}
+			err = Errno(rc)
+			return err
+		}
+		elapsed = runtime.Nanotime1() - t0
 	}
-	return Fstatfs(fd, stat)
+	// sleep the remainder
+	if total > elapsed {
+		rv, rc, _ = BpxCondTimedWait(uint32(0), uint32(total-elapsed), uint32(CW_CONDVAR), &secrem, &nsecrem)
+	}
+	if leftover != nil && rc == 120 {
+		leftover.Sec = int64(secrem)
+		leftover.Nsec = int64(nsecrem)
+	}
+	if rv != 0 && rc != 112 {
+		err = Errno(rc)
+	}
+	return err
 }
 
+// End of Nanosleep
+
 var (
 	Stdin  = 0
 	Stdout = 1
@@ -1395,6 +2287,9 @@ var (
 	errENOENT error = syscall.ENOENT
 )
 
+var ZosTraceLevel int
+var ZosTracefile *os.File
+
 var (
 	signalNameMapOnce sync.Once
 	signalNameMap     map[string]syscall.Signal
@@ -1416,6 +2311,56 @@ func errnoErr(e Errno) error {
 	return e
 }
 
+var reg *regexp.Regexp
+
+// enhanced with zos specific errno2
+func errnoErr2(e Errno, e2 uintptr) error {
+	switch e {
+	case 0:
+		return nil
+	case EAGAIN:
+		return errEAGAIN
+		/*
+			Allow the retrieval of errno2 for EINVAL and ENOENT on zos
+				case EINVAL:
+					return errEINVAL
+				case ENOENT:
+					return errENOENT
+		*/
+	}
+	if ZosTraceLevel > 0 {
+		var name string
+		if reg == nil {
+			reg = regexp.MustCompile("(^unix\\.[^/]+$|.*\\/unix\\.[^/]+$)")
+		}
+		i := 1
+		pc, file, line, ok := runtime.Caller(i)
+		if ok {
+			name = runtime.FuncForPC(pc).Name()
+		}
+		for ok && reg.MatchString(runtime.FuncForPC(pc).Name()) {
+			i += 1
+			pc, file, line, ok = runtime.Caller(i)
+		}
+		if ok {
+			if ZosTracefile == nil {
+				ZosConsolePrintf("From %s:%d\n", file, line)
+				ZosConsolePrintf("%s: %s (errno2=0x%x)\n", name, e.Error(), e2)
+			} else {
+				fmt.Fprintf(ZosTracefile, "From %s:%d\n", file, line)
+				fmt.Fprintf(ZosTracefile, "%s: %s (errno2=0x%x)\n", name, e.Error(), e2)
+			}
+		} else {
+			if ZosTracefile == nil {
+				ZosConsolePrintf("%s (errno2=0x%x)\n", e.Error(), e2)
+			} else {
+				fmt.Fprintf(ZosTracefile, "%s (errno2=0x%x)\n", e.Error(), e2)
+			}
+		}
+	}
+	return e
+}
+
 // ErrnoName returns the error name for error number e.
 func ErrnoName(e Errno) string {
 	i := sort.Search(len(errorList), func(i int) bool {
@@ -1474,6 +2419,9 @@ func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (d
 		return nil, EINVAL
 	}
 
+	// Set __MAP_64 by default
+	flags |= __MAP_64
+
 	// Map the requested memory.
 	addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
 	if errno != nil {
@@ -1778,83 +2726,170 @@ func Exec(argv0 string, argv []string, envv []string) error {
 	return syscall.Exec(argv0, argv, envv)
 }
 
-func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
+func Getag(path string) (ccsid uint16, flag uint16, err error) {
+	var val [8]byte
+	sz, err := Getxattr(path, "ccsid", val[:])
+	if err != nil {
+		return
+	}
+	ccsid = uint16(EncodeData(val[0:sz]))
+	sz, err = Getxattr(path, "flags", val[:])
+	if err != nil {
+		return
+	}
+	flag = uint16(EncodeData(val[0:sz]) >> 15)
+	return
+}
+
+// Mount begin
+func impl_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(source)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(target)
+	if err != nil {
+		return
+	}
+	var _p2 *byte
+	_p2, err = BytePtrFromString(fstype)
+	if err != nil {
+		return
+	}
+	var _p3 *byte
+	_p3, err = BytePtrFromString(data)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MOUNT1_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(_p3)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_MountAddr() *(func(source string, target string, fstype string, flags uintptr, data string) (err error))
+
+var Mount = enter_Mount
+
+func enter_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
+	funcref := get_MountAddr()
+	if validMount() {
+		*funcref = impl_Mount
+	} else {
+		*funcref = legacyMount
+	}
+	return (*funcref)(source, target, fstype, flags, data)
+}
+
+func legacyMount(source string, target string, fstype string, flags uintptr, data string) (err error) {
 	if needspace := 8 - len(fstype); needspace <= 0 {
-		fstype = fstype[:8]
+		fstype = fstype[0:8]
 	} else {
-		fstype += "        "[:needspace]
+		fstype += "        "[0:needspace]
 	}
 	return mount_LE(target, source, fstype, uint32(flags), int32(len(data)), data)
 }
 
-func Unmount(name string, mtm int) (err error) {
+func validMount() bool {
+	if funcptrtest(GetZosLibVec()+SYS___MOUNT1_A<<4, "") == 0 {
+		if name, err := getLeFuncName(GetZosLibVec() + SYS___MOUNT1_A<<4); err == nil {
+			return name == "__mount1_a"
+		}
+	}
+	return false
+}
+
+// Mount end
+
+// Unmount begin
+func impl_Unmount(target string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(target)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___UMOUNT2_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_UnmountAddr() *(func(target string, flags int) (err error))
+
+var Unmount = enter_Unmount
+
+func enter_Unmount(target string, flags int) (err error) {
+	funcref := get_UnmountAddr()
+	if funcptrtest(GetZosLibVec()+SYS___UMOUNT2_A<<4, "") == 0 {
+		*funcref = impl_Unmount
+	} else {
+		*funcref = legacyUnmount
+	}
+	return (*funcref)(target, flags)
+}
+
+func legacyUnmount(name string, mtm int) (err error) {
 	// mountpoint is always a full path and starts with a '/'
 	// check if input string is not a mountpoint but a filesystem name
 	if name[0] != '/' {
-		return unmount(name, mtm)
+		return unmount_LE(name, mtm)
 	}
 	// treat name as mountpoint
 	b2s := func(arr []byte) string {
-		nulli := bytes.IndexByte(arr, 0)
-		if nulli == -1 {
-			return string(arr)
-		} else {
-			return string(arr[:nulli])
+		var str string
+		for i := 0; i < len(arr); i++ {
+			if arr[i] == 0 {
+				str = string(arr[:i])
+				break
+			}
 		}
+		return str
 	}
 	var buffer struct {
 		header W_Mnth
 		fsinfo [64]W_Mntent
 	}
-	fsCount, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))
-	if err != nil {
-		return err
-	}
-	if fsCount == 0 {
-		return EINVAL
-	}
-	for i := 0; i < fsCount; i++ {
-		if b2s(buffer.fsinfo[i].Mountpoint[:]) == name {
-			err = unmount(b2s(buffer.fsinfo[i].Fsname[:]), mtm)
-			break
+	fs_count, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))
+	if err == nil {
+		err = EINVAL
+		for i := 0; i < fs_count; i++ {
+			if b2s(buffer.fsinfo[i].Mountpoint[:]) == name {
+				err = unmount_LE(b2s(buffer.fsinfo[i].Fsname[:]), mtm)
+				break
+			}
 		}
+	} else if fs_count == 0 {
+		err = EINVAL
 	}
 	return err
 }
 
-func fdToPath(dirfd int) (path string, err error) {
-	var buffer [1024]byte
-	// w_ctrl()
-	ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
-		[]uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
-	if ret == 0 {
-		zb := bytes.IndexByte(buffer[:], 0)
-		if zb == -1 {
-			zb = len(buffer)
-		}
-		// __e2a_l()
-		runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
-			[]uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
-		return string(buffer[:zb]), nil
-	}
-	// __errno()
-	errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
-		[]uintptr{}))))
-	// __errno2()
-	errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
-		[]uintptr{}))
-	// strerror_r()
-	ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
-		[]uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
-	if ret == 0 {
-		zb := bytes.IndexByte(buffer[:], 0)
-		if zb == -1 {
-			zb = len(buffer)
-		}
-		return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
-	} else {
-		return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
+// Unmount end
+
+func direntIno(buf []byte) (uint64, bool) {
+	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
+}
+
+func direntReclen(buf []byte) (uint64, bool) {
+	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
+}
+
+func direntNamlen(buf []byte) (uint64, bool) {
+	reclen, ok := direntReclen(buf)
+	if !ok {
+		return 0, false
 	}
+	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
 }
 
 func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {
@@ -1896,7 +2931,7 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
 	}
 
 	// Get path from fd to avoid unavailable call (fdopendir)
-	path, err := fdToPath(fd)
+	path, err := ZosFdToPath(fd)
 	if err != nil {
 		return 0, err
 	}
@@ -1910,7 +2945,7 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
 	for {
 		var entryLE direntLE
 		var entrypLE *direntLE
-		e := readdir_r(d, &entryLE, &entrypLE)
+		e := Readdir_r(d, &entryLE, &entrypLE)
 		if e != nil {
 			return n, e
 		}
@@ -1956,23 +2991,127 @@ func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
 	return n, nil
 }
 
-func ReadDirent(fd int, buf []byte) (n int, err error) {
-	var base = (*uintptr)(unsafe.Pointer(new(uint64)))
-	return Getdirentries(fd, buf, base)
+func Err2ad() (eadd *int) {
+	r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS___ERR2AD<<4)
+	eadd = (*int)(unsafe.Pointer(r0))
+	return
 }
 
-func direntIno(buf []byte) (uint64, bool) {
-	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
+func ZosConsolePrintf(format string, v ...interface{}) (int, error) {
+	type __cmsg struct {
+		_            uint16
+		_            [2]uint8
+		__msg_length uint32
+		__msg        uintptr
+		_            [4]uint8
+	}
+	msg := fmt.Sprintf(format, v...)
+	strptr := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&msg)).Data)
+	len := (*reflect.StringHeader)(unsafe.Pointer(&msg)).Len
+	cmsg := __cmsg{__msg_length: uint32(len), __msg: uintptr(strptr)}
+	cmd := uint32(0)
+	runtime.EnterSyscall()
+	rc, err2, err1 := CallLeFuncWithErr(GetZosLibVec()+SYS_____CONSOLE_A<<4, uintptr(unsafe.Pointer(&cmsg)), 0, uintptr(unsafe.Pointer(&cmd)))
+	runtime.ExitSyscall()
+	if rc != 0 {
+		return 0, fmt.Errorf("%s (errno2=0x%x)\n", err1.Error(), err2)
+	}
+	return 0, nil
+}
+func ZosStringToEbcdicBytes(str string, nullterm bool) (ebcdicBytes []byte) {
+	if nullterm {
+		ebcdicBytes = []byte(str + "\x00")
+	} else {
+		ebcdicBytes = []byte(str)
+	}
+	A2e(ebcdicBytes)
+	return
+}
+func ZosEbcdicBytesToString(b []byte, trimRight bool) (str string) {
+	res := make([]byte, len(b))
+	copy(res, b)
+	E2a(res)
+	if trimRight {
+		str = string(bytes.TrimRight(res, " \x00"))
+	} else {
+		str = string(res)
+	}
+	return
 }
 
-func direntReclen(buf []byte) (uint64, bool) {
-	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
+func fdToPath(dirfd int) (path string, err error) {
+	var buffer [1024]byte
+	// w_ctrl()
+	ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
+		[]uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
+	if ret == 0 {
+		zb := bytes.IndexByte(buffer[:], 0)
+		if zb == -1 {
+			zb = len(buffer)
+		}
+		// __e2a_l()
+		runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
+			[]uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
+		return string(buffer[:zb]), nil
+	}
+	// __errno()
+	errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
+		[]uintptr{}))))
+	// __errno2()
+	errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
+		[]uintptr{}))
+	// strerror_r()
+	ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
+		[]uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
+	if ret == 0 {
+		zb := bytes.IndexByte(buffer[:], 0)
+		if zb == -1 {
+			zb = len(buffer)
+		}
+		return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
+	} else {
+		return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
+	}
 }
 
-func direntNamlen(buf []byte) (uint64, bool) {
-	reclen, ok := direntReclen(buf)
-	if !ok {
-		return 0, false
+func impl_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
 	}
-	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MKFIFOAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_MkfifoatAddr() *(func(dirfd int, path string, mode uint32) (err error))
+
+var Mkfifoat = enter_Mkfifoat
+
+func enter_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
+	funcref := get_MkfifoatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___MKFIFOAT_A<<4, "") == 0 {
+		*funcref = impl_Mkfifoat
+	} else {
+		*funcref = legacy_Mkfifoat
+	}
+	return (*funcref)(dirfd, path, mode)
+}
+
+func legacy_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
+	dirname, err := ZosFdToPath(dirfd)
+	if err != nil {
+		return err
+	}
+	return Mkfifo(dirname+"/"+path, mode)
 }
+
+//sys	Posix_openpt(oflag int) (fd int, err error) = SYS_POSIX_OPENPT
+//sys	Grantpt(fildes int) (rc int, err error) = SYS_GRANTPT
+//sys	Unlockpt(fildes int) (rc int, err error) = SYS_UNLOCKPT
diff --git a/vendor/golang.org/x/sys/unix/sysvshm_unix.go b/vendor/golang.org/x/sys/unix/sysvshm_unix.go
index 79a84f18..672d6b0a 100644
--- a/vendor/golang.org/x/sys/unix/sysvshm_unix.go
+++ b/vendor/golang.org/x/sys/unix/sysvshm_unix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (darwin && !ios) || linux
+//go:build (darwin && !ios) || linux || zos
 
 package unix
 
diff --git a/vendor/golang.org/x/sys/unix/sysvshm_unix_other.go b/vendor/golang.org/x/sys/unix/sysvshm_unix_other.go
index 9eb0db66..8b7977a2 100644
--- a/vendor/golang.org/x/sys/unix/sysvshm_unix_other.go
+++ b/vendor/golang.org/x/sys/unix/sysvshm_unix_other.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build darwin && !ios
+//go:build (darwin && !ios) || zos
 
 package unix
 
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go
index 36bf8399..877a62b4 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go
@@ -491,6 +491,7 @@ const (
 	BPF_F_REPLACE                               = 0x4
 	BPF_F_SLEEPABLE                             = 0x10
 	BPF_F_STRICT_ALIGNMENT                      = 0x1
+	BPF_F_TEST_REG_INVARIANTS                   = 0x80
 	BPF_F_TEST_RND_HI32                         = 0x4
 	BPF_F_TEST_RUN_ON_CPU                       = 0x1
 	BPF_F_TEST_STATE_FREQ                       = 0x8
@@ -501,6 +502,7 @@ const (
 	BPF_IMM                                     = 0x0
 	BPF_IND                                     = 0x40
 	BPF_JA                                      = 0x0
+	BPF_JCOND                                   = 0xe0
 	BPF_JEQ                                     = 0x10
 	BPF_JGE                                     = 0x30
 	BPF_JGT                                     = 0x20
@@ -656,6 +658,9 @@ const (
 	CAN_NPROTO                                  = 0x8
 	CAN_RAW                                     = 0x1
 	CAN_RAW_FILTER_MAX                          = 0x200
+	CAN_RAW_XL_VCID_RX_FILTER                   = 0x4
+	CAN_RAW_XL_VCID_TX_PASS                     = 0x2
+	CAN_RAW_XL_VCID_TX_SET                      = 0x1
 	CAN_RTR_FLAG                                = 0x40000000
 	CAN_SFF_ID_BITS                             = 0xb
 	CAN_SFF_MASK                                = 0x7ff
@@ -1338,6 +1343,7 @@ const (
 	F_OFD_SETLK                                 = 0x25
 	F_OFD_SETLKW                                = 0x26
 	F_OK                                        = 0x0
+	F_SEAL_EXEC                                 = 0x20
 	F_SEAL_FUTURE_WRITE                         = 0x10
 	F_SEAL_GROW                                 = 0x4
 	F_SEAL_SEAL                                 = 0x1
@@ -1626,6 +1632,7 @@ const (
 	IP_FREEBIND                                 = 0xf
 	IP_HDRINCL                                  = 0x3
 	IP_IPSEC_POLICY                             = 0x10
+	IP_LOCAL_PORT_RANGE                         = 0x33
 	IP_MAXPACKET                                = 0xffff
 	IP_MAX_MEMBERSHIPS                          = 0x14
 	IP_MF                                       = 0x2000
@@ -1652,6 +1659,7 @@ const (
 	IP_PMTUDISC_OMIT                            = 0x5
 	IP_PMTUDISC_PROBE                           = 0x3
 	IP_PMTUDISC_WANT                            = 0x1
+	IP_PROTOCOL                                 = 0x34
 	IP_RECVERR                                  = 0xb
 	IP_RECVERR_RFC4884                          = 0x1a
 	IP_RECVFRAGSIZE                             = 0x19
@@ -1697,6 +1705,7 @@ const (
 	KEXEC_ARCH_S390                             = 0x160000
 	KEXEC_ARCH_SH                               = 0x2a0000
 	KEXEC_ARCH_X86_64                           = 0x3e0000
+	KEXEC_FILE_DEBUG                            = 0x8
 	KEXEC_FILE_NO_INITRAMFS                     = 0x4
 	KEXEC_FILE_ON_CRASH                         = 0x2
 	KEXEC_FILE_UNLOAD                           = 0x1
@@ -1898,6 +1907,7 @@ const (
 	MNT_DETACH                                  = 0x2
 	MNT_EXPIRE                                  = 0x4
 	MNT_FORCE                                   = 0x1
+	MNT_ID_REQ_SIZE_VER0                        = 0x18
 	MODULE_INIT_COMPRESSED_FILE                 = 0x4
 	MODULE_INIT_IGNORE_MODVERSIONS              = 0x1
 	MODULE_INIT_IGNORE_VERMAGIC                 = 0x2
@@ -2166,7 +2176,7 @@ const (
 	NFT_SECMARK_CTX_MAXLEN                      = 0x100
 	NFT_SET_MAXNAMELEN                          = 0x100
 	NFT_SOCKET_MAX                              = 0x3
-	NFT_TABLE_F_MASK                            = 0x3
+	NFT_TABLE_F_MASK                            = 0x7
 	NFT_TABLE_MAXNAMELEN                        = 0x100
 	NFT_TRACETYPE_MAX                           = 0x3
 	NFT_TUNNEL_F_MASK                           = 0x7
@@ -2302,6 +2312,7 @@ const (
 	PERF_AUX_FLAG_PARTIAL                       = 0x4
 	PERF_AUX_FLAG_PMU_FORMAT_TYPE_MASK          = 0xff00
 	PERF_AUX_FLAG_TRUNCATED                     = 0x1
+	PERF_BRANCH_ENTRY_INFO_BITS_MAX             = 0x21
 	PERF_BR_ARM64_DEBUG_DATA                    = 0x7
 	PERF_BR_ARM64_DEBUG_EXIT                    = 0x5
 	PERF_BR_ARM64_DEBUG_HALT                    = 0x4
@@ -2399,6 +2410,7 @@ const (
 	PERF_RECORD_MISC_USER                       = 0x2
 	PERF_SAMPLE_BRANCH_PLM_ALL                  = 0x7
 	PERF_SAMPLE_WEIGHT_TYPE                     = 0x1004000
+	PID_FS_MAGIC                                = 0x50494446
 	PIPEFS_MAGIC                                = 0x50495045
 	PPPIOCGNPMODE                               = 0xc008744c
 	PPPIOCNEWUNIT                               = 0xc004743e
@@ -2892,8 +2904,9 @@ const (
 	RWF_APPEND                                  = 0x10
 	RWF_DSYNC                                   = 0x2
 	RWF_HIPRI                                   = 0x1
+	RWF_NOAPPEND                                = 0x20
 	RWF_NOWAIT                                  = 0x8
-	RWF_SUPPORTED                               = 0x1f
+	RWF_SUPPORTED                               = 0x3f
 	RWF_SYNC                                    = 0x4
 	RWF_WRITE_LIFE_NOT_SET                      = 0x0
 	SCHED_BATCH                                 = 0x3
@@ -2914,7 +2927,9 @@ const (
 	SCHED_RESET_ON_FORK                         = 0x40000000
 	SCHED_RR                                    = 0x2
 	SCM_CREDENTIALS                             = 0x2
+	SCM_PIDFD                                   = 0x4
 	SCM_RIGHTS                                  = 0x1
+	SCM_SECURITY                                = 0x3
 	SCM_TIMESTAMP                               = 0x1d
 	SC_LOG_FLUSH                                = 0x100000
 	SECCOMP_ADDFD_FLAG_SEND                     = 0x2
@@ -3047,6 +3062,8 @@ const (
 	SIOCSMIIREG                                 = 0x8949
 	SIOCSRARP                                   = 0x8962
 	SIOCWANDEV                                  = 0x894a
+	SK_DIAG_BPF_STORAGE_MAX                     = 0x3
+	SK_DIAG_BPF_STORAGE_REQ_MAX                 = 0x1
 	SMACK_MAGIC                                 = 0x43415d53
 	SMART_AUTOSAVE                              = 0xd2
 	SMART_AUTO_OFFLINE                          = 0xdb
@@ -3067,6 +3084,8 @@ const (
 	SOCKFS_MAGIC                                = 0x534f434b
 	SOCK_BUF_LOCK_MASK                          = 0x3
 	SOCK_DCCP                                   = 0x6
+	SOCK_DESTROY                                = 0x15
+	SOCK_DIAG_BY_FAMILY                         = 0x14
 	SOCK_IOC_TYPE                               = 0x89
 	SOCK_PACKET                                 = 0xa
 	SOCK_RAW                                    = 0x3
@@ -3168,6 +3187,7 @@ const (
 	STATX_GID                                   = 0x10
 	STATX_INO                                   = 0x100
 	STATX_MNT_ID                                = 0x1000
+	STATX_MNT_ID_UNIQUE                         = 0x4000
 	STATX_MODE                                  = 0x2
 	STATX_MTIME                                 = 0x40
 	STATX_NLINK                                 = 0x4
@@ -3255,6 +3275,7 @@ const (
 	TCP_MAX_WINSHIFT                            = 0xe
 	TCP_MD5SIG                                  = 0xe
 	TCP_MD5SIG_EXT                              = 0x20
+	TCP_MD5SIG_FLAG_IFINDEX                     = 0x2
 	TCP_MD5SIG_FLAG_PREFIX                      = 0x1
 	TCP_MD5SIG_MAXKEYLEN                        = 0x50
 	TCP_MSS                                     = 0x200
@@ -3562,12 +3583,16 @@ const (
 	XDP_RX_RING                                 = 0x2
 	XDP_SHARED_UMEM                             = 0x1
 	XDP_STATISTICS                              = 0x7
+	XDP_TXMD_FLAGS_CHECKSUM                     = 0x2
+	XDP_TXMD_FLAGS_TIMESTAMP                    = 0x1
+	XDP_TX_METADATA                             = 0x2
 	XDP_TX_RING                                 = 0x3
 	XDP_UMEM_COMPLETION_RING                    = 0x6
 	XDP_UMEM_FILL_RING                          = 0x5
 	XDP_UMEM_PGOFF_COMPLETION_RING              = 0x180000000
 	XDP_UMEM_PGOFF_FILL_RING                    = 0x100000000
 	XDP_UMEM_REG                                = 0x4
+	XDP_UMEM_TX_SW_CSUM                         = 0x2
 	XDP_UMEM_UNALIGNED_CHUNK_FLAG               = 0x1
 	XDP_USE_NEED_WAKEUP                         = 0x8
 	XDP_USE_SG                                  = 0x10
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
index 42ff8c3c..e4bc0bd5 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
@@ -118,6 +118,7 @@ const (
 	IXOFF                            = 0x1000
 	IXON                             = 0x400
 	MAP_32BIT                        = 0x40
+	MAP_ABOVE4G                      = 0x80
 	MAP_ANON                         = 0x20
 	MAP_ANONYMOUS                    = 0x20
 	MAP_DENYWRITE                    = 0x800
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
index dca43600..689317af 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
@@ -118,6 +118,7 @@ const (
 	IXOFF                            = 0x1000
 	IXON                             = 0x400
 	MAP_32BIT                        = 0x40
+	MAP_ABOVE4G                      = 0x80
 	MAP_ANON                         = 0x20
 	MAP_ANONYMOUS                    = 0x20
 	MAP_DENYWRITE                    = 0x800
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
index d8cae6d1..14270508 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
@@ -87,6 +87,7 @@ const (
 	FICLONE                          = 0x40049409
 	FICLONERANGE                     = 0x4020940d
 	FLUSHO                           = 0x1000
+	FPMR_MAGIC                       = 0x46504d52
 	FPSIMD_MAGIC                     = 0x46508001
 	FS_IOC_ENABLE_VERITY             = 0x40806685
 	FS_IOC_GETFLAGS                  = 0x80086601
diff --git a/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go
index 4dfd2e05..da08b2ab 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go
@@ -10,41 +10,99 @@
 package unix
 
 const (
-	BRKINT                          = 0x0001
-	CLOCK_MONOTONIC                 = 0x1
-	CLOCK_PROCESS_CPUTIME_ID        = 0x2
-	CLOCK_REALTIME                  = 0x0
-	CLOCK_THREAD_CPUTIME_ID         = 0x3
-	CS8                             = 0x0030
-	CSIZE                           = 0x0030
-	ECHO                            = 0x00000008
-	ECHONL                          = 0x00000001
-	FD_CLOEXEC                      = 0x01
-	FD_CLOFORK                      = 0x02
-	FNDELAY                         = 0x04
-	F_CLOSFD                        = 9
-	F_CONTROL_CVT                   = 13
-	F_DUPFD                         = 0
-	F_DUPFD2                        = 8
-	F_GETFD                         = 1
-	F_GETFL                         = 259
-	F_GETLK                         = 5
-	F_GETOWN                        = 10
-	F_OK                            = 0x0
-	F_RDLCK                         = 1
-	F_SETFD                         = 2
-	F_SETFL                         = 4
-	F_SETLK                         = 6
-	F_SETLKW                        = 7
-	F_SETOWN                        = 11
-	F_SETTAG                        = 12
-	F_UNLCK                         = 3
-	F_WRLCK                         = 2
-	FSTYPE_ZFS                      = 0xe9 //"Z"
-	FSTYPE_HFS                      = 0xc8 //"H"
-	FSTYPE_NFS                      = 0xd5 //"N"
-	FSTYPE_TFS                      = 0xe3 //"T"
-	FSTYPE_AUTOMOUNT                = 0xc1 //"A"
+	BRKINT                   = 0x0001
+	CLOCAL                   = 0x1
+	CLOCK_MONOTONIC          = 0x1
+	CLOCK_PROCESS_CPUTIME_ID = 0x2
+	CLOCK_REALTIME           = 0x0
+	CLOCK_THREAD_CPUTIME_ID  = 0x3
+	CLONE_NEWIPC             = 0x08000000
+	CLONE_NEWNET             = 0x40000000
+	CLONE_NEWNS              = 0x00020000
+	CLONE_NEWPID             = 0x20000000
+	CLONE_NEWUTS             = 0x04000000
+	CLONE_PARENT             = 0x00008000
+	CS8                      = 0x0030
+	CSIZE                    = 0x0030
+	ECHO                     = 0x00000008
+	ECHONL                   = 0x00000001
+	EFD_SEMAPHORE            = 0x00002000
+	EFD_CLOEXEC              = 0x00001000
+	EFD_NONBLOCK             = 0x00000004
+	EPOLL_CLOEXEC            = 0x00001000
+	EPOLL_CTL_ADD            = 0
+	EPOLL_CTL_MOD            = 1
+	EPOLL_CTL_DEL            = 2
+	EPOLLRDNORM              = 0x0001
+	EPOLLRDBAND              = 0x0002
+	EPOLLIN                  = 0x0003
+	EPOLLOUT                 = 0x0004
+	EPOLLWRBAND              = 0x0008
+	EPOLLPRI                 = 0x0010
+	EPOLLERR                 = 0x0020
+	EPOLLHUP                 = 0x0040
+	EPOLLEXCLUSIVE           = 0x20000000
+	EPOLLONESHOT             = 0x40000000
+	FD_CLOEXEC               = 0x01
+	FD_CLOFORK               = 0x02
+	FD_SETSIZE               = 0x800
+	FNDELAY                  = 0x04
+	F_CLOSFD                 = 9
+	F_CONTROL_CVT            = 13
+	F_DUPFD                  = 0
+	F_DUPFD2                 = 8
+	F_GETFD                  = 1
+	F_GETFL                  = 259
+	F_GETLK                  = 5
+	F_GETOWN                 = 10
+	F_OK                     = 0x0
+	F_RDLCK                  = 1
+	F_SETFD                  = 2
+	F_SETFL                  = 4
+	F_SETLK                  = 6
+	F_SETLKW                 = 7
+	F_SETOWN                 = 11
+	F_SETTAG                 = 12
+	F_UNLCK                  = 3
+	F_WRLCK                  = 2
+	FSTYPE_ZFS               = 0xe9 //"Z"
+	FSTYPE_HFS               = 0xc8 //"H"
+	FSTYPE_NFS               = 0xd5 //"N"
+	FSTYPE_TFS               = 0xe3 //"T"
+	FSTYPE_AUTOMOUNT         = 0xc1 //"A"
+	GRND_NONBLOCK            = 1
+	GRND_RANDOM              = 2
+	HUPCL                    = 0x0100 // Hang up on last close
+	IN_CLOEXEC               = 0x00001000
+	IN_NONBLOCK              = 0x00000004
+	IN_ACCESS                = 0x00000001
+	IN_MODIFY                = 0x00000002
+	IN_ATTRIB                = 0x00000004
+	IN_CLOSE_WRITE           = 0x00000008
+	IN_CLOSE_NOWRITE         = 0x00000010
+	IN_OPEN                  = 0x00000020
+	IN_MOVED_FROM            = 0x00000040
+	IN_MOVED_TO              = 0x00000080
+	IN_CREATE                = 0x00000100
+	IN_DELETE                = 0x00000200
+	IN_DELETE_SELF           = 0x00000400
+	IN_MOVE_SELF             = 0x00000800
+	IN_UNMOUNT               = 0x00002000
+	IN_Q_OVERFLOW            = 0x00004000
+	IN_IGNORED               = 0x00008000
+	IN_CLOSE                 = (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
+	IN_MOVE                  = (IN_MOVED_FROM | IN_MOVED_TO)
+	IN_ALL_EVENTS            = (IN_ACCESS | IN_MODIFY | IN_ATTRIB |
+		IN_CLOSE | IN_OPEN | IN_MOVE |
+		IN_CREATE | IN_DELETE | IN_DELETE_SELF |
+		IN_MOVE_SELF)
+	IN_ONLYDIR                      = 0x01000000
+	IN_DONT_FOLLOW                  = 0x02000000
+	IN_EXCL_UNLINK                  = 0x04000000
+	IN_MASK_CREATE                  = 0x10000000
+	IN_MASK_ADD                     = 0x20000000
+	IN_ISDIR                        = 0x40000000
+	IN_ONESHOT                      = 0x80000000
 	IP6F_MORE_FRAG                  = 0x0001
 	IP6F_OFF_MASK                   = 0xfff8
 	IP6F_RESERVED_MASK              = 0x0006
@@ -152,10 +210,18 @@ const (
 	IP_PKTINFO                      = 101
 	IP_RECVPKTINFO                  = 102
 	IP_TOS                          = 2
-	IP_TTL                          = 3
+	IP_TTL                          = 14
 	IP_UNBLOCK_SOURCE               = 11
+	ICMP6_FILTER                    = 1
+	MCAST_INCLUDE                   = 0
+	MCAST_EXCLUDE                   = 1
+	MCAST_JOIN_GROUP                = 40
+	MCAST_LEAVE_GROUP               = 41
+	MCAST_JOIN_SOURCE_GROUP         = 42
+	MCAST_LEAVE_SOURCE_GROUP        = 43
+	MCAST_BLOCK_SOURCE              = 44
+	MCAST_UNBLOCK_SOURCE            = 46
 	ICANON                          = 0x0010
-	ICMP6_FILTER                    = 0x26
 	ICRNL                           = 0x0002
 	IEXTEN                          = 0x0020
 	IGNBRK                          = 0x0004
@@ -165,10 +231,10 @@ const (
 	ISTRIP                          = 0x0080
 	IXON                            = 0x0200
 	IXOFF                           = 0x0100
-	LOCK_SH                         = 0x1 // Not exist on zOS
-	LOCK_EX                         = 0x2 // Not exist on zOS
-	LOCK_NB                         = 0x4 // Not exist on zOS
-	LOCK_UN                         = 0x8 // Not exist on zOS
+	LOCK_SH                         = 0x1
+	LOCK_EX                         = 0x2
+	LOCK_NB                         = 0x4
+	LOCK_UN                         = 0x8
 	POLLIN                          = 0x0003
 	POLLOUT                         = 0x0004
 	POLLPRI                         = 0x0010
@@ -182,15 +248,29 @@ const (
 	MAP_PRIVATE                     = 0x1 // changes are private
 	MAP_SHARED                      = 0x2 // changes are shared
 	MAP_FIXED                       = 0x4 // place exactly
-	MCAST_JOIN_GROUP                = 40
-	MCAST_LEAVE_GROUP               = 41
-	MCAST_JOIN_SOURCE_GROUP         = 42
-	MCAST_LEAVE_SOURCE_GROUP        = 43
-	MCAST_BLOCK_SOURCE              = 44
-	MCAST_UNBLOCK_SOURCE            = 45
+	__MAP_MEGA                      = 0x8
+	__MAP_64                        = 0x10
+	MAP_ANON                        = 0x20
+	MAP_ANONYMOUS                   = 0x20
 	MS_SYNC                         = 0x1 // msync - synchronous writes
 	MS_ASYNC                        = 0x2 // asynchronous writes
 	MS_INVALIDATE                   = 0x4 // invalidate mappings
+	MS_BIND                         = 0x00001000
+	MS_MOVE                         = 0x00002000
+	MS_NOSUID                       = 0x00000002
+	MS_PRIVATE                      = 0x00040000
+	MS_REC                          = 0x00004000
+	MS_REMOUNT                      = 0x00008000
+	MS_RDONLY                       = 0x00000001
+	MS_UNBINDABLE                   = 0x00020000
+	MNT_DETACH                      = 0x00000004
+	ZOSDSFS_SUPER_MAGIC             = 0x44534653 // zOS DSFS
+	NFS_SUPER_MAGIC                 = 0x6969     // NFS
+	NSFS_MAGIC                      = 0x6e736673 // PROCNS
+	PROC_SUPER_MAGIC                = 0x9fa0     // proc FS
+	ZOSTFS_SUPER_MAGIC              = 0x544653   // zOS TFS
+	ZOSUFS_SUPER_MAGIC              = 0x554653   // zOS UFS
+	ZOSZFS_SUPER_MAGIC              = 0x5A4653   // zOS ZFS
 	MTM_RDONLY                      = 0x80000000
 	MTM_RDWR                        = 0x40000000
 	MTM_UMOUNT                      = 0x10000000
@@ -205,13 +285,20 @@ const (
 	MTM_REMOUNT                     = 0x00000100
 	MTM_NOSECURITY                  = 0x00000080
 	NFDBITS                         = 0x20
+	ONLRET                          = 0x0020 // NL performs CR function
 	O_ACCMODE                       = 0x03
 	O_APPEND                        = 0x08
 	O_ASYNCSIG                      = 0x0200
 	O_CREAT                         = 0x80
+	O_DIRECT                        = 0x00002000
+	O_NOFOLLOW                      = 0x00004000
+	O_DIRECTORY                     = 0x00008000
+	O_PATH                          = 0x00080000
+	O_CLOEXEC                       = 0x00001000
 	O_EXCL                          = 0x40
 	O_GETFL                         = 0x0F
 	O_LARGEFILE                     = 0x0400
+	O_NDELAY                        = 0x4
 	O_NONBLOCK                      = 0x04
 	O_RDONLY                        = 0x02
 	O_RDWR                          = 0x03
@@ -248,6 +335,7 @@ const (
 	AF_IUCV                         = 17
 	AF_LAT                          = 14
 	AF_LINK                         = 18
+	AF_LOCAL                        = AF_UNIX // AF_LOCAL is an alias for AF_UNIX
 	AF_MAX                          = 30
 	AF_NBS                          = 7
 	AF_NDD                          = 23
@@ -285,15 +373,33 @@ const (
 	RLIMIT_AS                       = 5
 	RLIMIT_NOFILE                   = 6
 	RLIMIT_MEMLIMIT                 = 7
+	RLIMIT_MEMLOCK                  = 0x8
 	RLIM_INFINITY                   = 2147483647
+	SCHED_FIFO                      = 0x2
+	SCM_CREDENTIALS                 = 0x2
 	SCM_RIGHTS                      = 0x01
 	SF_CLOSE                        = 0x00000002
 	SF_REUSE                        = 0x00000001
+	SHM_RND                         = 0x2
+	SHM_RDONLY                      = 0x1
+	SHMLBA                          = 0x1000
+	IPC_STAT                        = 0x3
+	IPC_SET                         = 0x2
+	IPC_RMID                        = 0x1
+	IPC_PRIVATE                     = 0x0
+	IPC_CREAT                       = 0x1000000
+	__IPC_MEGA                      = 0x4000000
+	__IPC_SHAREAS                   = 0x20000000
+	__IPC_BELOWBAR                  = 0x10000000
+	IPC_EXCL                        = 0x2000000
+	__IPC_GIGA                      = 0x8000000
 	SHUT_RD                         = 0
 	SHUT_RDWR                       = 2
 	SHUT_WR                         = 1
+	SOCK_CLOEXEC                    = 0x00001000
 	SOCK_CONN_DGRAM                 = 6
 	SOCK_DGRAM                      = 2
+	SOCK_NONBLOCK                   = 0x800
 	SOCK_RAW                        = 3
 	SOCK_RDM                        = 4
 	SOCK_SEQPACKET                  = 5
@@ -378,8 +484,6 @@ const (
 	S_IFMST                         = 0x00FF0000
 	TCP_KEEPALIVE                   = 0x8
 	TCP_NODELAY                     = 0x1
-	TCP_INFO                        = 0xb
-	TCP_USER_TIMEOUT                = 0x1
 	TIOCGWINSZ                      = 0x4008a368
 	TIOCSWINSZ                      = 0x8008a367
 	TIOCSBRK                        = 0x2000a77b
@@ -427,7 +531,10 @@ const (
 	VSUSP                           = 9
 	VTIME                           = 10
 	WCONTINUED                      = 0x4
+	WEXITED                         = 0x8
 	WNOHANG                         = 0x1
+	WNOWAIT                         = 0x20
+	WSTOPPED                        = 0x10
 	WUNTRACED                       = 0x2
 	_BPX_SWAP                       = 1
 	_BPX_NONSWAP                    = 2
@@ -452,8 +559,28 @@ const (
 	MADV_FREE                       = 15 // for Linux compatibility -- no zos semantics
 	MADV_WIPEONFORK                 = 16 // for Linux compatibility -- no zos semantics
 	MADV_KEEPONFORK                 = 17 // for Linux compatibility -- no zos semantics
-	AT_SYMLINK_NOFOLLOW             = 1  // for Unix  compatibility -- no zos semantics
-	AT_FDCWD                        = 2  // for Unix  compatibility -- no zos semantics
+	AT_SYMLINK_FOLLOW               = 0x400
+	AT_SYMLINK_NOFOLLOW             = 0x100
+	XATTR_CREATE                    = 0x1
+	XATTR_REPLACE                   = 0x2
+	P_PID                           = 0
+	P_PGID                          = 1
+	P_ALL                           = 2
+	PR_SET_NAME                     = 15
+	PR_GET_NAME                     = 16
+	PR_SET_NO_NEW_PRIVS             = 38
+	PR_GET_NO_NEW_PRIVS             = 39
+	PR_SET_DUMPABLE                 = 4
+	PR_GET_DUMPABLE                 = 3
+	PR_SET_PDEATHSIG                = 1
+	PR_GET_PDEATHSIG                = 2
+	PR_SET_CHILD_SUBREAPER          = 36
+	PR_GET_CHILD_SUBREAPER          = 37
+	AT_FDCWD                        = -100
+	AT_EACCESS                      = 0x200
+	AT_EMPTY_PATH                   = 0x1000
+	AT_REMOVEDIR                    = 0x200
+	RENAME_NOREPLACE                = 1 << 0
 )
 
 const (
@@ -476,6 +603,7 @@ const (
 	EMLINK             = Errno(125)
 	ENAMETOOLONG       = Errno(126)
 	ENFILE             = Errno(127)
+	ENOATTR            = Errno(265)
 	ENODEV             = Errno(128)
 	ENOENT             = Errno(129)
 	ENOEXEC            = Errno(130)
@@ -700,7 +828,7 @@ var errorList = [...]struct {
 	{145, "EDC5145I", "The parameter list is too long, or the message to receive was too large for the buffer."},
 	{146, "EDC5146I", "Too many levels of symbolic links."},
 	{147, "EDC5147I", "Illegal byte sequence."},
-	{148, "", ""},
+	{148, "EDC5148I", "The named attribute or data not available."},
 	{149, "EDC5149I", "Value Overflow Error."},
 	{150, "EDC5150I", "UNIX System Services is not active."},
 	{151, "EDC5151I", "Dynamic allocation error."},
@@ -743,6 +871,7 @@ var errorList = [...]struct {
 	{259, "EDC5259I", "A CUN_RS_NO_CONVERSION error was issued by Unicode Services."},
 	{260, "EDC5260I", "A CUN_RS_TABLE_NOT_ALIGNED error was issued by Unicode Services."},
 	{262, "EDC5262I", "An iconv() function encountered an unexpected error while using Unicode Services."},
+	{265, "EDC5265I", "The named attribute not available."},
 	{1000, "EDC8000I", "A bad socket-call constant was found in the IUCV header."},
 	{1001, "EDC8001I", "An error was found in the IUCV header."},
 	{1002, "EDC8002I", "A socket descriptor is out of range."},
diff --git a/vendor/golang.org/x/sys/unix/zsymaddr_zos_s390x.s b/vendor/golang.org/x/sys/unix/zsymaddr_zos_s390x.s
new file mode 100644
index 00000000..b77ff5db
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/zsymaddr_zos_s390x.s
@@ -0,0 +1,364 @@
+// go run mksyscall_zos_s390x.go -o_sysnum zsysnum_zos_s390x.go -o_syscall zsyscall_zos_s390x.go -i_syscall syscall_zos_s390x.go -o_asm zsymaddr_zos_s390x.s
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build zos && s390x
+#include "textflag.h"
+
+//  provide the address of function variable to be fixed up.
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_FlistxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Flistxattr(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_FremovexattrAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Fremovexattr(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_FgetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Fgetxattr(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_FsetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Fsetxattr(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_accept4Addr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·accept4(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_RemovexattrAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Removexattr(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_Dup3Addr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Dup3(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_DirfdAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Dirfd(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_EpollCreateAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·EpollCreate(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_EpollCreate1Addr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·EpollCreate1(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_EpollCtlAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·EpollCtl(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_EpollPwaitAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·EpollPwait(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_EpollWaitAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·EpollWait(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_EventfdAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Eventfd(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_FaccessatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Faccessat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_FchmodatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Fchmodat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_FchownatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Fchownat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_FdatasyncAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Fdatasync(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_fstatatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·fstatat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_LgetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Lgetxattr(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_LsetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Lsetxattr(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_FstatfsAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Fstatfs(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_FutimesAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Futimes(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_FutimesatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Futimesat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_GetrandomAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Getrandom(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_InotifyInitAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·InotifyInit(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_InotifyInit1Addr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·InotifyInit1(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_InotifyAddWatchAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·InotifyAddWatch(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_InotifyRmWatchAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·InotifyRmWatch(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_ListxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Listxattr(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_LlistxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Llistxattr(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_LremovexattrAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Lremovexattr(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_LutimesAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Lutimes(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_StatfsAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Statfs(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_SyncfsAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Syncfs(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_UnshareAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Unshare(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_LinkatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Linkat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_MkdiratAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Mkdirat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_MknodatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Mknodat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_PivotRootAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·PivotRoot(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_PrctlAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Prctl(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_PrlimitAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Prlimit(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_RenameatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Renameat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_Renameat2Addr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Renameat2(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_SethostnameAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Sethostname(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_SetnsAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Setns(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_SymlinkatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Symlinkat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_UnlinkatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·Unlinkat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_openatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·openat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_openat2Addr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·openat2(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+TEXT ·get_utimensatAddr(SB), NOSPLIT|NOFRAME, $0-8
+	MOVD $·utimensat(SB), R8
+	MOVD R8, ret+0(FP)
+	RET
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
index ccb02f24..07642c30 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
@@ -760,6 +760,39 @@ var libc_sysctl_trampoline_addr uintptr
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func pthread_chdir_np(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_pthread_chdir_np_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pthread_fchdir_np(fd int) (err error) {
+	_, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_pthread_fchdir_np_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
 	_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
index 8b8bb284..923e08cb 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
@@ -228,6 +228,16 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
 GLOBL	·libc_sysctl_trampoline_addr(SB), RODATA, $8
 DATA	·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
 
+TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pthread_chdir_np(SB)
+GLOBL	·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB)
+
+TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pthread_fchdir_np(SB)
+GLOBL	·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB)
+
 TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_sendfile(SB)
 GLOBL	·libc_sendfile_trampoline_addr(SB), RODATA, $8
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
index 1b40b997..7d73dda6 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
@@ -760,6 +760,39 @@ var libc_sysctl_trampoline_addr uintptr
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func pthread_chdir_np(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_pthread_chdir_np_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pthread_fchdir_np(fd int) (err error) {
+	_, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_pthread_fchdir_np_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
 	_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
index 08362c1a..05770011 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
@@ -228,6 +228,16 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
 GLOBL	·libc_sysctl_trampoline_addr(SB), RODATA, $8
 DATA	·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
 
+TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pthread_chdir_np(SB)
+GLOBL	·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB)
+
+TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pthread_fchdir_np(SB)
+GLOBL	·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB)
+
 TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_sendfile(SB)
 GLOBL	·libc_sendfile_trampoline_addr(SB), RODATA, $8
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go
index 1488d271..87d8612a 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go
@@ -906,6 +906,16 @@ func Fspick(dirfd int, pathName string, flags int) (fd int, err error) {
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) {
+	_, _, e1 := Syscall6(SYS_FSCONFIG, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(value)), uintptr(aux), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Getdents(fd int, buf []byte) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(buf) > 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go
index 94f01123..7ccf66b7 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -tags zos,s390x syscall_zos_s390x.go
+// go run mksyscall_zos_s390x.go -o_sysnum zsysnum_zos_s390x.go -o_syscall zsyscall_zos_s390x.go -i_syscall syscall_zos_s390x.go -o_asm zsymaddr_zos_s390x.s
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build zos && s390x
@@ -6,17 +6,100 @@
 package unix
 
 import (
+	"runtime"
+	"syscall"
 	"unsafe"
 )
 
+var _ syscall.Errno
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := syscall_syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, uintptr(fd), uintptr(cmd), uintptr(arg))
+	runtime.ExitSyscall()
 	val = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Flistxattr(fd int, dest []byte) (sz int, err error) {
+	var _p0 unsafe.Pointer
+	if len(dest) > 0 {
+		_p0 = unsafe.Pointer(&dest[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___FLISTXATTR_A<<4, uintptr(fd), uintptr(_p0), uintptr(len(dest)))
+	runtime.ExitSyscall()
+	sz = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_FlistxattrAddr() *(func(fd int, dest []byte) (sz int, err error))
+
+var Flistxattr = enter_Flistxattr
+
+func enter_Flistxattr(fd int, dest []byte) (sz int, err error) {
+	funcref := get_FlistxattrAddr()
+	if funcptrtest(GetZosLibVec()+SYS___FLISTXATTR_A<<4, "") == 0 {
+		*funcref = impl_Flistxattr
+	} else {
+		*funcref = error_Flistxattr
+	}
+	return (*funcref)(fd, dest)
+}
+
+func error_Flistxattr(fd int, dest []byte) (sz int, err error) {
+	sz = -1
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Fremovexattr(fd int, attr string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___FREMOVEXATTR_A<<4, uintptr(fd), uintptr(unsafe.Pointer(_p0)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_FremovexattrAddr() *(func(fd int, attr string) (err error))
+
+var Fremovexattr = enter_Fremovexattr
+
+func enter_Fremovexattr(fd int, attr string) (err error) {
+	funcref := get_FremovexattrAddr()
+	if funcptrtest(GetZosLibVec()+SYS___FREMOVEXATTR_A<<4, "") == 0 {
+		*funcref = impl_Fremovexattr
+	} else {
+		*funcref = error_Fremovexattr
 	}
+	return (*funcref)(fd, attr)
+}
+
+func error_Fremovexattr(fd int, attr string) (err error) {
+	err = ENOSYS
 	return
 }
 
@@ -29,10 +112,12 @@ func read(fd int, p []byte) (n int, err error) {
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_READ<<4, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	runtime.ExitSyscall()
 	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -46,31 +131,159 @@ func write(fd int, p []byte) (n int, err error) {
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_WRITE<<4, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	runtime.ExitSyscall()
 	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(dest) > 0 {
+		_p1 = unsafe.Pointer(&dest[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___FGETXATTR_A<<4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
+	runtime.ExitSyscall()
+	sz = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_FgetxattrAddr() *(func(fd int, attr string, dest []byte) (sz int, err error))
+
+var Fgetxattr = enter_Fgetxattr
+
+func enter_Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
+	funcref := get_FgetxattrAddr()
+	if funcptrtest(GetZosLibVec()+SYS___FGETXATTR_A<<4, "") == 0 {
+		*funcref = impl_Fgetxattr
+	} else {
+		*funcref = error_Fgetxattr
+	}
+	return (*funcref)(fd, attr, dest)
+}
+
+func error_Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
+	sz = -1
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Fsetxattr(fd int, attr string, data []byte, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(data) > 0 {
+		_p1 = unsafe.Pointer(&data[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___FSETXATTR_A<<4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(data)), uintptr(flag))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_FsetxattrAddr() *(func(fd int, attr string, data []byte, flag int) (err error))
+
+var Fsetxattr = enter_Fsetxattr
+
+func enter_Fsetxattr(fd int, attr string, data []byte, flag int) (err error) {
+	funcref := get_FsetxattrAddr()
+	if funcptrtest(GetZosLibVec()+SYS___FSETXATTR_A<<4, "") == 0 {
+		*funcref = impl_Fsetxattr
+	} else {
+		*funcref = error_Fsetxattr
 	}
+	return (*funcref)(fd, attr, data, flag)
+}
+
+func error_Fsetxattr(fd int, attr string, data []byte, flag int) (err error) {
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := syscall_syscall(SYS___ACCEPT_A, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___ACCEPT_A<<4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	runtime.ExitSyscall()
+	fd = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___ACCEPT4_A<<4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags))
+	runtime.ExitSyscall()
 	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_accept4Addr() *(func(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error))
+
+var accept4 = enter_accept4
+
+func enter_accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
+	funcref := get_accept4Addr()
+	if funcptrtest(GetZosLibVec()+SYS___ACCEPT4_A<<4, "") == 0 {
+		*funcref = impl_accept4
+	} else {
+		*funcref = error_accept4
 	}
+	return (*funcref)(s, rsa, addrlen, flags)
+}
+
+func error_accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
+	fd = -1
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall_syscall(SYS___BIND_A, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___BIND_A<<4, uintptr(s), uintptr(addr), uintptr(addrlen))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -78,9 +291,11 @@ func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := syscall_syscall(SYS___CONNECT_A, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___CONNECT_A<<4, uintptr(s), uintptr(addr), uintptr(addrlen))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -88,10 +303,10 @@ func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(n int, list *_Gid_t) (nn int, err error) {
-	r0, _, e1 := syscall_rawsyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_GETGROUPS<<4, uintptr(n), uintptr(unsafe.Pointer(list)))
 	nn = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -99,9 +314,9 @@ func getgroups(n int, list *_Gid_t) (nn int, err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(n int, list *_Gid_t) (err error) {
-	_, _, e1 := syscall_rawsyscall(SYS_SETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SETGROUPS<<4, uintptr(n), uintptr(unsafe.Pointer(list)))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -109,9 +324,11 @@ func setgroups(n int, list *_Gid_t) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := syscall_syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_GETSOCKOPT<<4, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -119,9 +336,11 @@ func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := syscall_syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SETSOCKOPT<<4, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -129,10 +348,10 @@ func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr)
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := syscall_rawsyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SOCKET<<4, uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -140,9 +359,9 @@ func socket(domain int, typ int, proto int) (fd int, err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := syscall_rawsyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SOCKETPAIR<<4, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -150,9 +369,9 @@ func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := syscall_rawsyscall(SYS___GETPEERNAME_A, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___GETPEERNAME_A<<4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -160,10 +379,52 @@ func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := syscall_rawsyscall(SYS___GETSOCKNAME_A, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___GETSOCKNAME_A<<4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Removexattr(path string, attr string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___REMOVEXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_RemovexattrAddr() *(func(path string, attr string) (err error))
+
+var Removexattr = enter_Removexattr
+
+func enter_Removexattr(path string, attr string) (err error) {
+	funcref := get_RemovexattrAddr()
+	if funcptrtest(GetZosLibVec()+SYS___REMOVEXATTR_A<<4, "") == 0 {
+		*funcref = impl_Removexattr
+	} else {
+		*funcref = error_Removexattr
 	}
+	return (*funcref)(path, attr)
+}
+
+func error_Removexattr(path string, attr string) (err error) {
+	err = ENOSYS
 	return
 }
 
@@ -176,10 +437,12 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall6(SYS___RECVFROM_A, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___RECVFROM_A<<4, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	runtime.ExitSyscall()
 	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -193,9 +456,11 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall6(SYS___SENDTO_A, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___SENDTO_A<<4, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -203,10 +468,12 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(SYS___RECVMSG_A, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___RECVMSG_A<<4, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	runtime.ExitSyscall()
 	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -214,10 +481,12 @@ func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := syscall_syscall(SYS___SENDMSG_A, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___SENDMSG_A<<4, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	runtime.ExitSyscall()
 	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -225,10 +494,12 @@ func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := syscall_syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_MMAP<<4, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	runtime.ExitSyscall()
 	ret = uintptr(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -236,9 +507,11 @@ func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := syscall_syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_MUNMAP<<4, uintptr(addr), uintptr(length))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -246,9 +519,11 @@ func munmap(addr uintptr, length uintptr) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctl(fd int, req int, arg uintptr) (err error) {
-	_, _, e1 := syscall_syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_IOCTL<<4, uintptr(fd), uintptr(req), uintptr(arg))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -256,9 +531,62 @@ func ioctl(fd int, req int, arg uintptr) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) {
-	_, _, e1 := syscall_syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_IOCTL<<4, uintptr(fd), uintptr(req), uintptr(arg))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func shmat(id int, addr uintptr, flag int) (ret uintptr, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SHMAT<<4, uintptr(id), uintptr(addr), uintptr(flag))
+	runtime.ExitSyscall()
+	ret = uintptr(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SHMCTL64<<4, uintptr(id), uintptr(cmd), uintptr(unsafe.Pointer(buf)))
+	runtime.ExitSyscall()
+	result = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func shmdt(addr uintptr) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SHMDT<<4, uintptr(addr))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func shmget(key int, size int, flag int) (id int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SHMGET<<4, uintptr(key), uintptr(size), uintptr(flag))
+	runtime.ExitSyscall()
+	id = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -271,9 +599,11 @@ func Access(path string, mode uint32) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___ACCESS_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___ACCESS_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -286,9 +616,11 @@ func Chdir(path string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___CHDIR_A, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___CHDIR_A<<4, uintptr(unsafe.Pointer(_p0)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -301,9 +633,11 @@ func Chown(path string, uid int, gid int) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___CHOWN_A, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___CHOWN_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -316,9 +650,11 @@ func Chmod(path string, mode uint32) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___CHMOD_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___CHMOD_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -331,10 +667,12 @@ func Creat(path string, mode uint32) (fd int, err error) {
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall(SYS___CREAT_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___CREAT_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	runtime.ExitSyscall()
 	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -342,10 +680,12 @@ func Creat(path string, mode uint32) (fd int, err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(oldfd int) (fd int, err error) {
-	r0, _, e1 := syscall_syscall(SYS_DUP, uintptr(oldfd), 0, 0)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_DUP<<4, uintptr(oldfd))
+	runtime.ExitSyscall()
 	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -353,617 +693,2216 @@ func Dup(oldfd int) (fd int, err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(oldfd int, newfd int) (err error) {
-	_, _, e1 := syscall_syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_DUP2<<4, uintptr(oldfd), uintptr(newfd))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Errno2() (er2 int) {
-	uer2, _, _ := syscall_syscall(SYS___ERRNO2, 0, 0, 0)
-	er2 = int(uer2)
+func impl_Dup3(oldfd int, newfd int, flags int) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_DUP3<<4, uintptr(oldfd), uintptr(newfd), uintptr(flags))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_Dup3Addr() *(func(oldfd int, newfd int, flags int) (err error))
 
-func Err2ad() (eadd *int) {
-	ueadd, _, _ := syscall_syscall(SYS___ERR2AD, 0, 0, 0)
-	eadd = (*int)(unsafe.Pointer(ueadd))
-	return
-}
+var Dup3 = enter_Dup3
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func enter_Dup3(oldfd int, newfd int, flags int) (err error) {
+	funcref := get_Dup3Addr()
+	if funcptrtest(GetZosLibVec()+SYS_DUP3<<4, "") == 0 {
+		*funcref = impl_Dup3
+	} else {
+		*funcref = error_Dup3
+	}
+	return (*funcref)(oldfd, newfd, flags)
+}
 
-func Exit(code int) {
-	syscall_syscall(SYS_EXIT, uintptr(code), 0, 0)
+func error_Dup3(oldfd int, newfd int, flags int) (err error) {
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fchdir(fd int) (err error) {
-	_, _, e1 := syscall_syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+func impl_Dirfd(dirp uintptr) (fd int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_DIRFD<<4, uintptr(dirp))
+	runtime.ExitSyscall()
+	fd = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_DirfdAddr() *(func(dirp uintptr) (fd int, err error))
 
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := syscall_syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+var Dirfd = enter_Dirfd
+
+func enter_Dirfd(dirp uintptr) (fd int, err error) {
+	funcref := get_DirfdAddr()
+	if funcptrtest(GetZosLibVec()+SYS_DIRFD<<4, "") == 0 {
+		*funcref = impl_Dirfd
+	} else {
+		*funcref = error_Dirfd
 	}
+	return (*funcref)(dirp)
+}
+
+func error_Dirfd(dirp uintptr) (fd int, err error) {
+	fd = -1
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := syscall_syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = errnoErr(e1)
+func impl_EpollCreate(size int) (fd int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_EPOLL_CREATE<<4, uintptr(size))
+	runtime.ExitSyscall()
+	fd = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_EpollCreateAddr() *(func(size int) (fd int, err error))
 
-func FcntlInt(fd uintptr, cmd int, arg int) (retval int, err error) {
-	r0, _, e1 := syscall_syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	retval = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+var EpollCreate = enter_EpollCreate
+
+func enter_EpollCreate(size int) (fd int, err error) {
+	funcref := get_EpollCreateAddr()
+	if funcptrtest(GetZosLibVec()+SYS_EPOLL_CREATE<<4, "") == 0 {
+		*funcref = impl_EpollCreate
+	} else {
+		*funcref = error_EpollCreate
 	}
+	return (*funcref)(size)
+}
+
+func error_EpollCreate(size int) (fd int, err error) {
+	fd = -1
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat(fd int, stat *Stat_LE_t) (err error) {
-	_, _, e1 := syscall_syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+func impl_EpollCreate1(flags int) (fd int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_EPOLL_CREATE1<<4, uintptr(flags))
+	runtime.ExitSyscall()
+	fd = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_EpollCreate1Addr() *(func(flags int) (fd int, err error))
 
-func Fstatvfs(fd int, stat *Statvfs_t) (err error) {
-	_, _, e1 := syscall_syscall(SYS_FSTATVFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+var EpollCreate1 = enter_EpollCreate1
+
+func enter_EpollCreate1(flags int) (fd int, err error) {
+	funcref := get_EpollCreate1Addr()
+	if funcptrtest(GetZosLibVec()+SYS_EPOLL_CREATE1<<4, "") == 0 {
+		*funcref = impl_EpollCreate1
+	} else {
+		*funcref = error_EpollCreate1
 	}
+	return (*funcref)(flags)
+}
+
+func error_EpollCreate1(flags int) (fd int, err error) {
+	fd = -1
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fsync(fd int) (err error) {
-	_, _, e1 := syscall_syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+func impl_EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_EPOLL_CTL<<4, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_EpollCtlAddr() *(func(epfd int, op int, fd int, event *EpollEvent) (err error))
 
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := syscall_syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+var EpollCtl = enter_EpollCtl
+
+func enter_EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+	funcref := get_EpollCtlAddr()
+	if funcptrtest(GetZosLibVec()+SYS_EPOLL_CTL<<4, "") == 0 {
+		*funcref = impl_EpollCtl
+	} else {
+		*funcref = error_EpollCtl
 	}
-	return
+	return (*funcref)(epfd, op, fd, event)
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpagesize() (pgsize int) {
-	r0, _, _ := syscall_syscall(SYS_GETPAGESIZE, 0, 0, 0)
-	pgsize = int(r0)
+func error_EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mprotect(b []byte, prot int) (err error) {
+func impl_EpollPwait(epfd int, events []EpollEvent, msec int, sigmask *int) (n int, err error) {
 	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
+	if len(events) > 0 {
+		_p0 = unsafe.Pointer(&events[0])
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_EPOLL_PWAIT<<4, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), uintptr(unsafe.Pointer(sigmask)))
+	runtime.ExitSyscall()
+	n = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_EpollPwaitAddr() *(func(epfd int, events []EpollEvent, msec int, sigmask *int) (n int, err error))
 
-func Msync(b []byte, flags int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
+var EpollPwait = enter_EpollPwait
+
+func enter_EpollPwait(epfd int, events []EpollEvent, msec int, sigmask *int) (n int, err error) {
+	funcref := get_EpollPwaitAddr()
+	if funcptrtest(GetZosLibVec()+SYS_EPOLL_PWAIT<<4, "") == 0 {
+		*funcref = impl_EpollPwait
 	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := syscall_syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
-	if e1 != 0 {
-		err = errnoErr(e1)
+		*funcref = error_EpollPwait
 	}
+	return (*funcref)(epfd, events, msec, sigmask)
+}
+
+func error_EpollPwait(epfd int, events []EpollEvent, msec int, sigmask *int) (n int, err error) {
+	n = -1
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Poll(fds []PollFd, timeout int) (n int, err error) {
+func impl_EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
 	var _p0 unsafe.Pointer
-	if len(fds) > 0 {
-		_p0 = unsafe.Pointer(&fds[0])
+	if len(events) > 0 {
+		_p0 = unsafe.Pointer(&events[0])
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall(SYS_POLL, uintptr(_p0), uintptr(len(fds)), uintptr(timeout))
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_EPOLL_WAIT<<4, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec))
+	runtime.ExitSyscall()
 	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_EpollWaitAddr() *(func(epfd int, events []EpollEvent, msec int) (n int, err error))
 
-func Times(tms *Tms) (ticks uintptr, err error) {
-	r0, _, e1 := syscall_syscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
-	ticks = uintptr(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+var EpollWait = enter_EpollWait
+
+func enter_EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+	funcref := get_EpollWaitAddr()
+	if funcptrtest(GetZosLibVec()+SYS_EPOLL_WAIT<<4, "") == 0 {
+		*funcref = impl_EpollWait
+	} else {
+		*funcref = error_EpollWait
 	}
+	return (*funcref)(epfd, events, msec)
+}
+
+func error_EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+	n = -1
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func W_Getmntent(buff *byte, size int) (lastsys int, err error) {
-	r0, _, e1 := syscall_syscall(SYS_W_GETMNTENT, uintptr(unsafe.Pointer(buff)), uintptr(size), 0)
-	lastsys = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
+func Errno2() (er2 int) {
+	runtime.EnterSyscall()
+	r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS___ERRNO2<<4)
+	runtime.ExitSyscall()
+	er2 = int(r0)
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func W_Getmntent_A(buff *byte, size int) (lastsys int, err error) {
-	r0, _, e1 := syscall_syscall(SYS___W_GETMNTENT_A, uintptr(unsafe.Pointer(buff)), uintptr(size), 0)
-	lastsys = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+func impl_Eventfd(initval uint, flags int) (fd int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_EVENTFD<<4, uintptr(initval), uintptr(flags))
+	runtime.ExitSyscall()
+	fd = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
+//go:nosplit
+func get_EventfdAddr() *(func(initval uint, flags int) (fd int, err error))
+
+var Eventfd = enter_Eventfd
+
+func enter_Eventfd(initval uint, flags int) (fd int, err error) {
+	funcref := get_EventfdAddr()
+	if funcptrtest(GetZosLibVec()+SYS_EVENTFD<<4, "") == 0 {
+		*funcref = impl_Eventfd
+	} else {
+		*funcref = error_Eventfd
+	}
+	return (*funcref)(initval, flags)
+}
+
+func error_Eventfd(initval uint, flags int) (fd int, err error) {
+	fd = -1
+	err = ENOSYS
+	return
+}
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func mount_LE(path string, filesystem string, fstype string, mtm uint32, parmlen int32, parm string) (err error) {
+func Exit(code int) {
+	runtime.EnterSyscall()
+	CallLeFuncWithErr(GetZosLibVec()+SYS_EXIT<<4, uintptr(code))
+	runtime.ExitSyscall()
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(filesystem)
-	if err != nil {
-		return
-	}
-	var _p2 *byte
-	_p2, err = BytePtrFromString(fstype)
-	if err != nil {
-		return
-	}
-	var _p3 *byte
-	_p3, err = BytePtrFromString(parm)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall6(SYS___MOUNT_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(mtm), uintptr(parmlen), uintptr(unsafe.Pointer(_p3)))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___FACCESSAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_FaccessatAddr() *(func(dirfd int, path string, mode uint32, flags int) (err error))
 
-func unmount(filesystem string, mtm int) (err error) {
+var Faccessat = enter_Faccessat
+
+func enter_Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	funcref := get_FaccessatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___FACCESSAT_A<<4, "") == 0 {
+		*funcref = impl_Faccessat
+	} else {
+		*funcref = error_Faccessat
+	}
+	return (*funcref)(dirfd, path, mode, flags)
+}
+
+func error_Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCHDIR<<4, uintptr(fd))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCHMOD<<4, uintptr(fd), uintptr(mode))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
 	var _p0 *byte
-	_p0, err = BytePtrFromString(filesystem)
+	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___UMOUNT_A, uintptr(unsafe.Pointer(_p0)), uintptr(mtm), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___FCHMODAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_FchmodatAddr() *(func(dirfd int, path string, mode uint32, flags int) (err error))
+
+var Fchmodat = enter_Fchmodat
+
+func enter_Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	funcref := get_FchmodatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___FCHMODAT_A<<4, "") == 0 {
+		*funcref = impl_Fchmodat
+	} else {
+		*funcref = error_Fchmodat
+	}
+	return (*funcref)(dirfd, path, mode, flags)
+}
+
+func error_Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCHOWN<<4, uintptr(fd), uintptr(uid), uintptr(gid))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Chroot(path string) (err error) {
+func impl_Fchownat(fd int, path string, uid int, gid int, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___CHROOT_A, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___FCHOWNAT_A<<4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_FchownatAddr() *(func(fd int, path string, uid int, gid int, flags int) (err error))
+
+var Fchownat = enter_Fchownat
+
+func enter_Fchownat(fd int, path string, uid int, gid int, flags int) (err error) {
+	funcref := get_FchownatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___FCHOWNAT_A<<4, "") == 0 {
+		*funcref = impl_Fchownat
+	} else {
+		*funcref = error_Fchownat
 	}
+	return (*funcref)(fd, path, uid, gid, flags)
+}
+
+func error_Fchownat(fd int, path string, uid int, gid int, flags int) (err error) {
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Uname(buf *Utsname) (err error) {
-	_, _, e1 := syscall_rawsyscall(SYS___UNAME_A, uintptr(unsafe.Pointer(buf)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+func FcntlInt(fd uintptr, cmd int, arg int) (retval int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, uintptr(fd), uintptr(cmd), uintptr(arg))
+	runtime.ExitSyscall()
+	retval = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Gethostname(buf []byte) (err error) {
+func impl_Fdatasync(fd int) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FDATASYNC<<4, uintptr(fd))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_FdatasyncAddr() *(func(fd int) (err error))
+
+var Fdatasync = enter_Fdatasync
+
+func enter_Fdatasync(fd int) (err error) {
+	funcref := get_FdatasyncAddr()
+	if funcptrtest(GetZosLibVec()+SYS_FDATASYNC<<4, "") == 0 {
+		*funcref = impl_Fdatasync
+	} else {
+		*funcref = error_Fdatasync
+	}
+	return (*funcref)(fd)
+}
+
+func error_Fdatasync(fd int) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fstat(fd int, stat *Stat_LE_t) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FSTAT<<4, uintptr(fd), uintptr(unsafe.Pointer(stat)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_fstatat(dirfd int, path string, stat *Stat_LE_t, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___FSTATAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_fstatatAddr() *(func(dirfd int, path string, stat *Stat_LE_t, flags int) (err error))
+
+var fstatat = enter_fstatat
+
+func enter_fstatat(dirfd int, path string, stat *Stat_LE_t, flags int) (err error) {
+	funcref := get_fstatatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___FSTATAT_A<<4, "") == 0 {
+		*funcref = impl_fstatat
+	} else {
+		*funcref = error_fstatat
+	}
+	return (*funcref)(dirfd, path, stat, flags)
+}
+
+func error_fstatat(dirfd int, path string, stat *Stat_LE_t, flags int) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	var _p2 unsafe.Pointer
+	if len(dest) > 0 {
+		_p2 = unsafe.Pointer(&dest[0])
+	} else {
+		_p2 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___LGETXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)))
+	runtime.ExitSyscall()
+	sz = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_LgetxattrAddr() *(func(link string, attr string, dest []byte) (sz int, err error))
+
+var Lgetxattr = enter_Lgetxattr
+
+func enter_Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
+	funcref := get_LgetxattrAddr()
+	if funcptrtest(GetZosLibVec()+SYS___LGETXATTR_A<<4, "") == 0 {
+		*funcref = impl_Lgetxattr
+	} else {
+		*funcref = error_Lgetxattr
+	}
+	return (*funcref)(link, attr, dest)
+}
+
+func error_Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
+	sz = -1
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Lsetxattr(path string, attr string, data []byte, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	var _p2 unsafe.Pointer
+	if len(data) > 0 {
+		_p2 = unsafe.Pointer(&data[0])
+	} else {
+		_p2 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___LSETXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_LsetxattrAddr() *(func(path string, attr string, data []byte, flags int) (err error))
+
+var Lsetxattr = enter_Lsetxattr
+
+func enter_Lsetxattr(path string, attr string, data []byte, flags int) (err error) {
+	funcref := get_LsetxattrAddr()
+	if funcptrtest(GetZosLibVec()+SYS___LSETXATTR_A<<4, "") == 0 {
+		*funcref = impl_Lsetxattr
+	} else {
+		*funcref = error_Lsetxattr
+	}
+	return (*funcref)(path, attr, data, flags)
+}
+
+func error_Lsetxattr(path string, attr string, data []byte, flags int) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Fstatfs(fd int, buf *Statfs_t) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FSTATFS<<4, uintptr(fd), uintptr(unsafe.Pointer(buf)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_FstatfsAddr() *(func(fd int, buf *Statfs_t) (err error))
+
+var Fstatfs = enter_Fstatfs
+
+func enter_Fstatfs(fd int, buf *Statfs_t) (err error) {
+	funcref := get_FstatfsAddr()
+	if funcptrtest(GetZosLibVec()+SYS_FSTATFS<<4, "") == 0 {
+		*funcref = impl_Fstatfs
+	} else {
+		*funcref = error_Fstatfs
+	}
+	return (*funcref)(fd, buf)
+}
+
+func error_Fstatfs(fd int, buf *Statfs_t) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatvfs(fd int, stat *Statvfs_t) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FSTATVFS<<4, uintptr(fd), uintptr(unsafe.Pointer(stat)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FSYNC<<4, uintptr(fd))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Futimes(fd int, tv []Timeval) (err error) {
 	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
+	if len(tv) > 0 {
+		_p0 = unsafe.Pointer(&tv[0])
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := syscall_syscall(SYS___GETHOSTNAME_A, uintptr(_p0), uintptr(len(buf)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FUTIMES<<4, uintptr(fd), uintptr(_p0), uintptr(len(tv)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_FutimesAddr() *(func(fd int, tv []Timeval) (err error))
 
-func Getegid() (egid int) {
-	r0, _, _ := syscall_rawsyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
+var Futimes = enter_Futimes
+
+func enter_Futimes(fd int, tv []Timeval) (err error) {
+	funcref := get_FutimesAddr()
+	if funcptrtest(GetZosLibVec()+SYS_FUTIMES<<4, "") == 0 {
+		*funcref = impl_Futimes
+	} else {
+		*funcref = error_Futimes
+	}
+	return (*funcref)(fd, tv)
+}
+
+func error_Futimes(fd int, tv []Timeval) (err error) {
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Geteuid() (uid int) {
-	r0, _, _ := syscall_rawsyscall(SYS_GETEUID, 0, 0, 0)
-	uid = int(r0)
+func impl_Futimesat(dirfd int, path string, tv []Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(tv) > 0 {
+		_p1 = unsafe.Pointer(&tv[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___FUTIMESAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(tv)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_FutimesatAddr() *(func(dirfd int, path string, tv []Timeval) (err error))
+
+var Futimesat = enter_Futimesat
+
+func enter_Futimesat(dirfd int, path string, tv []Timeval) (err error) {
+	funcref := get_FutimesatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___FUTIMESAT_A<<4, "") == 0 {
+		*funcref = impl_Futimesat
+	} else {
+		*funcref = error_Futimesat
+	}
+	return (*funcref)(dirfd, path, tv)
+}
+
+func error_Futimesat(dirfd int, path string, tv []Timeval) (err error) {
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Getgid() (gid int) {
-	r0, _, _ := syscall_rawsyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
+func Ftruncate(fd int, length int64) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FTRUNCATE<<4, uintptr(fd), uintptr(length))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Getpid() (pid int) {
-	r0, _, _ := syscall_rawsyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
+func impl_Getrandom(buf []byte, flags int) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_GETRANDOM<<4, uintptr(_p0), uintptr(len(buf)), uintptr(flags))
+	runtime.ExitSyscall()
+	n = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_GetrandomAddr() *(func(buf []byte, flags int) (n int, err error))
+
+var Getrandom = enter_Getrandom
+
+func enter_Getrandom(buf []byte, flags int) (n int, err error) {
+	funcref := get_GetrandomAddr()
+	if funcptrtest(GetZosLibVec()+SYS_GETRANDOM<<4, "") == 0 {
+		*funcref = impl_Getrandom
+	} else {
+		*funcref = error_Getrandom
+	}
+	return (*funcref)(buf, flags)
+}
+
+func error_Getrandom(buf []byte, flags int) (n int, err error) {
+	n = -1
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := syscall_rawsyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+func impl_InotifyInit() (fd int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec() + SYS_INOTIFY_INIT<<4)
+	runtime.ExitSyscall()
+	fd = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_InotifyInitAddr() *(func() (fd int, err error))
+
+var InotifyInit = enter_InotifyInit
+
+func enter_InotifyInit() (fd int, err error) {
+	funcref := get_InotifyInitAddr()
+	if funcptrtest(GetZosLibVec()+SYS_INOTIFY_INIT<<4, "") == 0 {
+		*funcref = impl_InotifyInit
+	} else {
+		*funcref = error_InotifyInit
 	}
+	return (*funcref)()
+}
+
+func error_InotifyInit() (fd int, err error) {
+	fd = -1
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Getppid() (pid int) {
-	r0, _, _ := syscall_rawsyscall(SYS_GETPPID, 0, 0, 0)
-	pid = int(r0)
+func impl_InotifyInit1(flags int) (fd int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_INOTIFY_INIT1<<4, uintptr(flags))
+	runtime.ExitSyscall()
+	fd = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_InotifyInit1Addr() *(func(flags int) (fd int, err error))
+
+var InotifyInit1 = enter_InotifyInit1
+
+func enter_InotifyInit1(flags int) (fd int, err error) {
+	funcref := get_InotifyInit1Addr()
+	if funcptrtest(GetZosLibVec()+SYS_INOTIFY_INIT1<<4, "") == 0 {
+		*funcref = impl_InotifyInit1
+	} else {
+		*funcref = error_InotifyInit1
+	}
+	return (*funcref)(flags)
+}
+
+func error_InotifyInit1(flags int) (fd int, err error) {
+	fd = -1
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(pathname)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___INOTIFY_ADD_WATCH_A<<4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask))
+	runtime.ExitSyscall()
+	watchdesc = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_InotifyAddWatchAddr() *(func(fd int, pathname string, mask uint32) (watchdesc int, err error))
+
+var InotifyAddWatch = enter_InotifyAddWatch
+
+func enter_InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
+	funcref := get_InotifyAddWatchAddr()
+	if funcptrtest(GetZosLibVec()+SYS___INOTIFY_ADD_WATCH_A<<4, "") == 0 {
+		*funcref = impl_InotifyAddWatch
+	} else {
+		*funcref = error_InotifyAddWatch
+	}
+	return (*funcref)(fd, pathname, mask)
+}
+
+func error_InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
+	watchdesc = -1
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_INOTIFY_RM_WATCH<<4, uintptr(fd), uintptr(watchdesc))
+	runtime.ExitSyscall()
+	success = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_InotifyRmWatchAddr() *(func(fd int, watchdesc uint32) (success int, err error))
+
+var InotifyRmWatch = enter_InotifyRmWatch
+
+func enter_InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
+	funcref := get_InotifyRmWatchAddr()
+	if funcptrtest(GetZosLibVec()+SYS_INOTIFY_RM_WATCH<<4, "") == 0 {
+		*funcref = impl_InotifyRmWatch
+	} else {
+		*funcref = error_InotifyRmWatch
+	}
+	return (*funcref)(fd, watchdesc)
+}
+
+func error_InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
+	success = -1
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Listxattr(path string, dest []byte) (sz int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(dest) > 0 {
+		_p1 = unsafe.Pointer(&dest[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___LISTXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
+	runtime.ExitSyscall()
+	sz = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_ListxattrAddr() *(func(path string, dest []byte) (sz int, err error))
+
+var Listxattr = enter_Listxattr
+
+func enter_Listxattr(path string, dest []byte) (sz int, err error) {
+	funcref := get_ListxattrAddr()
+	if funcptrtest(GetZosLibVec()+SYS___LISTXATTR_A<<4, "") == 0 {
+		*funcref = impl_Listxattr
+	} else {
+		*funcref = error_Listxattr
+	}
+	return (*funcref)(path, dest)
+}
+
+func error_Listxattr(path string, dest []byte) (sz int, err error) {
+	sz = -1
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Llistxattr(path string, dest []byte) (sz int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(dest) > 0 {
+		_p1 = unsafe.Pointer(&dest[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___LLISTXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
+	runtime.ExitSyscall()
+	sz = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_LlistxattrAddr() *(func(path string, dest []byte) (sz int, err error))
+
+var Llistxattr = enter_Llistxattr
+
+func enter_Llistxattr(path string, dest []byte) (sz int, err error) {
+	funcref := get_LlistxattrAddr()
+	if funcptrtest(GetZosLibVec()+SYS___LLISTXATTR_A<<4, "") == 0 {
+		*funcref = impl_Llistxattr
+	} else {
+		*funcref = error_Llistxattr
+	}
+	return (*funcref)(path, dest)
+}
+
+func error_Llistxattr(path string, dest []byte) (sz int, err error) {
+	sz = -1
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Lremovexattr(path string, attr string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___LREMOVEXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_LremovexattrAddr() *(func(path string, attr string) (err error))
+
+var Lremovexattr = enter_Lremovexattr
+
+func enter_Lremovexattr(path string, attr string) (err error) {
+	funcref := get_LremovexattrAddr()
+	if funcptrtest(GetZosLibVec()+SYS___LREMOVEXATTR_A<<4, "") == 0 {
+		*funcref = impl_Lremovexattr
+	} else {
+		*funcref = error_Lremovexattr
+	}
+	return (*funcref)(path, attr)
+}
+
+func error_Lremovexattr(path string, attr string) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Lutimes(path string, tv []Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(tv) > 0 {
+		_p1 = unsafe.Pointer(&tv[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___LUTIMES_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(tv)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_LutimesAddr() *(func(path string, tv []Timeval) (err error))
+
+var Lutimes = enter_Lutimes
+
+func enter_Lutimes(path string, tv []Timeval) (err error) {
+	funcref := get_LutimesAddr()
+	if funcptrtest(GetZosLibVec()+SYS___LUTIMES_A<<4, "") == 0 {
+		*funcref = impl_Lutimes
+	} else {
+		*funcref = error_Lutimes
+	}
+	return (*funcref)(path, tv)
+}
+
+func error_Lutimes(path string, tv []Timeval) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_MPROTECT<<4, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_MSYNC<<4, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Console2(cmsg *ConsMsg2, modstr *byte, concmd *uint32) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___CONSOLE2<<4, uintptr(unsafe.Pointer(cmsg)), uintptr(unsafe.Pointer(modstr)), uintptr(unsafe.Pointer(concmd)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Poll(fds []PollFd, timeout int) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(fds) > 0 {
+		_p0 = unsafe.Pointer(&fds[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_POLL<<4, uintptr(_p0), uintptr(len(fds)), uintptr(timeout))
+	runtime.ExitSyscall()
+	n = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readdir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___READDIR_R_A<<4, uintptr(dirp), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Statfs(path string, buf *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___STATFS_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_StatfsAddr() *(func(path string, buf *Statfs_t) (err error))
+
+var Statfs = enter_Statfs
+
+func enter_Statfs(path string, buf *Statfs_t) (err error) {
+	funcref := get_StatfsAddr()
+	if funcptrtest(GetZosLibVec()+SYS___STATFS_A<<4, "") == 0 {
+		*funcref = impl_Statfs
+	} else {
+		*funcref = error_Statfs
+	}
+	return (*funcref)(path, buf)
+}
+
+func error_Statfs(path string, buf *Statfs_t) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Syncfs(fd int) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SYNCFS<<4, uintptr(fd))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_SyncfsAddr() *(func(fd int) (err error))
+
+var Syncfs = enter_Syncfs
+
+func enter_Syncfs(fd int) (err error) {
+	funcref := get_SyncfsAddr()
+	if funcptrtest(GetZosLibVec()+SYS_SYNCFS<<4, "") == 0 {
+		*funcref = impl_Syncfs
+	} else {
+		*funcref = error_Syncfs
+	}
+	return (*funcref)(fd)
+}
+
+func error_Syncfs(fd int) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Times(tms *Tms) (ticks uintptr, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_TIMES<<4, uintptr(unsafe.Pointer(tms)))
+	runtime.ExitSyscall()
+	ticks = uintptr(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func W_Getmntent(buff *byte, size int) (lastsys int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_W_GETMNTENT<<4, uintptr(unsafe.Pointer(buff)), uintptr(size))
+	runtime.ExitSyscall()
+	lastsys = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func W_Getmntent_A(buff *byte, size int) (lastsys int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___W_GETMNTENT_A<<4, uintptr(unsafe.Pointer(buff)), uintptr(size))
+	runtime.ExitSyscall()
+	lastsys = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount_LE(path string, filesystem string, fstype string, mtm uint32, parmlen int32, parm string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(filesystem)
+	if err != nil {
+		return
+	}
+	var _p2 *byte
+	_p2, err = BytePtrFromString(fstype)
+	if err != nil {
+		return
+	}
+	var _p3 *byte
+	_p3, err = BytePtrFromString(parm)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MOUNT_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(mtm), uintptr(parmlen), uintptr(unsafe.Pointer(_p3)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func unmount_LE(filesystem string, mtm int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(filesystem)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___UMOUNT_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(mtm))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___CHROOT_A<<4, uintptr(unsafe.Pointer(_p0)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(nmsgsfds int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (ret int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SELECT<<4, uintptr(nmsgsfds), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)))
+	runtime.ExitSyscall()
+	ret = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Uname(buf *Utsname) (err error) {
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_____OSNAME_A<<4, uintptr(unsafe.Pointer(buf)))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Unshare(flags int) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_UNSHARE<<4, uintptr(flags))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_UnshareAddr() *(func(flags int) (err error))
+
+var Unshare = enter_Unshare
+
+func enter_Unshare(flags int) (err error) {
+	funcref := get_UnshareAddr()
+	if funcptrtest(GetZosLibVec()+SYS_UNSHARE<<4, "") == 0 {
+		*funcref = impl_Unshare
+	} else {
+		*funcref = error_Unshare
+	}
+	return (*funcref)(flags)
+}
+
+func error_Unshare(flags int) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gethostname(buf []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___GETHOSTNAME_A<<4, uintptr(_p0), uintptr(len(buf)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS_GETGID<<4)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS_GETPID<<4)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_GETPGID<<4, uintptr(pid))
+	pgid = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (pid int) {
+	r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS_GETPPID<<4)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_GETPRIORITY<<4, uintptr(which), uintptr(who))
+	runtime.ExitSyscall()
+	prio = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(resource int, rlim *Rlimit) (err error) {
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_GETRLIMIT<<4, uintptr(resource), uintptr(unsafe.Pointer(rlim)))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getrusage(who int, rusage *rusage_zos) (err error) {
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_GETRUSAGE<<4, uintptr(who), uintptr(unsafe.Pointer(rusage)))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	runtime.EnterSyscall()
+	r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS_GETEGID<<4)
+	runtime.ExitSyscall()
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (euid int) {
+	runtime.EnterSyscall()
+	r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS_GETEUID<<4)
+	runtime.ExitSyscall()
+	euid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_GETSID<<4, uintptr(pid))
+	sid = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS_GETUID<<4)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, sig Signal) (err error) {
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_KILL<<4, uintptr(pid), uintptr(sig))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___LCHOWN_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___LINK_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Linkat(oldDirFd int, oldPath string, newDirFd int, newPath string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldPath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newPath)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___LINKAT_A<<4, uintptr(oldDirFd), uintptr(unsafe.Pointer(_p0)), uintptr(newDirFd), uintptr(unsafe.Pointer(_p1)), uintptr(flags))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_LinkatAddr() *(func(oldDirFd int, oldPath string, newDirFd int, newPath string, flags int) (err error))
+
+var Linkat = enter_Linkat
+
+func enter_Linkat(oldDirFd int, oldPath string, newDirFd int, newPath string, flags int) (err error) {
+	funcref := get_LinkatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___LINKAT_A<<4, "") == 0 {
+		*funcref = impl_Linkat
+	} else {
+		*funcref = error_Linkat
+	}
+	return (*funcref)(oldDirFd, oldPath, newDirFd, newPath, flags)
+}
+
+func error_Linkat(oldDirFd int, oldPath string, newDirFd int, newPath string, flags int) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, n int) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_LISTEN<<4, uintptr(s), uintptr(n))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func lstat(path string, stat *Stat_LE_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___LSTAT_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MKDIR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MKDIRAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_MkdiratAddr() *(func(dirfd int, path string, mode uint32) (err error))
+
+var Mkdirat = enter_Mkdirat
+
+func enter_Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	funcref := get_MkdiratAddr()
+	if funcptrtest(GetZosLibVec()+SYS___MKDIRAT_A<<4, "") == 0 {
+		*funcref = impl_Mkdirat
+	} else {
+		*funcref = error_Mkdirat
+	}
+	return (*funcref)(dirfd, path, mode)
+}
+
+func error_Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MKFIFO_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MKNOD_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MKNODAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_MknodatAddr() *(func(dirfd int, path string, mode uint32, dev int) (err error))
+
+var Mknodat = enter_Mknodat
+
+func enter_Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
+	funcref := get_MknodatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___MKNODAT_A<<4, "") == 0 {
+		*funcref = impl_Mknodat
+	} else {
+		*funcref = error_Mknodat
+	}
+	return (*funcref)(dirfd, path, mode, dev)
+}
+
+func error_Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_PivotRoot(newroot string, oldroot string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(newroot)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(oldroot)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___PIVOT_ROOT_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_PivotRootAddr() *(func(newroot string, oldroot string) (err error))
+
+var PivotRoot = enter_PivotRoot
+
+func enter_PivotRoot(newroot string, oldroot string) (err error) {
+	funcref := get_PivotRootAddr()
+	if funcptrtest(GetZosLibVec()+SYS___PIVOT_ROOT_A<<4, "") == 0 {
+		*funcref = impl_PivotRoot
+	} else {
+		*funcref = error_PivotRoot
+	}
+	return (*funcref)(newroot, oldroot)
+}
+
+func error_PivotRoot(newroot string, oldroot string) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_PREAD<<4, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset))
+	runtime.ExitSyscall()
+	n = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := syscall_syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_PWRITE<<4, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset))
+	runtime.ExitSyscall()
+	n = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Getrlimit(resource int, rlim *Rlimit) (err error) {
-	_, _, e1 := syscall_rawsyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+func impl_Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___PRCTL_A<<4, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_PrctlAddr() *(func(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error))
 
-func getrusage(who int, rusage *rusage_zos) (err error) {
-	_, _, e1 := syscall_rawsyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+var Prctl = enter_Prctl
+
+func enter_Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) {
+	funcref := get_PrctlAddr()
+	if funcptrtest(GetZosLibVec()+SYS___PRCTL_A<<4, "") == 0 {
+		*funcref = impl_Prctl
+	} else {
+		*funcref = error_Prctl
 	}
-	return
+	return (*funcref)(option, arg2, arg3, arg4, arg5)
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := syscall_rawsyscall(SYS_GETSID, uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
+func error_Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) {
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Getuid() (uid int) {
-	r0, _, _ := syscall_rawsyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
+func impl_Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_PRLIMIT<<4, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_PrlimitAddr() *(func(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error))
 
-func Kill(pid int, sig Signal) (err error) {
-	_, _, e1 := syscall_rawsyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+var Prlimit = enter_Prlimit
+
+func enter_Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
+	funcref := get_PrlimitAddr()
+	if funcptrtest(GetZosLibVec()+SYS_PRLIMIT<<4, "") == 0 {
+		*funcref = impl_Prlimit
+	} else {
+		*funcref = error_Prlimit
 	}
+	return (*funcref)(pid, resource, newlimit, old)
+}
+
+func error_Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Lchown(path string, uid int, gid int) (err error) {
+func Rename(from string, to string) (err error) {
 	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___LCHOWN_A, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___RENAME_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Link(path string, link string) (err error) {
+func impl_Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
 	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
+	_p0, err = BytePtrFromString(oldpath)
 	if err != nil {
 		return
 	}
 	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
+	_p1, err = BytePtrFromString(newpath)
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___LINK_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___RENAMEAT_A<<4, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_RenameatAddr() *(func(olddirfd int, oldpath string, newdirfd int, newpath string) (err error))
 
-func Listen(s int, n int) (err error) {
-	_, _, e1 := syscall_syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+var Renameat = enter_Renameat
+
+func enter_Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
+	funcref := get_RenameatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___RENAMEAT_A<<4, "") == 0 {
+		*funcref = impl_Renameat
+	} else {
+		*funcref = error_Renameat
 	}
+	return (*funcref)(olddirfd, oldpath, newdirfd, newpath)
+}
+
+func error_Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func lstat(path string, stat *Stat_LE_t) (err error) {
+func impl_Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) {
 	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___LSTAT_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___RENAMEAT2_A<<4, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_Renameat2Addr() *(func(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error))
 
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(SYS___MKDIR_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+var Renameat2 = enter_Renameat2
+
+func enter_Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) {
+	funcref := get_Renameat2Addr()
+	if funcptrtest(GetZosLibVec()+SYS___RENAMEAT2_A<<4, "") == 0 {
+		*funcref = impl_Renameat2
+	} else {
+		*funcref = error_Renameat2
 	}
+	return (*funcref)(olddirfd, oldpath, newdirfd, newpath, flags)
+}
+
+func error_Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) {
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mkfifo(path string, mode uint32) (err error) {
+func Rmdir(path string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___MKFIFO_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___RMDIR_A<<4, uintptr(unsafe.Pointer(_p0)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(SYS___MKNOD_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = errnoErr(e1)
+func Seek(fd int, offset int64, whence int) (off int64, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_LSEEK<<4, uintptr(fd), uintptr(offset), uintptr(whence))
+	runtime.ExitSyscall()
+	off = int64(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
+func Setegid(egid int) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SETEGID<<4, uintptr(egid))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
-	r0, _, e1 := syscall_syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SETEUID<<4, uintptr(euid))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+func impl_Sethostname(p []byte) (err error) {
 	var _p0 unsafe.Pointer
 	if len(p) > 0 {
 		_p0 = unsafe.Pointer(&p[0])
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := syscall_syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___SETHOSTNAME_A<<4, uintptr(_p0), uintptr(len(p)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_SethostnameAddr() *(func(p []byte) (err error))
 
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
+var Sethostname = enter_Sethostname
+
+func enter_Sethostname(p []byte) (err error) {
+	funcref := get_SethostnameAddr()
+	if funcptrtest(GetZosLibVec()+SYS___SETHOSTNAME_A<<4, "") == 0 {
+		*funcref = impl_Sethostname
 	} else {
-		_p1 = unsafe.Pointer(&_zero)
+		*funcref = error_Sethostname
 	}
-	r0, _, e1 := syscall_syscall(SYS___READLINK_A, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
+	return (*funcref)(p)
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(SYS___RENAME_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
+func error_Sethostname(p []byte) (err error) {
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := syscall_syscall(SYS___RMDIR_A, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+func impl_Setns(fd int, nstype int) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SETNS<<4, uintptr(fd), uintptr(nstype))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+//go:nosplit
+func get_SetnsAddr() *(func(fd int, nstype int) (err error))
 
-func Seek(fd int, offset int64, whence int) (off int64, err error) {
-	r0, _, e1 := syscall_syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
-	off = int64(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+var Setns = enter_Setns
+
+func enter_Setns(fd int, nstype int) (err error) {
+	funcref := get_SetnsAddr()
+	if funcptrtest(GetZosLibVec()+SYS_SETNS<<4, "") == 0 {
+		*funcref = impl_Setns
+	} else {
+		*funcref = error_Setns
 	}
+	return (*funcref)(fd, nstype)
+}
+
+func error_Setns(fd int, nstype int) (err error) {
+	err = ENOSYS
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := syscall_syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SETPRIORITY<<4, uintptr(which), uintptr(who), uintptr(prio))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -971,9 +2910,9 @@ func Setpriority(which int, who int, prio int) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := syscall_rawsyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SETPGID<<4, uintptr(pid), uintptr(pgid))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -981,9 +2920,9 @@ func Setpgid(pid int, pgid int) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(resource int, lim *Rlimit) (err error) {
-	_, _, e1 := syscall_rawsyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SETRLIMIT<<4, uintptr(resource), uintptr(unsafe.Pointer(lim)))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -991,9 +2930,9 @@ func Setrlimit(resource int, lim *Rlimit) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := syscall_rawsyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SETREGID<<4, uintptr(rgid), uintptr(egid))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1001,9 +2940,9 @@ func Setregid(rgid int, egid int) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := syscall_rawsyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SETREUID<<4, uintptr(ruid), uintptr(euid))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1011,10 +2950,10 @@ func Setreuid(ruid int, euid int) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := syscall_rawsyscall(SYS_SETSID, 0, 0, 0)
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec() + SYS_SETSID<<4)
 	pid = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1022,9 +2961,11 @@ func Setsid() (pid int, err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := syscall_syscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SETUID<<4, uintptr(uid))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1032,9 +2973,11 @@ func Setuid(uid int) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(uid int) (err error) {
-	_, _, e1 := syscall_syscall(SYS_SETGID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SETGID<<4, uintptr(uid))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1042,9 +2985,11 @@ func Setgid(uid int) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(fd int, how int) (err error) {
-	_, _, e1 := syscall_syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_SHUTDOWN<<4, uintptr(fd), uintptr(how))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1057,9 +3002,11 @@ func stat(path string, statLE *Stat_LE_t) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___STAT_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(statLE)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___STAT_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(statLE)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1077,17 +3024,63 @@ func Symlink(path string, link string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___SYMLINK_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___SYMLINK_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Symlinkat(oldPath string, dirfd int, newPath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldPath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newPath)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___SYMLINKAT_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(dirfd), uintptr(unsafe.Pointer(_p1)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
+//go:nosplit
+func get_SymlinkatAddr() *(func(oldPath string, dirfd int, newPath string) (err error))
+
+var Symlinkat = enter_Symlinkat
+
+func enter_Symlinkat(oldPath string, dirfd int, newPath string) (err error) {
+	funcref := get_SymlinkatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___SYMLINKAT_A<<4, "") == 0 {
+		*funcref = impl_Symlinkat
+	} else {
+		*funcref = error_Symlinkat
+	}
+	return (*funcref)(oldPath, dirfd, newPath)
+}
+
+func error_Symlinkat(oldPath string, dirfd int, newPath string) (err error) {
+	err = ENOSYS
+	return
+}
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() {
-	syscall_syscall(SYS_SYNC, 0, 0, 0)
+	runtime.EnterSyscall()
+	CallLeFuncWithErr(GetZosLibVec() + SYS_SYNC<<4)
+	runtime.ExitSyscall()
 	return
 }
 
@@ -1099,9 +3092,11 @@ func Truncate(path string, length int64) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___TRUNCATE_A, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___TRUNCATE_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(length))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1109,9 +3104,11 @@ func Truncate(path string, length int64) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Tcgetattr(fildes int, termptr *Termios) (err error) {
-	_, _, e1 := syscall_syscall(SYS_TCGETATTR, uintptr(fildes), uintptr(unsafe.Pointer(termptr)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_TCGETATTR<<4, uintptr(fildes), uintptr(unsafe.Pointer(termptr)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1119,9 +3116,11 @@ func Tcgetattr(fildes int, termptr *Termios) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Tcsetattr(fildes int, when int, termptr *Termios) (err error) {
-	_, _, e1 := syscall_syscall(SYS_TCSETATTR, uintptr(fildes), uintptr(when), uintptr(unsafe.Pointer(termptr)))
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_TCSETATTR<<4, uintptr(fildes), uintptr(when), uintptr(unsafe.Pointer(termptr)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1129,7 +3128,9 @@ func Tcsetattr(fildes int, when int, termptr *Termios) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(mask int) (oldmask int) {
-	r0, _, _ := syscall_syscall(SYS_UMASK, uintptr(mask), 0, 0)
+	runtime.EnterSyscall()
+	r0, _, _ := CallLeFuncWithErr(GetZosLibVec()+SYS_UMASK<<4, uintptr(mask))
+	runtime.ExitSyscall()
 	oldmask = int(r0)
 	return
 }
@@ -1142,10 +3143,49 @@ func Unlink(path string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___UNLINK_A, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___UNLINK_A<<4, uintptr(unsafe.Pointer(_p0)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_Unlinkat(dirfd int, path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___UNLINKAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_UnlinkatAddr() *(func(dirfd int, path string, flags int) (err error))
+
+var Unlinkat = enter_Unlinkat
+
+func enter_Unlinkat(dirfd int, path string, flags int) (err error) {
+	funcref := get_UnlinkatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___UNLINKAT_A<<4, "") == 0 {
+		*funcref = impl_Unlinkat
+	} else {
+		*funcref = error_Unlinkat
 	}
+	return (*funcref)(dirfd, path, flags)
+}
+
+func error_Unlinkat(dirfd int, path string, flags int) (err error) {
+	err = ENOSYS
 	return
 }
 
@@ -1157,9 +3197,11 @@ func Utime(path string, utim *Utimbuf) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___UTIME_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(utim)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___UTIME_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(utim)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1172,11 +3214,91 @@ func open(path string, mode int, perm uint32) (fd int, err error) {
 	if err != nil {
 		return
 	}
-	r0, _, e1 := syscall_syscall(SYS___OPEN_A, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___OPEN_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	runtime.ExitSyscall()
+	fd = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___OPENAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode))
+	runtime.ExitSyscall()
+	fd = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_openatAddr() *(func(dirfd int, path string, flags int, mode uint32) (fd int, err error))
+
+var openat = enter_openat
+
+func enter_openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
+	funcref := get_openatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___OPENAT_A<<4, "") == 0 {
+		*funcref = impl_openat
+	} else {
+		*funcref = error_openat
+	}
+	return (*funcref)(dirfd, path, flags, mode)
+}
+
+func error_openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
+	fd = -1
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func impl_openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___OPENAT2_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(open_how)), uintptr(size))
+	runtime.ExitSyscall()
 	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_openat2Addr() *(func(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error))
+
+var openat2 = enter_openat2
+
+func enter_openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) {
+	funcref := get_openat2Addr()
+	if funcptrtest(GetZosLibVec()+SYS___OPENAT2_A<<4, "") == 0 {
+		*funcref = impl_openat2
+	} else {
+		*funcref = error_openat2
 	}
+	return (*funcref)(dirfd, path, open_how, size)
+}
+
+func error_openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) {
+	fd = -1
+	err = ENOSYS
 	return
 }
 
@@ -1188,9 +3310,23 @@ func remove(path string) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_REMOVE<<4, uintptr(unsafe.Pointer(_p0)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func waitid(idType int, id int, info *Siginfo, options int) (err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_WAITID<<4, uintptr(idType), uintptr(id), uintptr(unsafe.Pointer(info)), uintptr(options))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1198,10 +3334,12 @@ func remove(path string) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func waitpid(pid int, wstatus *_C_int, options int) (wpid int, err error) {
-	r0, _, e1 := syscall_syscall(SYS_WAITPID, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options))
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_WAITPID<<4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options))
+	runtime.ExitSyscall()
 	wpid = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1209,9 +3347,9 @@ func waitpid(pid int, wstatus *_C_int, options int) (wpid int, err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func gettimeofday(tv *timeval_zos) (err error) {
-	_, _, e1 := syscall_rawsyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_GETTIMEOFDAY<<4, uintptr(unsafe.Pointer(tv)))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1219,9 +3357,9 @@ func gettimeofday(tv *timeval_zos) (err error) {
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pipe(p *[2]_C_int) (err error) {
-	_, _, e1 := syscall_rawsyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_PIPE<<4, uintptr(unsafe.Pointer(p)))
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
@@ -1234,20 +3372,87 @@ func utimes(path string, timeval *[2]Timeval) (err error) {
 	if err != nil {
 		return
 	}
-	_, _, e1 := syscall_syscall(SYS___UTIMES_A, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___UTIMES_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Select(nmsgsfds int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (ret int, err error) {
-	r0, _, e1 := syscall_syscall6(SYS_SELECT, uintptr(nmsgsfds), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	ret = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
+func impl_utimensat(dirfd int, path string, ts *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___UTIMENSAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(ts)), uintptr(flags))
+	runtime.ExitSyscall()
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+//go:nosplit
+func get_utimensatAddr() *(func(dirfd int, path string, ts *[2]Timespec, flags int) (err error))
+
+var utimensat = enter_utimensat
+
+func enter_utimensat(dirfd int, path string, ts *[2]Timespec, flags int) (err error) {
+	funcref := get_utimensatAddr()
+	if funcptrtest(GetZosLibVec()+SYS___UTIMENSAT_A<<4, "") == 0 {
+		*funcref = impl_utimensat
+	} else {
+		*funcref = error_utimensat
+	}
+	return (*funcref)(dirfd, path, ts, flags)
+}
+
+func error_utimensat(dirfd int, path string, ts *[2]Timespec, flags int) (err error) {
+	err = ENOSYS
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Posix_openpt(oflag int) (fd int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_POSIX_OPENPT<<4, uintptr(oflag))
+	runtime.ExitSyscall()
+	fd = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Grantpt(fildes int) (rc int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_GRANTPT<<4, uintptr(fildes))
+	runtime.ExitSyscall()
+	rc = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlockpt(fildes int) (rc int, err error) {
+	runtime.EnterSyscall()
+	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_UNLOCKPT<<4, uintptr(fildes))
+	runtime.ExitSyscall()
+	rc = int(r0)
+	if int64(r0) == -1 {
+		err = errnoErr2(e1, e2)
 	}
 	return
 }
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
index 0cc3ce49..53aef5dc 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
@@ -452,4 +452,9 @@ const (
 	SYS_FUTEX_WAKE                   = 454
 	SYS_FUTEX_WAIT                   = 455
 	SYS_FUTEX_REQUEUE                = 456
+	SYS_STATMOUNT                    = 457
+	SYS_LISTMOUNT                    = 458
+	SYS_LSM_GET_SELF_ATTR            = 459
+	SYS_LSM_SET_SELF_ATTR            = 460
+	SYS_LSM_LIST_MODULES             = 461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
index 856d92d6..71d52476 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
@@ -374,4 +374,9 @@ const (
 	SYS_FUTEX_WAKE              = 454
 	SYS_FUTEX_WAIT              = 455
 	SYS_FUTEX_REQUEUE           = 456
+	SYS_STATMOUNT               = 457
+	SYS_LISTMOUNT               = 458
+	SYS_LSM_GET_SELF_ATTR       = 459
+	SYS_LSM_SET_SELF_ATTR       = 460
+	SYS_LSM_LIST_MODULES        = 461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
index 8d467094..c7477061 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
@@ -416,4 +416,9 @@ const (
 	SYS_FUTEX_WAKE                   = 454
 	SYS_FUTEX_WAIT                   = 455
 	SYS_FUTEX_REQUEUE                = 456
+	SYS_STATMOUNT                    = 457
+	SYS_LISTMOUNT                    = 458
+	SYS_LSM_GET_SELF_ATTR            = 459
+	SYS_LSM_SET_SELF_ATTR            = 460
+	SYS_LSM_LIST_MODULES             = 461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
index edc17324..f96e214f 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
@@ -319,4 +319,9 @@ const (
 	SYS_FUTEX_WAKE              = 454
 	SYS_FUTEX_WAIT              = 455
 	SYS_FUTEX_REQUEUE           = 456
+	SYS_STATMOUNT               = 457
+	SYS_LISTMOUNT               = 458
+	SYS_LSM_GET_SELF_ATTR       = 459
+	SYS_LSM_SET_SELF_ATTR       = 460
+	SYS_LSM_LIST_MODULES        = 461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go
index 445eba20..28425346 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go
@@ -313,4 +313,9 @@ const (
 	SYS_FUTEX_WAKE              = 454
 	SYS_FUTEX_WAIT              = 455
 	SYS_FUTEX_REQUEUE           = 456
+	SYS_STATMOUNT               = 457
+	SYS_LISTMOUNT               = 458
+	SYS_LSM_GET_SELF_ATTR       = 459
+	SYS_LSM_SET_SELF_ATTR       = 460
+	SYS_LSM_LIST_MODULES        = 461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go
index adba01bc..d0953018 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go
@@ -436,4 +436,9 @@ const (
 	SYS_FUTEX_WAKE                   = 4454
 	SYS_FUTEX_WAIT                   = 4455
 	SYS_FUTEX_REQUEUE                = 4456
+	SYS_STATMOUNT                    = 4457
+	SYS_LISTMOUNT                    = 4458
+	SYS_LSM_GET_SELF_ATTR            = 4459
+	SYS_LSM_SET_SELF_ATTR            = 4460
+	SYS_LSM_LIST_MODULES             = 4461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go
index 014c4e9c..295c7f4b 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go
@@ -366,4 +366,9 @@ const (
 	SYS_FUTEX_WAKE              = 5454
 	SYS_FUTEX_WAIT              = 5455
 	SYS_FUTEX_REQUEUE           = 5456
+	SYS_STATMOUNT               = 5457
+	SYS_LISTMOUNT               = 5458
+	SYS_LSM_GET_SELF_ATTR       = 5459
+	SYS_LSM_SET_SELF_ATTR       = 5460
+	SYS_LSM_LIST_MODULES        = 5461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go
index ccc97d74..d1a9eaca 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go
@@ -366,4 +366,9 @@ const (
 	SYS_FUTEX_WAKE              = 5454
 	SYS_FUTEX_WAIT              = 5455
 	SYS_FUTEX_REQUEUE           = 5456
+	SYS_STATMOUNT               = 5457
+	SYS_LISTMOUNT               = 5458
+	SYS_LSM_GET_SELF_ATTR       = 5459
+	SYS_LSM_SET_SELF_ATTR       = 5460
+	SYS_LSM_LIST_MODULES        = 5461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go
index ec2b64a9..bec157c3 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go
@@ -436,4 +436,9 @@ const (
 	SYS_FUTEX_WAKE                   = 4454
 	SYS_FUTEX_WAIT                   = 4455
 	SYS_FUTEX_REQUEUE                = 4456
+	SYS_STATMOUNT                    = 4457
+	SYS_LISTMOUNT                    = 4458
+	SYS_LSM_GET_SELF_ATTR            = 4459
+	SYS_LSM_SET_SELF_ATTR            = 4460
+	SYS_LSM_LIST_MODULES             = 4461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go
index 21a839e3..7ee7bdc4 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go
@@ -443,4 +443,9 @@ const (
 	SYS_FUTEX_WAKE                   = 454
 	SYS_FUTEX_WAIT                   = 455
 	SYS_FUTEX_REQUEUE                = 456
+	SYS_STATMOUNT                    = 457
+	SYS_LISTMOUNT                    = 458
+	SYS_LSM_GET_SELF_ATTR            = 459
+	SYS_LSM_SET_SELF_ATTR            = 460
+	SYS_LSM_LIST_MODULES             = 461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
index c11121ec..fad1f25b 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
@@ -415,4 +415,9 @@ const (
 	SYS_FUTEX_WAKE              = 454
 	SYS_FUTEX_WAIT              = 455
 	SYS_FUTEX_REQUEUE           = 456
+	SYS_STATMOUNT               = 457
+	SYS_LISTMOUNT               = 458
+	SYS_LSM_GET_SELF_ATTR       = 459
+	SYS_LSM_SET_SELF_ATTR       = 460
+	SYS_LSM_LIST_MODULES        = 461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
index 909b631f..7d3e1635 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
@@ -415,4 +415,9 @@ const (
 	SYS_FUTEX_WAKE              = 454
 	SYS_FUTEX_WAIT              = 455
 	SYS_FUTEX_REQUEUE           = 456
+	SYS_STATMOUNT               = 457
+	SYS_LISTMOUNT               = 458
+	SYS_LSM_GET_SELF_ATTR       = 459
+	SYS_LSM_SET_SELF_ATTR       = 460
+	SYS_LSM_LIST_MODULES        = 461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
index e49bed16..0ed53ad9 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
@@ -320,4 +320,9 @@ const (
 	SYS_FUTEX_WAKE              = 454
 	SYS_FUTEX_WAIT              = 455
 	SYS_FUTEX_REQUEUE           = 456
+	SYS_STATMOUNT               = 457
+	SYS_LISTMOUNT               = 458
+	SYS_LSM_GET_SELF_ATTR       = 459
+	SYS_LSM_SET_SELF_ATTR       = 460
+	SYS_LSM_LIST_MODULES        = 461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go
index 66017d2d..2fba04ad 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go
@@ -381,4 +381,9 @@ const (
 	SYS_FUTEX_WAKE              = 454
 	SYS_FUTEX_WAIT              = 455
 	SYS_FUTEX_REQUEUE           = 456
+	SYS_STATMOUNT               = 457
+	SYS_LISTMOUNT               = 458
+	SYS_LSM_GET_SELF_ATTR       = 459
+	SYS_LSM_SET_SELF_ATTR       = 460
+	SYS_LSM_LIST_MODULES        = 461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go
index 47bab18d..621d00d7 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go
@@ -394,4 +394,9 @@ const (
 	SYS_FUTEX_WAKE              = 454
 	SYS_FUTEX_WAIT              = 455
 	SYS_FUTEX_REQUEUE           = 456
+	SYS_STATMOUNT               = 457
+	SYS_LISTMOUNT               = 458
+	SYS_LSM_GET_SELF_ATTR       = 459
+	SYS_LSM_SET_SELF_ATTR       = 460
+	SYS_LSM_LIST_MODULES        = 461
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_zos_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_zos_s390x.go
index b2e30858..5e8c263c 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_zos_s390x.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_zos_s390x.go
@@ -1,2669 +1,2852 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
+// go run mksyscall_zos_s390x.go -o_sysnum zsysnum_zos_s390x.go -o_syscall zsyscall_zos_s390x.go -i_syscall syscall_zos_s390x.go -o_asm zsymaddr_zos_s390x.s
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build zos && s390x
 
 package unix
 
-// TODO: auto-generate.
-
 const (
-	SYS_ACOSD128                        = 0xB80
-	SYS_ACOSD32                         = 0xB7E
-	SYS_ACOSD64                         = 0xB7F
-	SYS_ACOSHD128                       = 0xB83
-	SYS_ACOSHD32                        = 0xB81
-	SYS_ACOSHD64                        = 0xB82
-	SYS_AIO_FSYNC                       = 0xC69
-	SYS_ASCTIME                         = 0x0AE
-	SYS_ASCTIME64                       = 0xCD7
-	SYS_ASCTIME64_R                     = 0xCD8
-	SYS_ASIND128                        = 0xB86
-	SYS_ASIND32                         = 0xB84
-	SYS_ASIND64                         = 0xB85
-	SYS_ASINHD128                       = 0xB89
-	SYS_ASINHD32                        = 0xB87
-	SYS_ASINHD64                        = 0xB88
-	SYS_ATAN2D128                       = 0xB8F
-	SYS_ATAN2D32                        = 0xB8D
-	SYS_ATAN2D64                        = 0xB8E
-	SYS_ATAND128                        = 0xB8C
-	SYS_ATAND32                         = 0xB8A
-	SYS_ATAND64                         = 0xB8B
-	SYS_ATANHD128                       = 0xB92
-	SYS_ATANHD32                        = 0xB90
-	SYS_ATANHD64                        = 0xB91
-	SYS_BIND2ADDRSEL                    = 0xD59
-	SYS_C16RTOMB                        = 0xD40
-	SYS_C32RTOMB                        = 0xD41
-	SYS_CBRTD128                        = 0xB95
-	SYS_CBRTD32                         = 0xB93
-	SYS_CBRTD64                         = 0xB94
-	SYS_CEILD128                        = 0xB98
-	SYS_CEILD32                         = 0xB96
-	SYS_CEILD64                         = 0xB97
-	SYS_CLEARENV                        = 0x0C9
-	SYS_CLEARERR_UNLOCKED               = 0xCA1
-	SYS_CLOCK                           = 0x0AA
-	SYS_CLOGL                           = 0xA00
-	SYS_CLRMEMF                         = 0x0BD
-	SYS_CONJ                            = 0xA03
-	SYS_CONJF                           = 0xA06
-	SYS_CONJL                           = 0xA09
-	SYS_COPYSIGND128                    = 0xB9E
-	SYS_COPYSIGND32                     = 0xB9C
-	SYS_COPYSIGND64                     = 0xB9D
-	SYS_COSD128                         = 0xBA1
-	SYS_COSD32                          = 0xB9F
-	SYS_COSD64                          = 0xBA0
-	SYS_COSHD128                        = 0xBA4
-	SYS_COSHD32                         = 0xBA2
-	SYS_COSHD64                         = 0xBA3
-	SYS_CPOW                            = 0xA0C
-	SYS_CPOWF                           = 0xA0F
-	SYS_CPOWL                           = 0xA12
-	SYS_CPROJ                           = 0xA15
-	SYS_CPROJF                          = 0xA18
-	SYS_CPROJL                          = 0xA1B
-	SYS_CREAL                           = 0xA1E
-	SYS_CREALF                          = 0xA21
-	SYS_CREALL                          = 0xA24
-	SYS_CSIN                            = 0xA27
-	SYS_CSINF                           = 0xA2A
-	SYS_CSINH                           = 0xA30
-	SYS_CSINHF                          = 0xA33
-	SYS_CSINHL                          = 0xA36
-	SYS_CSINL                           = 0xA2D
-	SYS_CSNAP                           = 0x0C5
-	SYS_CSQRT                           = 0xA39
-	SYS_CSQRTF                          = 0xA3C
-	SYS_CSQRTL                          = 0xA3F
-	SYS_CTAN                            = 0xA42
-	SYS_CTANF                           = 0xA45
-	SYS_CTANH                           = 0xA4B
-	SYS_CTANHF                          = 0xA4E
-	SYS_CTANHL                          = 0xA51
-	SYS_CTANL                           = 0xA48
-	SYS_CTIME                           = 0x0AB
-	SYS_CTIME64                         = 0xCD9
-	SYS_CTIME64_R                       = 0xCDA
-	SYS_CTRACE                          = 0x0C6
-	SYS_DIFFTIME                        = 0x0A7
-	SYS_DIFFTIME64                      = 0xCDB
-	SYS_DLADDR                          = 0xC82
-	SYS_DYNALLOC                        = 0x0C3
-	SYS_DYNFREE                         = 0x0C2
-	SYS_ERFCD128                        = 0xBAA
-	SYS_ERFCD32                         = 0xBA8
-	SYS_ERFCD64                         = 0xBA9
-	SYS_ERFD128                         = 0xBA7
-	SYS_ERFD32                          = 0xBA5
-	SYS_ERFD64                          = 0xBA6
-	SYS_EXP2D128                        = 0xBB0
-	SYS_EXP2D32                         = 0xBAE
-	SYS_EXP2D64                         = 0xBAF
-	SYS_EXPD128                         = 0xBAD
-	SYS_EXPD32                          = 0xBAB
-	SYS_EXPD64                          = 0xBAC
-	SYS_EXPM1D128                       = 0xBB3
-	SYS_EXPM1D32                        = 0xBB1
-	SYS_EXPM1D64                        = 0xBB2
-	SYS_FABSD128                        = 0xBB6
-	SYS_FABSD32                         = 0xBB4
-	SYS_FABSD64                         = 0xBB5
-	SYS_FDELREC_UNLOCKED                = 0xCA2
-	SYS_FDIMD128                        = 0xBB9
-	SYS_FDIMD32                         = 0xBB7
-	SYS_FDIMD64                         = 0xBB8
-	SYS_FDOPEN_UNLOCKED                 = 0xCFC
-	SYS_FECLEAREXCEPT                   = 0xAEA
-	SYS_FEGETENV                        = 0xAEB
-	SYS_FEGETEXCEPTFLAG                 = 0xAEC
-	SYS_FEGETROUND                      = 0xAED
-	SYS_FEHOLDEXCEPT                    = 0xAEE
-	SYS_FEOF_UNLOCKED                   = 0xCA3
-	SYS_FERAISEEXCEPT                   = 0xAEF
-	SYS_FERROR_UNLOCKED                 = 0xCA4
-	SYS_FESETENV                        = 0xAF0
-	SYS_FESETEXCEPTFLAG                 = 0xAF1
-	SYS_FESETROUND                      = 0xAF2
-	SYS_FETCHEP                         = 0x0BF
-	SYS_FETESTEXCEPT                    = 0xAF3
-	SYS_FEUPDATEENV                     = 0xAF4
-	SYS_FE_DEC_GETROUND                 = 0xBBA
-	SYS_FE_DEC_SETROUND                 = 0xBBB
-	SYS_FFLUSH_UNLOCKED                 = 0xCA5
-	SYS_FGETC_UNLOCKED                  = 0xC80
-	SYS_FGETPOS64                       = 0xCEE
-	SYS_FGETPOS64_UNLOCKED              = 0xCF4
-	SYS_FGETPOS_UNLOCKED                = 0xCA6
-	SYS_FGETS_UNLOCKED                  = 0xC7C
-	SYS_FGETWC_UNLOCKED                 = 0xCA7
-	SYS_FGETWS_UNLOCKED                 = 0xCA8
-	SYS_FILENO_UNLOCKED                 = 0xCA9
-	SYS_FLDATA                          = 0x0C1
-	SYS_FLDATA_UNLOCKED                 = 0xCAA
-	SYS_FLOCATE_UNLOCKED                = 0xCAB
-	SYS_FLOORD128                       = 0xBBE
-	SYS_FLOORD32                        = 0xBBC
-	SYS_FLOORD64                        = 0xBBD
-	SYS_FMA                             = 0xA63
-	SYS_FMAD128                         = 0xBC1
-	SYS_FMAD32                          = 0xBBF
-	SYS_FMAD64                          = 0xBC0
-	SYS_FMAF                            = 0xA66
-	SYS_FMAL                            = 0xA69
-	SYS_FMAX                            = 0xA6C
-	SYS_FMAXD128                        = 0xBC4
-	SYS_FMAXD32                         = 0xBC2
-	SYS_FMAXD64                         = 0xBC3
-	SYS_FMAXF                           = 0xA6F
-	SYS_FMAXL                           = 0xA72
-	SYS_FMIN                            = 0xA75
-	SYS_FMIND128                        = 0xBC7
-	SYS_FMIND32                         = 0xBC5
-	SYS_FMIND64                         = 0xBC6
-	SYS_FMINF                           = 0xA78
-	SYS_FMINL                           = 0xA7B
-	SYS_FMODD128                        = 0xBCA
-	SYS_FMODD32                         = 0xBC8
-	SYS_FMODD64                         = 0xBC9
-	SYS_FOPEN64                         = 0xD49
-	SYS_FOPEN64_UNLOCKED                = 0xD4A
-	SYS_FOPEN_UNLOCKED                  = 0xCFA
-	SYS_FPRINTF_UNLOCKED                = 0xCAC
-	SYS_FPUTC_UNLOCKED                  = 0xC81
-	SYS_FPUTS_UNLOCKED                  = 0xC7E
-	SYS_FPUTWC_UNLOCKED                 = 0xCAD
-	SYS_FPUTWS_UNLOCKED                 = 0xCAE
-	SYS_FREAD_NOUPDATE                  = 0xCEC
-	SYS_FREAD_NOUPDATE_UNLOCKED         = 0xCED
-	SYS_FREAD_UNLOCKED                  = 0xC7B
-	SYS_FREEIFADDRS                     = 0xCE6
-	SYS_FREOPEN64                       = 0xD4B
-	SYS_FREOPEN64_UNLOCKED              = 0xD4C
-	SYS_FREOPEN_UNLOCKED                = 0xCFB
-	SYS_FREXPD128                       = 0xBCE
-	SYS_FREXPD32                        = 0xBCC
-	SYS_FREXPD64                        = 0xBCD
-	SYS_FSCANF_UNLOCKED                 = 0xCAF
-	SYS_FSEEK64                         = 0xCEF
-	SYS_FSEEK64_UNLOCKED                = 0xCF5
-	SYS_FSEEKO64                        = 0xCF0
-	SYS_FSEEKO64_UNLOCKED               = 0xCF6
-	SYS_FSEEKO_UNLOCKED                 = 0xCB1
-	SYS_FSEEK_UNLOCKED                  = 0xCB0
-	SYS_FSETPOS64                       = 0xCF1
-	SYS_FSETPOS64_UNLOCKED              = 0xCF7
-	SYS_FSETPOS_UNLOCKED                = 0xCB3
-	SYS_FTELL64                         = 0xCF2
-	SYS_FTELL64_UNLOCKED                = 0xCF8
-	SYS_FTELLO64                        = 0xCF3
-	SYS_FTELLO64_UNLOCKED               = 0xCF9
-	SYS_FTELLO_UNLOCKED                 = 0xCB5
-	SYS_FTELL_UNLOCKED                  = 0xCB4
-	SYS_FUPDATE                         = 0x0B5
-	SYS_FUPDATE_UNLOCKED                = 0xCB7
-	SYS_FWIDE_UNLOCKED                  = 0xCB8
-	SYS_FWPRINTF_UNLOCKED               = 0xCB9
-	SYS_FWRITE_UNLOCKED                 = 0xC7A
-	SYS_FWSCANF_UNLOCKED                = 0xCBA
-	SYS_GETDATE64                       = 0xD4F
-	SYS_GETIFADDRS                      = 0xCE7
-	SYS_GETIPV4SOURCEFILTER             = 0xC77
-	SYS_GETSOURCEFILTER                 = 0xC79
-	SYS_GETSYNTX                        = 0x0FD
-	SYS_GETS_UNLOCKED                   = 0xC7D
-	SYS_GETTIMEOFDAY64                  = 0xD50
-	SYS_GETWCHAR_UNLOCKED               = 0xCBC
-	SYS_GETWC_UNLOCKED                  = 0xCBB
-	SYS_GMTIME                          = 0x0B0
-	SYS_GMTIME64                        = 0xCDC
-	SYS_GMTIME64_R                      = 0xCDD
-	SYS_HYPOTD128                       = 0xBD1
-	SYS_HYPOTD32                        = 0xBCF
-	SYS_HYPOTD64                        = 0xBD0
-	SYS_ILOGBD128                       = 0xBD4
-	SYS_ILOGBD32                        = 0xBD2
-	SYS_ILOGBD64                        = 0xBD3
-	SYS_ILOGBF                          = 0xA7E
-	SYS_ILOGBL                          = 0xA81
-	SYS_INET6_IS_SRCADDR                = 0xD5A
-	SYS_ISBLANK                         = 0x0FE
-	SYS_ISWALNUM                        = 0x0FF
-	SYS_LDEXPD128                       = 0xBD7
-	SYS_LDEXPD32                        = 0xBD5
-	SYS_LDEXPD64                        = 0xBD6
-	SYS_LGAMMAD128                      = 0xBDA
-	SYS_LGAMMAD32                       = 0xBD8
-	SYS_LGAMMAD64                       = 0xBD9
-	SYS_LIO_LISTIO                      = 0xC6A
-	SYS_LLRINT                          = 0xA84
-	SYS_LLRINTD128                      = 0xBDD
-	SYS_LLRINTD32                       = 0xBDB
-	SYS_LLRINTD64                       = 0xBDC
-	SYS_LLRINTF                         = 0xA87
-	SYS_LLRINTL                         = 0xA8A
-	SYS_LLROUND                         = 0xA8D
-	SYS_LLROUNDD128                     = 0xBE0
-	SYS_LLROUNDD32                      = 0xBDE
-	SYS_LLROUNDD64                      = 0xBDF
-	SYS_LLROUNDF                        = 0xA90
-	SYS_LLROUNDL                        = 0xA93
-	SYS_LOCALTIM                        = 0x0B1
-	SYS_LOCALTIME                       = 0x0B1
-	SYS_LOCALTIME64                     = 0xCDE
-	SYS_LOCALTIME64_R                   = 0xCDF
-	SYS_LOG10D128                       = 0xBE6
-	SYS_LOG10D32                        = 0xBE4
-	SYS_LOG10D64                        = 0xBE5
-	SYS_LOG1PD128                       = 0xBE9
-	SYS_LOG1PD32                        = 0xBE7
-	SYS_LOG1PD64                        = 0xBE8
-	SYS_LOG2D128                        = 0xBEC
-	SYS_LOG2D32                         = 0xBEA
-	SYS_LOG2D64                         = 0xBEB
-	SYS_LOGBD128                        = 0xBEF
-	SYS_LOGBD32                         = 0xBED
-	SYS_LOGBD64                         = 0xBEE
-	SYS_LOGBF                           = 0xA96
-	SYS_LOGBL                           = 0xA99
-	SYS_LOGD128                         = 0xBE3
-	SYS_LOGD32                          = 0xBE1
-	SYS_LOGD64                          = 0xBE2
-	SYS_LRINT                           = 0xA9C
-	SYS_LRINTD128                       = 0xBF2
-	SYS_LRINTD32                        = 0xBF0
-	SYS_LRINTD64                        = 0xBF1
-	SYS_LRINTF                          = 0xA9F
-	SYS_LRINTL                          = 0xAA2
-	SYS_LROUNDD128                      = 0xBF5
-	SYS_LROUNDD32                       = 0xBF3
-	SYS_LROUNDD64                       = 0xBF4
-	SYS_LROUNDL                         = 0xAA5
-	SYS_MBLEN                           = 0x0AF
-	SYS_MBRTOC16                        = 0xD42
-	SYS_MBRTOC32                        = 0xD43
-	SYS_MEMSET                          = 0x0A3
-	SYS_MKTIME                          = 0x0AC
-	SYS_MKTIME64                        = 0xCE0
-	SYS_MODFD128                        = 0xBF8
-	SYS_MODFD32                         = 0xBF6
-	SYS_MODFD64                         = 0xBF7
-	SYS_NAN                             = 0xAA8
-	SYS_NAND128                         = 0xBFB
-	SYS_NAND32                          = 0xBF9
-	SYS_NAND64                          = 0xBFA
-	SYS_NANF                            = 0xAAA
-	SYS_NANL                            = 0xAAC
-	SYS_NEARBYINT                       = 0xAAE
-	SYS_NEARBYINTD128                   = 0xBFE
-	SYS_NEARBYINTD32                    = 0xBFC
-	SYS_NEARBYINTD64                    = 0xBFD
-	SYS_NEARBYINTF                      = 0xAB1
-	SYS_NEARBYINTL                      = 0xAB4
-	SYS_NEXTAFTERD128                   = 0xC01
-	SYS_NEXTAFTERD32                    = 0xBFF
-	SYS_NEXTAFTERD64                    = 0xC00
-	SYS_NEXTAFTERF                      = 0xAB7
-	SYS_NEXTAFTERL                      = 0xABA
-	SYS_NEXTTOWARD                      = 0xABD
-	SYS_NEXTTOWARDD128                  = 0xC04
-	SYS_NEXTTOWARDD32                   = 0xC02
-	SYS_NEXTTOWARDD64                   = 0xC03
-	SYS_NEXTTOWARDF                     = 0xAC0
-	SYS_NEXTTOWARDL                     = 0xAC3
-	SYS_NL_LANGINFO                     = 0x0FC
-	SYS_PERROR_UNLOCKED                 = 0xCBD
-	SYS_POSIX_FALLOCATE                 = 0xCE8
-	SYS_POSIX_MEMALIGN                  = 0xCE9
-	SYS_POSIX_OPENPT                    = 0xC66
-	SYS_POWD128                         = 0xC07
-	SYS_POWD32                          = 0xC05
-	SYS_POWD64                          = 0xC06
-	SYS_PRINTF_UNLOCKED                 = 0xCBE
-	SYS_PSELECT                         = 0xC67
-	SYS_PTHREAD_ATTR_GETSTACK           = 0xB3E
-	SYS_PTHREAD_ATTR_SETSTACK           = 0xB3F
-	SYS_PTHREAD_SECURITY_APPLID_NP      = 0xCE4
-	SYS_PUTS_UNLOCKED                   = 0xC7F
-	SYS_PUTWCHAR_UNLOCKED               = 0xCC0
-	SYS_PUTWC_UNLOCKED                  = 0xCBF
-	SYS_QUANTEXPD128                    = 0xD46
-	SYS_QUANTEXPD32                     = 0xD44
-	SYS_QUANTEXPD64                     = 0xD45
-	SYS_QUANTIZED128                    = 0xC0A
-	SYS_QUANTIZED32                     = 0xC08
-	SYS_QUANTIZED64                     = 0xC09
-	SYS_REMAINDERD128                   = 0xC0D
-	SYS_REMAINDERD32                    = 0xC0B
-	SYS_REMAINDERD64                    = 0xC0C
-	SYS_RESIZE_ALLOC                    = 0xCEB
-	SYS_REWIND_UNLOCKED                 = 0xCC1
-	SYS_RINTD128                        = 0xC13
-	SYS_RINTD32                         = 0xC11
-	SYS_RINTD64                         = 0xC12
-	SYS_RINTF                           = 0xACB
-	SYS_RINTL                           = 0xACD
-	SYS_ROUND                           = 0xACF
-	SYS_ROUNDD128                       = 0xC16
-	SYS_ROUNDD32                        = 0xC14
-	SYS_ROUNDD64                        = 0xC15
-	SYS_ROUNDF                          = 0xAD2
-	SYS_ROUNDL                          = 0xAD5
-	SYS_SAMEQUANTUMD128                 = 0xC19
-	SYS_SAMEQUANTUMD32                  = 0xC17
-	SYS_SAMEQUANTUMD64                  = 0xC18
-	SYS_SCALBLN                         = 0xAD8
-	SYS_SCALBLND128                     = 0xC1C
-	SYS_SCALBLND32                      = 0xC1A
-	SYS_SCALBLND64                      = 0xC1B
-	SYS_SCALBLNF                        = 0xADB
-	SYS_SCALBLNL                        = 0xADE
-	SYS_SCALBND128                      = 0xC1F
-	SYS_SCALBND32                       = 0xC1D
-	SYS_SCALBND64                       = 0xC1E
-	SYS_SCALBNF                         = 0xAE3
-	SYS_SCALBNL                         = 0xAE6
-	SYS_SCANF_UNLOCKED                  = 0xCC2
-	SYS_SCHED_YIELD                     = 0xB32
-	SYS_SETENV                          = 0x0C8
-	SYS_SETIPV4SOURCEFILTER             = 0xC76
-	SYS_SETSOURCEFILTER                 = 0xC78
-	SYS_SHM_OPEN                        = 0xC8C
-	SYS_SHM_UNLINK                      = 0xC8D
-	SYS_SIND128                         = 0xC22
-	SYS_SIND32                          = 0xC20
-	SYS_SIND64                          = 0xC21
-	SYS_SINHD128                        = 0xC25
-	SYS_SINHD32                         = 0xC23
-	SYS_SINHD64                         = 0xC24
-	SYS_SIZEOF_ALLOC                    = 0xCEA
-	SYS_SOCKATMARK                      = 0xC68
-	SYS_SQRTD128                        = 0xC28
-	SYS_SQRTD32                         = 0xC26
-	SYS_SQRTD64                         = 0xC27
-	SYS_STRCHR                          = 0x0A0
-	SYS_STRCSPN                         = 0x0A1
-	SYS_STRERROR                        = 0x0A8
-	SYS_STRERROR_R                      = 0xB33
-	SYS_STRFTIME                        = 0x0B2
-	SYS_STRLEN                          = 0x0A9
-	SYS_STRPBRK                         = 0x0A2
-	SYS_STRSPN                          = 0x0A4
-	SYS_STRSTR                          = 0x0A5
-	SYS_STRTOD128                       = 0xC2B
-	SYS_STRTOD32                        = 0xC29
-	SYS_STRTOD64                        = 0xC2A
-	SYS_STRTOK                          = 0x0A6
-	SYS_TAND128                         = 0xC2E
-	SYS_TAND32                          = 0xC2C
-	SYS_TAND64                          = 0xC2D
-	SYS_TANHD128                        = 0xC31
-	SYS_TANHD32                         = 0xC2F
-	SYS_TANHD64                         = 0xC30
-	SYS_TGAMMAD128                      = 0xC34
-	SYS_TGAMMAD32                       = 0xC32
-	SYS_TGAMMAD64                       = 0xC33
-	SYS_TIME                            = 0x0AD
-	SYS_TIME64                          = 0xCE1
-	SYS_TMPFILE64                       = 0xD4D
-	SYS_TMPFILE64_UNLOCKED              = 0xD4E
-	SYS_TMPFILE_UNLOCKED                = 0xCFD
-	SYS_TRUNCD128                       = 0xC40
-	SYS_TRUNCD32                        = 0xC3E
-	SYS_TRUNCD64                        = 0xC3F
-	SYS_UNGETC_UNLOCKED                 = 0xCC3
-	SYS_UNGETWC_UNLOCKED                = 0xCC4
-	SYS_UNSETENV                        = 0xB34
-	SYS_VFPRINTF_UNLOCKED               = 0xCC5
-	SYS_VFSCANF_UNLOCKED                = 0xCC7
-	SYS_VFWPRINTF_UNLOCKED              = 0xCC9
-	SYS_VFWSCANF_UNLOCKED               = 0xCCB
-	SYS_VPRINTF_UNLOCKED                = 0xCCD
-	SYS_VSCANF_UNLOCKED                 = 0xCCF
-	SYS_VWPRINTF_UNLOCKED               = 0xCD1
-	SYS_VWSCANF_UNLOCKED                = 0xCD3
-	SYS_WCSTOD128                       = 0xC43
-	SYS_WCSTOD32                        = 0xC41
-	SYS_WCSTOD64                        = 0xC42
-	SYS_WPRINTF_UNLOCKED                = 0xCD5
-	SYS_WSCANF_UNLOCKED                 = 0xCD6
-	SYS__FLUSHLBF                       = 0xD68
-	SYS__FLUSHLBF_UNLOCKED              = 0xD6F
-	SYS___ACOSHF_H                      = 0xA54
-	SYS___ACOSHL_H                      = 0xA55
-	SYS___ASINHF_H                      = 0xA56
-	SYS___ASINHL_H                      = 0xA57
-	SYS___ATANPID128                    = 0xC6D
-	SYS___ATANPID32                     = 0xC6B
-	SYS___ATANPID64                     = 0xC6C
-	SYS___CBRTF_H                       = 0xA58
-	SYS___CBRTL_H                       = 0xA59
-	SYS___CDUMP                         = 0x0C4
-	SYS___CLASS                         = 0xAFA
-	SYS___CLASS2                        = 0xB99
-	SYS___CLASS2D128                    = 0xC99
-	SYS___CLASS2D32                     = 0xC97
-	SYS___CLASS2D64                     = 0xC98
-	SYS___CLASS2F                       = 0xC91
-	SYS___CLASS2F_B                     = 0xC93
-	SYS___CLASS2F_H                     = 0xC94
-	SYS___CLASS2L                       = 0xC92
-	SYS___CLASS2L_B                     = 0xC95
-	SYS___CLASS2L_H                     = 0xC96
-	SYS___CLASS2_B                      = 0xB9A
-	SYS___CLASS2_H                      = 0xB9B
-	SYS___CLASS_B                       = 0xAFB
-	SYS___CLASS_H                       = 0xAFC
-	SYS___CLOGL_B                       = 0xA01
-	SYS___CLOGL_H                       = 0xA02
-	SYS___CLRENV                        = 0x0C9
-	SYS___CLRMF                         = 0x0BD
-	SYS___CODEPAGE_INFO                 = 0xC64
-	SYS___CONJF_B                       = 0xA07
-	SYS___CONJF_H                       = 0xA08
-	SYS___CONJL_B                       = 0xA0A
-	SYS___CONJL_H                       = 0xA0B
-	SYS___CONJ_B                        = 0xA04
-	SYS___CONJ_H                        = 0xA05
-	SYS___COPYSIGN_B                    = 0xA5A
-	SYS___COPYSIGN_H                    = 0xAF5
-	SYS___COSPID128                     = 0xC70
-	SYS___COSPID32                      = 0xC6E
-	SYS___COSPID64                      = 0xC6F
-	SYS___CPOWF_B                       = 0xA10
-	SYS___CPOWF_H                       = 0xA11
-	SYS___CPOWL_B                       = 0xA13
-	SYS___CPOWL_H                       = 0xA14
-	SYS___CPOW_B                        = 0xA0D
-	SYS___CPOW_H                        = 0xA0E
-	SYS___CPROJF_B                      = 0xA19
-	SYS___CPROJF_H                      = 0xA1A
-	SYS___CPROJL_B                      = 0xA1C
-	SYS___CPROJL_H                      = 0xA1D
-	SYS___CPROJ_B                       = 0xA16
-	SYS___CPROJ_H                       = 0xA17
-	SYS___CREALF_B                      = 0xA22
-	SYS___CREALF_H                      = 0xA23
-	SYS___CREALL_B                      = 0xA25
-	SYS___CREALL_H                      = 0xA26
-	SYS___CREAL_B                       = 0xA1F
-	SYS___CREAL_H                       = 0xA20
-	SYS___CSINF_B                       = 0xA2B
-	SYS___CSINF_H                       = 0xA2C
-	SYS___CSINHF_B                      = 0xA34
-	SYS___CSINHF_H                      = 0xA35
-	SYS___CSINHL_B                      = 0xA37
-	SYS___CSINHL_H                      = 0xA38
-	SYS___CSINH_B                       = 0xA31
-	SYS___CSINH_H                       = 0xA32
-	SYS___CSINL_B                       = 0xA2E
-	SYS___CSINL_H                       = 0xA2F
-	SYS___CSIN_B                        = 0xA28
-	SYS___CSIN_H                        = 0xA29
-	SYS___CSNAP                         = 0x0C5
-	SYS___CSQRTF_B                      = 0xA3D
-	SYS___CSQRTF_H                      = 0xA3E
-	SYS___CSQRTL_B                      = 0xA40
-	SYS___CSQRTL_H                      = 0xA41
-	SYS___CSQRT_B                       = 0xA3A
-	SYS___CSQRT_H                       = 0xA3B
-	SYS___CTANF_B                       = 0xA46
-	SYS___CTANF_H                       = 0xA47
-	SYS___CTANHF_B                      = 0xA4F
-	SYS___CTANHF_H                      = 0xA50
-	SYS___CTANHL_B                      = 0xA52
-	SYS___CTANHL_H                      = 0xA53
-	SYS___CTANH_B                       = 0xA4C
-	SYS___CTANH_H                       = 0xA4D
-	SYS___CTANL_B                       = 0xA49
-	SYS___CTANL_H                       = 0xA4A
-	SYS___CTAN_B                        = 0xA43
-	SYS___CTAN_H                        = 0xA44
-	SYS___CTEST                         = 0x0C7
-	SYS___CTRACE                        = 0x0C6
-	SYS___D1TOP                         = 0xC9B
-	SYS___D2TOP                         = 0xC9C
-	SYS___D4TOP                         = 0xC9D
-	SYS___DYNALL                        = 0x0C3
-	SYS___DYNFRE                        = 0x0C2
-	SYS___EXP2F_H                       = 0xA5E
-	SYS___EXP2L_H                       = 0xA5F
-	SYS___EXP2_H                        = 0xA5D
-	SYS___EXPM1F_H                      = 0xA5B
-	SYS___EXPM1L_H                      = 0xA5C
-	SYS___FBUFSIZE                      = 0xD60
-	SYS___FLBF                          = 0xD62
-	SYS___FLDATA                        = 0x0C1
-	SYS___FMAF_B                        = 0xA67
-	SYS___FMAF_H                        = 0xA68
-	SYS___FMAL_B                        = 0xA6A
-	SYS___FMAL_H                        = 0xA6B
-	SYS___FMAXF_B                       = 0xA70
-	SYS___FMAXF_H                       = 0xA71
-	SYS___FMAXL_B                       = 0xA73
-	SYS___FMAXL_H                       = 0xA74
-	SYS___FMAX_B                        = 0xA6D
-	SYS___FMAX_H                        = 0xA6E
-	SYS___FMA_B                         = 0xA64
-	SYS___FMA_H                         = 0xA65
-	SYS___FMINF_B                       = 0xA79
-	SYS___FMINF_H                       = 0xA7A
-	SYS___FMINL_B                       = 0xA7C
-	SYS___FMINL_H                       = 0xA7D
-	SYS___FMIN_B                        = 0xA76
-	SYS___FMIN_H                        = 0xA77
-	SYS___FPENDING                      = 0xD61
-	SYS___FPENDING_UNLOCKED             = 0xD6C
-	SYS___FPURGE                        = 0xD69
-	SYS___FPURGE_UNLOCKED               = 0xD70
-	SYS___FP_CAST_D                     = 0xBCB
-	SYS___FREADABLE                     = 0xD63
-	SYS___FREADAHEAD                    = 0xD6A
-	SYS___FREADAHEAD_UNLOCKED           = 0xD71
-	SYS___FREADING                      = 0xD65
-	SYS___FREADING_UNLOCKED             = 0xD6D
-	SYS___FSEEK2                        = 0xB3C
-	SYS___FSETERR                       = 0xD6B
-	SYS___FSETLOCKING                   = 0xD67
-	SYS___FTCHEP                        = 0x0BF
-	SYS___FTELL2                        = 0xB3B
-	SYS___FUPDT                         = 0x0B5
-	SYS___FWRITABLE                     = 0xD64
-	SYS___FWRITING                      = 0xD66
-	SYS___FWRITING_UNLOCKED             = 0xD6E
-	SYS___GETCB                         = 0x0B4
-	SYS___GETGRGID1                     = 0xD5B
-	SYS___GETGRNAM1                     = 0xD5C
-	SYS___GETTHENT                      = 0xCE5
-	SYS___GETTOD                        = 0xD3E
-	SYS___HYPOTF_H                      = 0xAF6
-	SYS___HYPOTL_H                      = 0xAF7
-	SYS___ILOGBF_B                      = 0xA7F
-	SYS___ILOGBF_H                      = 0xA80
-	SYS___ILOGBL_B                      = 0xA82
-	SYS___ILOGBL_H                      = 0xA83
-	SYS___ISBLANK_A                     = 0xB2E
-	SYS___ISBLNK                        = 0x0FE
-	SYS___ISWBLANK_A                    = 0xB2F
-	SYS___LE_CEEGTJS                    = 0xD72
-	SYS___LE_TRACEBACK                  = 0xB7A
-	SYS___LGAMMAL_H                     = 0xA62
-	SYS___LGAMMA_B_C99                  = 0xB39
-	SYS___LGAMMA_H_C99                  = 0xB38
-	SYS___LGAMMA_R_C99                  = 0xB3A
-	SYS___LLRINTF_B                     = 0xA88
-	SYS___LLRINTF_H                     = 0xA89
-	SYS___LLRINTL_B                     = 0xA8B
-	SYS___LLRINTL_H                     = 0xA8C
-	SYS___LLRINT_B                      = 0xA85
-	SYS___LLRINT_H                      = 0xA86
-	SYS___LLROUNDF_B                    = 0xA91
-	SYS___LLROUNDF_H                    = 0xA92
-	SYS___LLROUNDL_B                    = 0xA94
-	SYS___LLROUNDL_H                    = 0xA95
-	SYS___LLROUND_B                     = 0xA8E
-	SYS___LLROUND_H                     = 0xA8F
-	SYS___LOCALE_CTL                    = 0xD47
-	SYS___LOG1PF_H                      = 0xA60
-	SYS___LOG1PL_H                      = 0xA61
-	SYS___LOGBF_B                       = 0xA97
-	SYS___LOGBF_H                       = 0xA98
-	SYS___LOGBL_B                       = 0xA9A
-	SYS___LOGBL_H                       = 0xA9B
-	SYS___LOGIN_APPLID                  = 0xCE2
-	SYS___LRINTF_B                      = 0xAA0
-	SYS___LRINTF_H                      = 0xAA1
-	SYS___LRINTL_B                      = 0xAA3
-	SYS___LRINTL_H                      = 0xAA4
-	SYS___LRINT_B                       = 0xA9D
-	SYS___LRINT_H                       = 0xA9E
-	SYS___LROUNDF_FIXUP                 = 0xB31
-	SYS___LROUNDL_B                     = 0xAA6
-	SYS___LROUNDL_H                     = 0xAA7
-	SYS___LROUND_FIXUP                  = 0xB30
-	SYS___MOSERVICES                    = 0xD3D
-	SYS___MUST_STAY_CLEAN               = 0xB7C
-	SYS___NANF_B                        = 0xAAB
-	SYS___NANL_B                        = 0xAAD
-	SYS___NAN_B                         = 0xAA9
-	SYS___NEARBYINTF_B                  = 0xAB2
-	SYS___NEARBYINTF_H                  = 0xAB3
-	SYS___NEARBYINTL_B                  = 0xAB5
-	SYS___NEARBYINTL_H                  = 0xAB6
-	SYS___NEARBYINT_B                   = 0xAAF
-	SYS___NEARBYINT_H                   = 0xAB0
-	SYS___NEXTAFTERF_B                  = 0xAB8
-	SYS___NEXTAFTERF_H                  = 0xAB9
-	SYS___NEXTAFTERL_B                  = 0xABB
-	SYS___NEXTAFTERL_H                  = 0xABC
-	SYS___NEXTTOWARDF_B                 = 0xAC1
-	SYS___NEXTTOWARDF_H                 = 0xAC2
-	SYS___NEXTTOWARDL_B                 = 0xAC4
-	SYS___NEXTTOWARDL_H                 = 0xAC5
-	SYS___NEXTTOWARD_B                  = 0xABE
-	SYS___NEXTTOWARD_H                  = 0xABF
-	SYS___O_ENV                         = 0xB7D
-	SYS___PASSWD_APPLID                 = 0xCE3
-	SYS___PTOD1                         = 0xC9E
-	SYS___PTOD2                         = 0xC9F
-	SYS___PTOD4                         = 0xCA0
-	SYS___REGCOMP_STD                   = 0x0EA
-	SYS___REMAINDERF_H                  = 0xAC6
-	SYS___REMAINDERL_H                  = 0xAC7
-	SYS___REMQUOD128                    = 0xC10
-	SYS___REMQUOD32                     = 0xC0E
-	SYS___REMQUOD64                     = 0xC0F
-	SYS___REMQUOF_H                     = 0xAC9
-	SYS___REMQUOL_H                     = 0xACA
-	SYS___REMQUO_H                      = 0xAC8
-	SYS___RINTF_B                       = 0xACC
-	SYS___RINTL_B                       = 0xACE
-	SYS___ROUNDF_B                      = 0xAD3
-	SYS___ROUNDF_H                      = 0xAD4
-	SYS___ROUNDL_B                      = 0xAD6
-	SYS___ROUNDL_H                      = 0xAD7
-	SYS___ROUND_B                       = 0xAD0
-	SYS___ROUND_H                       = 0xAD1
-	SYS___SCALBLNF_B                    = 0xADC
-	SYS___SCALBLNF_H                    = 0xADD
-	SYS___SCALBLNL_B                    = 0xADF
-	SYS___SCALBLNL_H                    = 0xAE0
-	SYS___SCALBLN_B                     = 0xAD9
-	SYS___SCALBLN_H                     = 0xADA
-	SYS___SCALBNF_B                     = 0xAE4
-	SYS___SCALBNF_H                     = 0xAE5
-	SYS___SCALBNL_B                     = 0xAE7
-	SYS___SCALBNL_H                     = 0xAE8
-	SYS___SCALBN_B                      = 0xAE1
-	SYS___SCALBN_H                      = 0xAE2
-	SYS___SETENV                        = 0x0C8
-	SYS___SINPID128                     = 0xC73
-	SYS___SINPID32                      = 0xC71
-	SYS___SINPID64                      = 0xC72
-	SYS___SMF_RECORD2                   = 0xD48
-	SYS___STATIC_REINIT                 = 0xB3D
-	SYS___TGAMMAF_H_C99                 = 0xB79
-	SYS___TGAMMAL_H                     = 0xAE9
-	SYS___TGAMMA_H_C99                  = 0xB78
-	SYS___TOCSNAME2                     = 0xC9A
-	SYS_CEIL                            = 0x01F
-	SYS_CHAUDIT                         = 0x1E0
-	SYS_EXP                             = 0x01A
-	SYS_FCHAUDIT                        = 0x1E1
-	SYS_FREXP                           = 0x01D
-	SYS_GETGROUPSBYNAME                 = 0x1E2
-	SYS_GETPWUID                        = 0x1A0
-	SYS_GETUID                          = 0x1A1
-	SYS_ISATTY                          = 0x1A3
-	SYS_KILL                            = 0x1A4
-	SYS_LDEXP                           = 0x01E
-	SYS_LINK                            = 0x1A5
-	SYS_LOG10                           = 0x01C
-	SYS_LSEEK                           = 0x1A6
-	SYS_LSTAT                           = 0x1A7
-	SYS_MKDIR                           = 0x1A8
-	SYS_MKFIFO                          = 0x1A9
-	SYS_MKNOD                           = 0x1AA
-	SYS_MODF                            = 0x01B
-	SYS_MOUNT                           = 0x1AB
-	SYS_OPEN                            = 0x1AC
-	SYS_OPENDIR                         = 0x1AD
-	SYS_PATHCONF                        = 0x1AE
-	SYS_PAUSE                           = 0x1AF
-	SYS_PIPE                            = 0x1B0
-	SYS_PTHREAD_ATTR_DESTROY            = 0x1E7
-	SYS_PTHREAD_ATTR_GETDETACHSTATE     = 0x1EB
-	SYS_PTHREAD_ATTR_GETSTACKSIZE       = 0x1E9
-	SYS_PTHREAD_ATTR_GETWEIGHT_NP       = 0x1ED
-	SYS_PTHREAD_ATTR_INIT               = 0x1E6
-	SYS_PTHREAD_ATTR_SETDETACHSTATE     = 0x1EA
-	SYS_PTHREAD_ATTR_SETSTACKSIZE       = 0x1E8
-	SYS_PTHREAD_ATTR_SETWEIGHT_NP       = 0x1EC
-	SYS_PTHREAD_CANCEL                  = 0x1EE
-	SYS_PTHREAD_CLEANUP_POP             = 0x1F0
-	SYS_PTHREAD_CLEANUP_PUSH            = 0x1EF
-	SYS_PTHREAD_CONDATTR_DESTROY        = 0x1F2
-	SYS_PTHREAD_CONDATTR_INIT           = 0x1F1
-	SYS_PTHREAD_COND_BROADCAST          = 0x1F6
-	SYS_PTHREAD_COND_DESTROY            = 0x1F4
-	SYS_PTHREAD_COND_INIT               = 0x1F3
-	SYS_PTHREAD_COND_SIGNAL             = 0x1F5
-	SYS_PTHREAD_COND_TIMEDWAIT          = 0x1F8
-	SYS_PTHREAD_COND_WAIT               = 0x1F7
-	SYS_PTHREAD_CREATE                  = 0x1F9
-	SYS_PTHREAD_DETACH                  = 0x1FA
-	SYS_PTHREAD_EQUAL                   = 0x1FB
-	SYS_PTHREAD_EXIT                    = 0x1E4
-	SYS_PTHREAD_GETSPECIFIC             = 0x1FC
-	SYS_PTHREAD_JOIN                    = 0x1FD
-	SYS_PTHREAD_KEY_CREATE              = 0x1FE
-	SYS_PTHREAD_KILL                    = 0x1E5
-	SYS_PTHREAD_MUTEXATTR_INIT          = 0x1FF
-	SYS_READ                            = 0x1B2
-	SYS_READDIR                         = 0x1B3
-	SYS_READLINK                        = 0x1B4
-	SYS_REWINDDIR                       = 0x1B5
-	SYS_RMDIR                           = 0x1B6
-	SYS_SETEGID                         = 0x1B7
-	SYS_SETEUID                         = 0x1B8
-	SYS_SETGID                          = 0x1B9
-	SYS_SETPGID                         = 0x1BA
-	SYS_SETSID                          = 0x1BB
-	SYS_SETUID                          = 0x1BC
-	SYS_SIGACTION                       = 0x1BD
-	SYS_SIGADDSET                       = 0x1BE
-	SYS_SIGDELSET                       = 0x1BF
-	SYS_SIGEMPTYSET                     = 0x1C0
-	SYS_SIGFILLSET                      = 0x1C1
-	SYS_SIGISMEMBER                     = 0x1C2
-	SYS_SIGLONGJMP                      = 0x1C3
-	SYS_SIGPENDING                      = 0x1C4
-	SYS_SIGPROCMASK                     = 0x1C5
-	SYS_SIGSETJMP                       = 0x1C6
-	SYS_SIGSUSPEND                      = 0x1C7
-	SYS_SIGWAIT                         = 0x1E3
-	SYS_SLEEP                           = 0x1C8
-	SYS_STAT                            = 0x1C9
-	SYS_SYMLINK                         = 0x1CB
-	SYS_SYSCONF                         = 0x1CC
-	SYS_TCDRAIN                         = 0x1CD
-	SYS_TCFLOW                          = 0x1CE
-	SYS_TCFLUSH                         = 0x1CF
-	SYS_TCGETATTR                       = 0x1D0
-	SYS_TCGETPGRP                       = 0x1D1
-	SYS_TCSENDBREAK                     = 0x1D2
-	SYS_TCSETATTR                       = 0x1D3
-	SYS_TCSETPGRP                       = 0x1D4
-	SYS_TIMES                           = 0x1D5
-	SYS_TTYNAME                         = 0x1D6
-	SYS_TZSET                           = 0x1D7
-	SYS_UMASK                           = 0x1D8
-	SYS_UMOUNT                          = 0x1D9
-	SYS_UNAME                           = 0x1DA
-	SYS_UNLINK                          = 0x1DB
-	SYS_UTIME                           = 0x1DC
-	SYS_WAIT                            = 0x1DD
-	SYS_WAITPID                         = 0x1DE
-	SYS_WRITE                           = 0x1DF
-	SYS_W_GETPSENT                      = 0x1B1
-	SYS_W_IOCTL                         = 0x1A2
-	SYS_W_STATFS                        = 0x1CA
-	SYS_A64L                            = 0x2EF
-	SYS_BCMP                            = 0x2B9
-	SYS_BCOPY                           = 0x2BA
-	SYS_BZERO                           = 0x2BB
-	SYS_CATCLOSE                        = 0x2B6
-	SYS_CATGETS                         = 0x2B7
-	SYS_CATOPEN                         = 0x2B8
-	SYS_CRYPT                           = 0x2AC
-	SYS_DBM_CLEARERR                    = 0x2F7
-	SYS_DBM_CLOSE                       = 0x2F8
-	SYS_DBM_DELETE                      = 0x2F9
-	SYS_DBM_ERROR                       = 0x2FA
-	SYS_DBM_FETCH                       = 0x2FB
-	SYS_DBM_FIRSTKEY                    = 0x2FC
-	SYS_DBM_NEXTKEY                     = 0x2FD
-	SYS_DBM_OPEN                        = 0x2FE
-	SYS_DBM_STORE                       = 0x2FF
-	SYS_DRAND48                         = 0x2B2
-	SYS_ENCRYPT                         = 0x2AD
-	SYS_ENDUTXENT                       = 0x2E1
-	SYS_ERAND48                         = 0x2B3
-	SYS_ERF                             = 0x02C
-	SYS_ERFC                            = 0x02D
-	SYS_FCHDIR                          = 0x2D9
-	SYS_FFS                             = 0x2BC
-	SYS_FMTMSG                          = 0x2E5
-	SYS_FSTATVFS                        = 0x2B4
-	SYS_FTIME                           = 0x2F5
-	SYS_GAMMA                           = 0x02E
-	SYS_GETDATE                         = 0x2A6
-	SYS_GETPAGESIZE                     = 0x2D8
-	SYS_GETTIMEOFDAY                    = 0x2F6
-	SYS_GETUTXENT                       = 0x2E0
-	SYS_GETUTXID                        = 0x2E2
-	SYS_GETUTXLINE                      = 0x2E3
-	SYS_HCREATE                         = 0x2C6
-	SYS_HDESTROY                        = 0x2C7
-	SYS_HSEARCH                         = 0x2C8
-	SYS_HYPOT                           = 0x02B
-	SYS_INDEX                           = 0x2BD
-	SYS_INITSTATE                       = 0x2C2
-	SYS_INSQUE                          = 0x2CF
-	SYS_ISASCII                         = 0x2ED
-	SYS_JRAND48                         = 0x2E6
-	SYS_L64A                            = 0x2F0
-	SYS_LCONG48                         = 0x2EA
-	SYS_LFIND                           = 0x2C9
-	SYS_LRAND48                         = 0x2E7
-	SYS_LSEARCH                         = 0x2CA
-	SYS_MEMCCPY                         = 0x2D4
-	SYS_MRAND48                         = 0x2E8
-	SYS_NRAND48                         = 0x2E9
-	SYS_PCLOSE                          = 0x2D2
-	SYS_POPEN                           = 0x2D1
-	SYS_PUTUTXLINE                      = 0x2E4
-	SYS_RANDOM                          = 0x2C4
-	SYS_REMQUE                          = 0x2D0
-	SYS_RINDEX                          = 0x2BE
-	SYS_SEED48                          = 0x2EC
-	SYS_SETKEY                          = 0x2AE
-	SYS_SETSTATE                        = 0x2C3
-	SYS_SETUTXENT                       = 0x2DF
-	SYS_SRAND48                         = 0x2EB
-	SYS_SRANDOM                         = 0x2C5
-	SYS_STATVFS                         = 0x2B5
-	SYS_STRCASECMP                      = 0x2BF
-	SYS_STRDUP                          = 0x2C0
-	SYS_STRNCASECMP                     = 0x2C1
-	SYS_SWAB                            = 0x2D3
-	SYS_TDELETE                         = 0x2CB
-	SYS_TFIND                           = 0x2CC
-	SYS_TOASCII                         = 0x2EE
-	SYS_TSEARCH                         = 0x2CD
-	SYS_TWALK                           = 0x2CE
-	SYS_UALARM                          = 0x2F1
-	SYS_USLEEP                          = 0x2F2
-	SYS_WAIT3                           = 0x2A7
-	SYS_WAITID                          = 0x2A8
-	SYS_Y1                              = 0x02A
-	SYS___ATOE                          = 0x2DB
-	SYS___ATOE_L                        = 0x2DC
-	SYS___CATTRM                        = 0x2A9
-	SYS___CNVBLK                        = 0x2AF
-	SYS___CRYTRM                        = 0x2B0
-	SYS___DLGHT                         = 0x2A1
-	SYS___ECRTRM                        = 0x2B1
-	SYS___ETOA                          = 0x2DD
-	SYS___ETOA_L                        = 0x2DE
-	SYS___GDTRM                         = 0x2AA
-	SYS___OCLCK                         = 0x2DA
-	SYS___OPARGF                        = 0x2A2
-	SYS___OPERRF                        = 0x2A5
-	SYS___OPINDF                        = 0x2A4
-	SYS___OPOPTF                        = 0x2A3
-	SYS___RNDTRM                        = 0x2AB
-	SYS___SRCTRM                        = 0x2F4
-	SYS___TZONE                         = 0x2A0
-	SYS___UTXTRM                        = 0x2F3
-	SYS_ASIN                            = 0x03E
-	SYS_ISXDIGIT                        = 0x03B
-	SYS_SETLOCAL                        = 0x03A
-	SYS_SETLOCALE                       = 0x03A
-	SYS_SIN                             = 0x03F
-	SYS_TOLOWER                         = 0x03C
-	SYS_TOUPPER                         = 0x03D
-	SYS_ACCEPT_AND_RECV                 = 0x4F7
-	SYS_ATOL                            = 0x04E
-	SYS_CHECKSCH                        = 0x4BC
-	SYS_CHECKSCHENV                     = 0x4BC
-	SYS_CLEARERR                        = 0x04C
-	SYS_CONNECTS                        = 0x4B5
-	SYS_CONNECTSERVER                   = 0x4B5
-	SYS_CONNECTW                        = 0x4B4
-	SYS_CONNECTWORKMGR                  = 0x4B4
-	SYS_CONTINUE                        = 0x4B3
-	SYS_CONTINUEWORKUNIT                = 0x4B3
-	SYS_COPYSIGN                        = 0x4C2
-	SYS_CREATEWO                        = 0x4B2
-	SYS_CREATEWORKUNIT                  = 0x4B2
-	SYS_DELETEWO                        = 0x4B9
-	SYS_DELETEWORKUNIT                  = 0x4B9
-	SYS_DISCONNE                        = 0x4B6
-	SYS_DISCONNECTSERVER                = 0x4B6
-	SYS_FEOF                            = 0x04D
-	SYS_FERROR                          = 0x04A
-	SYS_FINITE                          = 0x4C8
-	SYS_GAMMA_R                         = 0x4E2
-	SYS_JOINWORK                        = 0x4B7
-	SYS_JOINWORKUNIT                    = 0x4B7
-	SYS_LEAVEWOR                        = 0x4B8
-	SYS_LEAVEWORKUNIT                   = 0x4B8
-	SYS_LGAMMA_R                        = 0x4EB
-	SYS_MATHERR                         = 0x4D0
-	SYS_PERROR                          = 0x04F
-	SYS_QUERYMET                        = 0x4BA
-	SYS_QUERYMETRICS                    = 0x4BA
-	SYS_QUERYSCH                        = 0x4BB
-	SYS_QUERYSCHENV                     = 0x4BB
-	SYS_REWIND                          = 0x04B
-	SYS_SCALBN                          = 0x4D4
-	SYS_SIGNIFIC                        = 0x4D5
-	SYS_SIGNIFICAND                     = 0x4D5
-	SYS___ACOSH_B                       = 0x4DA
-	SYS___ACOS_B                        = 0x4D9
-	SYS___ASINH_B                       = 0x4BE
-	SYS___ASIN_B                        = 0x4DB
-	SYS___ATAN2_B                       = 0x4DC
-	SYS___ATANH_B                       = 0x4DD
-	SYS___ATAN_B                        = 0x4BF
-	SYS___CBRT_B                        = 0x4C0
-	SYS___CEIL_B                        = 0x4C1
-	SYS___COSH_B                        = 0x4DE
-	SYS___COS_B                         = 0x4C3
-	SYS___DGHT                          = 0x4A8
-	SYS___ENVN                          = 0x4B0
-	SYS___ERFC_B                        = 0x4C5
-	SYS___ERF_B                         = 0x4C4
-	SYS___EXPM1_B                       = 0x4C6
-	SYS___EXP_B                         = 0x4DF
-	SYS___FABS_B                        = 0x4C7
-	SYS___FLOOR_B                       = 0x4C9
-	SYS___FMOD_B                        = 0x4E0
-	SYS___FP_SETMODE                    = 0x4F8
-	SYS___FREXP_B                       = 0x4CA
-	SYS___GAMMA_B                       = 0x4E1
-	SYS___GDRR                          = 0x4A1
-	SYS___HRRNO                         = 0x4A2
-	SYS___HYPOT_B                       = 0x4E3
-	SYS___ILOGB_B                       = 0x4CB
-	SYS___ISNAN_B                       = 0x4CC
-	SYS___J0_B                          = 0x4E4
-	SYS___J1_B                          = 0x4E6
-	SYS___JN_B                          = 0x4E8
-	SYS___LDEXP_B                       = 0x4CD
-	SYS___LGAMMA_B                      = 0x4EA
-	SYS___LOG10_B                       = 0x4ED
-	SYS___LOG1P_B                       = 0x4CE
-	SYS___LOGB_B                        = 0x4CF
-	SYS___LOGIN                         = 0x4F5
-	SYS___LOG_B                         = 0x4EC
-	SYS___MLOCKALL                      = 0x4B1
-	SYS___MODF_B                        = 0x4D1
-	SYS___NEXTAFTER_B                   = 0x4D2
-	SYS___OPENDIR2                      = 0x4F3
-	SYS___OPEN_STAT                     = 0x4F6
-	SYS___OPND                          = 0x4A5
-	SYS___OPPT                          = 0x4A6
-	SYS___OPRG                          = 0x4A3
-	SYS___OPRR                          = 0x4A4
-	SYS___PID_AFFINITY                  = 0x4BD
-	SYS___POW_B                         = 0x4EE
-	SYS___READDIR2                      = 0x4F4
-	SYS___REMAINDER_B                   = 0x4EF
-	SYS___RINT_B                        = 0x4D3
-	SYS___SCALB_B                       = 0x4F0
-	SYS___SIGACTIONSET                  = 0x4FB
-	SYS___SIGGM                         = 0x4A7
-	SYS___SINH_B                        = 0x4F1
-	SYS___SIN_B                         = 0x4D6
-	SYS___SQRT_B                        = 0x4F2
-	SYS___TANH_B                        = 0x4D8
-	SYS___TAN_B                         = 0x4D7
-	SYS___TRRNO                         = 0x4AF
-	SYS___TZNE                          = 0x4A9
-	SYS___TZZN                          = 0x4AA
-	SYS___UCREATE                       = 0x4FC
-	SYS___UFREE                         = 0x4FE
-	SYS___UHEAPREPORT                   = 0x4FF
-	SYS___UMALLOC                       = 0x4FD
-	SYS___Y0_B                          = 0x4E5
-	SYS___Y1_B                          = 0x4E7
-	SYS___YN_B                          = 0x4E9
-	SYS_ABORT                           = 0x05C
-	SYS_ASCTIME_R                       = 0x5E0
-	SYS_ATEXIT                          = 0x05D
-	SYS_CONNECTE                        = 0x5AE
-	SYS_CONNECTEXPORTIMPORT             = 0x5AE
-	SYS_CTIME_R                         = 0x5E1
-	SYS_DN_COMP                         = 0x5DF
-	SYS_DN_EXPAND                       = 0x5DD
-	SYS_DN_SKIPNAME                     = 0x5DE
-	SYS_EXIT                            = 0x05A
-	SYS_EXPORTWO                        = 0x5A1
-	SYS_EXPORTWORKUNIT                  = 0x5A1
-	SYS_EXTRACTW                        = 0x5A5
-	SYS_EXTRACTWORKUNIT                 = 0x5A5
-	SYS_FSEEKO                          = 0x5C9
-	SYS_FTELLO                          = 0x5C8
-	SYS_GETGRGID_R                      = 0x5E7
-	SYS_GETGRNAM_R                      = 0x5E8
-	SYS_GETLOGIN_R                      = 0x5E9
-	SYS_GETPWNAM_R                      = 0x5EA
-	SYS_GETPWUID_R                      = 0x5EB
-	SYS_GMTIME_R                        = 0x5E2
-	SYS_IMPORTWO                        = 0x5A3
-	SYS_IMPORTWORKUNIT                  = 0x5A3
-	SYS_INET_NTOP                       = 0x5D3
-	SYS_INET_PTON                       = 0x5D4
-	SYS_LLABS                           = 0x5CE
-	SYS_LLDIV                           = 0x5CB
-	SYS_LOCALTIME_R                     = 0x5E3
-	SYS_PTHREAD_ATFORK                  = 0x5ED
-	SYS_PTHREAD_ATTR_GETDETACHSTATE_U98 = 0x5FB
-	SYS_PTHREAD_ATTR_GETGUARDSIZE       = 0x5EE
-	SYS_PTHREAD_ATTR_GETSCHEDPARAM      = 0x5F9
-	SYS_PTHREAD_ATTR_GETSTACKADDR       = 0x5EF
-	SYS_PTHREAD_ATTR_SETDETACHSTATE_U98 = 0x5FC
-	SYS_PTHREAD_ATTR_SETGUARDSIZE       = 0x5F0
-	SYS_PTHREAD_ATTR_SETSCHEDPARAM      = 0x5FA
-	SYS_PTHREAD_ATTR_SETSTACKADDR       = 0x5F1
-	SYS_PTHREAD_CONDATTR_GETPSHARED     = 0x5F2
-	SYS_PTHREAD_CONDATTR_SETPSHARED     = 0x5F3
-	SYS_PTHREAD_DETACH_U98              = 0x5FD
-	SYS_PTHREAD_GETCONCURRENCY          = 0x5F4
-	SYS_PTHREAD_GETSPECIFIC_U98         = 0x5FE
-	SYS_PTHREAD_KEY_DELETE              = 0x5F5
-	SYS_PTHREAD_SETCANCELSTATE          = 0x5FF
-	SYS_PTHREAD_SETCONCURRENCY          = 0x5F6
-	SYS_PTHREAD_SIGMASK                 = 0x5F7
-	SYS_QUERYENC                        = 0x5AD
-	SYS_QUERYWORKUNITCLASSIFICATION     = 0x5AD
-	SYS_RAISE                           = 0x05E
-	SYS_RAND_R                          = 0x5E4
-	SYS_READDIR_R                       = 0x5E6
-	SYS_REALLOC                         = 0x05B
-	SYS_RES_INIT                        = 0x5D8
-	SYS_RES_MKQUERY                     = 0x5D7
-	SYS_RES_QUERY                       = 0x5D9
-	SYS_RES_QUERYDOMAIN                 = 0x5DC
-	SYS_RES_SEARCH                      = 0x5DA
-	SYS_RES_SEND                        = 0x5DB
-	SYS_SETJMP                          = 0x05F
-	SYS_SIGQUEUE                        = 0x5A9
-	SYS_STRTOK_R                        = 0x5E5
-	SYS_STRTOLL                         = 0x5B0
-	SYS_STRTOULL                        = 0x5B1
-	SYS_TTYNAME_R                       = 0x5EC
-	SYS_UNDOEXPO                        = 0x5A2
-	SYS_UNDOEXPORTWORKUNIT              = 0x5A2
-	SYS_UNDOIMPO                        = 0x5A4
-	SYS_UNDOIMPORTWORKUNIT              = 0x5A4
-	SYS_WCSTOLL                         = 0x5CC
-	SYS_WCSTOULL                        = 0x5CD
-	SYS___ABORT                         = 0x05C
-	SYS___CONSOLE2                      = 0x5D2
-	SYS___CPL                           = 0x5A6
-	SYS___DISCARDDATA                   = 0x5F8
-	SYS___DSA_PREV                      = 0x5B2
-	SYS___EP_FIND                       = 0x5B3
-	SYS___FP_SWAPMODE                   = 0x5AF
-	SYS___GETUSERID                     = 0x5AB
-	SYS___GET_CPUID                     = 0x5B9
-	SYS___GET_SYSTEM_SETTINGS           = 0x5BA
-	SYS___IPDOMAINNAME                  = 0x5AC
-	SYS___MAP_INIT                      = 0x5A7
-	SYS___MAP_SERVICE                   = 0x5A8
-	SYS___MOUNT                         = 0x5AA
-	SYS___MSGRCV_TIMED                  = 0x5B7
-	SYS___RES                           = 0x5D6
-	SYS___SEMOP_TIMED                   = 0x5B8
-	SYS___SERVER_THREADS_QUERY          = 0x5B4
-	SYS_FPRINTF                         = 0x06D
-	SYS_FSCANF                          = 0x06A
-	SYS_PRINTF                          = 0x06F
-	SYS_SETBUF                          = 0x06B
-	SYS_SETVBUF                         = 0x06C
-	SYS_SSCANF                          = 0x06E
-	SYS___CATGETS_A                     = 0x6C0
-	SYS___CHAUDIT_A                     = 0x6F4
-	SYS___CHMOD_A                       = 0x6E8
-	SYS___COLLATE_INIT_A                = 0x6AC
-	SYS___CREAT_A                       = 0x6F6
-	SYS___CTYPE_INIT_A                  = 0x6AF
-	SYS___DLLLOAD_A                     = 0x6DF
-	SYS___DLLQUERYFN_A                  = 0x6E0
-	SYS___DLLQUERYVAR_A                 = 0x6E1
-	SYS___E2A_L                         = 0x6E3
-	SYS___EXECLE_A                      = 0x6A0
-	SYS___EXECLP_A                      = 0x6A4
-	SYS___EXECVE_A                      = 0x6C1
-	SYS___EXECVP_A                      = 0x6C2
-	SYS___EXECV_A                       = 0x6B1
-	SYS___FPRINTF_A                     = 0x6FA
-	SYS___GETADDRINFO_A                 = 0x6BF
-	SYS___GETNAMEINFO_A                 = 0x6C4
-	SYS___GET_WCTYPE_STD_A              = 0x6AE
-	SYS___ICONV_OPEN_A                  = 0x6DE
-	SYS___IF_INDEXTONAME_A              = 0x6DC
-	SYS___IF_NAMETOINDEX_A              = 0x6DB
-	SYS___ISWCTYPE_A                    = 0x6B0
-	SYS___IS_WCTYPE_STD_A               = 0x6B2
-	SYS___LOCALECONV_A                  = 0x6B8
-	SYS___LOCALECONV_STD_A              = 0x6B9
-	SYS___LOCALE_INIT_A                 = 0x6B7
-	SYS___LSTAT_A                       = 0x6EE
-	SYS___LSTAT_O_A                     = 0x6EF
-	SYS___MKDIR_A                       = 0x6E9
-	SYS___MKFIFO_A                      = 0x6EC
-	SYS___MKNOD_A                       = 0x6F0
-	SYS___MONETARY_INIT_A               = 0x6BC
-	SYS___MOUNT_A                       = 0x6F1
-	SYS___NL_CSINFO_A                   = 0x6D6
-	SYS___NL_LANGINFO_A                 = 0x6BA
-	SYS___NL_LNAGINFO_STD_A             = 0x6BB
-	SYS___NL_MONINFO_A                  = 0x6D7
-	SYS___NL_NUMINFO_A                  = 0x6D8
-	SYS___NL_RESPINFO_A                 = 0x6D9
-	SYS___NL_TIMINFO_A                  = 0x6DA
-	SYS___NUMERIC_INIT_A                = 0x6C6
-	SYS___OPEN_A                        = 0x6F7
-	SYS___PRINTF_A                      = 0x6DD
-	SYS___RESP_INIT_A                   = 0x6C7
-	SYS___RPMATCH_A                     = 0x6C8
-	SYS___RPMATCH_C_A                   = 0x6C9
-	SYS___RPMATCH_STD_A                 = 0x6CA
-	SYS___SETLOCALE_A                   = 0x6F9
-	SYS___SPAWNP_A                      = 0x6C5
-	SYS___SPAWN_A                       = 0x6C3
-	SYS___SPRINTF_A                     = 0x6FB
-	SYS___STAT_A                        = 0x6EA
-	SYS___STAT_O_A                      = 0x6EB
-	SYS___STRCOLL_STD_A                 = 0x6A1
-	SYS___STRFMON_A                     = 0x6BD
-	SYS___STRFMON_STD_A                 = 0x6BE
-	SYS___STRFTIME_A                    = 0x6CC
-	SYS___STRFTIME_STD_A                = 0x6CD
-	SYS___STRPTIME_A                    = 0x6CE
-	SYS___STRPTIME_STD_A                = 0x6CF
-	SYS___STRXFRM_A                     = 0x6A2
-	SYS___STRXFRM_C_A                   = 0x6A3
-	SYS___STRXFRM_STD_A                 = 0x6A5
-	SYS___SYNTAX_INIT_A                 = 0x6D4
-	SYS___TIME_INIT_A                   = 0x6CB
-	SYS___TOD_INIT_A                    = 0x6D5
-	SYS___TOWLOWER_A                    = 0x6B3
-	SYS___TOWLOWER_STD_A                = 0x6B4
-	SYS___TOWUPPER_A                    = 0x6B5
-	SYS___TOWUPPER_STD_A                = 0x6B6
-	SYS___UMOUNT_A                      = 0x6F2
-	SYS___VFPRINTF_A                    = 0x6FC
-	SYS___VPRINTF_A                     = 0x6FD
-	SYS___VSPRINTF_A                    = 0x6FE
-	SYS___VSWPRINTF_A                   = 0x6FF
-	SYS___WCSCOLL_A                     = 0x6A6
-	SYS___WCSCOLL_C_A                   = 0x6A7
-	SYS___WCSCOLL_STD_A                 = 0x6A8
-	SYS___WCSFTIME_A                    = 0x6D0
-	SYS___WCSFTIME_STD_A                = 0x6D1
-	SYS___WCSXFRM_A                     = 0x6A9
-	SYS___WCSXFRM_C_A                   = 0x6AA
-	SYS___WCSXFRM_STD_A                 = 0x6AB
-	SYS___WCTYPE_A                      = 0x6AD
-	SYS___W_GETMNTENT_A                 = 0x6F5
-	SYS_____CCSIDTYPE_A                 = 0x6E6
-	SYS_____CHATTR_A                    = 0x6E2
-	SYS_____CSNAMETYPE_A                = 0x6E7
-	SYS_____OPEN_STAT_A                 = 0x6ED
-	SYS_____SPAWN2_A                    = 0x6D2
-	SYS_____SPAWNP2_A                   = 0x6D3
-	SYS_____TOCCSID_A                   = 0x6E4
-	SYS_____TOCSNAME_A                  = 0x6E5
-	SYS_ACL_FREE                        = 0x7FF
-	SYS_ACL_INIT                        = 0x7FE
-	SYS_FWIDE                           = 0x7DF
-	SYS_FWPRINTF                        = 0x7D1
-	SYS_FWRITE                          = 0x07E
-	SYS_FWSCANF                         = 0x7D5
-	SYS_GETCHAR                         = 0x07B
-	SYS_GETS                            = 0x07C
-	SYS_M_CREATE_LAYOUT                 = 0x7C9
-	SYS_M_DESTROY_LAYOUT                = 0x7CA
-	SYS_M_GETVALUES_LAYOUT              = 0x7CB
-	SYS_M_SETVALUES_LAYOUT              = 0x7CC
-	SYS_M_TRANSFORM_LAYOUT              = 0x7CD
-	SYS_M_WTRANSFORM_LAYOUT             = 0x7CE
-	SYS_PREAD                           = 0x7C7
-	SYS_PUTC                            = 0x07D
-	SYS_PUTCHAR                         = 0x07A
-	SYS_PUTS                            = 0x07F
-	SYS_PWRITE                          = 0x7C8
-	SYS_TOWCTRAN                        = 0x7D8
-	SYS_TOWCTRANS                       = 0x7D8
-	SYS_UNATEXIT                        = 0x7B5
-	SYS_VFWPRINT                        = 0x7D3
-	SYS_VFWPRINTF                       = 0x7D3
-	SYS_VWPRINTF                        = 0x7D4
-	SYS_WCTRANS                         = 0x7D7
-	SYS_WPRINTF                         = 0x7D2
-	SYS_WSCANF                          = 0x7D6
-	SYS___ASCTIME_R_A                   = 0x7A1
-	SYS___BASENAME_A                    = 0x7DC
-	SYS___BTOWC_A                       = 0x7E4
-	SYS___CDUMP_A                       = 0x7B7
-	SYS___CEE3DMP_A                     = 0x7B6
-	SYS___CEILF_H                       = 0x7F4
-	SYS___CEILL_H                       = 0x7F5
-	SYS___CEIL_H                        = 0x7EA
-	SYS___CRYPT_A                       = 0x7BE
-	SYS___CSNAP_A                       = 0x7B8
-	SYS___CTEST_A                       = 0x7B9
-	SYS___CTIME_R_A                     = 0x7A2
-	SYS___CTRACE_A                      = 0x7BA
-	SYS___DBM_OPEN_A                    = 0x7E6
-	SYS___DIRNAME_A                     = 0x7DD
-	SYS___FABSF_H                       = 0x7FA
-	SYS___FABSL_H                       = 0x7FB
-	SYS___FABS_H                        = 0x7ED
-	SYS___FGETWC_A                      = 0x7AA
-	SYS___FGETWS_A                      = 0x7AD
-	SYS___FLOORF_H                      = 0x7F6
-	SYS___FLOORL_H                      = 0x7F7
-	SYS___FLOOR_H                       = 0x7EB
-	SYS___FPUTWC_A                      = 0x7A5
-	SYS___FPUTWS_A                      = 0x7A8
-	SYS___GETTIMEOFDAY_A                = 0x7AE
-	SYS___GETWCHAR_A                    = 0x7AC
-	SYS___GETWC_A                       = 0x7AB
-	SYS___GLOB_A                        = 0x7DE
-	SYS___GMTIME_A                      = 0x7AF
-	SYS___GMTIME_R_A                    = 0x7B0
-	SYS___INET_PTON_A                   = 0x7BC
-	SYS___J0_H                          = 0x7EE
-	SYS___J1_H                          = 0x7EF
-	SYS___JN_H                          = 0x7F0
-	SYS___LOCALTIME_A                   = 0x7B1
-	SYS___LOCALTIME_R_A                 = 0x7B2
-	SYS___MALLOC24                      = 0x7FC
-	SYS___MALLOC31                      = 0x7FD
-	SYS___MKTIME_A                      = 0x7B3
-	SYS___MODFF_H                       = 0x7F8
-	SYS___MODFL_H                       = 0x7F9
-	SYS___MODF_H                        = 0x7EC
-	SYS___OPENDIR_A                     = 0x7C2
-	SYS___OSNAME                        = 0x7E0
-	SYS___PUTWCHAR_A                    = 0x7A7
-	SYS___PUTWC_A                       = 0x7A6
-	SYS___READDIR_A                     = 0x7C3
-	SYS___STRTOLL_A                     = 0x7A3
-	SYS___STRTOULL_A                    = 0x7A4
-	SYS___SYSLOG_A                      = 0x7BD
-	SYS___TZZNA                         = 0x7B4
-	SYS___UNGETWC_A                     = 0x7A9
-	SYS___UTIME_A                       = 0x7A0
-	SYS___VFPRINTF2_A                   = 0x7E7
-	SYS___VPRINTF2_A                    = 0x7E8
-	SYS___VSPRINTF2_A                   = 0x7E9
-	SYS___VSWPRNTF2_A                   = 0x7BB
-	SYS___WCSTOD_A                      = 0x7D9
-	SYS___WCSTOL_A                      = 0x7DA
-	SYS___WCSTOUL_A                     = 0x7DB
-	SYS___WCTOB_A                       = 0x7E5
-	SYS___Y0_H                          = 0x7F1
-	SYS___Y1_H                          = 0x7F2
-	SYS___YN_H                          = 0x7F3
-	SYS_____OPENDIR2_A                  = 0x7BF
-	SYS_____OSNAME_A                    = 0x7E1
-	SYS_____READDIR2_A                  = 0x7C0
-	SYS_DLCLOSE                         = 0x8DF
-	SYS_DLERROR                         = 0x8E0
-	SYS_DLOPEN                          = 0x8DD
-	SYS_DLSYM                           = 0x8DE
-	SYS_FLOCKFILE                       = 0x8D3
-	SYS_FTRYLOCKFILE                    = 0x8D4
-	SYS_FUNLOCKFILE                     = 0x8D5
-	SYS_GETCHAR_UNLOCKED                = 0x8D7
-	SYS_GETC_UNLOCKED                   = 0x8D6
-	SYS_PUTCHAR_UNLOCKED                = 0x8D9
-	SYS_PUTC_UNLOCKED                   = 0x8D8
-	SYS_SNPRINTF                        = 0x8DA
-	SYS_VSNPRINTF                       = 0x8DB
-	SYS_WCSCSPN                         = 0x08B
-	SYS_WCSLEN                          = 0x08C
-	SYS_WCSNCAT                         = 0x08D
-	SYS_WCSNCMP                         = 0x08A
-	SYS_WCSNCPY                         = 0x08F
-	SYS_WCSSPN                          = 0x08E
-	SYS___ABSF_H                        = 0x8E7
-	SYS___ABSL_H                        = 0x8E8
-	SYS___ABS_H                         = 0x8E6
-	SYS___ACOSF_H                       = 0x8EA
-	SYS___ACOSH_H                       = 0x8EC
-	SYS___ACOSL_H                       = 0x8EB
-	SYS___ACOS_H                        = 0x8E9
-	SYS___ASINF_H                       = 0x8EE
-	SYS___ASINH_H                       = 0x8F0
-	SYS___ASINL_H                       = 0x8EF
-	SYS___ASIN_H                        = 0x8ED
-	SYS___ATAN2F_H                      = 0x8F8
-	SYS___ATAN2L_H                      = 0x8F9
-	SYS___ATAN2_H                       = 0x8F7
-	SYS___ATANF_H                       = 0x8F2
-	SYS___ATANHF_H                      = 0x8F5
-	SYS___ATANHL_H                      = 0x8F6
-	SYS___ATANH_H                       = 0x8F4
-	SYS___ATANL_H                       = 0x8F3
-	SYS___ATAN_H                        = 0x8F1
-	SYS___CBRT_H                        = 0x8FA
-	SYS___COPYSIGNF_H                   = 0x8FB
-	SYS___COPYSIGNL_H                   = 0x8FC
-	SYS___COSF_H                        = 0x8FE
-	SYS___COSL_H                        = 0x8FF
-	SYS___COS_H                         = 0x8FD
-	SYS___DLERROR_A                     = 0x8D2
-	SYS___DLOPEN_A                      = 0x8D0
-	SYS___DLSYM_A                       = 0x8D1
-	SYS___GETUTXENT_A                   = 0x8C6
-	SYS___GETUTXID_A                    = 0x8C7
-	SYS___GETUTXLINE_A                  = 0x8C8
-	SYS___ITOA                          = 0x8AA
-	SYS___ITOA_A                        = 0x8B0
-	SYS___LE_CONDITION_TOKEN_BUILD      = 0x8A5
-	SYS___LE_MSG_ADD_INSERT             = 0x8A6
-	SYS___LE_MSG_GET                    = 0x8A7
-	SYS___LE_MSG_GET_AND_WRITE          = 0x8A8
-	SYS___LE_MSG_WRITE                  = 0x8A9
-	SYS___LLTOA                         = 0x8AE
-	SYS___LLTOA_A                       = 0x8B4
-	SYS___LTOA                          = 0x8AC
-	SYS___LTOA_A                        = 0x8B2
-	SYS___PUTCHAR_UNLOCKED_A            = 0x8CC
-	SYS___PUTC_UNLOCKED_A               = 0x8CB
-	SYS___PUTUTXLINE_A                  = 0x8C9
-	SYS___RESET_EXCEPTION_HANDLER       = 0x8E3
-	SYS___REXEC_A                       = 0x8C4
-	SYS___REXEC_AF_A                    = 0x8C5
-	SYS___SET_EXCEPTION_HANDLER         = 0x8E2
-	SYS___SNPRINTF_A                    = 0x8CD
-	SYS___SUPERKILL                     = 0x8A4
-	SYS___TCGETATTR_A                   = 0x8A1
-	SYS___TCSETATTR_A                   = 0x8A2
-	SYS___ULLTOA                        = 0x8AF
-	SYS___ULLTOA_A                      = 0x8B5
-	SYS___ULTOA                         = 0x8AD
-	SYS___ULTOA_A                       = 0x8B3
-	SYS___UTOA                          = 0x8AB
-	SYS___UTOA_A                        = 0x8B1
-	SYS___VHM_EVENT                     = 0x8E4
-	SYS___VSNPRINTF_A                   = 0x8CE
-	SYS_____GETENV_A                    = 0x8C3
-	SYS_____UTMPXNAME_A                 = 0x8CA
-	SYS_CACOSH                          = 0x9A0
-	SYS_CACOSHF                         = 0x9A3
-	SYS_CACOSHL                         = 0x9A6
-	SYS_CARG                            = 0x9A9
-	SYS_CARGF                           = 0x9AC
-	SYS_CARGL                           = 0x9AF
-	SYS_CASIN                           = 0x9B2
-	SYS_CASINF                          = 0x9B5
-	SYS_CASINH                          = 0x9BB
-	SYS_CASINHF                         = 0x9BE
-	SYS_CASINHL                         = 0x9C1
-	SYS_CASINL                          = 0x9B8
-	SYS_CATAN                           = 0x9C4
-	SYS_CATANF                          = 0x9C7
-	SYS_CATANH                          = 0x9CD
-	SYS_CATANHF                         = 0x9D0
-	SYS_CATANHL                         = 0x9D3
-	SYS_CATANL                          = 0x9CA
-	SYS_CCOS                            = 0x9D6
-	SYS_CCOSF                           = 0x9D9
-	SYS_CCOSH                           = 0x9DF
-	SYS_CCOSHF                          = 0x9E2
-	SYS_CCOSHL                          = 0x9E5
-	SYS_CCOSL                           = 0x9DC
-	SYS_CEXP                            = 0x9E8
-	SYS_CEXPF                           = 0x9EB
-	SYS_CEXPL                           = 0x9EE
-	SYS_CIMAG                           = 0x9F1
-	SYS_CIMAGF                          = 0x9F4
-	SYS_CIMAGL                          = 0x9F7
-	SYS_CLOGF                           = 0x9FD
-	SYS_MEMCHR                          = 0x09B
-	SYS_MEMCMP                          = 0x09A
-	SYS_STRCOLL                         = 0x09C
-	SYS_STRNCMP                         = 0x09D
-	SYS_STRRCHR                         = 0x09F
-	SYS_STRXFRM                         = 0x09E
-	SYS___CACOSHF_B                     = 0x9A4
-	SYS___CACOSHF_H                     = 0x9A5
-	SYS___CACOSHL_B                     = 0x9A7
-	SYS___CACOSHL_H                     = 0x9A8
-	SYS___CACOSH_B                      = 0x9A1
-	SYS___CACOSH_H                      = 0x9A2
-	SYS___CARGF_B                       = 0x9AD
-	SYS___CARGF_H                       = 0x9AE
-	SYS___CARGL_B                       = 0x9B0
-	SYS___CARGL_H                       = 0x9B1
-	SYS___CARG_B                        = 0x9AA
-	SYS___CARG_H                        = 0x9AB
-	SYS___CASINF_B                      = 0x9B6
-	SYS___CASINF_H                      = 0x9B7
-	SYS___CASINHF_B                     = 0x9BF
-	SYS___CASINHF_H                     = 0x9C0
-	SYS___CASINHL_B                     = 0x9C2
-	SYS___CASINHL_H                     = 0x9C3
-	SYS___CASINH_B                      = 0x9BC
-	SYS___CASINH_H                      = 0x9BD
-	SYS___CASINL_B                      = 0x9B9
-	SYS___CASINL_H                      = 0x9BA
-	SYS___CASIN_B                       = 0x9B3
-	SYS___CASIN_H                       = 0x9B4
-	SYS___CATANF_B                      = 0x9C8
-	SYS___CATANF_H                      = 0x9C9
-	SYS___CATANHF_B                     = 0x9D1
-	SYS___CATANHF_H                     = 0x9D2
-	SYS___CATANHL_B                     = 0x9D4
-	SYS___CATANHL_H                     = 0x9D5
-	SYS___CATANH_B                      = 0x9CE
-	SYS___CATANH_H                      = 0x9CF
-	SYS___CATANL_B                      = 0x9CB
-	SYS___CATANL_H                      = 0x9CC
-	SYS___CATAN_B                       = 0x9C5
-	SYS___CATAN_H                       = 0x9C6
-	SYS___CCOSF_B                       = 0x9DA
-	SYS___CCOSF_H                       = 0x9DB
-	SYS___CCOSHF_B                      = 0x9E3
-	SYS___CCOSHF_H                      = 0x9E4
-	SYS___CCOSHL_B                      = 0x9E6
-	SYS___CCOSHL_H                      = 0x9E7
-	SYS___CCOSH_B                       = 0x9E0
-	SYS___CCOSH_H                       = 0x9E1
-	SYS___CCOSL_B                       = 0x9DD
-	SYS___CCOSL_H                       = 0x9DE
-	SYS___CCOS_B                        = 0x9D7
-	SYS___CCOS_H                        = 0x9D8
-	SYS___CEXPF_B                       = 0x9EC
-	SYS___CEXPF_H                       = 0x9ED
-	SYS___CEXPL_B                       = 0x9EF
-	SYS___CEXPL_H                       = 0x9F0
-	SYS___CEXP_B                        = 0x9E9
-	SYS___CEXP_H                        = 0x9EA
-	SYS___CIMAGF_B                      = 0x9F5
-	SYS___CIMAGF_H                      = 0x9F6
-	SYS___CIMAGL_B                      = 0x9F8
-	SYS___CIMAGL_H                      = 0x9F9
-	SYS___CIMAG_B                       = 0x9F2
-	SYS___CIMAG_H                       = 0x9F3
-	SYS___CLOG                          = 0x9FA
-	SYS___CLOGF_B                       = 0x9FE
-	SYS___CLOGF_H                       = 0x9FF
-	SYS___CLOG_B                        = 0x9FB
-	SYS___CLOG_H                        = 0x9FC
-	SYS_ISWCTYPE                        = 0x10C
-	SYS_ISWXDIGI                        = 0x10A
-	SYS_ISWXDIGIT                       = 0x10A
-	SYS_MBSINIT                         = 0x10F
-	SYS_TOWLOWER                        = 0x10D
-	SYS_TOWUPPER                        = 0x10E
-	SYS_WCTYPE                          = 0x10B
-	SYS_WCSSTR                          = 0x11B
-	SYS___RPMTCH                        = 0x11A
-	SYS_WCSTOD                          = 0x12E
-	SYS_WCSTOK                          = 0x12C
-	SYS_WCSTOL                          = 0x12D
-	SYS_WCSTOUL                         = 0x12F
-	SYS_FGETWC                          = 0x13C
-	SYS_FGETWS                          = 0x13D
-	SYS_FPUTWC                          = 0x13E
-	SYS_FPUTWS                          = 0x13F
-	SYS_REGERROR                        = 0x13B
-	SYS_REGFREE                         = 0x13A
-	SYS_COLLEQUIV                       = 0x14F
-	SYS_COLLTOSTR                       = 0x14E
-	SYS_ISMCCOLLEL                      = 0x14C
-	SYS_STRTOCOLL                       = 0x14D
-	SYS_DLLFREE                         = 0x16F
-	SYS_DLLQUERYFN                      = 0x16D
-	SYS_DLLQUERYVAR                     = 0x16E
-	SYS_GETMCCOLL                       = 0x16A
-	SYS_GETWMCCOLL                      = 0x16B
-	SYS___ERR2AD                        = 0x16C
-	SYS_CFSETOSPEED                     = 0x17A
-	SYS_CHDIR                           = 0x17B
-	SYS_CHMOD                           = 0x17C
-	SYS_CHOWN                           = 0x17D
-	SYS_CLOSE                           = 0x17E
-	SYS_CLOSEDIR                        = 0x17F
-	SYS_LOG                             = 0x017
-	SYS_COSH                            = 0x018
-	SYS_FCHMOD                          = 0x18A
-	SYS_FCHOWN                          = 0x18B
-	SYS_FCNTL                           = 0x18C
-	SYS_FILENO                          = 0x18D
-	SYS_FORK                            = 0x18E
-	SYS_FPATHCONF                       = 0x18F
-	SYS_GETLOGIN                        = 0x19A
-	SYS_GETPGRP                         = 0x19C
-	SYS_GETPID                          = 0x19D
-	SYS_GETPPID                         = 0x19E
-	SYS_GETPWNAM                        = 0x19F
-	SYS_TANH                            = 0x019
-	SYS_W_GETMNTENT                     = 0x19B
-	SYS_POW                             = 0x020
-	SYS_PTHREAD_SELF                    = 0x20A
-	SYS_PTHREAD_SETINTR                 = 0x20B
-	SYS_PTHREAD_SETINTRTYPE             = 0x20C
-	SYS_PTHREAD_SETSPECIFIC             = 0x20D
-	SYS_PTHREAD_TESTINTR                = 0x20E
-	SYS_PTHREAD_YIELD                   = 0x20F
-	SYS_SQRT                            = 0x021
-	SYS_FLOOR                           = 0x022
-	SYS_J1                              = 0x023
-	SYS_WCSPBRK                         = 0x23F
-	SYS_BSEARCH                         = 0x24C
-	SYS_FABS                            = 0x024
-	SYS_GETENV                          = 0x24A
-	SYS_LDIV                            = 0x24D
-	SYS_SYSTEM                          = 0x24B
-	SYS_FMOD                            = 0x025
-	SYS___RETHROW                       = 0x25F
-	SYS___THROW                         = 0x25E
-	SYS_J0                              = 0x026
-	SYS_PUTENV                          = 0x26A
-	SYS___GETENV                        = 0x26F
-	SYS_SEMCTL                          = 0x27A
-	SYS_SEMGET                          = 0x27B
-	SYS_SEMOP                           = 0x27C
-	SYS_SHMAT                           = 0x27D
-	SYS_SHMCTL                          = 0x27E
-	SYS_SHMDT                           = 0x27F
-	SYS_YN                              = 0x027
-	SYS_JN                              = 0x028
-	SYS_SIGALTSTACK                     = 0x28A
-	SYS_SIGHOLD                         = 0x28B
-	SYS_SIGIGNORE                       = 0x28C
-	SYS_SIGINTERRUPT                    = 0x28D
-	SYS_SIGPAUSE                        = 0x28E
-	SYS_SIGRELSE                        = 0x28F
-	SYS_GETOPT                          = 0x29A
-	SYS_GETSUBOPT                       = 0x29D
-	SYS_LCHOWN                          = 0x29B
-	SYS_SETPGRP                         = 0x29E
-	SYS_TRUNCATE                        = 0x29C
-	SYS_Y0                              = 0x029
-	SYS___GDERR                         = 0x29F
-	SYS_ISALPHA                         = 0x030
-	SYS_VFORK                           = 0x30F
-	SYS__LONGJMP                        = 0x30D
-	SYS__SETJMP                         = 0x30E
-	SYS_GLOB                            = 0x31A
-	SYS_GLOBFREE                        = 0x31B
-	SYS_ISALNUM                         = 0x031
-	SYS_PUTW                            = 0x31C
-	SYS_SEEKDIR                         = 0x31D
-	SYS_TELLDIR                         = 0x31E
-	SYS_TEMPNAM                         = 0x31F
-	SYS_GETTIMEOFDAY_R                  = 0x32E
-	SYS_ISLOWER                         = 0x032
-	SYS_LGAMMA                          = 0x32C
-	SYS_REMAINDER                       = 0x32A
-	SYS_SCALB                           = 0x32B
-	SYS_SYNC                            = 0x32F
-	SYS_TTYSLOT                         = 0x32D
-	SYS_ENDPROTOENT                     = 0x33A
-	SYS_ENDSERVENT                      = 0x33B
-	SYS_GETHOSTBYADDR                   = 0x33D
-	SYS_GETHOSTBYADDR_R                 = 0x33C
-	SYS_GETHOSTBYNAME                   = 0x33F
-	SYS_GETHOSTBYNAME_R                 = 0x33E
-	SYS_ISCNTRL                         = 0x033
-	SYS_GETSERVBYNAME                   = 0x34A
-	SYS_GETSERVBYPORT                   = 0x34B
-	SYS_GETSERVENT                      = 0x34C
-	SYS_GETSOCKNAME                     = 0x34D
-	SYS_GETSOCKOPT                      = 0x34E
-	SYS_INET_ADDR                       = 0x34F
-	SYS_ISDIGIT                         = 0x034
-	SYS_ISGRAPH                         = 0x035
-	SYS_SELECT                          = 0x35B
-	SYS_SELECTEX                        = 0x35C
-	SYS_SEND                            = 0x35D
-	SYS_SENDTO                          = 0x35F
-	SYS_CHROOT                          = 0x36A
-	SYS_ISNAN                           = 0x36D
-	SYS_ISUPPER                         = 0x036
-	SYS_ULIMIT                          = 0x36C
-	SYS_UTIMES                          = 0x36E
-	SYS_W_STATVFS                       = 0x36B
-	SYS___H_ERRNO                       = 0x36F
-	SYS_GRANTPT                         = 0x37A
-	SYS_ISPRINT                         = 0x037
-	SYS_TCGETSID                        = 0x37C
-	SYS_UNLOCKPT                        = 0x37B
-	SYS___TCGETCP                       = 0x37D
-	SYS___TCSETCP                       = 0x37E
-	SYS___TCSETTABLES                   = 0x37F
-	SYS_ISPUNCT                         = 0x038
-	SYS_NLIST                           = 0x38C
-	SYS___IPDBCS                        = 0x38D
-	SYS___IPDSPX                        = 0x38E
-	SYS___IPMSGC                        = 0x38F
-	SYS___STHOSTENT                     = 0x38B
-	SYS___STSERVENT                     = 0x38A
-	SYS_ISSPACE                         = 0x039
-	SYS_COS                             = 0x040
-	SYS_T_ALLOC                         = 0x40A
-	SYS_T_BIND                          = 0x40B
-	SYS_T_CLOSE                         = 0x40C
-	SYS_T_CONNECT                       = 0x40D
-	SYS_T_ERROR                         = 0x40E
-	SYS_T_FREE                          = 0x40F
-	SYS_TAN                             = 0x041
-	SYS_T_RCVREL                        = 0x41A
-	SYS_T_RCVUDATA                      = 0x41B
-	SYS_T_RCVUDERR                      = 0x41C
-	SYS_T_SND                           = 0x41D
-	SYS_T_SNDDIS                        = 0x41E
-	SYS_T_SNDREL                        = 0x41F
-	SYS_GETPMSG                         = 0x42A
-	SYS_ISASTREAM                       = 0x42B
-	SYS_PUTMSG                          = 0x42C
-	SYS_PUTPMSG                         = 0x42D
-	SYS_SINH                            = 0x042
-	SYS___ISPOSIXON                     = 0x42E
-	SYS___OPENMVSREL                    = 0x42F
-	SYS_ACOS                            = 0x043
-	SYS_ATAN                            = 0x044
-	SYS_ATAN2                           = 0x045
-	SYS_FTELL                           = 0x046
-	SYS_FGETPOS                         = 0x047
-	SYS_SOCK_DEBUG                      = 0x47A
-	SYS_SOCK_DO_TESTSTOR                = 0x47D
-	SYS_TAKESOCKET                      = 0x47E
-	SYS___SERVER_INIT                   = 0x47F
-	SYS_FSEEK                           = 0x048
-	SYS___IPHOST                        = 0x48B
-	SYS___IPNODE                        = 0x48C
-	SYS___SERVER_CLASSIFY_CREATE        = 0x48D
-	SYS___SERVER_CLASSIFY_DESTROY       = 0x48E
-	SYS___SERVER_CLASSIFY_RESET         = 0x48F
-	SYS___SMF_RECORD                    = 0x48A
-	SYS_FSETPOS                         = 0x049
-	SYS___FNWSA                         = 0x49B
-	SYS___SPAWN2                        = 0x49D
-	SYS___SPAWNP2                       = 0x49E
-	SYS_ATOF                            = 0x050
-	SYS_PTHREAD_MUTEXATTR_GETPSHARED    = 0x50A
-	SYS_PTHREAD_MUTEXATTR_SETPSHARED    = 0x50B
-	SYS_PTHREAD_RWLOCK_DESTROY          = 0x50C
-	SYS_PTHREAD_RWLOCK_INIT             = 0x50D
-	SYS_PTHREAD_RWLOCK_RDLOCK           = 0x50E
-	SYS_PTHREAD_RWLOCK_TRYRDLOCK        = 0x50F
-	SYS_ATOI                            = 0x051
-	SYS___FP_CLASS                      = 0x51D
-	SYS___FP_CLR_FLAG                   = 0x51A
-	SYS___FP_FINITE                     = 0x51E
-	SYS___FP_ISNAN                      = 0x51F
-	SYS___FP_RAISE_XCP                  = 0x51C
-	SYS___FP_READ_FLAG                  = 0x51B
-	SYS_RAND                            = 0x052
-	SYS_SIGTIMEDWAIT                    = 0x52D
-	SYS_SIGWAITINFO                     = 0x52E
-	SYS___CHKBFP                        = 0x52F
-	SYS___FPC_RS                        = 0x52C
-	SYS___FPC_RW                        = 0x52A
-	SYS___FPC_SM                        = 0x52B
-	SYS_STRTOD                          = 0x053
-	SYS_STRTOL                          = 0x054
-	SYS_STRTOUL                         = 0x055
-	SYS_MALLOC                          = 0x056
-	SYS_SRAND                           = 0x057
-	SYS_CALLOC                          = 0x058
-	SYS_FREE                            = 0x059
-	SYS___OSENV                         = 0x59F
-	SYS___W_PIOCTL                      = 0x59E
-	SYS_LONGJMP                         = 0x060
-	SYS___FLOORF_B                      = 0x60A
-	SYS___FLOORL_B                      = 0x60B
-	SYS___FREXPF_B                      = 0x60C
-	SYS___FREXPL_B                      = 0x60D
-	SYS___LDEXPF_B                      = 0x60E
-	SYS___LDEXPL_B                      = 0x60F
-	SYS_SIGNAL                          = 0x061
-	SYS___ATAN2F_B                      = 0x61A
-	SYS___ATAN2L_B                      = 0x61B
-	SYS___COSHF_B                       = 0x61C
-	SYS___COSHL_B                       = 0x61D
-	SYS___EXPF_B                        = 0x61E
-	SYS___EXPL_B                        = 0x61F
-	SYS_TMPNAM                          = 0x062
-	SYS___ABSF_B                        = 0x62A
-	SYS___ABSL_B                        = 0x62C
-	SYS___ABS_B                         = 0x62B
-	SYS___FMODF_B                       = 0x62D
-	SYS___FMODL_B                       = 0x62E
-	SYS___MODFF_B                       = 0x62F
-	SYS_ATANL                           = 0x63A
-	SYS_CEILF                           = 0x63B
-	SYS_CEILL                           = 0x63C
-	SYS_COSF                            = 0x63D
-	SYS_COSHF                           = 0x63F
-	SYS_COSL                            = 0x63E
-	SYS_REMOVE                          = 0x063
-	SYS_POWL                            = 0x64A
-	SYS_RENAME                          = 0x064
-	SYS_SINF                            = 0x64B
-	SYS_SINHF                           = 0x64F
-	SYS_SINL                            = 0x64C
-	SYS_SQRTF                           = 0x64D
-	SYS_SQRTL                           = 0x64E
-	SYS_BTOWC                           = 0x65F
-	SYS_FREXPL                          = 0x65A
-	SYS_LDEXPF                          = 0x65B
-	SYS_LDEXPL                          = 0x65C
-	SYS_MODFF                           = 0x65D
-	SYS_MODFL                           = 0x65E
-	SYS_TMPFILE                         = 0x065
-	SYS_FREOPEN                         = 0x066
-	SYS___CHARMAP_INIT_A                = 0x66E
-	SYS___GETHOSTBYADDR_R_A             = 0x66C
-	SYS___GETHOSTBYNAME_A               = 0x66A
-	SYS___GETHOSTBYNAME_R_A             = 0x66D
-	SYS___MBLEN_A                       = 0x66F
-	SYS___RES_INIT_A                    = 0x66B
-	SYS_FCLOSE                          = 0x067
-	SYS___GETGRGID_R_A                  = 0x67D
-	SYS___WCSTOMBS_A                    = 0x67A
-	SYS___WCSTOMBS_STD_A                = 0x67B
-	SYS___WCSWIDTH_A                    = 0x67C
-	SYS___WCSWIDTH_ASIA                 = 0x67F
-	SYS___WCSWIDTH_STD_A                = 0x67E
-	SYS_FFLUSH                          = 0x068
-	SYS___GETLOGIN_R_A                  = 0x68E
-	SYS___GETPWNAM_R_A                  = 0x68C
-	SYS___GETPWUID_R_A                  = 0x68D
-	SYS___TTYNAME_R_A                   = 0x68F
-	SYS___WCWIDTH_ASIA                  = 0x68B
-	SYS___WCWIDTH_STD_A                 = 0x68A
-	SYS_FOPEN                           = 0x069
-	SYS___REGEXEC_A                     = 0x69A
-	SYS___REGEXEC_STD_A                 = 0x69B
-	SYS___REGFREE_A                     = 0x69C
-	SYS___REGFREE_STD_A                 = 0x69D
-	SYS___STRCOLL_A                     = 0x69E
-	SYS___STRCOLL_C_A                   = 0x69F
-	SYS_SCANF                           = 0x070
-	SYS___A64L_A                        = 0x70C
-	SYS___ECVT_A                        = 0x70D
-	SYS___FCVT_A                        = 0x70E
-	SYS___GCVT_A                        = 0x70F
-	SYS___STRTOUL_A                     = 0x70A
-	SYS_____AE_CORRESTBL_QUERY_A        = 0x70B
-	SYS_SPRINTF                         = 0x071
-	SYS___ACCESS_A                      = 0x71F
-	SYS___CATOPEN_A                     = 0x71E
-	SYS___GETOPT_A                      = 0x71D
-	SYS___REALPATH_A                    = 0x71A
-	SYS___SETENV_A                      = 0x71B
-	SYS___SYSTEM_A                      = 0x71C
-	SYS_FGETC                           = 0x072
-	SYS___GAI_STRERROR_A                = 0x72F
-	SYS___RMDIR_A                       = 0x72A
-	SYS___STATVFS_A                     = 0x72B
-	SYS___SYMLINK_A                     = 0x72C
-	SYS___TRUNCATE_A                    = 0x72D
-	SYS___UNLINK_A                      = 0x72E
-	SYS_VFPRINTF                        = 0x073
-	SYS___ISSPACE_A                     = 0x73A
-	SYS___ISUPPER_A                     = 0x73B
-	SYS___ISWALNUM_A                    = 0x73F
-	SYS___ISXDIGIT_A                    = 0x73C
-	SYS___TOLOWER_A                     = 0x73D
-	SYS___TOUPPER_A                     = 0x73E
-	SYS_VPRINTF                         = 0x074
-	SYS___CONFSTR_A                     = 0x74B
-	SYS___FDOPEN_A                      = 0x74E
-	SYS___FLDATA_A                      = 0x74F
-	SYS___FTOK_A                        = 0x74C
-	SYS___ISWXDIGIT_A                   = 0x74A
-	SYS___MKTEMP_A                      = 0x74D
-	SYS_VSPRINTF                        = 0x075
-	SYS___GETGRGID_A                    = 0x75A
-	SYS___GETGRNAM_A                    = 0x75B
-	SYS___GETGROUPSBYNAME_A             = 0x75C
-	SYS___GETHOSTENT_A                  = 0x75D
-	SYS___GETHOSTNAME_A                 = 0x75E
-	SYS___GETLOGIN_A                    = 0x75F
-	SYS_GETC                            = 0x076
-	SYS___CREATEWORKUNIT_A              = 0x76A
-	SYS___CTERMID_A                     = 0x76B
-	SYS___FMTMSG_A                      = 0x76C
-	SYS___INITGROUPS_A                  = 0x76D
-	SYS___MSGRCV_A                      = 0x76F
-	SYS_____LOGIN_A                     = 0x76E
-	SYS_FGETS                           = 0x077
-	SYS___STRCASECMP_A                  = 0x77B
-	SYS___STRNCASECMP_A                 = 0x77C
-	SYS___TTYNAME_A                     = 0x77D
-	SYS___UNAME_A                       = 0x77E
-	SYS___UTIMES_A                      = 0x77F
-	SYS_____SERVER_PWU_A                = 0x77A
-	SYS_FPUTC                           = 0x078
-	SYS___CREAT_O_A                     = 0x78E
-	SYS___ENVNA                         = 0x78F
-	SYS___FREAD_A                       = 0x78A
-	SYS___FWRITE_A                      = 0x78B
-	SYS___ISASCII                       = 0x78D
-	SYS___OPEN_O_A                      = 0x78C
-	SYS_FPUTS                           = 0x079
-	SYS___ASCTIME_A                     = 0x79C
-	SYS___CTIME_A                       = 0x79D
-	SYS___GETDATE_A                     = 0x79E
-	SYS___GETSERVBYPORT_A               = 0x79A
-	SYS___GETSERVENT_A                  = 0x79B
-	SYS___TZSET_A                       = 0x79F
-	SYS_ACL_FROM_TEXT                   = 0x80C
-	SYS_ACL_SET_FD                      = 0x80A
-	SYS_ACL_SET_FILE                    = 0x80B
-	SYS_ACL_SORT                        = 0x80E
-	SYS_ACL_TO_TEXT                     = 0x80D
-	SYS_UNGETC                          = 0x080
-	SYS___SHUTDOWN_REGISTRATION         = 0x80F
-	SYS_FREAD                           = 0x081
-	SYS_FREEADDRINFO                    = 0x81A
-	SYS_GAI_STRERROR                    = 0x81B
-	SYS_REXEC_AF                        = 0x81C
-	SYS___DYNALLOC_A                    = 0x81F
-	SYS___POE                           = 0x81D
-	SYS_WCSTOMBS                        = 0x082
-	SYS___INET_ADDR_A                   = 0x82F
-	SYS___NLIST_A                       = 0x82A
-	SYS_____TCGETCP_A                   = 0x82B
-	SYS_____TCSETCP_A                   = 0x82C
-	SYS_____W_PIOCTL_A                  = 0x82E
-	SYS_MBTOWC                          = 0x083
-	SYS___CABEND                        = 0x83D
-	SYS___LE_CIB_GET                    = 0x83E
-	SYS___RECVMSG_A                     = 0x83B
-	SYS___SENDMSG_A                     = 0x83A
-	SYS___SET_LAA_FOR_JIT               = 0x83F
-	SYS_____LCHATTR_A                   = 0x83C
-	SYS_WCTOMB                          = 0x084
-	SYS___CBRTL_B                       = 0x84A
-	SYS___COPYSIGNF_B                   = 0x84B
-	SYS___COPYSIGNL_B                   = 0x84C
-	SYS___COTANF_B                      = 0x84D
-	SYS___COTANL_B                      = 0x84F
-	SYS___COTAN_B                       = 0x84E
-	SYS_MBSTOWCS                        = 0x085
-	SYS___LOG1PL_B                      = 0x85A
-	SYS___LOG2F_B                       = 0x85B
-	SYS___LOG2L_B                       = 0x85D
-	SYS___LOG2_B                        = 0x85C
-	SYS___REMAINDERF_B                  = 0x85E
-	SYS___REMAINDERL_B                  = 0x85F
-	SYS_ACOSHF                          = 0x86E
-	SYS_ACOSHL                          = 0x86F
-	SYS_WCSCPY                          = 0x086
-	SYS___ERFCF_B                       = 0x86D
-	SYS___ERFF_B                        = 0x86C
-	SYS___LROUNDF_B                     = 0x86A
-	SYS___LROUND_B                      = 0x86B
-	SYS_COTANL                          = 0x87A
-	SYS_EXP2F                           = 0x87B
-	SYS_EXP2L                           = 0x87C
-	SYS_EXPM1F                          = 0x87D
-	SYS_EXPM1L                          = 0x87E
-	SYS_FDIMF                           = 0x87F
-	SYS_WCSCAT                          = 0x087
-	SYS___COTANL                        = 0x87A
-	SYS_REMAINDERF                      = 0x88A
-	SYS_REMAINDERL                      = 0x88B
-	SYS_REMAINDF                        = 0x88A
-	SYS_REMAINDL                        = 0x88B
-	SYS_REMQUO                          = 0x88D
-	SYS_REMQUOF                         = 0x88C
-	SYS_REMQUOL                         = 0x88E
-	SYS_TGAMMAF                         = 0x88F
-	SYS_WCSCHR                          = 0x088
-	SYS_ERFCF                           = 0x89B
-	SYS_ERFCL                           = 0x89C
-	SYS_ERFL                            = 0x89A
-	SYS_EXP2                            = 0x89E
-	SYS_WCSCMP                          = 0x089
-	SYS___EXP2_B                        = 0x89D
-	SYS___FAR_JUMP                      = 0x89F
-	SYS_ABS                             = 0x090
-	SYS___ERFCL_H                       = 0x90A
-	SYS___EXPF_H                        = 0x90C
-	SYS___EXPL_H                        = 0x90D
-	SYS___EXPM1_H                       = 0x90E
-	SYS___EXP_H                         = 0x90B
-	SYS___FDIM_H                        = 0x90F
-	SYS_DIV                             = 0x091
-	SYS___LOG2F_H                       = 0x91F
-	SYS___LOG2_H                        = 0x91E
-	SYS___LOGB_H                        = 0x91D
-	SYS___LOGF_H                        = 0x91B
-	SYS___LOGL_H                        = 0x91C
-	SYS___LOG_H                         = 0x91A
-	SYS_LABS                            = 0x092
-	SYS___POWL_H                        = 0x92A
-	SYS___REMAINDER_H                   = 0x92B
-	SYS___RINT_H                        = 0x92C
-	SYS___SCALB_H                       = 0x92D
-	SYS___SINF_H                        = 0x92F
-	SYS___SIN_H                         = 0x92E
-	SYS_STRNCPY                         = 0x093
-	SYS___TANHF_H                       = 0x93B
-	SYS___TANHL_H                       = 0x93C
-	SYS___TANH_H                        = 0x93A
-	SYS___TGAMMAF_H                     = 0x93E
-	SYS___TGAMMA_H                      = 0x93D
-	SYS___TRUNC_H                       = 0x93F
-	SYS_MEMCPY                          = 0x094
-	SYS_VFWSCANF                        = 0x94A
-	SYS_VSWSCANF                        = 0x94E
-	SYS_VWSCANF                         = 0x94C
-	SYS_INET6_RTH_ADD                   = 0x95D
-	SYS_INET6_RTH_INIT                  = 0x95C
-	SYS_INET6_RTH_REVERSE               = 0x95E
-	SYS_INET6_RTH_SEGMENTS              = 0x95F
-	SYS_INET6_RTH_SPACE                 = 0x95B
-	SYS_MEMMOVE                         = 0x095
-	SYS_WCSTOLD                         = 0x95A
-	SYS_STRCPY                          = 0x096
-	SYS_STRCMP                          = 0x097
-	SYS_CABS                            = 0x98E
-	SYS_STRCAT                          = 0x098
-	SYS___CABS_B                        = 0x98F
-	SYS___POW_II                        = 0x98A
-	SYS___POW_II_B                      = 0x98B
-	SYS___POW_II_H                      = 0x98C
-	SYS_CACOSF                          = 0x99A
-	SYS_CACOSL                          = 0x99D
-	SYS_STRNCAT                         = 0x099
-	SYS___CACOSF_B                      = 0x99B
-	SYS___CACOSF_H                      = 0x99C
-	SYS___CACOSL_B                      = 0x99E
-	SYS___CACOSL_H                      = 0x99F
-	SYS_ISWALPHA                        = 0x100
-	SYS_ISWBLANK                        = 0x101
-	SYS___ISWBLK                        = 0x101
-	SYS_ISWCNTRL                        = 0x102
-	SYS_ISWDIGIT                        = 0x103
-	SYS_ISWGRAPH                        = 0x104
-	SYS_ISWLOWER                        = 0x105
-	SYS_ISWPRINT                        = 0x106
-	SYS_ISWPUNCT                        = 0x107
-	SYS_ISWSPACE                        = 0x108
-	SYS_ISWUPPER                        = 0x109
-	SYS_WCTOB                           = 0x110
-	SYS_MBRLEN                          = 0x111
-	SYS_MBRTOWC                         = 0x112
-	SYS_MBSRTOWC                        = 0x113
-	SYS_MBSRTOWCS                       = 0x113
-	SYS_WCRTOMB                         = 0x114
-	SYS_WCSRTOMB                        = 0x115
-	SYS_WCSRTOMBS                       = 0x115
-	SYS___CSID                          = 0x116
-	SYS___WCSID                         = 0x117
-	SYS_STRPTIME                        = 0x118
-	SYS___STRPTM                        = 0x118
-	SYS_STRFMON                         = 0x119
-	SYS_WCSCOLL                         = 0x130
-	SYS_WCSXFRM                         = 0x131
-	SYS_WCSWIDTH                        = 0x132
-	SYS_WCWIDTH                         = 0x133
-	SYS_WCSFTIME                        = 0x134
-	SYS_SWPRINTF                        = 0x135
-	SYS_VSWPRINT                        = 0x136
-	SYS_VSWPRINTF                       = 0x136
-	SYS_SWSCANF                         = 0x137
-	SYS_REGCOMP                         = 0x138
-	SYS_REGEXEC                         = 0x139
-	SYS_GETWC                           = 0x140
-	SYS_GETWCHAR                        = 0x141
-	SYS_PUTWC                           = 0x142
-	SYS_PUTWCHAR                        = 0x143
-	SYS_UNGETWC                         = 0x144
-	SYS_ICONV_OPEN                      = 0x145
-	SYS_ICONV                           = 0x146
-	SYS_ICONV_CLOSE                     = 0x147
-	SYS_COLLRANGE                       = 0x150
-	SYS_CCLASS                          = 0x151
-	SYS_COLLORDER                       = 0x152
-	SYS___DEMANGLE                      = 0x154
-	SYS_FDOPEN                          = 0x155
-	SYS___ERRNO                         = 0x156
-	SYS___ERRNO2                        = 0x157
-	SYS___TERROR                        = 0x158
-	SYS_MAXCOLL                         = 0x169
-	SYS_DLLLOAD                         = 0x170
-	SYS__EXIT                           = 0x174
-	SYS_ACCESS                          = 0x175
-	SYS_ALARM                           = 0x176
-	SYS_CFGETISPEED                     = 0x177
-	SYS_CFGETOSPEED                     = 0x178
-	SYS_CFSETISPEED                     = 0x179
-	SYS_CREAT                           = 0x180
-	SYS_CTERMID                         = 0x181
-	SYS_DUP                             = 0x182
-	SYS_DUP2                            = 0x183
-	SYS_EXECL                           = 0x184
-	SYS_EXECLE                          = 0x185
-	SYS_EXECLP                          = 0x186
-	SYS_EXECV                           = 0x187
-	SYS_EXECVE                          = 0x188
-	SYS_EXECVP                          = 0x189
-	SYS_FSTAT                           = 0x190
-	SYS_FSYNC                           = 0x191
-	SYS_FTRUNCATE                       = 0x192
-	SYS_GETCWD                          = 0x193
-	SYS_GETEGID                         = 0x194
-	SYS_GETEUID                         = 0x195
-	SYS_GETGID                          = 0x196
-	SYS_GETGRGID                        = 0x197
-	SYS_GETGRNAM                        = 0x198
-	SYS_GETGROUPS                       = 0x199
-	SYS_PTHREAD_MUTEXATTR_DESTROY       = 0x200
-	SYS_PTHREAD_MUTEXATTR_SETKIND_NP    = 0x201
-	SYS_PTHREAD_MUTEXATTR_GETKIND_NP    = 0x202
-	SYS_PTHREAD_MUTEX_INIT              = 0x203
-	SYS_PTHREAD_MUTEX_DESTROY           = 0x204
-	SYS_PTHREAD_MUTEX_LOCK              = 0x205
-	SYS_PTHREAD_MUTEX_TRYLOCK           = 0x206
-	SYS_PTHREAD_MUTEX_UNLOCK            = 0x207
-	SYS_PTHREAD_ONCE                    = 0x209
-	SYS_TW_OPEN                         = 0x210
-	SYS_TW_FCNTL                        = 0x211
-	SYS_PTHREAD_JOIN_D4_NP              = 0x212
-	SYS_PTHREAD_CONDATTR_SETKIND_NP     = 0x213
-	SYS_PTHREAD_CONDATTR_GETKIND_NP     = 0x214
-	SYS_EXTLINK_NP                      = 0x215
-	SYS___PASSWD                        = 0x216
-	SYS_SETGROUPS                       = 0x217
-	SYS_INITGROUPS                      = 0x218
-	SYS_WCSRCHR                         = 0x240
-	SYS_SVC99                           = 0x241
-	SYS___SVC99                         = 0x241
-	SYS_WCSWCS                          = 0x242
-	SYS_LOCALECO                        = 0x243
-	SYS_LOCALECONV                      = 0x243
-	SYS___LIBREL                        = 0x244
-	SYS_RELEASE                         = 0x245
-	SYS___RLSE                          = 0x245
-	SYS_FLOCATE                         = 0x246
-	SYS___FLOCT                         = 0x246
-	SYS_FDELREC                         = 0x247
-	SYS___FDLREC                        = 0x247
-	SYS_FETCH                           = 0x248
-	SYS___FETCH                         = 0x248
-	SYS_QSORT                           = 0x249
-	SYS___CLEANUPCATCH                  = 0x260
-	SYS___CATCHMATCH                    = 0x261
-	SYS___CLEAN2UPCATCH                 = 0x262
-	SYS_GETPRIORITY                     = 0x270
-	SYS_NICE                            = 0x271
-	SYS_SETPRIORITY                     = 0x272
-	SYS_GETITIMER                       = 0x273
-	SYS_SETITIMER                       = 0x274
-	SYS_MSGCTL                          = 0x275
-	SYS_MSGGET                          = 0x276
-	SYS_MSGRCV                          = 0x277
-	SYS_MSGSND                          = 0x278
-	SYS_MSGXRCV                         = 0x279
-	SYS___MSGXR                         = 0x279
-	SYS_SHMGET                          = 0x280
-	SYS___GETIPC                        = 0x281
-	SYS_SETGRENT                        = 0x282
-	SYS_GETGRENT                        = 0x283
-	SYS_ENDGRENT                        = 0x284
-	SYS_SETPWENT                        = 0x285
-	SYS_GETPWENT                        = 0x286
-	SYS_ENDPWENT                        = 0x287
-	SYS_BSD_SIGNAL                      = 0x288
-	SYS_KILLPG                          = 0x289
-	SYS_SIGSET                          = 0x290
-	SYS_SIGSTACK                        = 0x291
-	SYS_GETRLIMIT                       = 0x292
-	SYS_SETRLIMIT                       = 0x293
-	SYS_GETRUSAGE                       = 0x294
-	SYS_MMAP                            = 0x295
-	SYS_MPROTECT                        = 0x296
-	SYS_MSYNC                           = 0x297
-	SYS_MUNMAP                          = 0x298
-	SYS_CONFSTR                         = 0x299
-	SYS___NDMTRM                        = 0x300
-	SYS_FTOK                            = 0x301
-	SYS_BASENAME                        = 0x302
-	SYS_DIRNAME                         = 0x303
-	SYS_GETDTABLESIZE                   = 0x304
-	SYS_MKSTEMP                         = 0x305
-	SYS_MKTEMP                          = 0x306
-	SYS_NFTW                            = 0x307
-	SYS_GETWD                           = 0x308
-	SYS_LOCKF                           = 0x309
-	SYS_WORDEXP                         = 0x310
-	SYS_WORDFREE                        = 0x311
-	SYS_GETPGID                         = 0x312
-	SYS_GETSID                          = 0x313
-	SYS___UTMPXNAME                     = 0x314
-	SYS_CUSERID                         = 0x315
-	SYS_GETPASS                         = 0x316
-	SYS_FNMATCH                         = 0x317
-	SYS_FTW                             = 0x318
-	SYS_GETW                            = 0x319
-	SYS_ACOSH                           = 0x320
-	SYS_ASINH                           = 0x321
-	SYS_ATANH                           = 0x322
-	SYS_CBRT                            = 0x323
-	SYS_EXPM1                           = 0x324
-	SYS_ILOGB                           = 0x325
-	SYS_LOGB                            = 0x326
-	SYS_LOG1P                           = 0x327
-	SYS_NEXTAFTER                       = 0x328
-	SYS_RINT                            = 0x329
-	SYS_SPAWN                           = 0x330
-	SYS_SPAWNP                          = 0x331
-	SYS_GETLOGIN_UU                     = 0x332
-	SYS_ECVT                            = 0x333
-	SYS_FCVT                            = 0x334
-	SYS_GCVT                            = 0x335
-	SYS_ACCEPT                          = 0x336
-	SYS_BIND                            = 0x337
-	SYS_CONNECT                         = 0x338
-	SYS_ENDHOSTENT                      = 0x339
-	SYS_GETHOSTENT                      = 0x340
-	SYS_GETHOSTID                       = 0x341
-	SYS_GETHOSTNAME                     = 0x342
-	SYS_GETNETBYADDR                    = 0x343
-	SYS_GETNETBYNAME                    = 0x344
-	SYS_GETNETENT                       = 0x345
-	SYS_GETPEERNAME                     = 0x346
-	SYS_GETPROTOBYNAME                  = 0x347
-	SYS_GETPROTOBYNUMBER                = 0x348
-	SYS_GETPROTOENT                     = 0x349
-	SYS_INET_LNAOF                      = 0x350
-	SYS_INET_MAKEADDR                   = 0x351
-	SYS_INET_NETOF                      = 0x352
-	SYS_INET_NETWORK                    = 0x353
-	SYS_INET_NTOA                       = 0x354
-	SYS_IOCTL                           = 0x355
-	SYS_LISTEN                          = 0x356
-	SYS_READV                           = 0x357
-	SYS_RECV                            = 0x358
-	SYS_RECVFROM                        = 0x359
-	SYS_SETHOSTENT                      = 0x360
-	SYS_SETNETENT                       = 0x361
-	SYS_SETPEER                         = 0x362
-	SYS_SETPROTOENT                     = 0x363
-	SYS_SETSERVENT                      = 0x364
-	SYS_SETSOCKOPT                      = 0x365
-	SYS_SHUTDOWN                        = 0x366
-	SYS_SOCKET                          = 0x367
-	SYS_SOCKETPAIR                      = 0x368
-	SYS_WRITEV                          = 0x369
-	SYS_ENDNETENT                       = 0x370
-	SYS_CLOSELOG                        = 0x371
-	SYS_OPENLOG                         = 0x372
-	SYS_SETLOGMASK                      = 0x373
-	SYS_SYSLOG                          = 0x374
-	SYS_PTSNAME                         = 0x375
-	SYS_SETREUID                        = 0x376
-	SYS_SETREGID                        = 0x377
-	SYS_REALPATH                        = 0x378
-	SYS___SIGNGAM                       = 0x379
-	SYS_POLL                            = 0x380
-	SYS_REXEC                           = 0x381
-	SYS___ISASCII2                      = 0x382
-	SYS___TOASCII2                      = 0x383
-	SYS_CHPRIORITY                      = 0x384
-	SYS_PTHREAD_ATTR_SETSYNCTYPE_NP     = 0x385
-	SYS_PTHREAD_ATTR_GETSYNCTYPE_NP     = 0x386
-	SYS_PTHREAD_SET_LIMIT_NP            = 0x387
-	SYS___STNETENT                      = 0x388
-	SYS___STPROTOENT                    = 0x389
-	SYS___SELECT1                       = 0x390
-	SYS_PTHREAD_SECURITY_NP             = 0x391
-	SYS___CHECK_RESOURCE_AUTH_NP        = 0x392
-	SYS___CONVERT_ID_NP                 = 0x393
-	SYS___OPENVMREL                     = 0x394
-	SYS_WMEMCHR                         = 0x395
-	SYS_WMEMCMP                         = 0x396
-	SYS_WMEMCPY                         = 0x397
-	SYS_WMEMMOVE                        = 0x398
-	SYS_WMEMSET                         = 0x399
-	SYS___FPUTWC                        = 0x400
-	SYS___PUTWC                         = 0x401
-	SYS___PWCHAR                        = 0x402
-	SYS___WCSFTM                        = 0x403
-	SYS___WCSTOK                        = 0x404
-	SYS___WCWDTH                        = 0x405
-	SYS_T_ACCEPT                        = 0x409
-	SYS_T_GETINFO                       = 0x410
-	SYS_T_GETPROTADDR                   = 0x411
-	SYS_T_GETSTATE                      = 0x412
-	SYS_T_LISTEN                        = 0x413
-	SYS_T_LOOK                          = 0x414
-	SYS_T_OPEN                          = 0x415
-	SYS_T_OPTMGMT                       = 0x416
-	SYS_T_RCV                           = 0x417
-	SYS_T_RCVCONNECT                    = 0x418
-	SYS_T_RCVDIS                        = 0x419
-	SYS_T_SNDUDATA                      = 0x420
-	SYS_T_STRERROR                      = 0x421
-	SYS_T_SYNC                          = 0x422
-	SYS_T_UNBIND                        = 0x423
-	SYS___T_ERRNO                       = 0x424
-	SYS___RECVMSG2                      = 0x425
-	SYS___SENDMSG2                      = 0x426
-	SYS_FATTACH                         = 0x427
-	SYS_FDETACH                         = 0x428
-	SYS_GETMSG                          = 0x429
-	SYS_GETCONTEXT                      = 0x430
-	SYS_SETCONTEXT                      = 0x431
-	SYS_MAKECONTEXT                     = 0x432
-	SYS_SWAPCONTEXT                     = 0x433
-	SYS_PTHREAD_GETSPECIFIC_D8_NP       = 0x434
-	SYS_GETCLIENTID                     = 0x470
-	SYS___GETCLIENTID                   = 0x471
-	SYS_GETSTABLESIZE                   = 0x472
-	SYS_GETIBMOPT                       = 0x473
-	SYS_GETIBMSOCKOPT                   = 0x474
-	SYS_GIVESOCKET                      = 0x475
-	SYS_IBMSFLUSH                       = 0x476
-	SYS_MAXDESC                         = 0x477
-	SYS_SETIBMOPT                       = 0x478
-	SYS_SETIBMSOCKOPT                   = 0x479
-	SYS___SERVER_PWU                    = 0x480
-	SYS_PTHREAD_TAG_NP                  = 0x481
-	SYS___CONSOLE                       = 0x482
-	SYS___WSINIT                        = 0x483
-	SYS___IPTCPN                        = 0x489
-	SYS___SERVER_CLASSIFY               = 0x490
-	SYS___HEAPRPT                       = 0x496
-	SYS___ISBFP                         = 0x500
-	SYS___FP_CAST                       = 0x501
-	SYS___CERTIFICATE                   = 0x502
-	SYS_SEND_FILE                       = 0x503
-	SYS_AIO_CANCEL                      = 0x504
-	SYS_AIO_ERROR                       = 0x505
-	SYS_AIO_READ                        = 0x506
-	SYS_AIO_RETURN                      = 0x507
-	SYS_AIO_SUSPEND                     = 0x508
-	SYS_AIO_WRITE                       = 0x509
-	SYS_PTHREAD_RWLOCK_TRYWRLOCK        = 0x510
-	SYS_PTHREAD_RWLOCK_UNLOCK           = 0x511
-	SYS_PTHREAD_RWLOCK_WRLOCK           = 0x512
-	SYS_PTHREAD_RWLOCKATTR_GETPSHARED   = 0x513
-	SYS_PTHREAD_RWLOCKATTR_SETPSHARED   = 0x514
-	SYS_PTHREAD_RWLOCKATTR_INIT         = 0x515
-	SYS_PTHREAD_RWLOCKATTR_DESTROY      = 0x516
-	SYS___CTTBL                         = 0x517
-	SYS_PTHREAD_MUTEXATTR_SETTYPE       = 0x518
-	SYS_PTHREAD_MUTEXATTR_GETTYPE       = 0x519
-	SYS___FP_UNORDERED                  = 0x520
-	SYS___FP_READ_RND                   = 0x521
-	SYS___FP_READ_RND_B                 = 0x522
-	SYS___FP_SWAP_RND                   = 0x523
-	SYS___FP_SWAP_RND_B                 = 0x524
-	SYS___FP_LEVEL                      = 0x525
-	SYS___FP_BTOH                       = 0x526
-	SYS___FP_HTOB                       = 0x527
-	SYS___FPC_RD                        = 0x528
-	SYS___FPC_WR                        = 0x529
-	SYS_PTHREAD_SETCANCELTYPE           = 0x600
-	SYS_PTHREAD_TESTCANCEL              = 0x601
-	SYS___ATANF_B                       = 0x602
-	SYS___ATANL_B                       = 0x603
-	SYS___CEILF_B                       = 0x604
-	SYS___CEILL_B                       = 0x605
-	SYS___COSF_B                        = 0x606
-	SYS___COSL_B                        = 0x607
-	SYS___FABSF_B                       = 0x608
-	SYS___FABSL_B                       = 0x609
-	SYS___SINF_B                        = 0x610
-	SYS___SINL_B                        = 0x611
-	SYS___TANF_B                        = 0x612
-	SYS___TANL_B                        = 0x613
-	SYS___TANHF_B                       = 0x614
-	SYS___TANHL_B                       = 0x615
-	SYS___ACOSF_B                       = 0x616
-	SYS___ACOSL_B                       = 0x617
-	SYS___ASINF_B                       = 0x618
-	SYS___ASINL_B                       = 0x619
-	SYS___LOGF_B                        = 0x620
-	SYS___LOGL_B                        = 0x621
-	SYS___LOG10F_B                      = 0x622
-	SYS___LOG10L_B                      = 0x623
-	SYS___POWF_B                        = 0x624
-	SYS___POWL_B                        = 0x625
-	SYS___SINHF_B                       = 0x626
-	SYS___SINHL_B                       = 0x627
-	SYS___SQRTF_B                       = 0x628
-	SYS___SQRTL_B                       = 0x629
-	SYS___MODFL_B                       = 0x630
-	SYS_ABSF                            = 0x631
-	SYS_ABSL                            = 0x632
-	SYS_ACOSF                           = 0x633
-	SYS_ACOSL                           = 0x634
-	SYS_ASINF                           = 0x635
-	SYS_ASINL                           = 0x636
-	SYS_ATAN2F                          = 0x637
-	SYS_ATAN2L                          = 0x638
-	SYS_ATANF                           = 0x639
-	SYS_COSHL                           = 0x640
-	SYS_EXPF                            = 0x641
-	SYS_EXPL                            = 0x642
-	SYS_TANHF                           = 0x643
-	SYS_TANHL                           = 0x644
-	SYS_LOG10F                          = 0x645
-	SYS_LOG10L                          = 0x646
-	SYS_LOGF                            = 0x647
-	SYS_LOGL                            = 0x648
-	SYS_POWF                            = 0x649
-	SYS_SINHL                           = 0x650
-	SYS_TANF                            = 0x651
-	SYS_TANL                            = 0x652
-	SYS_FABSF                           = 0x653
-	SYS_FABSL                           = 0x654
-	SYS_FLOORF                          = 0x655
-	SYS_FLOORL                          = 0x656
-	SYS_FMODF                           = 0x657
-	SYS_FMODL                           = 0x658
-	SYS_FREXPF                          = 0x659
-	SYS___CHATTR                        = 0x660
-	SYS___FCHATTR                       = 0x661
-	SYS___TOCCSID                       = 0x662
-	SYS___CSNAMETYPE                    = 0x663
-	SYS___TOCSNAME                      = 0x664
-	SYS___CCSIDTYPE                     = 0x665
-	SYS___AE_CORRESTBL_QUERY            = 0x666
-	SYS___AE_AUTOCONVERT_STATE          = 0x667
-	SYS_DN_FIND                         = 0x668
-	SYS___GETHOSTBYADDR_A               = 0x669
-	SYS___MBLEN_SB_A                    = 0x670
-	SYS___MBLEN_STD_A                   = 0x671
-	SYS___MBLEN_UTF                     = 0x672
-	SYS___MBSTOWCS_A                    = 0x673
-	SYS___MBSTOWCS_STD_A                = 0x674
-	SYS___MBTOWC_A                      = 0x675
-	SYS___MBTOWC_ISO1                   = 0x676
-	SYS___MBTOWC_SBCS                   = 0x677
-	SYS___MBTOWC_MBCS                   = 0x678
-	SYS___MBTOWC_UTF                    = 0x679
-	SYS___CSID_A                        = 0x680
-	SYS___CSID_STD_A                    = 0x681
-	SYS___WCSID_A                       = 0x682
-	SYS___WCSID_STD_A                   = 0x683
-	SYS___WCTOMB_A                      = 0x684
-	SYS___WCTOMB_ISO1                   = 0x685
-	SYS___WCTOMB_STD_A                  = 0x686
-	SYS___WCTOMB_UTF                    = 0x687
-	SYS___WCWIDTH_A                     = 0x688
-	SYS___GETGRNAM_R_A                  = 0x689
-	SYS___READDIR_R_A                   = 0x690
-	SYS___E2A_S                         = 0x691
-	SYS___FNMATCH_A                     = 0x692
-	SYS___FNMATCH_C_A                   = 0x693
-	SYS___EXECL_A                       = 0x694
-	SYS___FNMATCH_STD_A                 = 0x695
-	SYS___REGCOMP_A                     = 0x696
-	SYS___REGCOMP_STD_A                 = 0x697
-	SYS___REGERROR_A                    = 0x698
-	SYS___REGERROR_STD_A                = 0x699
-	SYS___SWPRINTF_A                    = 0x700
-	SYS___FSCANF_A                      = 0x701
-	SYS___SCANF_A                       = 0x702
-	SYS___SSCANF_A                      = 0x703
-	SYS___SWSCANF_A                     = 0x704
-	SYS___ATOF_A                        = 0x705
-	SYS___ATOI_A                        = 0x706
-	SYS___ATOL_A                        = 0x707
-	SYS___STRTOD_A                      = 0x708
-	SYS___STRTOL_A                      = 0x709
-	SYS___L64A_A                        = 0x710
-	SYS___STRERROR_A                    = 0x711
-	SYS___PERROR_A                      = 0x712
-	SYS___FETCH_A                       = 0x713
-	SYS___GETENV_A                      = 0x714
-	SYS___MKSTEMP_A                     = 0x717
-	SYS___PTSNAME_A                     = 0x718
-	SYS___PUTENV_A                      = 0x719
-	SYS___CHDIR_A                       = 0x720
-	SYS___CHOWN_A                       = 0x721
-	SYS___CHROOT_A                      = 0x722
-	SYS___GETCWD_A                      = 0x723
-	SYS___GETWD_A                       = 0x724
-	SYS___LCHOWN_A                      = 0x725
-	SYS___LINK_A                        = 0x726
-	SYS___PATHCONF_A                    = 0x727
-	SYS___IF_NAMEINDEX_A                = 0x728
-	SYS___READLINK_A                    = 0x729
-	SYS___EXTLINK_NP_A                  = 0x730
-	SYS___ISALNUM_A                     = 0x731
-	SYS___ISALPHA_A                     = 0x732
-	SYS___A2E_S                         = 0x733
-	SYS___ISCNTRL_A                     = 0x734
-	SYS___ISDIGIT_A                     = 0x735
-	SYS___ISGRAPH_A                     = 0x736
-	SYS___ISLOWER_A                     = 0x737
-	SYS___ISPRINT_A                     = 0x738
-	SYS___ISPUNCT_A                     = 0x739
-	SYS___ISWALPHA_A                    = 0x740
-	SYS___A2E_L                         = 0x741
-	SYS___ISWCNTRL_A                    = 0x742
-	SYS___ISWDIGIT_A                    = 0x743
-	SYS___ISWGRAPH_A                    = 0x744
-	SYS___ISWLOWER_A                    = 0x745
-	SYS___ISWPRINT_A                    = 0x746
-	SYS___ISWPUNCT_A                    = 0x747
-	SYS___ISWSPACE_A                    = 0x748
-	SYS___ISWUPPER_A                    = 0x749
-	SYS___REMOVE_A                      = 0x750
-	SYS___RENAME_A                      = 0x751
-	SYS___TMPNAM_A                      = 0x752
-	SYS___FOPEN_A                       = 0x753
-	SYS___FREOPEN_A                     = 0x754
-	SYS___CUSERID_A                     = 0x755
-	SYS___POPEN_A                       = 0x756
-	SYS___TEMPNAM_A                     = 0x757
-	SYS___FTW_A                         = 0x758
-	SYS___GETGRENT_A                    = 0x759
-	SYS___INET_NTOP_A                   = 0x760
-	SYS___GETPASS_A                     = 0x761
-	SYS___GETPWENT_A                    = 0x762
-	SYS___GETPWNAM_A                    = 0x763
-	SYS___GETPWUID_A                    = 0x764
-	SYS_____CHECK_RESOURCE_AUTH_NP_A    = 0x765
-	SYS___CHECKSCHENV_A                 = 0x766
-	SYS___CONNECTSERVER_A               = 0x767
-	SYS___CONNECTWORKMGR_A              = 0x768
-	SYS_____CONSOLE_A                   = 0x769
-	SYS___MSGSND_A                      = 0x770
-	SYS___MSGXRCV_A                     = 0x771
-	SYS___NFTW_A                        = 0x772
-	SYS_____PASSWD_A                    = 0x773
-	SYS___PTHREAD_SECURITY_NP_A         = 0x774
-	SYS___QUERYMETRICS_A                = 0x775
-	SYS___QUERYSCHENV                   = 0x776
-	SYS___READV_A                       = 0x777
-	SYS_____SERVER_CLASSIFY_A           = 0x778
-	SYS_____SERVER_INIT_A               = 0x779
-	SYS___W_GETPSENT_A                  = 0x780
-	SYS___WRITEV_A                      = 0x781
-	SYS___W_STATFS_A                    = 0x782
-	SYS___W_STATVFS_A                   = 0x783
-	SYS___FPUTC_A                       = 0x784
-	SYS___PUTCHAR_A                     = 0x785
-	SYS___PUTS_A                        = 0x786
-	SYS___FGETS_A                       = 0x787
-	SYS___GETS_A                        = 0x788
-	SYS___FPUTS_A                       = 0x789
-	SYS___PUTC_A                        = 0x790
-	SYS___AE_THREAD_SETMODE             = 0x791
-	SYS___AE_THREAD_SWAPMODE            = 0x792
-	SYS___GETNETBYADDR_A                = 0x793
-	SYS___GETNETBYNAME_A                = 0x794
-	SYS___GETNETENT_A                   = 0x795
-	SYS___GETPROTOBYNAME_A              = 0x796
-	SYS___GETPROTOBYNUMBER_A            = 0x797
-	SYS___GETPROTOENT_A                 = 0x798
-	SYS___GETSERVBYNAME_A               = 0x799
-	SYS_ACL_FIRST_ENTRY                 = 0x800
-	SYS_ACL_GET_ENTRY                   = 0x801
-	SYS_ACL_VALID                       = 0x802
-	SYS_ACL_CREATE_ENTRY                = 0x803
-	SYS_ACL_DELETE_ENTRY                = 0x804
-	SYS_ACL_UPDATE_ENTRY                = 0x805
-	SYS_ACL_DELETE_FD                   = 0x806
-	SYS_ACL_DELETE_FILE                 = 0x807
-	SYS_ACL_GET_FD                      = 0x808
-	SYS_ACL_GET_FILE                    = 0x809
-	SYS___ERFL_B                        = 0x810
-	SYS___ERFCL_B                       = 0x811
-	SYS___LGAMMAL_B                     = 0x812
-	SYS___SETHOOKEVENTS                 = 0x813
-	SYS_IF_NAMETOINDEX                  = 0x814
-	SYS_IF_INDEXTONAME                  = 0x815
-	SYS_IF_NAMEINDEX                    = 0x816
-	SYS_IF_FREENAMEINDEX                = 0x817
-	SYS_GETADDRINFO                     = 0x818
-	SYS_GETNAMEINFO                     = 0x819
-	SYS___DYNFREE_A                     = 0x820
-	SYS___RES_QUERY_A                   = 0x821
-	SYS___RES_SEARCH_A                  = 0x822
-	SYS___RES_QUERYDOMAIN_A             = 0x823
-	SYS___RES_MKQUERY_A                 = 0x824
-	SYS___RES_SEND_A                    = 0x825
-	SYS___DN_EXPAND_A                   = 0x826
-	SYS___DN_SKIPNAME_A                 = 0x827
-	SYS___DN_COMP_A                     = 0x828
-	SYS___DN_FIND_A                     = 0x829
-	SYS___INET_NTOA_A                   = 0x830
-	SYS___INET_NETWORK_A                = 0x831
-	SYS___ACCEPT_A                      = 0x832
-	SYS___ACCEPT_AND_RECV_A             = 0x833
-	SYS___BIND_A                        = 0x834
-	SYS___CONNECT_A                     = 0x835
-	SYS___GETPEERNAME_A                 = 0x836
-	SYS___GETSOCKNAME_A                 = 0x837
-	SYS___RECVFROM_A                    = 0x838
-	SYS___SENDTO_A                      = 0x839
-	SYS___LCHATTR                       = 0x840
-	SYS___WRITEDOWN                     = 0x841
-	SYS_PTHREAD_MUTEX_INIT2             = 0x842
-	SYS___ACOSHF_B                      = 0x843
-	SYS___ACOSHL_B                      = 0x844
-	SYS___ASINHF_B                      = 0x845
-	SYS___ASINHL_B                      = 0x846
-	SYS___ATANHF_B                      = 0x847
-	SYS___ATANHL_B                      = 0x848
-	SYS___CBRTF_B                       = 0x849
-	SYS___EXP2F_B                       = 0x850
-	SYS___EXP2L_B                       = 0x851
-	SYS___EXPM1F_B                      = 0x852
-	SYS___EXPM1L_B                      = 0x853
-	SYS___FDIMF_B                       = 0x854
-	SYS___FDIM_B                        = 0x855
-	SYS___FDIML_B                       = 0x856
-	SYS___HYPOTF_B                      = 0x857
-	SYS___HYPOTL_B                      = 0x858
-	SYS___LOG1PF_B                      = 0x859
-	SYS___REMQUOF_B                     = 0x860
-	SYS___REMQUO_B                      = 0x861
-	SYS___REMQUOL_B                     = 0x862
-	SYS___TGAMMAF_B                     = 0x863
-	SYS___TGAMMA_B                      = 0x864
-	SYS___TGAMMAL_B                     = 0x865
-	SYS___TRUNCF_B                      = 0x866
-	SYS___TRUNC_B                       = 0x867
-	SYS___TRUNCL_B                      = 0x868
-	SYS___LGAMMAF_B                     = 0x869
-	SYS_ASINHF                          = 0x870
-	SYS_ASINHL                          = 0x871
-	SYS_ATANHF                          = 0x872
-	SYS_ATANHL                          = 0x873
-	SYS_CBRTF                           = 0x874
-	SYS_CBRTL                           = 0x875
-	SYS_COPYSIGNF                       = 0x876
-	SYS_CPYSIGNF                        = 0x876
-	SYS_COPYSIGNL                       = 0x877
-	SYS_CPYSIGNL                        = 0x877
-	SYS_COTANF                          = 0x878
-	SYS___COTANF                        = 0x878
-	SYS_COTAN                           = 0x879
-	SYS___COTAN                         = 0x879
-	SYS_FDIM                            = 0x881
-	SYS_FDIML                           = 0x882
-	SYS_HYPOTF                          = 0x883
-	SYS_HYPOTL                          = 0x884
-	SYS_LOG1PF                          = 0x885
-	SYS_LOG1PL                          = 0x886
-	SYS_LOG2F                           = 0x887
-	SYS_LOG2                            = 0x888
-	SYS_LOG2L                           = 0x889
-	SYS_TGAMMA                          = 0x890
-	SYS_TGAMMAL                         = 0x891
-	SYS_TRUNCF                          = 0x892
-	SYS_TRUNC                           = 0x893
-	SYS_TRUNCL                          = 0x894
-	SYS_LGAMMAF                         = 0x895
-	SYS_LGAMMAL                         = 0x896
-	SYS_LROUNDF                         = 0x897
-	SYS_LROUND                          = 0x898
-	SYS_ERFF                            = 0x899
-	SYS___COSHF_H                       = 0x900
-	SYS___COSHL_H                       = 0x901
-	SYS___COTAN_H                       = 0x902
-	SYS___COTANF_H                      = 0x903
-	SYS___COTANL_H                      = 0x904
-	SYS___ERF_H                         = 0x905
-	SYS___ERFF_H                        = 0x906
-	SYS___ERFL_H                        = 0x907
-	SYS___ERFC_H                        = 0x908
-	SYS___ERFCF_H                       = 0x909
-	SYS___FDIMF_H                       = 0x910
-	SYS___FDIML_H                       = 0x911
-	SYS___FMOD_H                        = 0x912
-	SYS___FMODF_H                       = 0x913
-	SYS___FMODL_H                       = 0x914
-	SYS___GAMMA_H                       = 0x915
-	SYS___HYPOT_H                       = 0x916
-	SYS___ILOGB_H                       = 0x917
-	SYS___LGAMMA_H                      = 0x918
-	SYS___LGAMMAF_H                     = 0x919
-	SYS___LOG2L_H                       = 0x920
-	SYS___LOG1P_H                       = 0x921
-	SYS___LOG10_H                       = 0x922
-	SYS___LOG10F_H                      = 0x923
-	SYS___LOG10L_H                      = 0x924
-	SYS___LROUND_H                      = 0x925
-	SYS___LROUNDF_H                     = 0x926
-	SYS___NEXTAFTER_H                   = 0x927
-	SYS___POW_H                         = 0x928
-	SYS___POWF_H                        = 0x929
-	SYS___SINL_H                        = 0x930
-	SYS___SINH_H                        = 0x931
-	SYS___SINHF_H                       = 0x932
-	SYS___SINHL_H                       = 0x933
-	SYS___SQRT_H                        = 0x934
-	SYS___SQRTF_H                       = 0x935
-	SYS___SQRTL_H                       = 0x936
-	SYS___TAN_H                         = 0x937
-	SYS___TANF_H                        = 0x938
-	SYS___TANL_H                        = 0x939
-	SYS___TRUNCF_H                      = 0x940
-	SYS___TRUNCL_H                      = 0x941
-	SYS___COSH_H                        = 0x942
-	SYS___LE_DEBUG_SET_RESUME_MCH       = 0x943
-	SYS_VFSCANF                         = 0x944
-	SYS_VSCANF                          = 0x946
-	SYS_VSSCANF                         = 0x948
-	SYS_IMAXABS                         = 0x950
-	SYS_IMAXDIV                         = 0x951
-	SYS_STRTOIMAX                       = 0x952
-	SYS_STRTOUMAX                       = 0x953
-	SYS_WCSTOIMAX                       = 0x954
-	SYS_WCSTOUMAX                       = 0x955
-	SYS_ATOLL                           = 0x956
-	SYS_STRTOF                          = 0x957
-	SYS_STRTOLD                         = 0x958
-	SYS_WCSTOF                          = 0x959
-	SYS_INET6_RTH_GETADDR               = 0x960
-	SYS_INET6_OPT_INIT                  = 0x961
-	SYS_INET6_OPT_APPEND                = 0x962
-	SYS_INET6_OPT_FINISH                = 0x963
-	SYS_INET6_OPT_SET_VAL               = 0x964
-	SYS_INET6_OPT_NEXT                  = 0x965
-	SYS_INET6_OPT_FIND                  = 0x966
-	SYS_INET6_OPT_GET_VAL               = 0x967
-	SYS___POW_I                         = 0x987
-	SYS___POW_I_B                       = 0x988
-	SYS___POW_I_H                       = 0x989
-	SYS___CABS_H                        = 0x990
-	SYS_CABSF                           = 0x991
-	SYS___CABSF_B                       = 0x992
-	SYS___CABSF_H                       = 0x993
-	SYS_CABSL                           = 0x994
-	SYS___CABSL_B                       = 0x995
-	SYS___CABSL_H                       = 0x996
-	SYS_CACOS                           = 0x997
-	SYS___CACOS_B                       = 0x998
-	SYS___CACOS_H                       = 0x999
+	SYS_LOG                             = 0x17  // 23
+	SYS_COSH                            = 0x18  // 24
+	SYS_TANH                            = 0x19  // 25
+	SYS_EXP                             = 0x1A  // 26
+	SYS_MODF                            = 0x1B  // 27
+	SYS_LOG10                           = 0x1C  // 28
+	SYS_FREXP                           = 0x1D  // 29
+	SYS_LDEXP                           = 0x1E  // 30
+	SYS_CEIL                            = 0x1F  // 31
+	SYS_POW                             = 0x20  // 32
+	SYS_SQRT                            = 0x21  // 33
+	SYS_FLOOR                           = 0x22  // 34
+	SYS_J1                              = 0x23  // 35
+	SYS_FABS                            = 0x24  // 36
+	SYS_FMOD                            = 0x25  // 37
+	SYS_J0                              = 0x26  // 38
+	SYS_YN                              = 0x27  // 39
+	SYS_JN                              = 0x28  // 40
+	SYS_Y0                              = 0x29  // 41
+	SYS_Y1                              = 0x2A  // 42
+	SYS_HYPOT                           = 0x2B  // 43
+	SYS_ERF                             = 0x2C  // 44
+	SYS_ERFC                            = 0x2D  // 45
+	SYS_GAMMA                           = 0x2E  // 46
+	SYS_ISALPHA                         = 0x30  // 48
+	SYS_ISALNUM                         = 0x31  // 49
+	SYS_ISLOWER                         = 0x32  // 50
+	SYS_ISCNTRL                         = 0x33  // 51
+	SYS_ISDIGIT                         = 0x34  // 52
+	SYS_ISGRAPH                         = 0x35  // 53
+	SYS_ISUPPER                         = 0x36  // 54
+	SYS_ISPRINT                         = 0x37  // 55
+	SYS_ISPUNCT                         = 0x38  // 56
+	SYS_ISSPACE                         = 0x39  // 57
+	SYS_SETLOCAL                        = 0x3A  // 58
+	SYS_SETLOCALE                       = 0x3A  // 58
+	SYS_ISXDIGIT                        = 0x3B  // 59
+	SYS_TOLOWER                         = 0x3C  // 60
+	SYS_TOUPPER                         = 0x3D  // 61
+	SYS_ASIN                            = 0x3E  // 62
+	SYS_SIN                             = 0x3F  // 63
+	SYS_COS                             = 0x40  // 64
+	SYS_TAN                             = 0x41  // 65
+	SYS_SINH                            = 0x42  // 66
+	SYS_ACOS                            = 0x43  // 67
+	SYS_ATAN                            = 0x44  // 68
+	SYS_ATAN2                           = 0x45  // 69
+	SYS_FTELL                           = 0x46  // 70
+	SYS_FGETPOS                         = 0x47  // 71
+	SYS_FSEEK                           = 0x48  // 72
+	SYS_FSETPOS                         = 0x49  // 73
+	SYS_FERROR                          = 0x4A  // 74
+	SYS_REWIND                          = 0x4B  // 75
+	SYS_CLEARERR                        = 0x4C  // 76
+	SYS_FEOF                            = 0x4D  // 77
+	SYS_ATOL                            = 0x4E  // 78
+	SYS_PERROR                          = 0x4F  // 79
+	SYS_ATOF                            = 0x50  // 80
+	SYS_ATOI                            = 0x51  // 81
+	SYS_RAND                            = 0x52  // 82
+	SYS_STRTOD                          = 0x53  // 83
+	SYS_STRTOL                          = 0x54  // 84
+	SYS_STRTOUL                         = 0x55  // 85
+	SYS_MALLOC                          = 0x56  // 86
+	SYS_SRAND                           = 0x57  // 87
+	SYS_CALLOC                          = 0x58  // 88
+	SYS_FREE                            = 0x59  // 89
+	SYS_EXIT                            = 0x5A  // 90
+	SYS_REALLOC                         = 0x5B  // 91
+	SYS_ABORT                           = 0x5C  // 92
+	SYS___ABORT                         = 0x5C  // 92
+	SYS_ATEXIT                          = 0x5D  // 93
+	SYS_RAISE                           = 0x5E  // 94
+	SYS_SETJMP                          = 0x5F  // 95
+	SYS_LONGJMP                         = 0x60  // 96
+	SYS_SIGNAL                          = 0x61  // 97
+	SYS_TMPNAM                          = 0x62  // 98
+	SYS_REMOVE                          = 0x63  // 99
+	SYS_RENAME                          = 0x64  // 100
+	SYS_TMPFILE                         = 0x65  // 101
+	SYS_FREOPEN                         = 0x66  // 102
+	SYS_FCLOSE                          = 0x67  // 103
+	SYS_FFLUSH                          = 0x68  // 104
+	SYS_FOPEN                           = 0x69  // 105
+	SYS_FSCANF                          = 0x6A  // 106
+	SYS_SETBUF                          = 0x6B  // 107
+	SYS_SETVBUF                         = 0x6C  // 108
+	SYS_FPRINTF                         = 0x6D  // 109
+	SYS_SSCANF                          = 0x6E  // 110
+	SYS_PRINTF                          = 0x6F  // 111
+	SYS_SCANF                           = 0x70  // 112
+	SYS_SPRINTF                         = 0x71  // 113
+	SYS_FGETC                           = 0x72  // 114
+	SYS_VFPRINTF                        = 0x73  // 115
+	SYS_VPRINTF                         = 0x74  // 116
+	SYS_VSPRINTF                        = 0x75  // 117
+	SYS_GETC                            = 0x76  // 118
+	SYS_FGETS                           = 0x77  // 119
+	SYS_FPUTC                           = 0x78  // 120
+	SYS_FPUTS                           = 0x79  // 121
+	SYS_PUTCHAR                         = 0x7A  // 122
+	SYS_GETCHAR                         = 0x7B  // 123
+	SYS_GETS                            = 0x7C  // 124
+	SYS_PUTC                            = 0x7D  // 125
+	SYS_FWRITE                          = 0x7E  // 126
+	SYS_PUTS                            = 0x7F  // 127
+	SYS_UNGETC                          = 0x80  // 128
+	SYS_FREAD                           = 0x81  // 129
+	SYS_WCSTOMBS                        = 0x82  // 130
+	SYS_MBTOWC                          = 0x83  // 131
+	SYS_WCTOMB                          = 0x84  // 132
+	SYS_MBSTOWCS                        = 0x85  // 133
+	SYS_WCSCPY                          = 0x86  // 134
+	SYS_WCSCAT                          = 0x87  // 135
+	SYS_WCSCHR                          = 0x88  // 136
+	SYS_WCSCMP                          = 0x89  // 137
+	SYS_WCSNCMP                         = 0x8A  // 138
+	SYS_WCSCSPN                         = 0x8B  // 139
+	SYS_WCSLEN                          = 0x8C  // 140
+	SYS_WCSNCAT                         = 0x8D  // 141
+	SYS_WCSSPN                          = 0x8E  // 142
+	SYS_WCSNCPY                         = 0x8F  // 143
+	SYS_ABS                             = 0x90  // 144
+	SYS_DIV                             = 0x91  // 145
+	SYS_LABS                            = 0x92  // 146
+	SYS_STRNCPY                         = 0x93  // 147
+	SYS_MEMCPY                          = 0x94  // 148
+	SYS_MEMMOVE                         = 0x95  // 149
+	SYS_STRCPY                          = 0x96  // 150
+	SYS_STRCMP                          = 0x97  // 151
+	SYS_STRCAT                          = 0x98  // 152
+	SYS_STRNCAT                         = 0x99  // 153
+	SYS_MEMCMP                          = 0x9A  // 154
+	SYS_MEMCHR                          = 0x9B  // 155
+	SYS_STRCOLL                         = 0x9C  // 156
+	SYS_STRNCMP                         = 0x9D  // 157
+	SYS_STRXFRM                         = 0x9E  // 158
+	SYS_STRRCHR                         = 0x9F  // 159
+	SYS_STRCHR                          = 0xA0  // 160
+	SYS_STRCSPN                         = 0xA1  // 161
+	SYS_STRPBRK                         = 0xA2  // 162
+	SYS_MEMSET                          = 0xA3  // 163
+	SYS_STRSPN                          = 0xA4  // 164
+	SYS_STRSTR                          = 0xA5  // 165
+	SYS_STRTOK                          = 0xA6  // 166
+	SYS_DIFFTIME                        = 0xA7  // 167
+	SYS_STRERROR                        = 0xA8  // 168
+	SYS_STRLEN                          = 0xA9  // 169
+	SYS_CLOCK                           = 0xAA  // 170
+	SYS_CTIME                           = 0xAB  // 171
+	SYS_MKTIME                          = 0xAC  // 172
+	SYS_TIME                            = 0xAD  // 173
+	SYS_ASCTIME                         = 0xAE  // 174
+	SYS_MBLEN                           = 0xAF  // 175
+	SYS_GMTIME                          = 0xB0  // 176
+	SYS_LOCALTIM                        = 0xB1  // 177
+	SYS_LOCALTIME                       = 0xB1  // 177
+	SYS_STRFTIME                        = 0xB2  // 178
+	SYS___GETCB                         = 0xB4  // 180
+	SYS_FUPDATE                         = 0xB5  // 181
+	SYS___FUPDT                         = 0xB5  // 181
+	SYS_CLRMEMF                         = 0xBD  // 189
+	SYS___CLRMF                         = 0xBD  // 189
+	SYS_FETCHEP                         = 0xBF  // 191
+	SYS___FTCHEP                        = 0xBF  // 191
+	SYS_FLDATA                          = 0xC1  // 193
+	SYS___FLDATA                        = 0xC1  // 193
+	SYS_DYNFREE                         = 0xC2  // 194
+	SYS___DYNFRE                        = 0xC2  // 194
+	SYS_DYNALLOC                        = 0xC3  // 195
+	SYS___DYNALL                        = 0xC3  // 195
+	SYS___CDUMP                         = 0xC4  // 196
+	SYS_CSNAP                           = 0xC5  // 197
+	SYS___CSNAP                         = 0xC5  // 197
+	SYS_CTRACE                          = 0xC6  // 198
+	SYS___CTRACE                        = 0xC6  // 198
+	SYS___CTEST                         = 0xC7  // 199
+	SYS_SETENV                          = 0xC8  // 200
+	SYS___SETENV                        = 0xC8  // 200
+	SYS_CLEARENV                        = 0xC9  // 201
+	SYS___CLRENV                        = 0xC9  // 201
+	SYS___REGCOMP_STD                   = 0xEA  // 234
+	SYS_NL_LANGINFO                     = 0xFC  // 252
+	SYS_GETSYNTX                        = 0xFD  // 253
+	SYS_ISBLANK                         = 0xFE  // 254
+	SYS___ISBLNK                        = 0xFE  // 254
+	SYS_ISWALNUM                        = 0xFF  // 255
+	SYS_ISWALPHA                        = 0x100 // 256
+	SYS_ISWBLANK                        = 0x101 // 257
+	SYS___ISWBLK                        = 0x101 // 257
+	SYS_ISWCNTRL                        = 0x102 // 258
+	SYS_ISWDIGIT                        = 0x103 // 259
+	SYS_ISWGRAPH                        = 0x104 // 260
+	SYS_ISWLOWER                        = 0x105 // 261
+	SYS_ISWPRINT                        = 0x106 // 262
+	SYS_ISWPUNCT                        = 0x107 // 263
+	SYS_ISWSPACE                        = 0x108 // 264
+	SYS_ISWUPPER                        = 0x109 // 265
+	SYS_ISWXDIGI                        = 0x10A // 266
+	SYS_ISWXDIGIT                       = 0x10A // 266
+	SYS_WCTYPE                          = 0x10B // 267
+	SYS_ISWCTYPE                        = 0x10C // 268
+	SYS_TOWLOWER                        = 0x10D // 269
+	SYS_TOWUPPER                        = 0x10E // 270
+	SYS_MBSINIT                         = 0x10F // 271
+	SYS_WCTOB                           = 0x110 // 272
+	SYS_MBRLEN                          = 0x111 // 273
+	SYS_MBRTOWC                         = 0x112 // 274
+	SYS_MBSRTOWC                        = 0x113 // 275
+	SYS_MBSRTOWCS                       = 0x113 // 275
+	SYS_WCRTOMB                         = 0x114 // 276
+	SYS_WCSRTOMB                        = 0x115 // 277
+	SYS_WCSRTOMBS                       = 0x115 // 277
+	SYS___CSID                          = 0x116 // 278
+	SYS___WCSID                         = 0x117 // 279
+	SYS_STRPTIME                        = 0x118 // 280
+	SYS___STRPTM                        = 0x118 // 280
+	SYS_STRFMON                         = 0x119 // 281
+	SYS___RPMTCH                        = 0x11A // 282
+	SYS_WCSSTR                          = 0x11B // 283
+	SYS_WCSTOK                          = 0x12C // 300
+	SYS_WCSTOL                          = 0x12D // 301
+	SYS_WCSTOD                          = 0x12E // 302
+	SYS_WCSTOUL                         = 0x12F // 303
+	SYS_WCSCOLL                         = 0x130 // 304
+	SYS_WCSXFRM                         = 0x131 // 305
+	SYS_WCSWIDTH                        = 0x132 // 306
+	SYS_WCWIDTH                         = 0x133 // 307
+	SYS_WCSFTIME                        = 0x134 // 308
+	SYS_SWPRINTF                        = 0x135 // 309
+	SYS_VSWPRINT                        = 0x136 // 310
+	SYS_VSWPRINTF                       = 0x136 // 310
+	SYS_SWSCANF                         = 0x137 // 311
+	SYS_REGCOMP                         = 0x138 // 312
+	SYS_REGEXEC                         = 0x139 // 313
+	SYS_REGFREE                         = 0x13A // 314
+	SYS_REGERROR                        = 0x13B // 315
+	SYS_FGETWC                          = 0x13C // 316
+	SYS_FGETWS                          = 0x13D // 317
+	SYS_FPUTWC                          = 0x13E // 318
+	SYS_FPUTWS                          = 0x13F // 319
+	SYS_GETWC                           = 0x140 // 320
+	SYS_GETWCHAR                        = 0x141 // 321
+	SYS_PUTWC                           = 0x142 // 322
+	SYS_PUTWCHAR                        = 0x143 // 323
+	SYS_UNGETWC                         = 0x144 // 324
+	SYS_ICONV_OPEN                      = 0x145 // 325
+	SYS_ICONV                           = 0x146 // 326
+	SYS_ICONV_CLOSE                     = 0x147 // 327
+	SYS_ISMCCOLLEL                      = 0x14C // 332
+	SYS_STRTOCOLL                       = 0x14D // 333
+	SYS_COLLTOSTR                       = 0x14E // 334
+	SYS_COLLEQUIV                       = 0x14F // 335
+	SYS_COLLRANGE                       = 0x150 // 336
+	SYS_CCLASS                          = 0x151 // 337
+	SYS_COLLORDER                       = 0x152 // 338
+	SYS___DEMANGLE                      = 0x154 // 340
+	SYS_FDOPEN                          = 0x155 // 341
+	SYS___ERRNO                         = 0x156 // 342
+	SYS___ERRNO2                        = 0x157 // 343
+	SYS___TERROR                        = 0x158 // 344
+	SYS_MAXCOLL                         = 0x169 // 361
+	SYS_GETMCCOLL                       = 0x16A // 362
+	SYS_GETWMCCOLL                      = 0x16B // 363
+	SYS___ERR2AD                        = 0x16C // 364
+	SYS_DLLQUERYFN                      = 0x16D // 365
+	SYS_DLLQUERYVAR                     = 0x16E // 366
+	SYS_DLLFREE                         = 0x16F // 367
+	SYS_DLLLOAD                         = 0x170 // 368
+	SYS__EXIT                           = 0x174 // 372
+	SYS_ACCESS                          = 0x175 // 373
+	SYS_ALARM                           = 0x176 // 374
+	SYS_CFGETISPEED                     = 0x177 // 375
+	SYS_CFGETOSPEED                     = 0x178 // 376
+	SYS_CFSETISPEED                     = 0x179 // 377
+	SYS_CFSETOSPEED                     = 0x17A // 378
+	SYS_CHDIR                           = 0x17B // 379
+	SYS_CHMOD                           = 0x17C // 380
+	SYS_CHOWN                           = 0x17D // 381
+	SYS_CLOSE                           = 0x17E // 382
+	SYS_CLOSEDIR                        = 0x17F // 383
+	SYS_CREAT                           = 0x180 // 384
+	SYS_CTERMID                         = 0x181 // 385
+	SYS_DUP                             = 0x182 // 386
+	SYS_DUP2                            = 0x183 // 387
+	SYS_EXECL                           = 0x184 // 388
+	SYS_EXECLE                          = 0x185 // 389
+	SYS_EXECLP                          = 0x186 // 390
+	SYS_EXECV                           = 0x187 // 391
+	SYS_EXECVE                          = 0x188 // 392
+	SYS_EXECVP                          = 0x189 // 393
+	SYS_FCHMOD                          = 0x18A // 394
+	SYS_FCHOWN                          = 0x18B // 395
+	SYS_FCNTL                           = 0x18C // 396
+	SYS_FILENO                          = 0x18D // 397
+	SYS_FORK                            = 0x18E // 398
+	SYS_FPATHCONF                       = 0x18F // 399
+	SYS_FSTAT                           = 0x190 // 400
+	SYS_FSYNC                           = 0x191 // 401
+	SYS_FTRUNCATE                       = 0x192 // 402
+	SYS_GETCWD                          = 0x193 // 403
+	SYS_GETEGID                         = 0x194 // 404
+	SYS_GETEUID                         = 0x195 // 405
+	SYS_GETGID                          = 0x196 // 406
+	SYS_GETGRGID                        = 0x197 // 407
+	SYS_GETGRNAM                        = 0x198 // 408
+	SYS_GETGROUPS                       = 0x199 // 409
+	SYS_GETLOGIN                        = 0x19A // 410
+	SYS_W_GETMNTENT                     = 0x19B // 411
+	SYS_GETPGRP                         = 0x19C // 412
+	SYS_GETPID                          = 0x19D // 413
+	SYS_GETPPID                         = 0x19E // 414
+	SYS_GETPWNAM                        = 0x19F // 415
+	SYS_GETPWUID                        = 0x1A0 // 416
+	SYS_GETUID                          = 0x1A1 // 417
+	SYS_W_IOCTL                         = 0x1A2 // 418
+	SYS_ISATTY                          = 0x1A3 // 419
+	SYS_KILL                            = 0x1A4 // 420
+	SYS_LINK                            = 0x1A5 // 421
+	SYS_LSEEK                           = 0x1A6 // 422
+	SYS_LSTAT                           = 0x1A7 // 423
+	SYS_MKDIR                           = 0x1A8 // 424
+	SYS_MKFIFO                          = 0x1A9 // 425
+	SYS_MKNOD                           = 0x1AA // 426
+	SYS_MOUNT                           = 0x1AB // 427
+	SYS_OPEN                            = 0x1AC // 428
+	SYS_OPENDIR                         = 0x1AD // 429
+	SYS_PATHCONF                        = 0x1AE // 430
+	SYS_PAUSE                           = 0x1AF // 431
+	SYS_PIPE                            = 0x1B0 // 432
+	SYS_W_GETPSENT                      = 0x1B1 // 433
+	SYS_READ                            = 0x1B2 // 434
+	SYS_READDIR                         = 0x1B3 // 435
+	SYS_READLINK                        = 0x1B4 // 436
+	SYS_REWINDDIR                       = 0x1B5 // 437
+	SYS_RMDIR                           = 0x1B6 // 438
+	SYS_SETEGID                         = 0x1B7 // 439
+	SYS_SETEUID                         = 0x1B8 // 440
+	SYS_SETGID                          = 0x1B9 // 441
+	SYS_SETPGID                         = 0x1BA // 442
+	SYS_SETSID                          = 0x1BB // 443
+	SYS_SETUID                          = 0x1BC // 444
+	SYS_SIGACTION                       = 0x1BD // 445
+	SYS_SIGADDSET                       = 0x1BE // 446
+	SYS_SIGDELSET                       = 0x1BF // 447
+	SYS_SIGEMPTYSET                     = 0x1C0 // 448
+	SYS_SIGFILLSET                      = 0x1C1 // 449
+	SYS_SIGISMEMBER                     = 0x1C2 // 450
+	SYS_SIGLONGJMP                      = 0x1C3 // 451
+	SYS_SIGPENDING                      = 0x1C4 // 452
+	SYS_SIGPROCMASK                     = 0x1C5 // 453
+	SYS_SIGSETJMP                       = 0x1C6 // 454
+	SYS_SIGSUSPEND                      = 0x1C7 // 455
+	SYS_SLEEP                           = 0x1C8 // 456
+	SYS_STAT                            = 0x1C9 // 457
+	SYS_W_STATFS                        = 0x1CA // 458
+	SYS_SYMLINK                         = 0x1CB // 459
+	SYS_SYSCONF                         = 0x1CC // 460
+	SYS_TCDRAIN                         = 0x1CD // 461
+	SYS_TCFLOW                          = 0x1CE // 462
+	SYS_TCFLUSH                         = 0x1CF // 463
+	SYS_TCGETATTR                       = 0x1D0 // 464
+	SYS_TCGETPGRP                       = 0x1D1 // 465
+	SYS_TCSENDBREAK                     = 0x1D2 // 466
+	SYS_TCSETATTR                       = 0x1D3 // 467
+	SYS_TCSETPGRP                       = 0x1D4 // 468
+	SYS_TIMES                           = 0x1D5 // 469
+	SYS_TTYNAME                         = 0x1D6 // 470
+	SYS_TZSET                           = 0x1D7 // 471
+	SYS_UMASK                           = 0x1D8 // 472
+	SYS_UMOUNT                          = 0x1D9 // 473
+	SYS_UNAME                           = 0x1DA // 474
+	SYS_UNLINK                          = 0x1DB // 475
+	SYS_UTIME                           = 0x1DC // 476
+	SYS_WAIT                            = 0x1DD // 477
+	SYS_WAITPID                         = 0x1DE // 478
+	SYS_WRITE                           = 0x1DF // 479
+	SYS_CHAUDIT                         = 0x1E0 // 480
+	SYS_FCHAUDIT                        = 0x1E1 // 481
+	SYS_GETGROUPSBYNAME                 = 0x1E2 // 482
+	SYS_SIGWAIT                         = 0x1E3 // 483
+	SYS_PTHREAD_EXIT                    = 0x1E4 // 484
+	SYS_PTHREAD_KILL                    = 0x1E5 // 485
+	SYS_PTHREAD_ATTR_INIT               = 0x1E6 // 486
+	SYS_PTHREAD_ATTR_DESTROY            = 0x1E7 // 487
+	SYS_PTHREAD_ATTR_SETSTACKSIZE       = 0x1E8 // 488
+	SYS_PTHREAD_ATTR_GETSTACKSIZE       = 0x1E9 // 489
+	SYS_PTHREAD_ATTR_SETDETACHSTATE     = 0x1EA // 490
+	SYS_PTHREAD_ATTR_GETDETACHSTATE     = 0x1EB // 491
+	SYS_PTHREAD_ATTR_SETWEIGHT_NP       = 0x1EC // 492
+	SYS_PTHREAD_ATTR_GETWEIGHT_NP       = 0x1ED // 493
+	SYS_PTHREAD_CANCEL                  = 0x1EE // 494
+	SYS_PTHREAD_CLEANUP_PUSH            = 0x1EF // 495
+	SYS_PTHREAD_CLEANUP_POP             = 0x1F0 // 496
+	SYS_PTHREAD_CONDATTR_INIT           = 0x1F1 // 497
+	SYS_PTHREAD_CONDATTR_DESTROY        = 0x1F2 // 498
+	SYS_PTHREAD_COND_INIT               = 0x1F3 // 499
+	SYS_PTHREAD_COND_DESTROY            = 0x1F4 // 500
+	SYS_PTHREAD_COND_SIGNAL             = 0x1F5 // 501
+	SYS_PTHREAD_COND_BROADCAST          = 0x1F6 // 502
+	SYS_PTHREAD_COND_WAIT               = 0x1F7 // 503
+	SYS_PTHREAD_COND_TIMEDWAIT          = 0x1F8 // 504
+	SYS_PTHREAD_CREATE                  = 0x1F9 // 505
+	SYS_PTHREAD_DETACH                  = 0x1FA // 506
+	SYS_PTHREAD_EQUAL                   = 0x1FB // 507
+	SYS_PTHREAD_GETSPECIFIC             = 0x1FC // 508
+	SYS_PTHREAD_JOIN                    = 0x1FD // 509
+	SYS_PTHREAD_KEY_CREATE              = 0x1FE // 510
+	SYS_PTHREAD_MUTEXATTR_INIT          = 0x1FF // 511
+	SYS_PTHREAD_MUTEXATTR_DESTROY       = 0x200 // 512
+	SYS_PTHREAD_MUTEXATTR_SETKIND_NP    = 0x201 // 513
+	SYS_PTHREAD_MUTEXATTR_GETKIND_NP    = 0x202 // 514
+	SYS_PTHREAD_MUTEX_INIT              = 0x203 // 515
+	SYS_PTHREAD_MUTEX_DESTROY           = 0x204 // 516
+	SYS_PTHREAD_MUTEX_LOCK              = 0x205 // 517
+	SYS_PTHREAD_MUTEX_TRYLOCK           = 0x206 // 518
+	SYS_PTHREAD_MUTEX_UNLOCK            = 0x207 // 519
+	SYS_PTHREAD_ONCE                    = 0x209 // 521
+	SYS_PTHREAD_SELF                    = 0x20A // 522
+	SYS_PTHREAD_SETINTR                 = 0x20B // 523
+	SYS_PTHREAD_SETINTRTYPE             = 0x20C // 524
+	SYS_PTHREAD_SETSPECIFIC             = 0x20D // 525
+	SYS_PTHREAD_TESTINTR                = 0x20E // 526
+	SYS_PTHREAD_YIELD                   = 0x20F // 527
+	SYS_TW_OPEN                         = 0x210 // 528
+	SYS_TW_FCNTL                        = 0x211 // 529
+	SYS_PTHREAD_JOIN_D4_NP              = 0x212 // 530
+	SYS_PTHREAD_CONDATTR_SETKIND_NP     = 0x213 // 531
+	SYS_PTHREAD_CONDATTR_GETKIND_NP     = 0x214 // 532
+	SYS_EXTLINK_NP                      = 0x215 // 533
+	SYS___PASSWD                        = 0x216 // 534
+	SYS_SETGROUPS                       = 0x217 // 535
+	SYS_INITGROUPS                      = 0x218 // 536
+	SYS_WCSPBRK                         = 0x23F // 575
+	SYS_WCSRCHR                         = 0x240 // 576
+	SYS_SVC99                           = 0x241 // 577
+	SYS___SVC99                         = 0x241 // 577
+	SYS_WCSWCS                          = 0x242 // 578
+	SYS_LOCALECO                        = 0x243 // 579
+	SYS_LOCALECONV                      = 0x243 // 579
+	SYS___LIBREL                        = 0x244 // 580
+	SYS_RELEASE                         = 0x245 // 581
+	SYS___RLSE                          = 0x245 // 581
+	SYS_FLOCATE                         = 0x246 // 582
+	SYS___FLOCT                         = 0x246 // 582
+	SYS_FDELREC                         = 0x247 // 583
+	SYS___FDLREC                        = 0x247 // 583
+	SYS_FETCH                           = 0x248 // 584
+	SYS___FETCH                         = 0x248 // 584
+	SYS_QSORT                           = 0x249 // 585
+	SYS_GETENV                          = 0x24A // 586
+	SYS_SYSTEM                          = 0x24B // 587
+	SYS_BSEARCH                         = 0x24C // 588
+	SYS_LDIV                            = 0x24D // 589
+	SYS___THROW                         = 0x25E // 606
+	SYS___RETHROW                       = 0x25F // 607
+	SYS___CLEANUPCATCH                  = 0x260 // 608
+	SYS___CATCHMATCH                    = 0x261 // 609
+	SYS___CLEAN2UPCATCH                 = 0x262 // 610
+	SYS_PUTENV                          = 0x26A // 618
+	SYS___GETENV                        = 0x26F // 623
+	SYS_GETPRIORITY                     = 0x270 // 624
+	SYS_NICE                            = 0x271 // 625
+	SYS_SETPRIORITY                     = 0x272 // 626
+	SYS_GETITIMER                       = 0x273 // 627
+	SYS_SETITIMER                       = 0x274 // 628
+	SYS_MSGCTL                          = 0x275 // 629
+	SYS_MSGGET                          = 0x276 // 630
+	SYS_MSGRCV                          = 0x277 // 631
+	SYS_MSGSND                          = 0x278 // 632
+	SYS_MSGXRCV                         = 0x279 // 633
+	SYS___MSGXR                         = 0x279 // 633
+	SYS_SEMCTL                          = 0x27A // 634
+	SYS_SEMGET                          = 0x27B // 635
+	SYS_SEMOP                           = 0x27C // 636
+	SYS_SHMAT                           = 0x27D // 637
+	SYS_SHMCTL                          = 0x27E // 638
+	SYS_SHMDT                           = 0x27F // 639
+	SYS_SHMGET                          = 0x280 // 640
+	SYS___GETIPC                        = 0x281 // 641
+	SYS_SETGRENT                        = 0x282 // 642
+	SYS_GETGRENT                        = 0x283 // 643
+	SYS_ENDGRENT                        = 0x284 // 644
+	SYS_SETPWENT                        = 0x285 // 645
+	SYS_GETPWENT                        = 0x286 // 646
+	SYS_ENDPWENT                        = 0x287 // 647
+	SYS_BSD_SIGNAL                      = 0x288 // 648
+	SYS_KILLPG                          = 0x289 // 649
+	SYS_SIGALTSTACK                     = 0x28A // 650
+	SYS_SIGHOLD                         = 0x28B // 651
+	SYS_SIGIGNORE                       = 0x28C // 652
+	SYS_SIGINTERRUPT                    = 0x28D // 653
+	SYS_SIGPAUSE                        = 0x28E // 654
+	SYS_SIGRELSE                        = 0x28F // 655
+	SYS_SIGSET                          = 0x290 // 656
+	SYS_SIGSTACK                        = 0x291 // 657
+	SYS_GETRLIMIT                       = 0x292 // 658
+	SYS_SETRLIMIT                       = 0x293 // 659
+	SYS_GETRUSAGE                       = 0x294 // 660
+	SYS_MMAP                            = 0x295 // 661
+	SYS_MPROTECT                        = 0x296 // 662
+	SYS_MSYNC                           = 0x297 // 663
+	SYS_MUNMAP                          = 0x298 // 664
+	SYS_CONFSTR                         = 0x299 // 665
+	SYS_GETOPT                          = 0x29A // 666
+	SYS_LCHOWN                          = 0x29B // 667
+	SYS_TRUNCATE                        = 0x29C // 668
+	SYS_GETSUBOPT                       = 0x29D // 669
+	SYS_SETPGRP                         = 0x29E // 670
+	SYS___GDERR                         = 0x29F // 671
+	SYS___TZONE                         = 0x2A0 // 672
+	SYS___DLGHT                         = 0x2A1 // 673
+	SYS___OPARGF                        = 0x2A2 // 674
+	SYS___OPOPTF                        = 0x2A3 // 675
+	SYS___OPINDF                        = 0x2A4 // 676
+	SYS___OPERRF                        = 0x2A5 // 677
+	SYS_GETDATE                         = 0x2A6 // 678
+	SYS_WAIT3                           = 0x2A7 // 679
+	SYS_WAITID                          = 0x2A8 // 680
+	SYS___CATTRM                        = 0x2A9 // 681
+	SYS___GDTRM                         = 0x2AA // 682
+	SYS___RNDTRM                        = 0x2AB // 683
+	SYS_CRYPT                           = 0x2AC // 684
+	SYS_ENCRYPT                         = 0x2AD // 685
+	SYS_SETKEY                          = 0x2AE // 686
+	SYS___CNVBLK                        = 0x2AF // 687
+	SYS___CRYTRM                        = 0x2B0 // 688
+	SYS___ECRTRM                        = 0x2B1 // 689
+	SYS_DRAND48                         = 0x2B2 // 690
+	SYS_ERAND48                         = 0x2B3 // 691
+	SYS_FSTATVFS                        = 0x2B4 // 692
+	SYS_STATVFS                         = 0x2B5 // 693
+	SYS_CATCLOSE                        = 0x2B6 // 694
+	SYS_CATGETS                         = 0x2B7 // 695
+	SYS_CATOPEN                         = 0x2B8 // 696
+	SYS_BCMP                            = 0x2B9 // 697
+	SYS_BCOPY                           = 0x2BA // 698
+	SYS_BZERO                           = 0x2BB // 699
+	SYS_FFS                             = 0x2BC // 700
+	SYS_INDEX                           = 0x2BD // 701
+	SYS_RINDEX                          = 0x2BE // 702
+	SYS_STRCASECMP                      = 0x2BF // 703
+	SYS_STRDUP                          = 0x2C0 // 704
+	SYS_STRNCASECMP                     = 0x2C1 // 705
+	SYS_INITSTATE                       = 0x2C2 // 706
+	SYS_SETSTATE                        = 0x2C3 // 707
+	SYS_RANDOM                          = 0x2C4 // 708
+	SYS_SRANDOM                         = 0x2C5 // 709
+	SYS_HCREATE                         = 0x2C6 // 710
+	SYS_HDESTROY                        = 0x2C7 // 711
+	SYS_HSEARCH                         = 0x2C8 // 712
+	SYS_LFIND                           = 0x2C9 // 713
+	SYS_LSEARCH                         = 0x2CA // 714
+	SYS_TDELETE                         = 0x2CB // 715
+	SYS_TFIND                           = 0x2CC // 716
+	SYS_TSEARCH                         = 0x2CD // 717
+	SYS_TWALK                           = 0x2CE // 718
+	SYS_INSQUE                          = 0x2CF // 719
+	SYS_REMQUE                          = 0x2D0 // 720
+	SYS_POPEN                           = 0x2D1 // 721
+	SYS_PCLOSE                          = 0x2D2 // 722
+	SYS_SWAB                            = 0x2D3 // 723
+	SYS_MEMCCPY                         = 0x2D4 // 724
+	SYS_GETPAGESIZE                     = 0x2D8 // 728
+	SYS_FCHDIR                          = 0x2D9 // 729
+	SYS___OCLCK                         = 0x2DA // 730
+	SYS___ATOE                          = 0x2DB // 731
+	SYS___ATOE_L                        = 0x2DC // 732
+	SYS___ETOA                          = 0x2DD // 733
+	SYS___ETOA_L                        = 0x2DE // 734
+	SYS_SETUTXENT                       = 0x2DF // 735
+	SYS_GETUTXENT                       = 0x2E0 // 736
+	SYS_ENDUTXENT                       = 0x2E1 // 737
+	SYS_GETUTXID                        = 0x2E2 // 738
+	SYS_GETUTXLINE                      = 0x2E3 // 739
+	SYS_PUTUTXLINE                      = 0x2E4 // 740
+	SYS_FMTMSG                          = 0x2E5 // 741
+	SYS_JRAND48                         = 0x2E6 // 742
+	SYS_LRAND48                         = 0x2E7 // 743
+	SYS_MRAND48                         = 0x2E8 // 744
+	SYS_NRAND48                         = 0x2E9 // 745
+	SYS_LCONG48                         = 0x2EA // 746
+	SYS_SRAND48                         = 0x2EB // 747
+	SYS_SEED48                          = 0x2EC // 748
+	SYS_ISASCII                         = 0x2ED // 749
+	SYS_TOASCII                         = 0x2EE // 750
+	SYS_A64L                            = 0x2EF // 751
+	SYS_L64A                            = 0x2F0 // 752
+	SYS_UALARM                          = 0x2F1 // 753
+	SYS_USLEEP                          = 0x2F2 // 754
+	SYS___UTXTRM                        = 0x2F3 // 755
+	SYS___SRCTRM                        = 0x2F4 // 756
+	SYS_FTIME                           = 0x2F5 // 757
+	SYS_GETTIMEOFDAY                    = 0x2F6 // 758
+	SYS_DBM_CLEARERR                    = 0x2F7 // 759
+	SYS_DBM_CLOSE                       = 0x2F8 // 760
+	SYS_DBM_DELETE                      = 0x2F9 // 761
+	SYS_DBM_ERROR                       = 0x2FA // 762
+	SYS_DBM_FETCH                       = 0x2FB // 763
+	SYS_DBM_FIRSTKEY                    = 0x2FC // 764
+	SYS_DBM_NEXTKEY                     = 0x2FD // 765
+	SYS_DBM_OPEN                        = 0x2FE // 766
+	SYS_DBM_STORE                       = 0x2FF // 767
+	SYS___NDMTRM                        = 0x300 // 768
+	SYS_FTOK                            = 0x301 // 769
+	SYS_BASENAME                        = 0x302 // 770
+	SYS_DIRNAME                         = 0x303 // 771
+	SYS_GETDTABLESIZE                   = 0x304 // 772
+	SYS_MKSTEMP                         = 0x305 // 773
+	SYS_MKTEMP                          = 0x306 // 774
+	SYS_NFTW                            = 0x307 // 775
+	SYS_GETWD                           = 0x308 // 776
+	SYS_LOCKF                           = 0x309 // 777
+	SYS__LONGJMP                        = 0x30D // 781
+	SYS__SETJMP                         = 0x30E // 782
+	SYS_VFORK                           = 0x30F // 783
+	SYS_WORDEXP                         = 0x310 // 784
+	SYS_WORDFREE                        = 0x311 // 785
+	SYS_GETPGID                         = 0x312 // 786
+	SYS_GETSID                          = 0x313 // 787
+	SYS___UTMPXNAME                     = 0x314 // 788
+	SYS_CUSERID                         = 0x315 // 789
+	SYS_GETPASS                         = 0x316 // 790
+	SYS_FNMATCH                         = 0x317 // 791
+	SYS_FTW                             = 0x318 // 792
+	SYS_GETW                            = 0x319 // 793
+	SYS_GLOB                            = 0x31A // 794
+	SYS_GLOBFREE                        = 0x31B // 795
+	SYS_PUTW                            = 0x31C // 796
+	SYS_SEEKDIR                         = 0x31D // 797
+	SYS_TELLDIR                         = 0x31E // 798
+	SYS_TEMPNAM                         = 0x31F // 799
+	SYS_ACOSH                           = 0x320 // 800
+	SYS_ASINH                           = 0x321 // 801
+	SYS_ATANH                           = 0x322 // 802
+	SYS_CBRT                            = 0x323 // 803
+	SYS_EXPM1                           = 0x324 // 804
+	SYS_ILOGB                           = 0x325 // 805
+	SYS_LOGB                            = 0x326 // 806
+	SYS_LOG1P                           = 0x327 // 807
+	SYS_NEXTAFTER                       = 0x328 // 808
+	SYS_RINT                            = 0x329 // 809
+	SYS_REMAINDER                       = 0x32A // 810
+	SYS_SCALB                           = 0x32B // 811
+	SYS_LGAMMA                          = 0x32C // 812
+	SYS_TTYSLOT                         = 0x32D // 813
+	SYS_GETTIMEOFDAY_R                  = 0x32E // 814
+	SYS_SYNC                            = 0x32F // 815
+	SYS_SPAWN                           = 0x330 // 816
+	SYS_SPAWNP                          = 0x331 // 817
+	SYS_GETLOGIN_UU                     = 0x332 // 818
+	SYS_ECVT                            = 0x333 // 819
+	SYS_FCVT                            = 0x334 // 820
+	SYS_GCVT                            = 0x335 // 821
+	SYS_ACCEPT                          = 0x336 // 822
+	SYS_BIND                            = 0x337 // 823
+	SYS_CONNECT                         = 0x338 // 824
+	SYS_ENDHOSTENT                      = 0x339 // 825
+	SYS_ENDPROTOENT                     = 0x33A // 826
+	SYS_ENDSERVENT                      = 0x33B // 827
+	SYS_GETHOSTBYADDR_R                 = 0x33C // 828
+	SYS_GETHOSTBYADDR                   = 0x33D // 829
+	SYS_GETHOSTBYNAME_R                 = 0x33E // 830
+	SYS_GETHOSTBYNAME                   = 0x33F // 831
+	SYS_GETHOSTENT                      = 0x340 // 832
+	SYS_GETHOSTID                       = 0x341 // 833
+	SYS_GETHOSTNAME                     = 0x342 // 834
+	SYS_GETNETBYADDR                    = 0x343 // 835
+	SYS_GETNETBYNAME                    = 0x344 // 836
+	SYS_GETNETENT                       = 0x345 // 837
+	SYS_GETPEERNAME                     = 0x346 // 838
+	SYS_GETPROTOBYNAME                  = 0x347 // 839
+	SYS_GETPROTOBYNUMBER                = 0x348 // 840
+	SYS_GETPROTOENT                     = 0x349 // 841
+	SYS_GETSERVBYNAME                   = 0x34A // 842
+	SYS_GETSERVBYPORT                   = 0x34B // 843
+	SYS_GETSERVENT                      = 0x34C // 844
+	SYS_GETSOCKNAME                     = 0x34D // 845
+	SYS_GETSOCKOPT                      = 0x34E // 846
+	SYS_INET_ADDR                       = 0x34F // 847
+	SYS_INET_LNAOF                      = 0x350 // 848
+	SYS_INET_MAKEADDR                   = 0x351 // 849
+	SYS_INET_NETOF                      = 0x352 // 850
+	SYS_INET_NETWORK                    = 0x353 // 851
+	SYS_INET_NTOA                       = 0x354 // 852
+	SYS_IOCTL                           = 0x355 // 853
+	SYS_LISTEN                          = 0x356 // 854
+	SYS_READV                           = 0x357 // 855
+	SYS_RECV                            = 0x358 // 856
+	SYS_RECVFROM                        = 0x359 // 857
+	SYS_SELECT                          = 0x35B // 859
+	SYS_SELECTEX                        = 0x35C // 860
+	SYS_SEND                            = 0x35D // 861
+	SYS_SENDTO                          = 0x35F // 863
+	SYS_SETHOSTENT                      = 0x360 // 864
+	SYS_SETNETENT                       = 0x361 // 865
+	SYS_SETPEER                         = 0x362 // 866
+	SYS_SETPROTOENT                     = 0x363 // 867
+	SYS_SETSERVENT                      = 0x364 // 868
+	SYS_SETSOCKOPT                      = 0x365 // 869
+	SYS_SHUTDOWN                        = 0x366 // 870
+	SYS_SOCKET                          = 0x367 // 871
+	SYS_SOCKETPAIR                      = 0x368 // 872
+	SYS_WRITEV                          = 0x369 // 873
+	SYS_CHROOT                          = 0x36A // 874
+	SYS_W_STATVFS                       = 0x36B // 875
+	SYS_ULIMIT                          = 0x36C // 876
+	SYS_ISNAN                           = 0x36D // 877
+	SYS_UTIMES                          = 0x36E // 878
+	SYS___H_ERRNO                       = 0x36F // 879
+	SYS_ENDNETENT                       = 0x370 // 880
+	SYS_CLOSELOG                        = 0x371 // 881
+	SYS_OPENLOG                         = 0x372 // 882
+	SYS_SETLOGMASK                      = 0x373 // 883
+	SYS_SYSLOG                          = 0x374 // 884
+	SYS_PTSNAME                         = 0x375 // 885
+	SYS_SETREUID                        = 0x376 // 886
+	SYS_SETREGID                        = 0x377 // 887
+	SYS_REALPATH                        = 0x378 // 888
+	SYS___SIGNGAM                       = 0x379 // 889
+	SYS_GRANTPT                         = 0x37A // 890
+	SYS_UNLOCKPT                        = 0x37B // 891
+	SYS_TCGETSID                        = 0x37C // 892
+	SYS___TCGETCP                       = 0x37D // 893
+	SYS___TCSETCP                       = 0x37E // 894
+	SYS___TCSETTABLES                   = 0x37F // 895
+	SYS_POLL                            = 0x380 // 896
+	SYS_REXEC                           = 0x381 // 897
+	SYS___ISASCII2                      = 0x382 // 898
+	SYS___TOASCII2                      = 0x383 // 899
+	SYS_CHPRIORITY                      = 0x384 // 900
+	SYS_PTHREAD_ATTR_SETSYNCTYPE_NP     = 0x385 // 901
+	SYS_PTHREAD_ATTR_GETSYNCTYPE_NP     = 0x386 // 902
+	SYS_PTHREAD_SET_LIMIT_NP            = 0x387 // 903
+	SYS___STNETENT                      = 0x388 // 904
+	SYS___STPROTOENT                    = 0x389 // 905
+	SYS___STSERVENT                     = 0x38A // 906
+	SYS___STHOSTENT                     = 0x38B // 907
+	SYS_NLIST                           = 0x38C // 908
+	SYS___IPDBCS                        = 0x38D // 909
+	SYS___IPDSPX                        = 0x38E // 910
+	SYS___IPMSGC                        = 0x38F // 911
+	SYS___SELECT1                       = 0x390 // 912
+	SYS_PTHREAD_SECURITY_NP             = 0x391 // 913
+	SYS___CHECK_RESOURCE_AUTH_NP        = 0x392 // 914
+	SYS___CONVERT_ID_NP                 = 0x393 // 915
+	SYS___OPENVMREL                     = 0x394 // 916
+	SYS_WMEMCHR                         = 0x395 // 917
+	SYS_WMEMCMP                         = 0x396 // 918
+	SYS_WMEMCPY                         = 0x397 // 919
+	SYS_WMEMMOVE                        = 0x398 // 920
+	SYS_WMEMSET                         = 0x399 // 921
+	SYS___FPUTWC                        = 0x400 // 1024
+	SYS___PUTWC                         = 0x401 // 1025
+	SYS___PWCHAR                        = 0x402 // 1026
+	SYS___WCSFTM                        = 0x403 // 1027
+	SYS___WCSTOK                        = 0x404 // 1028
+	SYS___WCWDTH                        = 0x405 // 1029
+	SYS_T_ACCEPT                        = 0x409 // 1033
+	SYS_T_ALLOC                         = 0x40A // 1034
+	SYS_T_BIND                          = 0x40B // 1035
+	SYS_T_CLOSE                         = 0x40C // 1036
+	SYS_T_CONNECT                       = 0x40D // 1037
+	SYS_T_ERROR                         = 0x40E // 1038
+	SYS_T_FREE                          = 0x40F // 1039
+	SYS_T_GETINFO                       = 0x410 // 1040
+	SYS_T_GETPROTADDR                   = 0x411 // 1041
+	SYS_T_GETSTATE                      = 0x412 // 1042
+	SYS_T_LISTEN                        = 0x413 // 1043
+	SYS_T_LOOK                          = 0x414 // 1044
+	SYS_T_OPEN                          = 0x415 // 1045
+	SYS_T_OPTMGMT                       = 0x416 // 1046
+	SYS_T_RCV                           = 0x417 // 1047
+	SYS_T_RCVCONNECT                    = 0x418 // 1048
+	SYS_T_RCVDIS                        = 0x419 // 1049
+	SYS_T_RCVREL                        = 0x41A // 1050
+	SYS_T_RCVUDATA                      = 0x41B // 1051
+	SYS_T_RCVUDERR                      = 0x41C // 1052
+	SYS_T_SND                           = 0x41D // 1053
+	SYS_T_SNDDIS                        = 0x41E // 1054
+	SYS_T_SNDREL                        = 0x41F // 1055
+	SYS_T_SNDUDATA                      = 0x420 // 1056
+	SYS_T_STRERROR                      = 0x421 // 1057
+	SYS_T_SYNC                          = 0x422 // 1058
+	SYS_T_UNBIND                        = 0x423 // 1059
+	SYS___T_ERRNO                       = 0x424 // 1060
+	SYS___RECVMSG2                      = 0x425 // 1061
+	SYS___SENDMSG2                      = 0x426 // 1062
+	SYS_FATTACH                         = 0x427 // 1063
+	SYS_FDETACH                         = 0x428 // 1064
+	SYS_GETMSG                          = 0x429 // 1065
+	SYS_GETPMSG                         = 0x42A // 1066
+	SYS_ISASTREAM                       = 0x42B // 1067
+	SYS_PUTMSG                          = 0x42C // 1068
+	SYS_PUTPMSG                         = 0x42D // 1069
+	SYS___ISPOSIXON                     = 0x42E // 1070
+	SYS___OPENMVSREL                    = 0x42F // 1071
+	SYS_GETCONTEXT                      = 0x430 // 1072
+	SYS_SETCONTEXT                      = 0x431 // 1073
+	SYS_MAKECONTEXT                     = 0x432 // 1074
+	SYS_SWAPCONTEXT                     = 0x433 // 1075
+	SYS_PTHREAD_GETSPECIFIC_D8_NP       = 0x434 // 1076
+	SYS_GETCLIENTID                     = 0x470 // 1136
+	SYS___GETCLIENTID                   = 0x471 // 1137
+	SYS_GETSTABLESIZE                   = 0x472 // 1138
+	SYS_GETIBMOPT                       = 0x473 // 1139
+	SYS_GETIBMSOCKOPT                   = 0x474 // 1140
+	SYS_GIVESOCKET                      = 0x475 // 1141
+	SYS_IBMSFLUSH                       = 0x476 // 1142
+	SYS_MAXDESC                         = 0x477 // 1143
+	SYS_SETIBMOPT                       = 0x478 // 1144
+	SYS_SETIBMSOCKOPT                   = 0x479 // 1145
+	SYS_SOCK_DEBUG                      = 0x47A // 1146
+	SYS_SOCK_DO_TESTSTOR                = 0x47D // 1149
+	SYS_TAKESOCKET                      = 0x47E // 1150
+	SYS___SERVER_INIT                   = 0x47F // 1151
+	SYS___SERVER_PWU                    = 0x480 // 1152
+	SYS_PTHREAD_TAG_NP                  = 0x481 // 1153
+	SYS___CONSOLE                       = 0x482 // 1154
+	SYS___WSINIT                        = 0x483 // 1155
+	SYS___IPTCPN                        = 0x489 // 1161
+	SYS___SMF_RECORD                    = 0x48A // 1162
+	SYS___IPHOST                        = 0x48B // 1163
+	SYS___IPNODE                        = 0x48C // 1164
+	SYS___SERVER_CLASSIFY_CREATE        = 0x48D // 1165
+	SYS___SERVER_CLASSIFY_DESTROY       = 0x48E // 1166
+	SYS___SERVER_CLASSIFY_RESET         = 0x48F // 1167
+	SYS___SERVER_CLASSIFY               = 0x490 // 1168
+	SYS___HEAPRPT                       = 0x496 // 1174
+	SYS___FNWSA                         = 0x49B // 1179
+	SYS___SPAWN2                        = 0x49D // 1181
+	SYS___SPAWNP2                       = 0x49E // 1182
+	SYS___GDRR                          = 0x4A1 // 1185
+	SYS___HRRNO                         = 0x4A2 // 1186
+	SYS___OPRG                          = 0x4A3 // 1187
+	SYS___OPRR                          = 0x4A4 // 1188
+	SYS___OPND                          = 0x4A5 // 1189
+	SYS___OPPT                          = 0x4A6 // 1190
+	SYS___SIGGM                         = 0x4A7 // 1191
+	SYS___DGHT                          = 0x4A8 // 1192
+	SYS___TZNE                          = 0x4A9 // 1193
+	SYS___TZZN                          = 0x4AA // 1194
+	SYS___TRRNO                         = 0x4AF // 1199
+	SYS___ENVN                          = 0x4B0 // 1200
+	SYS___MLOCKALL                      = 0x4B1 // 1201
+	SYS_CREATEWO                        = 0x4B2 // 1202
+	SYS_CREATEWORKUNIT                  = 0x4B2 // 1202
+	SYS_CONTINUE                        = 0x4B3 // 1203
+	SYS_CONTINUEWORKUNIT                = 0x4B3 // 1203
+	SYS_CONNECTW                        = 0x4B4 // 1204
+	SYS_CONNECTWORKMGR                  = 0x4B4 // 1204
+	SYS_CONNECTS                        = 0x4B5 // 1205
+	SYS_CONNECTSERVER                   = 0x4B5 // 1205
+	SYS_DISCONNE                        = 0x4B6 // 1206
+	SYS_DISCONNECTSERVER                = 0x4B6 // 1206
+	SYS_JOINWORK                        = 0x4B7 // 1207
+	SYS_JOINWORKUNIT                    = 0x4B7 // 1207
+	SYS_LEAVEWOR                        = 0x4B8 // 1208
+	SYS_LEAVEWORKUNIT                   = 0x4B8 // 1208
+	SYS_DELETEWO                        = 0x4B9 // 1209
+	SYS_DELETEWORKUNIT                  = 0x4B9 // 1209
+	SYS_QUERYMET                        = 0x4BA // 1210
+	SYS_QUERYMETRICS                    = 0x4BA // 1210
+	SYS_QUERYSCH                        = 0x4BB // 1211
+	SYS_QUERYSCHENV                     = 0x4BB // 1211
+	SYS_CHECKSCH                        = 0x4BC // 1212
+	SYS_CHECKSCHENV                     = 0x4BC // 1212
+	SYS___PID_AFFINITY                  = 0x4BD // 1213
+	SYS___ASINH_B                       = 0x4BE // 1214
+	SYS___ATAN_B                        = 0x4BF // 1215
+	SYS___CBRT_B                        = 0x4C0 // 1216
+	SYS___CEIL_B                        = 0x4C1 // 1217
+	SYS_COPYSIGN                        = 0x4C2 // 1218
+	SYS___COS_B                         = 0x4C3 // 1219
+	SYS___ERF_B                         = 0x4C4 // 1220
+	SYS___ERFC_B                        = 0x4C5 // 1221
+	SYS___EXPM1_B                       = 0x4C6 // 1222
+	SYS___FABS_B                        = 0x4C7 // 1223
+	SYS_FINITE                          = 0x4C8 // 1224
+	SYS___FLOOR_B                       = 0x4C9 // 1225
+	SYS___FREXP_B                       = 0x4CA // 1226
+	SYS___ILOGB_B                       = 0x4CB // 1227
+	SYS___ISNAN_B                       = 0x4CC // 1228
+	SYS___LDEXP_B                       = 0x4CD // 1229
+	SYS___LOG1P_B                       = 0x4CE // 1230
+	SYS___LOGB_B                        = 0x4CF // 1231
+	SYS_MATHERR                         = 0x4D0 // 1232
+	SYS___MODF_B                        = 0x4D1 // 1233
+	SYS___NEXTAFTER_B                   = 0x4D2 // 1234
+	SYS___RINT_B                        = 0x4D3 // 1235
+	SYS_SCALBN                          = 0x4D4 // 1236
+	SYS_SIGNIFIC                        = 0x4D5 // 1237
+	SYS_SIGNIFICAND                     = 0x4D5 // 1237
+	SYS___SIN_B                         = 0x4D6 // 1238
+	SYS___TAN_B                         = 0x4D7 // 1239
+	SYS___TANH_B                        = 0x4D8 // 1240
+	SYS___ACOS_B                        = 0x4D9 // 1241
+	SYS___ACOSH_B                       = 0x4DA // 1242
+	SYS___ASIN_B                        = 0x4DB // 1243
+	SYS___ATAN2_B                       = 0x4DC // 1244
+	SYS___ATANH_B                       = 0x4DD // 1245
+	SYS___COSH_B                        = 0x4DE // 1246
+	SYS___EXP_B                         = 0x4DF // 1247
+	SYS___FMOD_B                        = 0x4E0 // 1248
+	SYS___GAMMA_B                       = 0x4E1 // 1249
+	SYS_GAMMA_R                         = 0x4E2 // 1250
+	SYS___HYPOT_B                       = 0x4E3 // 1251
+	SYS___J0_B                          = 0x4E4 // 1252
+	SYS___Y0_B                          = 0x4E5 // 1253
+	SYS___J1_B                          = 0x4E6 // 1254
+	SYS___Y1_B                          = 0x4E7 // 1255
+	SYS___JN_B                          = 0x4E8 // 1256
+	SYS___YN_B                          = 0x4E9 // 1257
+	SYS___LGAMMA_B                      = 0x4EA // 1258
+	SYS_LGAMMA_R                        = 0x4EB // 1259
+	SYS___LOG_B                         = 0x4EC // 1260
+	SYS___LOG10_B                       = 0x4ED // 1261
+	SYS___POW_B                         = 0x4EE // 1262
+	SYS___REMAINDER_B                   = 0x4EF // 1263
+	SYS___SCALB_B                       = 0x4F0 // 1264
+	SYS___SINH_B                        = 0x4F1 // 1265
+	SYS___SQRT_B                        = 0x4F2 // 1266
+	SYS___OPENDIR2                      = 0x4F3 // 1267
+	SYS___READDIR2                      = 0x4F4 // 1268
+	SYS___LOGIN                         = 0x4F5 // 1269
+	SYS___OPEN_STAT                     = 0x4F6 // 1270
+	SYS_ACCEPT_AND_RECV                 = 0x4F7 // 1271
+	SYS___FP_SETMODE                    = 0x4F8 // 1272
+	SYS___SIGACTIONSET                  = 0x4FB // 1275
+	SYS___UCREATE                       = 0x4FC // 1276
+	SYS___UMALLOC                       = 0x4FD // 1277
+	SYS___UFREE                         = 0x4FE // 1278
+	SYS___UHEAPREPORT                   = 0x4FF // 1279
+	SYS___ISBFP                         = 0x500 // 1280
+	SYS___FP_CAST                       = 0x501 // 1281
+	SYS___CERTIFICATE                   = 0x502 // 1282
+	SYS_SEND_FILE                       = 0x503 // 1283
+	SYS_AIO_CANCEL                      = 0x504 // 1284
+	SYS_AIO_ERROR                       = 0x505 // 1285
+	SYS_AIO_READ                        = 0x506 // 1286
+	SYS_AIO_RETURN                      = 0x507 // 1287
+	SYS_AIO_SUSPEND                     = 0x508 // 1288
+	SYS_AIO_WRITE                       = 0x509 // 1289
+	SYS_PTHREAD_MUTEXATTR_GETPSHARED    = 0x50A // 1290
+	SYS_PTHREAD_MUTEXATTR_SETPSHARED    = 0x50B // 1291
+	SYS_PTHREAD_RWLOCK_DESTROY          = 0x50C // 1292
+	SYS_PTHREAD_RWLOCK_INIT             = 0x50D // 1293
+	SYS_PTHREAD_RWLOCK_RDLOCK           = 0x50E // 1294
+	SYS_PTHREAD_RWLOCK_TRYRDLOCK        = 0x50F // 1295
+	SYS_PTHREAD_RWLOCK_TRYWRLOCK        = 0x510 // 1296
+	SYS_PTHREAD_RWLOCK_UNLOCK           = 0x511 // 1297
+	SYS_PTHREAD_RWLOCK_WRLOCK           = 0x512 // 1298
+	SYS_PTHREAD_RWLOCKATTR_GETPSHARED   = 0x513 // 1299
+	SYS_PTHREAD_RWLOCKATTR_SETPSHARED   = 0x514 // 1300
+	SYS_PTHREAD_RWLOCKATTR_INIT         = 0x515 // 1301
+	SYS_PTHREAD_RWLOCKATTR_DESTROY      = 0x516 // 1302
+	SYS___CTTBL                         = 0x517 // 1303
+	SYS_PTHREAD_MUTEXATTR_SETTYPE       = 0x518 // 1304
+	SYS_PTHREAD_MUTEXATTR_GETTYPE       = 0x519 // 1305
+	SYS___FP_CLR_FLAG                   = 0x51A // 1306
+	SYS___FP_READ_FLAG                  = 0x51B // 1307
+	SYS___FP_RAISE_XCP                  = 0x51C // 1308
+	SYS___FP_CLASS                      = 0x51D // 1309
+	SYS___FP_FINITE                     = 0x51E // 1310
+	SYS___FP_ISNAN                      = 0x51F // 1311
+	SYS___FP_UNORDERED                  = 0x520 // 1312
+	SYS___FP_READ_RND                   = 0x521 // 1313
+	SYS___FP_READ_RND_B                 = 0x522 // 1314
+	SYS___FP_SWAP_RND                   = 0x523 // 1315
+	SYS___FP_SWAP_RND_B                 = 0x524 // 1316
+	SYS___FP_LEVEL                      = 0x525 // 1317
+	SYS___FP_BTOH                       = 0x526 // 1318
+	SYS___FP_HTOB                       = 0x527 // 1319
+	SYS___FPC_RD                        = 0x528 // 1320
+	SYS___FPC_WR                        = 0x529 // 1321
+	SYS___FPC_RW                        = 0x52A // 1322
+	SYS___FPC_SM                        = 0x52B // 1323
+	SYS___FPC_RS                        = 0x52C // 1324
+	SYS_SIGTIMEDWAIT                    = 0x52D // 1325
+	SYS_SIGWAITINFO                     = 0x52E // 1326
+	SYS___CHKBFP                        = 0x52F // 1327
+	SYS___W_PIOCTL                      = 0x59E // 1438
+	SYS___OSENV                         = 0x59F // 1439
+	SYS_EXPORTWO                        = 0x5A1 // 1441
+	SYS_EXPORTWORKUNIT                  = 0x5A1 // 1441
+	SYS_UNDOEXPO                        = 0x5A2 // 1442
+	SYS_UNDOEXPORTWORKUNIT              = 0x5A2 // 1442
+	SYS_IMPORTWO                        = 0x5A3 // 1443
+	SYS_IMPORTWORKUNIT                  = 0x5A3 // 1443
+	SYS_UNDOIMPO                        = 0x5A4 // 1444
+	SYS_UNDOIMPORTWORKUNIT              = 0x5A4 // 1444
+	SYS_EXTRACTW                        = 0x5A5 // 1445
+	SYS_EXTRACTWORKUNIT                 = 0x5A5 // 1445
+	SYS___CPL                           = 0x5A6 // 1446
+	SYS___MAP_INIT                      = 0x5A7 // 1447
+	SYS___MAP_SERVICE                   = 0x5A8 // 1448
+	SYS_SIGQUEUE                        = 0x5A9 // 1449
+	SYS___MOUNT                         = 0x5AA // 1450
+	SYS___GETUSERID                     = 0x5AB // 1451
+	SYS___IPDOMAINNAME                  = 0x5AC // 1452
+	SYS_QUERYENC                        = 0x5AD // 1453
+	SYS_QUERYWORKUNITCLASSIFICATION     = 0x5AD // 1453
+	SYS_CONNECTE                        = 0x5AE // 1454
+	SYS_CONNECTEXPORTIMPORT             = 0x5AE // 1454
+	SYS___FP_SWAPMODE                   = 0x5AF // 1455
+	SYS_STRTOLL                         = 0x5B0 // 1456
+	SYS_STRTOULL                        = 0x5B1 // 1457
+	SYS___DSA_PREV                      = 0x5B2 // 1458
+	SYS___EP_FIND                       = 0x5B3 // 1459
+	SYS___SERVER_THREADS_QUERY          = 0x5B4 // 1460
+	SYS___MSGRCV_TIMED                  = 0x5B7 // 1463
+	SYS___SEMOP_TIMED                   = 0x5B8 // 1464
+	SYS___GET_CPUID                     = 0x5B9 // 1465
+	SYS___GET_SYSTEM_SETTINGS           = 0x5BA // 1466
+	SYS_FTELLO                          = 0x5C8 // 1480
+	SYS_FSEEKO                          = 0x5C9 // 1481
+	SYS_LLDIV                           = 0x5CB // 1483
+	SYS_WCSTOLL                         = 0x5CC // 1484
+	SYS_WCSTOULL                        = 0x5CD // 1485
+	SYS_LLABS                           = 0x5CE // 1486
+	SYS___CONSOLE2                      = 0x5D2 // 1490
+	SYS_INET_NTOP                       = 0x5D3 // 1491
+	SYS_INET_PTON                       = 0x5D4 // 1492
+	SYS___RES                           = 0x5D6 // 1494
+	SYS_RES_MKQUERY                     = 0x5D7 // 1495
+	SYS_RES_INIT                        = 0x5D8 // 1496
+	SYS_RES_QUERY                       = 0x5D9 // 1497
+	SYS_RES_SEARCH                      = 0x5DA // 1498
+	SYS_RES_SEND                        = 0x5DB // 1499
+	SYS_RES_QUERYDOMAIN                 = 0x5DC // 1500
+	SYS_DN_EXPAND                       = 0x5DD // 1501
+	SYS_DN_SKIPNAME                     = 0x5DE // 1502
+	SYS_DN_COMP                         = 0x5DF // 1503
+	SYS_ASCTIME_R                       = 0x5E0 // 1504
+	SYS_CTIME_R                         = 0x5E1 // 1505
+	SYS_GMTIME_R                        = 0x5E2 // 1506
+	SYS_LOCALTIME_R                     = 0x5E3 // 1507
+	SYS_RAND_R                          = 0x5E4 // 1508
+	SYS_STRTOK_R                        = 0x5E5 // 1509
+	SYS_READDIR_R                       = 0x5E6 // 1510
+	SYS_GETGRGID_R                      = 0x5E7 // 1511
+	SYS_GETGRNAM_R                      = 0x5E8 // 1512
+	SYS_GETLOGIN_R                      = 0x5E9 // 1513
+	SYS_GETPWNAM_R                      = 0x5EA // 1514
+	SYS_GETPWUID_R                      = 0x5EB // 1515
+	SYS_TTYNAME_R                       = 0x5EC // 1516
+	SYS_PTHREAD_ATFORK                  = 0x5ED // 1517
+	SYS_PTHREAD_ATTR_GETGUARDSIZE       = 0x5EE // 1518
+	SYS_PTHREAD_ATTR_GETSTACKADDR       = 0x5EF // 1519
+	SYS_PTHREAD_ATTR_SETGUARDSIZE       = 0x5F0 // 1520
+	SYS_PTHREAD_ATTR_SETSTACKADDR       = 0x5F1 // 1521
+	SYS_PTHREAD_CONDATTR_GETPSHARED     = 0x5F2 // 1522
+	SYS_PTHREAD_CONDATTR_SETPSHARED     = 0x5F3 // 1523
+	SYS_PTHREAD_GETCONCURRENCY          = 0x5F4 // 1524
+	SYS_PTHREAD_KEY_DELETE              = 0x5F5 // 1525
+	SYS_PTHREAD_SETCONCURRENCY          = 0x5F6 // 1526
+	SYS_PTHREAD_SIGMASK                 = 0x5F7 // 1527
+	SYS___DISCARDDATA                   = 0x5F8 // 1528
+	SYS_PTHREAD_ATTR_GETSCHEDPARAM      = 0x5F9 // 1529
+	SYS_PTHREAD_ATTR_SETSCHEDPARAM      = 0x5FA // 1530
+	SYS_PTHREAD_ATTR_GETDETACHSTATE_U98 = 0x5FB // 1531
+	SYS_PTHREAD_ATTR_SETDETACHSTATE_U98 = 0x5FC // 1532
+	SYS_PTHREAD_DETACH_U98              = 0x5FD // 1533
+	SYS_PTHREAD_GETSPECIFIC_U98         = 0x5FE // 1534
+	SYS_PTHREAD_SETCANCELSTATE          = 0x5FF // 1535
+	SYS_PTHREAD_SETCANCELTYPE           = 0x600 // 1536
+	SYS_PTHREAD_TESTCANCEL              = 0x601 // 1537
+	SYS___ATANF_B                       = 0x602 // 1538
+	SYS___ATANL_B                       = 0x603 // 1539
+	SYS___CEILF_B                       = 0x604 // 1540
+	SYS___CEILL_B                       = 0x605 // 1541
+	SYS___COSF_B                        = 0x606 // 1542
+	SYS___COSL_B                        = 0x607 // 1543
+	SYS___FABSF_B                       = 0x608 // 1544
+	SYS___FABSL_B                       = 0x609 // 1545
+	SYS___FLOORF_B                      = 0x60A // 1546
+	SYS___FLOORL_B                      = 0x60B // 1547
+	SYS___FREXPF_B                      = 0x60C // 1548
+	SYS___FREXPL_B                      = 0x60D // 1549
+	SYS___LDEXPF_B                      = 0x60E // 1550
+	SYS___LDEXPL_B                      = 0x60F // 1551
+	SYS___SINF_B                        = 0x610 // 1552
+	SYS___SINL_B                        = 0x611 // 1553
+	SYS___TANF_B                        = 0x612 // 1554
+	SYS___TANL_B                        = 0x613 // 1555
+	SYS___TANHF_B                       = 0x614 // 1556
+	SYS___TANHL_B                       = 0x615 // 1557
+	SYS___ACOSF_B                       = 0x616 // 1558
+	SYS___ACOSL_B                       = 0x617 // 1559
+	SYS___ASINF_B                       = 0x618 // 1560
+	SYS___ASINL_B                       = 0x619 // 1561
+	SYS___ATAN2F_B                      = 0x61A // 1562
+	SYS___ATAN2L_B                      = 0x61B // 1563
+	SYS___COSHF_B                       = 0x61C // 1564
+	SYS___COSHL_B                       = 0x61D // 1565
+	SYS___EXPF_B                        = 0x61E // 1566
+	SYS___EXPL_B                        = 0x61F // 1567
+	SYS___LOGF_B                        = 0x620 // 1568
+	SYS___LOGL_B                        = 0x621 // 1569
+	SYS___LOG10F_B                      = 0x622 // 1570
+	SYS___LOG10L_B                      = 0x623 // 1571
+	SYS___POWF_B                        = 0x624 // 1572
+	SYS___POWL_B                        = 0x625 // 1573
+	SYS___SINHF_B                       = 0x626 // 1574
+	SYS___SINHL_B                       = 0x627 // 1575
+	SYS___SQRTF_B                       = 0x628 // 1576
+	SYS___SQRTL_B                       = 0x629 // 1577
+	SYS___ABSF_B                        = 0x62A // 1578
+	SYS___ABS_B                         = 0x62B // 1579
+	SYS___ABSL_B                        = 0x62C // 1580
+	SYS___FMODF_B                       = 0x62D // 1581
+	SYS___FMODL_B                       = 0x62E // 1582
+	SYS___MODFF_B                       = 0x62F // 1583
+	SYS___MODFL_B                       = 0x630 // 1584
+	SYS_ABSF                            = 0x631 // 1585
+	SYS_ABSL                            = 0x632 // 1586
+	SYS_ACOSF                           = 0x633 // 1587
+	SYS_ACOSL                           = 0x634 // 1588
+	SYS_ASINF                           = 0x635 // 1589
+	SYS_ASINL                           = 0x636 // 1590
+	SYS_ATAN2F                          = 0x637 // 1591
+	SYS_ATAN2L                          = 0x638 // 1592
+	SYS_ATANF                           = 0x639 // 1593
+	SYS_ATANL                           = 0x63A // 1594
+	SYS_CEILF                           = 0x63B // 1595
+	SYS_CEILL                           = 0x63C // 1596
+	SYS_COSF                            = 0x63D // 1597
+	SYS_COSL                            = 0x63E // 1598
+	SYS_COSHF                           = 0x63F // 1599
+	SYS_COSHL                           = 0x640 // 1600
+	SYS_EXPF                            = 0x641 // 1601
+	SYS_EXPL                            = 0x642 // 1602
+	SYS_TANHF                           = 0x643 // 1603
+	SYS_TANHL                           = 0x644 // 1604
+	SYS_LOG10F                          = 0x645 // 1605
+	SYS_LOG10L                          = 0x646 // 1606
+	SYS_LOGF                            = 0x647 // 1607
+	SYS_LOGL                            = 0x648 // 1608
+	SYS_POWF                            = 0x649 // 1609
+	SYS_POWL                            = 0x64A // 1610
+	SYS_SINF                            = 0x64B // 1611
+	SYS_SINL                            = 0x64C // 1612
+	SYS_SQRTF                           = 0x64D // 1613
+	SYS_SQRTL                           = 0x64E // 1614
+	SYS_SINHF                           = 0x64F // 1615
+	SYS_SINHL                           = 0x650 // 1616
+	SYS_TANF                            = 0x651 // 1617
+	SYS_TANL                            = 0x652 // 1618
+	SYS_FABSF                           = 0x653 // 1619
+	SYS_FABSL                           = 0x654 // 1620
+	SYS_FLOORF                          = 0x655 // 1621
+	SYS_FLOORL                          = 0x656 // 1622
+	SYS_FMODF                           = 0x657 // 1623
+	SYS_FMODL                           = 0x658 // 1624
+	SYS_FREXPF                          = 0x659 // 1625
+	SYS_FREXPL                          = 0x65A // 1626
+	SYS_LDEXPF                          = 0x65B // 1627
+	SYS_LDEXPL                          = 0x65C // 1628
+	SYS_MODFF                           = 0x65D // 1629
+	SYS_MODFL                           = 0x65E // 1630
+	SYS_BTOWC                           = 0x65F // 1631
+	SYS___CHATTR                        = 0x660 // 1632
+	SYS___FCHATTR                       = 0x661 // 1633
+	SYS___TOCCSID                       = 0x662 // 1634
+	SYS___CSNAMETYPE                    = 0x663 // 1635
+	SYS___TOCSNAME                      = 0x664 // 1636
+	SYS___CCSIDTYPE                     = 0x665 // 1637
+	SYS___AE_CORRESTBL_QUERY            = 0x666 // 1638
+	SYS___AE_AUTOCONVERT_STATE          = 0x667 // 1639
+	SYS_DN_FIND                         = 0x668 // 1640
+	SYS___GETHOSTBYADDR_A               = 0x669 // 1641
+	SYS___GETHOSTBYNAME_A               = 0x66A // 1642
+	SYS___RES_INIT_A                    = 0x66B // 1643
+	SYS___GETHOSTBYADDR_R_A             = 0x66C // 1644
+	SYS___GETHOSTBYNAME_R_A             = 0x66D // 1645
+	SYS___CHARMAP_INIT_A                = 0x66E // 1646
+	SYS___MBLEN_A                       = 0x66F // 1647
+	SYS___MBLEN_SB_A                    = 0x670 // 1648
+	SYS___MBLEN_STD_A                   = 0x671 // 1649
+	SYS___MBLEN_UTF                     = 0x672 // 1650
+	SYS___MBSTOWCS_A                    = 0x673 // 1651
+	SYS___MBSTOWCS_STD_A                = 0x674 // 1652
+	SYS___MBTOWC_A                      = 0x675 // 1653
+	SYS___MBTOWC_ISO1                   = 0x676 // 1654
+	SYS___MBTOWC_SBCS                   = 0x677 // 1655
+	SYS___MBTOWC_MBCS                   = 0x678 // 1656
+	SYS___MBTOWC_UTF                    = 0x679 // 1657
+	SYS___WCSTOMBS_A                    = 0x67A // 1658
+	SYS___WCSTOMBS_STD_A                = 0x67B // 1659
+	SYS___WCSWIDTH_A                    = 0x67C // 1660
+	SYS___GETGRGID_R_A                  = 0x67D // 1661
+	SYS___WCSWIDTH_STD_A                = 0x67E // 1662
+	SYS___WCSWIDTH_ASIA                 = 0x67F // 1663
+	SYS___CSID_A                        = 0x680 // 1664
+	SYS___CSID_STD_A                    = 0x681 // 1665
+	SYS___WCSID_A                       = 0x682 // 1666
+	SYS___WCSID_STD_A                   = 0x683 // 1667
+	SYS___WCTOMB_A                      = 0x684 // 1668
+	SYS___WCTOMB_ISO1                   = 0x685 // 1669
+	SYS___WCTOMB_STD_A                  = 0x686 // 1670
+	SYS___WCTOMB_UTF                    = 0x687 // 1671
+	SYS___WCWIDTH_A                     = 0x688 // 1672
+	SYS___GETGRNAM_R_A                  = 0x689 // 1673
+	SYS___WCWIDTH_STD_A                 = 0x68A // 1674
+	SYS___WCWIDTH_ASIA                  = 0x68B // 1675
+	SYS___GETPWNAM_R_A                  = 0x68C // 1676
+	SYS___GETPWUID_R_A                  = 0x68D // 1677
+	SYS___GETLOGIN_R_A                  = 0x68E // 1678
+	SYS___TTYNAME_R_A                   = 0x68F // 1679
+	SYS___READDIR_R_A                   = 0x690 // 1680
+	SYS___E2A_S                         = 0x691 // 1681
+	SYS___FNMATCH_A                     = 0x692 // 1682
+	SYS___FNMATCH_C_A                   = 0x693 // 1683
+	SYS___EXECL_A                       = 0x694 // 1684
+	SYS___FNMATCH_STD_A                 = 0x695 // 1685
+	SYS___REGCOMP_A                     = 0x696 // 1686
+	SYS___REGCOMP_STD_A                 = 0x697 // 1687
+	SYS___REGERROR_A                    = 0x698 // 1688
+	SYS___REGERROR_STD_A                = 0x699 // 1689
+	SYS___REGEXEC_A                     = 0x69A // 1690
+	SYS___REGEXEC_STD_A                 = 0x69B // 1691
+	SYS___REGFREE_A                     = 0x69C // 1692
+	SYS___REGFREE_STD_A                 = 0x69D // 1693
+	SYS___STRCOLL_A                     = 0x69E // 1694
+	SYS___STRCOLL_C_A                   = 0x69F // 1695
+	SYS___EXECLE_A                      = 0x6A0 // 1696
+	SYS___STRCOLL_STD_A                 = 0x6A1 // 1697
+	SYS___STRXFRM_A                     = 0x6A2 // 1698
+	SYS___STRXFRM_C_A                   = 0x6A3 // 1699
+	SYS___EXECLP_A                      = 0x6A4 // 1700
+	SYS___STRXFRM_STD_A                 = 0x6A5 // 1701
+	SYS___WCSCOLL_A                     = 0x6A6 // 1702
+	SYS___WCSCOLL_C_A                   = 0x6A7 // 1703
+	SYS___WCSCOLL_STD_A                 = 0x6A8 // 1704
+	SYS___WCSXFRM_A                     = 0x6A9 // 1705
+	SYS___WCSXFRM_C_A                   = 0x6AA // 1706
+	SYS___WCSXFRM_STD_A                 = 0x6AB // 1707
+	SYS___COLLATE_INIT_A                = 0x6AC // 1708
+	SYS___WCTYPE_A                      = 0x6AD // 1709
+	SYS___GET_WCTYPE_STD_A              = 0x6AE // 1710
+	SYS___CTYPE_INIT_A                  = 0x6AF // 1711
+	SYS___ISWCTYPE_A                    = 0x6B0 // 1712
+	SYS___EXECV_A                       = 0x6B1 // 1713
+	SYS___IS_WCTYPE_STD_A               = 0x6B2 // 1714
+	SYS___TOWLOWER_A                    = 0x6B3 // 1715
+	SYS___TOWLOWER_STD_A                = 0x6B4 // 1716
+	SYS___TOWUPPER_A                    = 0x6B5 // 1717
+	SYS___TOWUPPER_STD_A                = 0x6B6 // 1718
+	SYS___LOCALE_INIT_A                 = 0x6B7 // 1719
+	SYS___LOCALECONV_A                  = 0x6B8 // 1720
+	SYS___LOCALECONV_STD_A              = 0x6B9 // 1721
+	SYS___NL_LANGINFO_A                 = 0x6BA // 1722
+	SYS___NL_LNAGINFO_STD_A             = 0x6BB // 1723
+	SYS___MONETARY_INIT_A               = 0x6BC // 1724
+	SYS___STRFMON_A                     = 0x6BD // 1725
+	SYS___STRFMON_STD_A                 = 0x6BE // 1726
+	SYS___GETADDRINFO_A                 = 0x6BF // 1727
+	SYS___CATGETS_A                     = 0x6C0 // 1728
+	SYS___EXECVE_A                      = 0x6C1 // 1729
+	SYS___EXECVP_A                      = 0x6C2 // 1730
+	SYS___SPAWN_A                       = 0x6C3 // 1731
+	SYS___GETNAMEINFO_A                 = 0x6C4 // 1732
+	SYS___SPAWNP_A                      = 0x6C5 // 1733
+	SYS___NUMERIC_INIT_A                = 0x6C6 // 1734
+	SYS___RESP_INIT_A                   = 0x6C7 // 1735
+	SYS___RPMATCH_A                     = 0x6C8 // 1736
+	SYS___RPMATCH_C_A                   = 0x6C9 // 1737
+	SYS___RPMATCH_STD_A                 = 0x6CA // 1738
+	SYS___TIME_INIT_A                   = 0x6CB // 1739
+	SYS___STRFTIME_A                    = 0x6CC // 1740
+	SYS___STRFTIME_STD_A                = 0x6CD // 1741
+	SYS___STRPTIME_A                    = 0x6CE // 1742
+	SYS___STRPTIME_STD_A                = 0x6CF // 1743
+	SYS___WCSFTIME_A                    = 0x6D0 // 1744
+	SYS___WCSFTIME_STD_A                = 0x6D1 // 1745
+	SYS_____SPAWN2_A                    = 0x6D2 // 1746
+	SYS_____SPAWNP2_A                   = 0x6D3 // 1747
+	SYS___SYNTAX_INIT_A                 = 0x6D4 // 1748
+	SYS___TOD_INIT_A                    = 0x6D5 // 1749
+	SYS___NL_CSINFO_A                   = 0x6D6 // 1750
+	SYS___NL_MONINFO_A                  = 0x6D7 // 1751
+	SYS___NL_NUMINFO_A                  = 0x6D8 // 1752
+	SYS___NL_RESPINFO_A                 = 0x6D9 // 1753
+	SYS___NL_TIMINFO_A                  = 0x6DA // 1754
+	SYS___IF_NAMETOINDEX_A              = 0x6DB // 1755
+	SYS___IF_INDEXTONAME_A              = 0x6DC // 1756
+	SYS___PRINTF_A                      = 0x6DD // 1757
+	SYS___ICONV_OPEN_A                  = 0x6DE // 1758
+	SYS___DLLLOAD_A                     = 0x6DF // 1759
+	SYS___DLLQUERYFN_A                  = 0x6E0 // 1760
+	SYS___DLLQUERYVAR_A                 = 0x6E1 // 1761
+	SYS_____CHATTR_A                    = 0x6E2 // 1762
+	SYS___E2A_L                         = 0x6E3 // 1763
+	SYS_____TOCCSID_A                   = 0x6E4 // 1764
+	SYS_____TOCSNAME_A                  = 0x6E5 // 1765
+	SYS_____CCSIDTYPE_A                 = 0x6E6 // 1766
+	SYS_____CSNAMETYPE_A                = 0x6E7 // 1767
+	SYS___CHMOD_A                       = 0x6E8 // 1768
+	SYS___MKDIR_A                       = 0x6E9 // 1769
+	SYS___STAT_A                        = 0x6EA // 1770
+	SYS___STAT_O_A                      = 0x6EB // 1771
+	SYS___MKFIFO_A                      = 0x6EC // 1772
+	SYS_____OPEN_STAT_A                 = 0x6ED // 1773
+	SYS___LSTAT_A                       = 0x6EE // 1774
+	SYS___LSTAT_O_A                     = 0x6EF // 1775
+	SYS___MKNOD_A                       = 0x6F0 // 1776
+	SYS___MOUNT_A                       = 0x6F1 // 1777
+	SYS___UMOUNT_A                      = 0x6F2 // 1778
+	SYS___CHAUDIT_A                     = 0x6F4 // 1780
+	SYS___W_GETMNTENT_A                 = 0x6F5 // 1781
+	SYS___CREAT_A                       = 0x6F6 // 1782
+	SYS___OPEN_A                        = 0x6F7 // 1783
+	SYS___SETLOCALE_A                   = 0x6F9 // 1785
+	SYS___FPRINTF_A                     = 0x6FA // 1786
+	SYS___SPRINTF_A                     = 0x6FB // 1787
+	SYS___VFPRINTF_A                    = 0x6FC // 1788
+	SYS___VPRINTF_A                     = 0x6FD // 1789
+	SYS___VSPRINTF_A                    = 0x6FE // 1790
+	SYS___VSWPRINTF_A                   = 0x6FF // 1791
+	SYS___SWPRINTF_A                    = 0x700 // 1792
+	SYS___FSCANF_A                      = 0x701 // 1793
+	SYS___SCANF_A                       = 0x702 // 1794
+	SYS___SSCANF_A                      = 0x703 // 1795
+	SYS___SWSCANF_A                     = 0x704 // 1796
+	SYS___ATOF_A                        = 0x705 // 1797
+	SYS___ATOI_A                        = 0x706 // 1798
+	SYS___ATOL_A                        = 0x707 // 1799
+	SYS___STRTOD_A                      = 0x708 // 1800
+	SYS___STRTOL_A                      = 0x709 // 1801
+	SYS___STRTOUL_A                     = 0x70A // 1802
+	SYS_____AE_CORRESTBL_QUERY_A        = 0x70B // 1803
+	SYS___A64L_A                        = 0x70C // 1804
+	SYS___ECVT_A                        = 0x70D // 1805
+	SYS___FCVT_A                        = 0x70E // 1806
+	SYS___GCVT_A                        = 0x70F // 1807
+	SYS___L64A_A                        = 0x710 // 1808
+	SYS___STRERROR_A                    = 0x711 // 1809
+	SYS___PERROR_A                      = 0x712 // 1810
+	SYS___FETCH_A                       = 0x713 // 1811
+	SYS___GETENV_A                      = 0x714 // 1812
+	SYS___MKSTEMP_A                     = 0x717 // 1815
+	SYS___PTSNAME_A                     = 0x718 // 1816
+	SYS___PUTENV_A                      = 0x719 // 1817
+	SYS___REALPATH_A                    = 0x71A // 1818
+	SYS___SETENV_A                      = 0x71B // 1819
+	SYS___SYSTEM_A                      = 0x71C // 1820
+	SYS___GETOPT_A                      = 0x71D // 1821
+	SYS___CATOPEN_A                     = 0x71E // 1822
+	SYS___ACCESS_A                      = 0x71F // 1823
+	SYS___CHDIR_A                       = 0x720 // 1824
+	SYS___CHOWN_A                       = 0x721 // 1825
+	SYS___CHROOT_A                      = 0x722 // 1826
+	SYS___GETCWD_A                      = 0x723 // 1827
+	SYS___GETWD_A                       = 0x724 // 1828
+	SYS___LCHOWN_A                      = 0x725 // 1829
+	SYS___LINK_A                        = 0x726 // 1830
+	SYS___PATHCONF_A                    = 0x727 // 1831
+	SYS___IF_NAMEINDEX_A                = 0x728 // 1832
+	SYS___READLINK_A                    = 0x729 // 1833
+	SYS___RMDIR_A                       = 0x72A // 1834
+	SYS___STATVFS_A                     = 0x72B // 1835
+	SYS___SYMLINK_A                     = 0x72C // 1836
+	SYS___TRUNCATE_A                    = 0x72D // 1837
+	SYS___UNLINK_A                      = 0x72E // 1838
+	SYS___GAI_STRERROR_A                = 0x72F // 1839
+	SYS___EXTLINK_NP_A                  = 0x730 // 1840
+	SYS___ISALNUM_A                     = 0x731 // 1841
+	SYS___ISALPHA_A                     = 0x732 // 1842
+	SYS___A2E_S                         = 0x733 // 1843
+	SYS___ISCNTRL_A                     = 0x734 // 1844
+	SYS___ISDIGIT_A                     = 0x735 // 1845
+	SYS___ISGRAPH_A                     = 0x736 // 1846
+	SYS___ISLOWER_A                     = 0x737 // 1847
+	SYS___ISPRINT_A                     = 0x738 // 1848
+	SYS___ISPUNCT_A                     = 0x739 // 1849
+	SYS___ISSPACE_A                     = 0x73A // 1850
+	SYS___ISUPPER_A                     = 0x73B // 1851
+	SYS___ISXDIGIT_A                    = 0x73C // 1852
+	SYS___TOLOWER_A                     = 0x73D // 1853
+	SYS___TOUPPER_A                     = 0x73E // 1854
+	SYS___ISWALNUM_A                    = 0x73F // 1855
+	SYS___ISWALPHA_A                    = 0x740 // 1856
+	SYS___A2E_L                         = 0x741 // 1857
+	SYS___ISWCNTRL_A                    = 0x742 // 1858
+	SYS___ISWDIGIT_A                    = 0x743 // 1859
+	SYS___ISWGRAPH_A                    = 0x744 // 1860
+	SYS___ISWLOWER_A                    = 0x745 // 1861
+	SYS___ISWPRINT_A                    = 0x746 // 1862
+	SYS___ISWPUNCT_A                    = 0x747 // 1863
+	SYS___ISWSPACE_A                    = 0x748 // 1864
+	SYS___ISWUPPER_A                    = 0x749 // 1865
+	SYS___ISWXDIGIT_A                   = 0x74A // 1866
+	SYS___CONFSTR_A                     = 0x74B // 1867
+	SYS___FTOK_A                        = 0x74C // 1868
+	SYS___MKTEMP_A                      = 0x74D // 1869
+	SYS___FDOPEN_A                      = 0x74E // 1870
+	SYS___FLDATA_A                      = 0x74F // 1871
+	SYS___REMOVE_A                      = 0x750 // 1872
+	SYS___RENAME_A                      = 0x751 // 1873
+	SYS___TMPNAM_A                      = 0x752 // 1874
+	SYS___FOPEN_A                       = 0x753 // 1875
+	SYS___FREOPEN_A                     = 0x754 // 1876
+	SYS___CUSERID_A                     = 0x755 // 1877
+	SYS___POPEN_A                       = 0x756 // 1878
+	SYS___TEMPNAM_A                     = 0x757 // 1879
+	SYS___FTW_A                         = 0x758 // 1880
+	SYS___GETGRENT_A                    = 0x759 // 1881
+	SYS___GETGRGID_A                    = 0x75A // 1882
+	SYS___GETGRNAM_A                    = 0x75B // 1883
+	SYS___GETGROUPSBYNAME_A             = 0x75C // 1884
+	SYS___GETHOSTENT_A                  = 0x75D // 1885
+	SYS___GETHOSTNAME_A                 = 0x75E // 1886
+	SYS___GETLOGIN_A                    = 0x75F // 1887
+	SYS___INET_NTOP_A                   = 0x760 // 1888
+	SYS___GETPASS_A                     = 0x761 // 1889
+	SYS___GETPWENT_A                    = 0x762 // 1890
+	SYS___GETPWNAM_A                    = 0x763 // 1891
+	SYS___GETPWUID_A                    = 0x764 // 1892
+	SYS_____CHECK_RESOURCE_AUTH_NP_A    = 0x765 // 1893
+	SYS___CHECKSCHENV_A                 = 0x766 // 1894
+	SYS___CONNECTSERVER_A               = 0x767 // 1895
+	SYS___CONNECTWORKMGR_A              = 0x768 // 1896
+	SYS_____CONSOLE_A                   = 0x769 // 1897
+	SYS___CREATEWORKUNIT_A              = 0x76A // 1898
+	SYS___CTERMID_A                     = 0x76B // 1899
+	SYS___FMTMSG_A                      = 0x76C // 1900
+	SYS___INITGROUPS_A                  = 0x76D // 1901
+	SYS_____LOGIN_A                     = 0x76E // 1902
+	SYS___MSGRCV_A                      = 0x76F // 1903
+	SYS___MSGSND_A                      = 0x770 // 1904
+	SYS___MSGXRCV_A                     = 0x771 // 1905
+	SYS___NFTW_A                        = 0x772 // 1906
+	SYS_____PASSWD_A                    = 0x773 // 1907
+	SYS___PTHREAD_SECURITY_NP_A         = 0x774 // 1908
+	SYS___QUERYMETRICS_A                = 0x775 // 1909
+	SYS___QUERYSCHENV                   = 0x776 // 1910
+	SYS___READV_A                       = 0x777 // 1911
+	SYS_____SERVER_CLASSIFY_A           = 0x778 // 1912
+	SYS_____SERVER_INIT_A               = 0x779 // 1913
+	SYS_____SERVER_PWU_A                = 0x77A // 1914
+	SYS___STRCASECMP_A                  = 0x77B // 1915
+	SYS___STRNCASECMP_A                 = 0x77C // 1916
+	SYS___TTYNAME_A                     = 0x77D // 1917
+	SYS___UNAME_A                       = 0x77E // 1918
+	SYS___UTIMES_A                      = 0x77F // 1919
+	SYS___W_GETPSENT_A                  = 0x780 // 1920
+	SYS___WRITEV_A                      = 0x781 // 1921
+	SYS___W_STATFS_A                    = 0x782 // 1922
+	SYS___W_STATVFS_A                   = 0x783 // 1923
+	SYS___FPUTC_A                       = 0x784 // 1924
+	SYS___PUTCHAR_A                     = 0x785 // 1925
+	SYS___PUTS_A                        = 0x786 // 1926
+	SYS___FGETS_A                       = 0x787 // 1927
+	SYS___GETS_A                        = 0x788 // 1928
+	SYS___FPUTS_A                       = 0x789 // 1929
+	SYS___FREAD_A                       = 0x78A // 1930
+	SYS___FWRITE_A                      = 0x78B // 1931
+	SYS___OPEN_O_A                      = 0x78C // 1932
+	SYS___ISASCII                       = 0x78D // 1933
+	SYS___CREAT_O_A                     = 0x78E // 1934
+	SYS___ENVNA                         = 0x78F // 1935
+	SYS___PUTC_A                        = 0x790 // 1936
+	SYS___AE_THREAD_SETMODE             = 0x791 // 1937
+	SYS___AE_THREAD_SWAPMODE            = 0x792 // 1938
+	SYS___GETNETBYADDR_A                = 0x793 // 1939
+	SYS___GETNETBYNAME_A                = 0x794 // 1940
+	SYS___GETNETENT_A                   = 0x795 // 1941
+	SYS___GETPROTOBYNAME_A              = 0x796 // 1942
+	SYS___GETPROTOBYNUMBER_A            = 0x797 // 1943
+	SYS___GETPROTOENT_A                 = 0x798 // 1944
+	SYS___GETSERVBYNAME_A               = 0x799 // 1945
+	SYS___GETSERVBYPORT_A               = 0x79A // 1946
+	SYS___GETSERVENT_A                  = 0x79B // 1947
+	SYS___ASCTIME_A                     = 0x79C // 1948
+	SYS___CTIME_A                       = 0x79D // 1949
+	SYS___GETDATE_A                     = 0x79E // 1950
+	SYS___TZSET_A                       = 0x79F // 1951
+	SYS___UTIME_A                       = 0x7A0 // 1952
+	SYS___ASCTIME_R_A                   = 0x7A1 // 1953
+	SYS___CTIME_R_A                     = 0x7A2 // 1954
+	SYS___STRTOLL_A                     = 0x7A3 // 1955
+	SYS___STRTOULL_A                    = 0x7A4 // 1956
+	SYS___FPUTWC_A                      = 0x7A5 // 1957
+	SYS___PUTWC_A                       = 0x7A6 // 1958
+	SYS___PUTWCHAR_A                    = 0x7A7 // 1959
+	SYS___FPUTWS_A                      = 0x7A8 // 1960
+	SYS___UNGETWC_A                     = 0x7A9 // 1961
+	SYS___FGETWC_A                      = 0x7AA // 1962
+	SYS___GETWC_A                       = 0x7AB // 1963
+	SYS___GETWCHAR_A                    = 0x7AC // 1964
+	SYS___FGETWS_A                      = 0x7AD // 1965
+	SYS___GETTIMEOFDAY_A                = 0x7AE // 1966
+	SYS___GMTIME_A                      = 0x7AF // 1967
+	SYS___GMTIME_R_A                    = 0x7B0 // 1968
+	SYS___LOCALTIME_A                   = 0x7B1 // 1969
+	SYS___LOCALTIME_R_A                 = 0x7B2 // 1970
+	SYS___MKTIME_A                      = 0x7B3 // 1971
+	SYS___TZZNA                         = 0x7B4 // 1972
+	SYS_UNATEXIT                        = 0x7B5 // 1973
+	SYS___CEE3DMP_A                     = 0x7B6 // 1974
+	SYS___CDUMP_A                       = 0x7B7 // 1975
+	SYS___CSNAP_A                       = 0x7B8 // 1976
+	SYS___CTEST_A                       = 0x7B9 // 1977
+	SYS___CTRACE_A                      = 0x7BA // 1978
+	SYS___VSWPRNTF2_A                   = 0x7BB // 1979
+	SYS___INET_PTON_A                   = 0x7BC // 1980
+	SYS___SYSLOG_A                      = 0x7BD // 1981
+	SYS___CRYPT_A                       = 0x7BE // 1982
+	SYS_____OPENDIR2_A                  = 0x7BF // 1983
+	SYS_____READDIR2_A                  = 0x7C0 // 1984
+	SYS___OPENDIR_A                     = 0x7C2 // 1986
+	SYS___READDIR_A                     = 0x7C3 // 1987
+	SYS_PREAD                           = 0x7C7 // 1991
+	SYS_PWRITE                          = 0x7C8 // 1992
+	SYS_M_CREATE_LAYOUT                 = 0x7C9 // 1993
+	SYS_M_DESTROY_LAYOUT                = 0x7CA // 1994
+	SYS_M_GETVALUES_LAYOUT              = 0x7CB // 1995
+	SYS_M_SETVALUES_LAYOUT              = 0x7CC // 1996
+	SYS_M_TRANSFORM_LAYOUT              = 0x7CD // 1997
+	SYS_M_WTRANSFORM_LAYOUT             = 0x7CE // 1998
+	SYS_FWPRINTF                        = 0x7D1 // 2001
+	SYS_WPRINTF                         = 0x7D2 // 2002
+	SYS_VFWPRINT                        = 0x7D3 // 2003
+	SYS_VFWPRINTF                       = 0x7D3 // 2003
+	SYS_VWPRINTF                        = 0x7D4 // 2004
+	SYS_FWSCANF                         = 0x7D5 // 2005
+	SYS_WSCANF                          = 0x7D6 // 2006
+	SYS_WCTRANS                         = 0x7D7 // 2007
+	SYS_TOWCTRAN                        = 0x7D8 // 2008
+	SYS_TOWCTRANS                       = 0x7D8 // 2008
+	SYS___WCSTOD_A                      = 0x7D9 // 2009
+	SYS___WCSTOL_A                      = 0x7DA // 2010
+	SYS___WCSTOUL_A                     = 0x7DB // 2011
+	SYS___BASENAME_A                    = 0x7DC // 2012
+	SYS___DIRNAME_A                     = 0x7DD // 2013
+	SYS___GLOB_A                        = 0x7DE // 2014
+	SYS_FWIDE                           = 0x7DF // 2015
+	SYS___OSNAME                        = 0x7E0 // 2016
+	SYS_____OSNAME_A                    = 0x7E1 // 2017
+	SYS___BTOWC_A                       = 0x7E4 // 2020
+	SYS___WCTOB_A                       = 0x7E5 // 2021
+	SYS___DBM_OPEN_A                    = 0x7E6 // 2022
+	SYS___VFPRINTF2_A                   = 0x7E7 // 2023
+	SYS___VPRINTF2_A                    = 0x7E8 // 2024
+	SYS___VSPRINTF2_A                   = 0x7E9 // 2025
+	SYS___CEIL_H                        = 0x7EA // 2026
+	SYS___FLOOR_H                       = 0x7EB // 2027
+	SYS___MODF_H                        = 0x7EC // 2028
+	SYS___FABS_H                        = 0x7ED // 2029
+	SYS___J0_H                          = 0x7EE // 2030
+	SYS___J1_H                          = 0x7EF // 2031
+	SYS___JN_H                          = 0x7F0 // 2032
+	SYS___Y0_H                          = 0x7F1 // 2033
+	SYS___Y1_H                          = 0x7F2 // 2034
+	SYS___YN_H                          = 0x7F3 // 2035
+	SYS___CEILF_H                       = 0x7F4 // 2036
+	SYS___CEILL_H                       = 0x7F5 // 2037
+	SYS___FLOORF_H                      = 0x7F6 // 2038
+	SYS___FLOORL_H                      = 0x7F7 // 2039
+	SYS___MODFF_H                       = 0x7F8 // 2040
+	SYS___MODFL_H                       = 0x7F9 // 2041
+	SYS___FABSF_H                       = 0x7FA // 2042
+	SYS___FABSL_H                       = 0x7FB // 2043
+	SYS___MALLOC24                      = 0x7FC // 2044
+	SYS___MALLOC31                      = 0x7FD // 2045
+	SYS_ACL_INIT                        = 0x7FE // 2046
+	SYS_ACL_FREE                        = 0x7FF // 2047
+	SYS_ACL_FIRST_ENTRY                 = 0x800 // 2048
+	SYS_ACL_GET_ENTRY                   = 0x801 // 2049
+	SYS_ACL_VALID                       = 0x802 // 2050
+	SYS_ACL_CREATE_ENTRY                = 0x803 // 2051
+	SYS_ACL_DELETE_ENTRY                = 0x804 // 2052
+	SYS_ACL_UPDATE_ENTRY                = 0x805 // 2053
+	SYS_ACL_DELETE_FD                   = 0x806 // 2054
+	SYS_ACL_DELETE_FILE                 = 0x807 // 2055
+	SYS_ACL_GET_FD                      = 0x808 // 2056
+	SYS_ACL_GET_FILE                    = 0x809 // 2057
+	SYS_ACL_SET_FD                      = 0x80A // 2058
+	SYS_ACL_SET_FILE                    = 0x80B // 2059
+	SYS_ACL_FROM_TEXT                   = 0x80C // 2060
+	SYS_ACL_TO_TEXT                     = 0x80D // 2061
+	SYS_ACL_SORT                        = 0x80E // 2062
+	SYS___SHUTDOWN_REGISTRATION         = 0x80F // 2063
+	SYS___ERFL_B                        = 0x810 // 2064
+	SYS___ERFCL_B                       = 0x811 // 2065
+	SYS___LGAMMAL_B                     = 0x812 // 2066
+	SYS___SETHOOKEVENTS                 = 0x813 // 2067
+	SYS_IF_NAMETOINDEX                  = 0x814 // 2068
+	SYS_IF_INDEXTONAME                  = 0x815 // 2069
+	SYS_IF_NAMEINDEX                    = 0x816 // 2070
+	SYS_IF_FREENAMEINDEX                = 0x817 // 2071
+	SYS_GETADDRINFO                     = 0x818 // 2072
+	SYS_GETNAMEINFO                     = 0x819 // 2073
+	SYS_FREEADDRINFO                    = 0x81A // 2074
+	SYS_GAI_STRERROR                    = 0x81B // 2075
+	SYS_REXEC_AF                        = 0x81C // 2076
+	SYS___POE                           = 0x81D // 2077
+	SYS___DYNALLOC_A                    = 0x81F // 2079
+	SYS___DYNFREE_A                     = 0x820 // 2080
+	SYS___RES_QUERY_A                   = 0x821 // 2081
+	SYS___RES_SEARCH_A                  = 0x822 // 2082
+	SYS___RES_QUERYDOMAIN_A             = 0x823 // 2083
+	SYS___RES_MKQUERY_A                 = 0x824 // 2084
+	SYS___RES_SEND_A                    = 0x825 // 2085
+	SYS___DN_EXPAND_A                   = 0x826 // 2086
+	SYS___DN_SKIPNAME_A                 = 0x827 // 2087
+	SYS___DN_COMP_A                     = 0x828 // 2088
+	SYS___DN_FIND_A                     = 0x829 // 2089
+	SYS___NLIST_A                       = 0x82A // 2090
+	SYS_____TCGETCP_A                   = 0x82B // 2091
+	SYS_____TCSETCP_A                   = 0x82C // 2092
+	SYS_____W_PIOCTL_A                  = 0x82E // 2094
+	SYS___INET_ADDR_A                   = 0x82F // 2095
+	SYS___INET_NTOA_A                   = 0x830 // 2096
+	SYS___INET_NETWORK_A                = 0x831 // 2097
+	SYS___ACCEPT_A                      = 0x832 // 2098
+	SYS___ACCEPT_AND_RECV_A             = 0x833 // 2099
+	SYS___BIND_A                        = 0x834 // 2100
+	SYS___CONNECT_A                     = 0x835 // 2101
+	SYS___GETPEERNAME_A                 = 0x836 // 2102
+	SYS___GETSOCKNAME_A                 = 0x837 // 2103
+	SYS___RECVFROM_A                    = 0x838 // 2104
+	SYS___SENDTO_A                      = 0x839 // 2105
+	SYS___SENDMSG_A                     = 0x83A // 2106
+	SYS___RECVMSG_A                     = 0x83B // 2107
+	SYS_____LCHATTR_A                   = 0x83C // 2108
+	SYS___CABEND                        = 0x83D // 2109
+	SYS___LE_CIB_GET                    = 0x83E // 2110
+	SYS___SET_LAA_FOR_JIT               = 0x83F // 2111
+	SYS___LCHATTR                       = 0x840 // 2112
+	SYS___WRITEDOWN                     = 0x841 // 2113
+	SYS_PTHREAD_MUTEX_INIT2             = 0x842 // 2114
+	SYS___ACOSHF_B                      = 0x843 // 2115
+	SYS___ACOSHL_B                      = 0x844 // 2116
+	SYS___ASINHF_B                      = 0x845 // 2117
+	SYS___ASINHL_B                      = 0x846 // 2118
+	SYS___ATANHF_B                      = 0x847 // 2119
+	SYS___ATANHL_B                      = 0x848 // 2120
+	SYS___CBRTF_B                       = 0x849 // 2121
+	SYS___CBRTL_B                       = 0x84A // 2122
+	SYS___COPYSIGNF_B                   = 0x84B // 2123
+	SYS___COPYSIGNL_B                   = 0x84C // 2124
+	SYS___COTANF_B                      = 0x84D // 2125
+	SYS___COTAN_B                       = 0x84E // 2126
+	SYS___COTANL_B                      = 0x84F // 2127
+	SYS___EXP2F_B                       = 0x850 // 2128
+	SYS___EXP2L_B                       = 0x851 // 2129
+	SYS___EXPM1F_B                      = 0x852 // 2130
+	SYS___EXPM1L_B                      = 0x853 // 2131
+	SYS___FDIMF_B                       = 0x854 // 2132
+	SYS___FDIM_B                        = 0x855 // 2133
+	SYS___FDIML_B                       = 0x856 // 2134
+	SYS___HYPOTF_B                      = 0x857 // 2135
+	SYS___HYPOTL_B                      = 0x858 // 2136
+	SYS___LOG1PF_B                      = 0x859 // 2137
+	SYS___LOG1PL_B                      = 0x85A // 2138
+	SYS___LOG2F_B                       = 0x85B // 2139
+	SYS___LOG2_B                        = 0x85C // 2140
+	SYS___LOG2L_B                       = 0x85D // 2141
+	SYS___REMAINDERF_B                  = 0x85E // 2142
+	SYS___REMAINDERL_B                  = 0x85F // 2143
+	SYS___REMQUOF_B                     = 0x860 // 2144
+	SYS___REMQUO_B                      = 0x861 // 2145
+	SYS___REMQUOL_B                     = 0x862 // 2146
+	SYS___TGAMMAF_B                     = 0x863 // 2147
+	SYS___TGAMMA_B                      = 0x864 // 2148
+	SYS___TGAMMAL_B                     = 0x865 // 2149
+	SYS___TRUNCF_B                      = 0x866 // 2150
+	SYS___TRUNC_B                       = 0x867 // 2151
+	SYS___TRUNCL_B                      = 0x868 // 2152
+	SYS___LGAMMAF_B                     = 0x869 // 2153
+	SYS___LROUNDF_B                     = 0x86A // 2154
+	SYS___LROUND_B                      = 0x86B // 2155
+	SYS___ERFF_B                        = 0x86C // 2156
+	SYS___ERFCF_B                       = 0x86D // 2157
+	SYS_ACOSHF                          = 0x86E // 2158
+	SYS_ACOSHL                          = 0x86F // 2159
+	SYS_ASINHF                          = 0x870 // 2160
+	SYS_ASINHL                          = 0x871 // 2161
+	SYS_ATANHF                          = 0x872 // 2162
+	SYS_ATANHL                          = 0x873 // 2163
+	SYS_CBRTF                           = 0x874 // 2164
+	SYS_CBRTL                           = 0x875 // 2165
+	SYS_COPYSIGNF                       = 0x876 // 2166
+	SYS_CPYSIGNF                        = 0x876 // 2166
+	SYS_COPYSIGNL                       = 0x877 // 2167
+	SYS_CPYSIGNL                        = 0x877 // 2167
+	SYS_COTANF                          = 0x878 // 2168
+	SYS___COTANF                        = 0x878 // 2168
+	SYS_COTAN                           = 0x879 // 2169
+	SYS___COTAN                         = 0x879 // 2169
+	SYS_COTANL                          = 0x87A // 2170
+	SYS___COTANL                        = 0x87A // 2170
+	SYS_EXP2F                           = 0x87B // 2171
+	SYS_EXP2L                           = 0x87C // 2172
+	SYS_EXPM1F                          = 0x87D // 2173
+	SYS_EXPM1L                          = 0x87E // 2174
+	SYS_FDIMF                           = 0x87F // 2175
+	SYS_FDIM                            = 0x881 // 2177
+	SYS_FDIML                           = 0x882 // 2178
+	SYS_HYPOTF                          = 0x883 // 2179
+	SYS_HYPOTL                          = 0x884 // 2180
+	SYS_LOG1PF                          = 0x885 // 2181
+	SYS_LOG1PL                          = 0x886 // 2182
+	SYS_LOG2F                           = 0x887 // 2183
+	SYS_LOG2                            = 0x888 // 2184
+	SYS_LOG2L                           = 0x889 // 2185
+	SYS_REMAINDERF                      = 0x88A // 2186
+	SYS_REMAINDF                        = 0x88A // 2186
+	SYS_REMAINDERL                      = 0x88B // 2187
+	SYS_REMAINDL                        = 0x88B // 2187
+	SYS_REMQUOF                         = 0x88C // 2188
+	SYS_REMQUO                          = 0x88D // 2189
+	SYS_REMQUOL                         = 0x88E // 2190
+	SYS_TGAMMAF                         = 0x88F // 2191
+	SYS_TGAMMA                          = 0x890 // 2192
+	SYS_TGAMMAL                         = 0x891 // 2193
+	SYS_TRUNCF                          = 0x892 // 2194
+	SYS_TRUNC                           = 0x893 // 2195
+	SYS_TRUNCL                          = 0x894 // 2196
+	SYS_LGAMMAF                         = 0x895 // 2197
+	SYS_LGAMMAL                         = 0x896 // 2198
+	SYS_LROUNDF                         = 0x897 // 2199
+	SYS_LROUND                          = 0x898 // 2200
+	SYS_ERFF                            = 0x899 // 2201
+	SYS_ERFL                            = 0x89A // 2202
+	SYS_ERFCF                           = 0x89B // 2203
+	SYS_ERFCL                           = 0x89C // 2204
+	SYS___EXP2_B                        = 0x89D // 2205
+	SYS_EXP2                            = 0x89E // 2206
+	SYS___FAR_JUMP                      = 0x89F // 2207
+	SYS___TCGETATTR_A                   = 0x8A1 // 2209
+	SYS___TCSETATTR_A                   = 0x8A2 // 2210
+	SYS___SUPERKILL                     = 0x8A4 // 2212
+	SYS___LE_CONDITION_TOKEN_BUILD      = 0x8A5 // 2213
+	SYS___LE_MSG_ADD_INSERT             = 0x8A6 // 2214
+	SYS___LE_MSG_GET                    = 0x8A7 // 2215
+	SYS___LE_MSG_GET_AND_WRITE          = 0x8A8 // 2216
+	SYS___LE_MSG_WRITE                  = 0x8A9 // 2217
+	SYS___ITOA                          = 0x8AA // 2218
+	SYS___UTOA                          = 0x8AB // 2219
+	SYS___LTOA                          = 0x8AC // 2220
+	SYS___ULTOA                         = 0x8AD // 2221
+	SYS___LLTOA                         = 0x8AE // 2222
+	SYS___ULLTOA                        = 0x8AF // 2223
+	SYS___ITOA_A                        = 0x8B0 // 2224
+	SYS___UTOA_A                        = 0x8B1 // 2225
+	SYS___LTOA_A                        = 0x8B2 // 2226
+	SYS___ULTOA_A                       = 0x8B3 // 2227
+	SYS___LLTOA_A                       = 0x8B4 // 2228
+	SYS___ULLTOA_A                      = 0x8B5 // 2229
+	SYS_____GETENV_A                    = 0x8C3 // 2243
+	SYS___REXEC_A                       = 0x8C4 // 2244
+	SYS___REXEC_AF_A                    = 0x8C5 // 2245
+	SYS___GETUTXENT_A                   = 0x8C6 // 2246
+	SYS___GETUTXID_A                    = 0x8C7 // 2247
+	SYS___GETUTXLINE_A                  = 0x8C8 // 2248
+	SYS___PUTUTXLINE_A                  = 0x8C9 // 2249
+	SYS_____UTMPXNAME_A                 = 0x8CA // 2250
+	SYS___PUTC_UNLOCKED_A               = 0x8CB // 2251
+	SYS___PUTCHAR_UNLOCKED_A            = 0x8CC // 2252
+	SYS___SNPRINTF_A                    = 0x8CD // 2253
+	SYS___VSNPRINTF_A                   = 0x8CE // 2254
+	SYS___DLOPEN_A                      = 0x8D0 // 2256
+	SYS___DLSYM_A                       = 0x8D1 // 2257
+	SYS___DLERROR_A                     = 0x8D2 // 2258
+	SYS_FLOCKFILE                       = 0x8D3 // 2259
+	SYS_FTRYLOCKFILE                    = 0x8D4 // 2260
+	SYS_FUNLOCKFILE                     = 0x8D5 // 2261
+	SYS_GETC_UNLOCKED                   = 0x8D6 // 2262
+	SYS_GETCHAR_UNLOCKED                = 0x8D7 // 2263
+	SYS_PUTC_UNLOCKED                   = 0x8D8 // 2264
+	SYS_PUTCHAR_UNLOCKED                = 0x8D9 // 2265
+	SYS_SNPRINTF                        = 0x8DA // 2266
+	SYS_VSNPRINTF                       = 0x8DB // 2267
+	SYS_DLOPEN                          = 0x8DD // 2269
+	SYS_DLSYM                           = 0x8DE // 2270
+	SYS_DLCLOSE                         = 0x8DF // 2271
+	SYS_DLERROR                         = 0x8E0 // 2272
+	SYS___SET_EXCEPTION_HANDLER         = 0x8E2 // 2274
+	SYS___RESET_EXCEPTION_HANDLER       = 0x8E3 // 2275
+	SYS___VHM_EVENT                     = 0x8E4 // 2276
+	SYS___ABS_H                         = 0x8E6 // 2278
+	SYS___ABSF_H                        = 0x8E7 // 2279
+	SYS___ABSL_H                        = 0x8E8 // 2280
+	SYS___ACOS_H                        = 0x8E9 // 2281
+	SYS___ACOSF_H                       = 0x8EA // 2282
+	SYS___ACOSL_H                       = 0x8EB // 2283
+	SYS___ACOSH_H                       = 0x8EC // 2284
+	SYS___ASIN_H                        = 0x8ED // 2285
+	SYS___ASINF_H                       = 0x8EE // 2286
+	SYS___ASINL_H                       = 0x8EF // 2287
+	SYS___ASINH_H                       = 0x8F0 // 2288
+	SYS___ATAN_H                        = 0x8F1 // 2289
+	SYS___ATANF_H                       = 0x8F2 // 2290
+	SYS___ATANL_H                       = 0x8F3 // 2291
+	SYS___ATANH_H                       = 0x8F4 // 2292
+	SYS___ATANHF_H                      = 0x8F5 // 2293
+	SYS___ATANHL_H                      = 0x8F6 // 2294
+	SYS___ATAN2_H                       = 0x8F7 // 2295
+	SYS___ATAN2F_H                      = 0x8F8 // 2296
+	SYS___ATAN2L_H                      = 0x8F9 // 2297
+	SYS___CBRT_H                        = 0x8FA // 2298
+	SYS___COPYSIGNF_H                   = 0x8FB // 2299
+	SYS___COPYSIGNL_H                   = 0x8FC // 2300
+	SYS___COS_H                         = 0x8FD // 2301
+	SYS___COSF_H                        = 0x8FE // 2302
+	SYS___COSL_H                        = 0x8FF // 2303
+	SYS___COSHF_H                       = 0x900 // 2304
+	SYS___COSHL_H                       = 0x901 // 2305
+	SYS___COTAN_H                       = 0x902 // 2306
+	SYS___COTANF_H                      = 0x903 // 2307
+	SYS___COTANL_H                      = 0x904 // 2308
+	SYS___ERF_H                         = 0x905 // 2309
+	SYS___ERFF_H                        = 0x906 // 2310
+	SYS___ERFL_H                        = 0x907 // 2311
+	SYS___ERFC_H                        = 0x908 // 2312
+	SYS___ERFCF_H                       = 0x909 // 2313
+	SYS___ERFCL_H                       = 0x90A // 2314
+	SYS___EXP_H                         = 0x90B // 2315
+	SYS___EXPF_H                        = 0x90C // 2316
+	SYS___EXPL_H                        = 0x90D // 2317
+	SYS___EXPM1_H                       = 0x90E // 2318
+	SYS___FDIM_H                        = 0x90F // 2319
+	SYS___FDIMF_H                       = 0x910 // 2320
+	SYS___FDIML_H                       = 0x911 // 2321
+	SYS___FMOD_H                        = 0x912 // 2322
+	SYS___FMODF_H                       = 0x913 // 2323
+	SYS___FMODL_H                       = 0x914 // 2324
+	SYS___GAMMA_H                       = 0x915 // 2325
+	SYS___HYPOT_H                       = 0x916 // 2326
+	SYS___ILOGB_H                       = 0x917 // 2327
+	SYS___LGAMMA_H                      = 0x918 // 2328
+	SYS___LGAMMAF_H                     = 0x919 // 2329
+	SYS___LOG_H                         = 0x91A // 2330
+	SYS___LOGF_H                        = 0x91B // 2331
+	SYS___LOGL_H                        = 0x91C // 2332
+	SYS___LOGB_H                        = 0x91D // 2333
+	SYS___LOG2_H                        = 0x91E // 2334
+	SYS___LOG2F_H                       = 0x91F // 2335
+	SYS___LOG2L_H                       = 0x920 // 2336
+	SYS___LOG1P_H                       = 0x921 // 2337
+	SYS___LOG10_H                       = 0x922 // 2338
+	SYS___LOG10F_H                      = 0x923 // 2339
+	SYS___LOG10L_H                      = 0x924 // 2340
+	SYS___LROUND_H                      = 0x925 // 2341
+	SYS___LROUNDF_H                     = 0x926 // 2342
+	SYS___NEXTAFTER_H                   = 0x927 // 2343
+	SYS___POW_H                         = 0x928 // 2344
+	SYS___POWF_H                        = 0x929 // 2345
+	SYS___POWL_H                        = 0x92A // 2346
+	SYS___REMAINDER_H                   = 0x92B // 2347
+	SYS___RINT_H                        = 0x92C // 2348
+	SYS___SCALB_H                       = 0x92D // 2349
+	SYS___SIN_H                         = 0x92E // 2350
+	SYS___SINF_H                        = 0x92F // 2351
+	SYS___SINL_H                        = 0x930 // 2352
+	SYS___SINH_H                        = 0x931 // 2353
+	SYS___SINHF_H                       = 0x932 // 2354
+	SYS___SINHL_H                       = 0x933 // 2355
+	SYS___SQRT_H                        = 0x934 // 2356
+	SYS___SQRTF_H                       = 0x935 // 2357
+	SYS___SQRTL_H                       = 0x936 // 2358
+	SYS___TAN_H                         = 0x937 // 2359
+	SYS___TANF_H                        = 0x938 // 2360
+	SYS___TANL_H                        = 0x939 // 2361
+	SYS___TANH_H                        = 0x93A // 2362
+	SYS___TANHF_H                       = 0x93B // 2363
+	SYS___TANHL_H                       = 0x93C // 2364
+	SYS___TGAMMA_H                      = 0x93D // 2365
+	SYS___TGAMMAF_H                     = 0x93E // 2366
+	SYS___TRUNC_H                       = 0x93F // 2367
+	SYS___TRUNCF_H                      = 0x940 // 2368
+	SYS___TRUNCL_H                      = 0x941 // 2369
+	SYS___COSH_H                        = 0x942 // 2370
+	SYS___LE_DEBUG_SET_RESUME_MCH       = 0x943 // 2371
+	SYS_VFSCANF                         = 0x944 // 2372
+	SYS_VSCANF                          = 0x946 // 2374
+	SYS_VSSCANF                         = 0x948 // 2376
+	SYS_VFWSCANF                        = 0x94A // 2378
+	SYS_VWSCANF                         = 0x94C // 2380
+	SYS_VSWSCANF                        = 0x94E // 2382
+	SYS_IMAXABS                         = 0x950 // 2384
+	SYS_IMAXDIV                         = 0x951 // 2385
+	SYS_STRTOIMAX                       = 0x952 // 2386
+	SYS_STRTOUMAX                       = 0x953 // 2387
+	SYS_WCSTOIMAX                       = 0x954 // 2388
+	SYS_WCSTOUMAX                       = 0x955 // 2389
+	SYS_ATOLL                           = 0x956 // 2390
+	SYS_STRTOF                          = 0x957 // 2391
+	SYS_STRTOLD                         = 0x958 // 2392
+	SYS_WCSTOF                          = 0x959 // 2393
+	SYS_WCSTOLD                         = 0x95A // 2394
+	SYS_INET6_RTH_SPACE                 = 0x95B // 2395
+	SYS_INET6_RTH_INIT                  = 0x95C // 2396
+	SYS_INET6_RTH_ADD                   = 0x95D // 2397
+	SYS_INET6_RTH_REVERSE               = 0x95E // 2398
+	SYS_INET6_RTH_SEGMENTS              = 0x95F // 2399
+	SYS_INET6_RTH_GETADDR               = 0x960 // 2400
+	SYS_INET6_OPT_INIT                  = 0x961 // 2401
+	SYS_INET6_OPT_APPEND                = 0x962 // 2402
+	SYS_INET6_OPT_FINISH                = 0x963 // 2403
+	SYS_INET6_OPT_SET_VAL               = 0x964 // 2404
+	SYS_INET6_OPT_NEXT                  = 0x965 // 2405
+	SYS_INET6_OPT_FIND                  = 0x966 // 2406
+	SYS_INET6_OPT_GET_VAL               = 0x967 // 2407
+	SYS___POW_I                         = 0x987 // 2439
+	SYS___POW_I_B                       = 0x988 // 2440
+	SYS___POW_I_H                       = 0x989 // 2441
+	SYS___POW_II                        = 0x98A // 2442
+	SYS___POW_II_B                      = 0x98B // 2443
+	SYS___POW_II_H                      = 0x98C // 2444
+	SYS_CABS                            = 0x98E // 2446
+	SYS___CABS_B                        = 0x98F // 2447
+	SYS___CABS_H                        = 0x990 // 2448
+	SYS_CABSF                           = 0x991 // 2449
+	SYS___CABSF_B                       = 0x992 // 2450
+	SYS___CABSF_H                       = 0x993 // 2451
+	SYS_CABSL                           = 0x994 // 2452
+	SYS___CABSL_B                       = 0x995 // 2453
+	SYS___CABSL_H                       = 0x996 // 2454
+	SYS_CACOS                           = 0x997 // 2455
+	SYS___CACOS_B                       = 0x998 // 2456
+	SYS___CACOS_H                       = 0x999 // 2457
+	SYS_CACOSF                          = 0x99A // 2458
+	SYS___CACOSF_B                      = 0x99B // 2459
+	SYS___CACOSF_H                      = 0x99C // 2460
+	SYS_CACOSL                          = 0x99D // 2461
+	SYS___CACOSL_B                      = 0x99E // 2462
+	SYS___CACOSL_H                      = 0x99F // 2463
+	SYS_CACOSH                          = 0x9A0 // 2464
+	SYS___CACOSH_B                      = 0x9A1 // 2465
+	SYS___CACOSH_H                      = 0x9A2 // 2466
+	SYS_CACOSHF                         = 0x9A3 // 2467
+	SYS___CACOSHF_B                     = 0x9A4 // 2468
+	SYS___CACOSHF_H                     = 0x9A5 // 2469
+	SYS_CACOSHL                         = 0x9A6 // 2470
+	SYS___CACOSHL_B                     = 0x9A7 // 2471
+	SYS___CACOSHL_H                     = 0x9A8 // 2472
+	SYS_CARG                            = 0x9A9 // 2473
+	SYS___CARG_B                        = 0x9AA // 2474
+	SYS___CARG_H                        = 0x9AB // 2475
+	SYS_CARGF                           = 0x9AC // 2476
+	SYS___CARGF_B                       = 0x9AD // 2477
+	SYS___CARGF_H                       = 0x9AE // 2478
+	SYS_CARGL                           = 0x9AF // 2479
+	SYS___CARGL_B                       = 0x9B0 // 2480
+	SYS___CARGL_H                       = 0x9B1 // 2481
+	SYS_CASIN                           = 0x9B2 // 2482
+	SYS___CASIN_B                       = 0x9B3 // 2483
+	SYS___CASIN_H                       = 0x9B4 // 2484
+	SYS_CASINF                          = 0x9B5 // 2485
+	SYS___CASINF_B                      = 0x9B6 // 2486
+	SYS___CASINF_H                      = 0x9B7 // 2487
+	SYS_CASINL                          = 0x9B8 // 2488
+	SYS___CASINL_B                      = 0x9B9 // 2489
+	SYS___CASINL_H                      = 0x9BA // 2490
+	SYS_CASINH                          = 0x9BB // 2491
+	SYS___CASINH_B                      = 0x9BC // 2492
+	SYS___CASINH_H                      = 0x9BD // 2493
+	SYS_CASINHF                         = 0x9BE // 2494
+	SYS___CASINHF_B                     = 0x9BF // 2495
+	SYS___CASINHF_H                     = 0x9C0 // 2496
+	SYS_CASINHL                         = 0x9C1 // 2497
+	SYS___CASINHL_B                     = 0x9C2 // 2498
+	SYS___CASINHL_H                     = 0x9C3 // 2499
+	SYS_CATAN                           = 0x9C4 // 2500
+	SYS___CATAN_B                       = 0x9C5 // 2501
+	SYS___CATAN_H                       = 0x9C6 // 2502
+	SYS_CATANF                          = 0x9C7 // 2503
+	SYS___CATANF_B                      = 0x9C8 // 2504
+	SYS___CATANF_H                      = 0x9C9 // 2505
+	SYS_CATANL                          = 0x9CA // 2506
+	SYS___CATANL_B                      = 0x9CB // 2507
+	SYS___CATANL_H                      = 0x9CC // 2508
+	SYS_CATANH                          = 0x9CD // 2509
+	SYS___CATANH_B                      = 0x9CE // 2510
+	SYS___CATANH_H                      = 0x9CF // 2511
+	SYS_CATANHF                         = 0x9D0 // 2512
+	SYS___CATANHF_B                     = 0x9D1 // 2513
+	SYS___CATANHF_H                     = 0x9D2 // 2514
+	SYS_CATANHL                         = 0x9D3 // 2515
+	SYS___CATANHL_B                     = 0x9D4 // 2516
+	SYS___CATANHL_H                     = 0x9D5 // 2517
+	SYS_CCOS                            = 0x9D6 // 2518
+	SYS___CCOS_B                        = 0x9D7 // 2519
+	SYS___CCOS_H                        = 0x9D8 // 2520
+	SYS_CCOSF                           = 0x9D9 // 2521
+	SYS___CCOSF_B                       = 0x9DA // 2522
+	SYS___CCOSF_H                       = 0x9DB // 2523
+	SYS_CCOSL                           = 0x9DC // 2524
+	SYS___CCOSL_B                       = 0x9DD // 2525
+	SYS___CCOSL_H                       = 0x9DE // 2526
+	SYS_CCOSH                           = 0x9DF // 2527
+	SYS___CCOSH_B                       = 0x9E0 // 2528
+	SYS___CCOSH_H                       = 0x9E1 // 2529
+	SYS_CCOSHF                          = 0x9E2 // 2530
+	SYS___CCOSHF_B                      = 0x9E3 // 2531
+	SYS___CCOSHF_H                      = 0x9E4 // 2532
+	SYS_CCOSHL                          = 0x9E5 // 2533
+	SYS___CCOSHL_B                      = 0x9E6 // 2534
+	SYS___CCOSHL_H                      = 0x9E7 // 2535
+	SYS_CEXP                            = 0x9E8 // 2536
+	SYS___CEXP_B                        = 0x9E9 // 2537
+	SYS___CEXP_H                        = 0x9EA // 2538
+	SYS_CEXPF                           = 0x9EB // 2539
+	SYS___CEXPF_B                       = 0x9EC // 2540
+	SYS___CEXPF_H                       = 0x9ED // 2541
+	SYS_CEXPL                           = 0x9EE // 2542
+	SYS___CEXPL_B                       = 0x9EF // 2543
+	SYS___CEXPL_H                       = 0x9F0 // 2544
+	SYS_CIMAG                           = 0x9F1 // 2545
+	SYS___CIMAG_B                       = 0x9F2 // 2546
+	SYS___CIMAG_H                       = 0x9F3 // 2547
+	SYS_CIMAGF                          = 0x9F4 // 2548
+	SYS___CIMAGF_B                      = 0x9F5 // 2549
+	SYS___CIMAGF_H                      = 0x9F6 // 2550
+	SYS_CIMAGL                          = 0x9F7 // 2551
+	SYS___CIMAGL_B                      = 0x9F8 // 2552
+	SYS___CIMAGL_H                      = 0x9F9 // 2553
+	SYS___CLOG                          = 0x9FA // 2554
+	SYS___CLOG_B                        = 0x9FB // 2555
+	SYS___CLOG_H                        = 0x9FC // 2556
+	SYS_CLOGF                           = 0x9FD // 2557
+	SYS___CLOGF_B                       = 0x9FE // 2558
+	SYS___CLOGF_H                       = 0x9FF // 2559
+	SYS_CLOGL                           = 0xA00 // 2560
+	SYS___CLOGL_B                       = 0xA01 // 2561
+	SYS___CLOGL_H                       = 0xA02 // 2562
+	SYS_CONJ                            = 0xA03 // 2563
+	SYS___CONJ_B                        = 0xA04 // 2564
+	SYS___CONJ_H                        = 0xA05 // 2565
+	SYS_CONJF                           = 0xA06 // 2566
+	SYS___CONJF_B                       = 0xA07 // 2567
+	SYS___CONJF_H                       = 0xA08 // 2568
+	SYS_CONJL                           = 0xA09 // 2569
+	SYS___CONJL_B                       = 0xA0A // 2570
+	SYS___CONJL_H                       = 0xA0B // 2571
+	SYS_CPOW                            = 0xA0C // 2572
+	SYS___CPOW_B                        = 0xA0D // 2573
+	SYS___CPOW_H                        = 0xA0E // 2574
+	SYS_CPOWF                           = 0xA0F // 2575
+	SYS___CPOWF_B                       = 0xA10 // 2576
+	SYS___CPOWF_H                       = 0xA11 // 2577
+	SYS_CPOWL                           = 0xA12 // 2578
+	SYS___CPOWL_B                       = 0xA13 // 2579
+	SYS___CPOWL_H                       = 0xA14 // 2580
+	SYS_CPROJ                           = 0xA15 // 2581
+	SYS___CPROJ_B                       = 0xA16 // 2582
+	SYS___CPROJ_H                       = 0xA17 // 2583
+	SYS_CPROJF                          = 0xA18 // 2584
+	SYS___CPROJF_B                      = 0xA19 // 2585
+	SYS___CPROJF_H                      = 0xA1A // 2586
+	SYS_CPROJL                          = 0xA1B // 2587
+	SYS___CPROJL_B                      = 0xA1C // 2588
+	SYS___CPROJL_H                      = 0xA1D // 2589
+	SYS_CREAL                           = 0xA1E // 2590
+	SYS___CREAL_B                       = 0xA1F // 2591
+	SYS___CREAL_H                       = 0xA20 // 2592
+	SYS_CREALF                          = 0xA21 // 2593
+	SYS___CREALF_B                      = 0xA22 // 2594
+	SYS___CREALF_H                      = 0xA23 // 2595
+	SYS_CREALL                          = 0xA24 // 2596
+	SYS___CREALL_B                      = 0xA25 // 2597
+	SYS___CREALL_H                      = 0xA26 // 2598
+	SYS_CSIN                            = 0xA27 // 2599
+	SYS___CSIN_B                        = 0xA28 // 2600
+	SYS___CSIN_H                        = 0xA29 // 2601
+	SYS_CSINF                           = 0xA2A // 2602
+	SYS___CSINF_B                       = 0xA2B // 2603
+	SYS___CSINF_H                       = 0xA2C // 2604
+	SYS_CSINL                           = 0xA2D // 2605
+	SYS___CSINL_B                       = 0xA2E // 2606
+	SYS___CSINL_H                       = 0xA2F // 2607
+	SYS_CSINH                           = 0xA30 // 2608
+	SYS___CSINH_B                       = 0xA31 // 2609
+	SYS___CSINH_H                       = 0xA32 // 2610
+	SYS_CSINHF                          = 0xA33 // 2611
+	SYS___CSINHF_B                      = 0xA34 // 2612
+	SYS___CSINHF_H                      = 0xA35 // 2613
+	SYS_CSINHL                          = 0xA36 // 2614
+	SYS___CSINHL_B                      = 0xA37 // 2615
+	SYS___CSINHL_H                      = 0xA38 // 2616
+	SYS_CSQRT                           = 0xA39 // 2617
+	SYS___CSQRT_B                       = 0xA3A // 2618
+	SYS___CSQRT_H                       = 0xA3B // 2619
+	SYS_CSQRTF                          = 0xA3C // 2620
+	SYS___CSQRTF_B                      = 0xA3D // 2621
+	SYS___CSQRTF_H                      = 0xA3E // 2622
+	SYS_CSQRTL                          = 0xA3F // 2623
+	SYS___CSQRTL_B                      = 0xA40 // 2624
+	SYS___CSQRTL_H                      = 0xA41 // 2625
+	SYS_CTAN                            = 0xA42 // 2626
+	SYS___CTAN_B                        = 0xA43 // 2627
+	SYS___CTAN_H                        = 0xA44 // 2628
+	SYS_CTANF                           = 0xA45 // 2629
+	SYS___CTANF_B                       = 0xA46 // 2630
+	SYS___CTANF_H                       = 0xA47 // 2631
+	SYS_CTANL                           = 0xA48 // 2632
+	SYS___CTANL_B                       = 0xA49 // 2633
+	SYS___CTANL_H                       = 0xA4A // 2634
+	SYS_CTANH                           = 0xA4B // 2635
+	SYS___CTANH_B                       = 0xA4C // 2636
+	SYS___CTANH_H                       = 0xA4D // 2637
+	SYS_CTANHF                          = 0xA4E // 2638
+	SYS___CTANHF_B                      = 0xA4F // 2639
+	SYS___CTANHF_H                      = 0xA50 // 2640
+	SYS_CTANHL                          = 0xA51 // 2641
+	SYS___CTANHL_B                      = 0xA52 // 2642
+	SYS___CTANHL_H                      = 0xA53 // 2643
+	SYS___ACOSHF_H                      = 0xA54 // 2644
+	SYS___ACOSHL_H                      = 0xA55 // 2645
+	SYS___ASINHF_H                      = 0xA56 // 2646
+	SYS___ASINHL_H                      = 0xA57 // 2647
+	SYS___CBRTF_H                       = 0xA58 // 2648
+	SYS___CBRTL_H                       = 0xA59 // 2649
+	SYS___COPYSIGN_B                    = 0xA5A // 2650
+	SYS___EXPM1F_H                      = 0xA5B // 2651
+	SYS___EXPM1L_H                      = 0xA5C // 2652
+	SYS___EXP2_H                        = 0xA5D // 2653
+	SYS___EXP2F_H                       = 0xA5E // 2654
+	SYS___EXP2L_H                       = 0xA5F // 2655
+	SYS___LOG1PF_H                      = 0xA60 // 2656
+	SYS___LOG1PL_H                      = 0xA61 // 2657
+	SYS___LGAMMAL_H                     = 0xA62 // 2658
+	SYS_FMA                             = 0xA63 // 2659
+	SYS___FMA_B                         = 0xA64 // 2660
+	SYS___FMA_H                         = 0xA65 // 2661
+	SYS_FMAF                            = 0xA66 // 2662
+	SYS___FMAF_B                        = 0xA67 // 2663
+	SYS___FMAF_H                        = 0xA68 // 2664
+	SYS_FMAL                            = 0xA69 // 2665
+	SYS___FMAL_B                        = 0xA6A // 2666
+	SYS___FMAL_H                        = 0xA6B // 2667
+	SYS_FMAX                            = 0xA6C // 2668
+	SYS___FMAX_B                        = 0xA6D // 2669
+	SYS___FMAX_H                        = 0xA6E // 2670
+	SYS_FMAXF                           = 0xA6F // 2671
+	SYS___FMAXF_B                       = 0xA70 // 2672
+	SYS___FMAXF_H                       = 0xA71 // 2673
+	SYS_FMAXL                           = 0xA72 // 2674
+	SYS___FMAXL_B                       = 0xA73 // 2675
+	SYS___FMAXL_H                       = 0xA74 // 2676
+	SYS_FMIN                            = 0xA75 // 2677
+	SYS___FMIN_B                        = 0xA76 // 2678
+	SYS___FMIN_H                        = 0xA77 // 2679
+	SYS_FMINF                           = 0xA78 // 2680
+	SYS___FMINF_B                       = 0xA79 // 2681
+	SYS___FMINF_H                       = 0xA7A // 2682
+	SYS_FMINL                           = 0xA7B // 2683
+	SYS___FMINL_B                       = 0xA7C // 2684
+	SYS___FMINL_H                       = 0xA7D // 2685
+	SYS_ILOGBF                          = 0xA7E // 2686
+	SYS___ILOGBF_B                      = 0xA7F // 2687
+	SYS___ILOGBF_H                      = 0xA80 // 2688
+	SYS_ILOGBL                          = 0xA81 // 2689
+	SYS___ILOGBL_B                      = 0xA82 // 2690
+	SYS___ILOGBL_H                      = 0xA83 // 2691
+	SYS_LLRINT                          = 0xA84 // 2692
+	SYS___LLRINT_B                      = 0xA85 // 2693
+	SYS___LLRINT_H                      = 0xA86 // 2694
+	SYS_LLRINTF                         = 0xA87 // 2695
+	SYS___LLRINTF_B                     = 0xA88 // 2696
+	SYS___LLRINTF_H                     = 0xA89 // 2697
+	SYS_LLRINTL                         = 0xA8A // 2698
+	SYS___LLRINTL_B                     = 0xA8B // 2699
+	SYS___LLRINTL_H                     = 0xA8C // 2700
+	SYS_LLROUND                         = 0xA8D // 2701
+	SYS___LLROUND_B                     = 0xA8E // 2702
+	SYS___LLROUND_H                     = 0xA8F // 2703
+	SYS_LLROUNDF                        = 0xA90 // 2704
+	SYS___LLROUNDF_B                    = 0xA91 // 2705
+	SYS___LLROUNDF_H                    = 0xA92 // 2706
+	SYS_LLROUNDL                        = 0xA93 // 2707
+	SYS___LLROUNDL_B                    = 0xA94 // 2708
+	SYS___LLROUNDL_H                    = 0xA95 // 2709
+	SYS_LOGBF                           = 0xA96 // 2710
+	SYS___LOGBF_B                       = 0xA97 // 2711
+	SYS___LOGBF_H                       = 0xA98 // 2712
+	SYS_LOGBL                           = 0xA99 // 2713
+	SYS___LOGBL_B                       = 0xA9A // 2714
+	SYS___LOGBL_H                       = 0xA9B // 2715
+	SYS_LRINT                           = 0xA9C // 2716
+	SYS___LRINT_B                       = 0xA9D // 2717
+	SYS___LRINT_H                       = 0xA9E // 2718
+	SYS_LRINTF                          = 0xA9F // 2719
+	SYS___LRINTF_B                      = 0xAA0 // 2720
+	SYS___LRINTF_H                      = 0xAA1 // 2721
+	SYS_LRINTL                          = 0xAA2 // 2722
+	SYS___LRINTL_B                      = 0xAA3 // 2723
+	SYS___LRINTL_H                      = 0xAA4 // 2724
+	SYS_LROUNDL                         = 0xAA5 // 2725
+	SYS___LROUNDL_B                     = 0xAA6 // 2726
+	SYS___LROUNDL_H                     = 0xAA7 // 2727
+	SYS_NAN                             = 0xAA8 // 2728
+	SYS___NAN_B                         = 0xAA9 // 2729
+	SYS_NANF                            = 0xAAA // 2730
+	SYS___NANF_B                        = 0xAAB // 2731
+	SYS_NANL                            = 0xAAC // 2732
+	SYS___NANL_B                        = 0xAAD // 2733
+	SYS_NEARBYINT                       = 0xAAE // 2734
+	SYS___NEARBYINT_B                   = 0xAAF // 2735
+	SYS___NEARBYINT_H                   = 0xAB0 // 2736
+	SYS_NEARBYINTF                      = 0xAB1 // 2737
+	SYS___NEARBYINTF_B                  = 0xAB2 // 2738
+	SYS___NEARBYINTF_H                  = 0xAB3 // 2739
+	SYS_NEARBYINTL                      = 0xAB4 // 2740
+	SYS___NEARBYINTL_B                  = 0xAB5 // 2741
+	SYS___NEARBYINTL_H                  = 0xAB6 // 2742
+	SYS_NEXTAFTERF                      = 0xAB7 // 2743
+	SYS___NEXTAFTERF_B                  = 0xAB8 // 2744
+	SYS___NEXTAFTERF_H                  = 0xAB9 // 2745
+	SYS_NEXTAFTERL                      = 0xABA // 2746
+	SYS___NEXTAFTERL_B                  = 0xABB // 2747
+	SYS___NEXTAFTERL_H                  = 0xABC // 2748
+	SYS_NEXTTOWARD                      = 0xABD // 2749
+	SYS___NEXTTOWARD_B                  = 0xABE // 2750
+	SYS___NEXTTOWARD_H                  = 0xABF // 2751
+	SYS_NEXTTOWARDF                     = 0xAC0 // 2752
+	SYS___NEXTTOWARDF_B                 = 0xAC1 // 2753
+	SYS___NEXTTOWARDF_H                 = 0xAC2 // 2754
+	SYS_NEXTTOWARDL                     = 0xAC3 // 2755
+	SYS___NEXTTOWARDL_B                 = 0xAC4 // 2756
+	SYS___NEXTTOWARDL_H                 = 0xAC5 // 2757
+	SYS___REMAINDERF_H                  = 0xAC6 // 2758
+	SYS___REMAINDERL_H                  = 0xAC7 // 2759
+	SYS___REMQUO_H                      = 0xAC8 // 2760
+	SYS___REMQUOF_H                     = 0xAC9 // 2761
+	SYS___REMQUOL_H                     = 0xACA // 2762
+	SYS_RINTF                           = 0xACB // 2763
+	SYS___RINTF_B                       = 0xACC // 2764
+	SYS_RINTL                           = 0xACD // 2765
+	SYS___RINTL_B                       = 0xACE // 2766
+	SYS_ROUND                           = 0xACF // 2767
+	SYS___ROUND_B                       = 0xAD0 // 2768
+	SYS___ROUND_H                       = 0xAD1 // 2769
+	SYS_ROUNDF                          = 0xAD2 // 2770
+	SYS___ROUNDF_B                      = 0xAD3 // 2771
+	SYS___ROUNDF_H                      = 0xAD4 // 2772
+	SYS_ROUNDL                          = 0xAD5 // 2773
+	SYS___ROUNDL_B                      = 0xAD6 // 2774
+	SYS___ROUNDL_H                      = 0xAD7 // 2775
+	SYS_SCALBLN                         = 0xAD8 // 2776
+	SYS___SCALBLN_B                     = 0xAD9 // 2777
+	SYS___SCALBLN_H                     = 0xADA // 2778
+	SYS_SCALBLNF                        = 0xADB // 2779
+	SYS___SCALBLNF_B                    = 0xADC // 2780
+	SYS___SCALBLNF_H                    = 0xADD // 2781
+	SYS_SCALBLNL                        = 0xADE // 2782
+	SYS___SCALBLNL_B                    = 0xADF // 2783
+	SYS___SCALBLNL_H                    = 0xAE0 // 2784
+	SYS___SCALBN_B                      = 0xAE1 // 2785
+	SYS___SCALBN_H                      = 0xAE2 // 2786
+	SYS_SCALBNF                         = 0xAE3 // 2787
+	SYS___SCALBNF_B                     = 0xAE4 // 2788
+	SYS___SCALBNF_H                     = 0xAE5 // 2789
+	SYS_SCALBNL                         = 0xAE6 // 2790
+	SYS___SCALBNL_B                     = 0xAE7 // 2791
+	SYS___SCALBNL_H                     = 0xAE8 // 2792
+	SYS___TGAMMAL_H                     = 0xAE9 // 2793
+	SYS_FECLEAREXCEPT                   = 0xAEA // 2794
+	SYS_FEGETENV                        = 0xAEB // 2795
+	SYS_FEGETEXCEPTFLAG                 = 0xAEC // 2796
+	SYS_FEGETROUND                      = 0xAED // 2797
+	SYS_FEHOLDEXCEPT                    = 0xAEE // 2798
+	SYS_FERAISEEXCEPT                   = 0xAEF // 2799
+	SYS_FESETENV                        = 0xAF0 // 2800
+	SYS_FESETEXCEPTFLAG                 = 0xAF1 // 2801
+	SYS_FESETROUND                      = 0xAF2 // 2802
+	SYS_FETESTEXCEPT                    = 0xAF3 // 2803
+	SYS_FEUPDATEENV                     = 0xAF4 // 2804
+	SYS___COPYSIGN_H                    = 0xAF5 // 2805
+	SYS___HYPOTF_H                      = 0xAF6 // 2806
+	SYS___HYPOTL_H                      = 0xAF7 // 2807
+	SYS___CLASS                         = 0xAFA // 2810
+	SYS___CLASS_B                       = 0xAFB // 2811
+	SYS___CLASS_H                       = 0xAFC // 2812
+	SYS___ISBLANK_A                     = 0xB2E // 2862
+	SYS___ISWBLANK_A                    = 0xB2F // 2863
+	SYS___LROUND_FIXUP                  = 0xB30 // 2864
+	SYS___LROUNDF_FIXUP                 = 0xB31 // 2865
+	SYS_SCHED_YIELD                     = 0xB32 // 2866
+	SYS_STRERROR_R                      = 0xB33 // 2867
+	SYS_UNSETENV                        = 0xB34 // 2868
+	SYS___LGAMMA_H_C99                  = 0xB38 // 2872
+	SYS___LGAMMA_B_C99                  = 0xB39 // 2873
+	SYS___LGAMMA_R_C99                  = 0xB3A // 2874
+	SYS___FTELL2                        = 0xB3B // 2875
+	SYS___FSEEK2                        = 0xB3C // 2876
+	SYS___STATIC_REINIT                 = 0xB3D // 2877
+	SYS_PTHREAD_ATTR_GETSTACK           = 0xB3E // 2878
+	SYS_PTHREAD_ATTR_SETSTACK           = 0xB3F // 2879
+	SYS___TGAMMA_H_C99                  = 0xB78 // 2936
+	SYS___TGAMMAF_H_C99                 = 0xB79 // 2937
+	SYS___LE_TRACEBACK                  = 0xB7A // 2938
+	SYS___MUST_STAY_CLEAN               = 0xB7C // 2940
+	SYS___O_ENV                         = 0xB7D // 2941
+	SYS_ACOSD32                         = 0xB7E // 2942
+	SYS_ACOSD64                         = 0xB7F // 2943
+	SYS_ACOSD128                        = 0xB80 // 2944
+	SYS_ACOSHD32                        = 0xB81 // 2945
+	SYS_ACOSHD64                        = 0xB82 // 2946
+	SYS_ACOSHD128                       = 0xB83 // 2947
+	SYS_ASIND32                         = 0xB84 // 2948
+	SYS_ASIND64                         = 0xB85 // 2949
+	SYS_ASIND128                        = 0xB86 // 2950
+	SYS_ASINHD32                        = 0xB87 // 2951
+	SYS_ASINHD64                        = 0xB88 // 2952
+	SYS_ASINHD128                       = 0xB89 // 2953
+	SYS_ATAND32                         = 0xB8A // 2954
+	SYS_ATAND64                         = 0xB8B // 2955
+	SYS_ATAND128                        = 0xB8C // 2956
+	SYS_ATAN2D32                        = 0xB8D // 2957
+	SYS_ATAN2D64                        = 0xB8E // 2958
+	SYS_ATAN2D128                       = 0xB8F // 2959
+	SYS_ATANHD32                        = 0xB90 // 2960
+	SYS_ATANHD64                        = 0xB91 // 2961
+	SYS_ATANHD128                       = 0xB92 // 2962
+	SYS_CBRTD32                         = 0xB93 // 2963
+	SYS_CBRTD64                         = 0xB94 // 2964
+	SYS_CBRTD128                        = 0xB95 // 2965
+	SYS_CEILD32                         = 0xB96 // 2966
+	SYS_CEILD64                         = 0xB97 // 2967
+	SYS_CEILD128                        = 0xB98 // 2968
+	SYS___CLASS2                        = 0xB99 // 2969
+	SYS___CLASS2_B                      = 0xB9A // 2970
+	SYS___CLASS2_H                      = 0xB9B // 2971
+	SYS_COPYSIGND32                     = 0xB9C // 2972
+	SYS_COPYSIGND64                     = 0xB9D // 2973
+	SYS_COPYSIGND128                    = 0xB9E // 2974
+	SYS_COSD32                          = 0xB9F // 2975
+	SYS_COSD64                          = 0xBA0 // 2976
+	SYS_COSD128                         = 0xBA1 // 2977
+	SYS_COSHD32                         = 0xBA2 // 2978
+	SYS_COSHD64                         = 0xBA3 // 2979
+	SYS_COSHD128                        = 0xBA4 // 2980
+	SYS_ERFD32                          = 0xBA5 // 2981
+	SYS_ERFD64                          = 0xBA6 // 2982
+	SYS_ERFD128                         = 0xBA7 // 2983
+	SYS_ERFCD32                         = 0xBA8 // 2984
+	SYS_ERFCD64                         = 0xBA9 // 2985
+	SYS_ERFCD128                        = 0xBAA // 2986
+	SYS_EXPD32                          = 0xBAB // 2987
+	SYS_EXPD64                          = 0xBAC // 2988
+	SYS_EXPD128                         = 0xBAD // 2989
+	SYS_EXP2D32                         = 0xBAE // 2990
+	SYS_EXP2D64                         = 0xBAF // 2991
+	SYS_EXP2D128                        = 0xBB0 // 2992
+	SYS_EXPM1D32                        = 0xBB1 // 2993
+	SYS_EXPM1D64                        = 0xBB2 // 2994
+	SYS_EXPM1D128                       = 0xBB3 // 2995
+	SYS_FABSD32                         = 0xBB4 // 2996
+	SYS_FABSD64                         = 0xBB5 // 2997
+	SYS_FABSD128                        = 0xBB6 // 2998
+	SYS_FDIMD32                         = 0xBB7 // 2999
+	SYS_FDIMD64                         = 0xBB8 // 3000
+	SYS_FDIMD128                        = 0xBB9 // 3001
+	SYS_FE_DEC_GETROUND                 = 0xBBA // 3002
+	SYS_FE_DEC_SETROUND                 = 0xBBB // 3003
+	SYS_FLOORD32                        = 0xBBC // 3004
+	SYS_FLOORD64                        = 0xBBD // 3005
+	SYS_FLOORD128                       = 0xBBE // 3006
+	SYS_FMAD32                          = 0xBBF // 3007
+	SYS_FMAD64                          = 0xBC0 // 3008
+	SYS_FMAD128                         = 0xBC1 // 3009
+	SYS_FMAXD32                         = 0xBC2 // 3010
+	SYS_FMAXD64                         = 0xBC3 // 3011
+	SYS_FMAXD128                        = 0xBC4 // 3012
+	SYS_FMIND32                         = 0xBC5 // 3013
+	SYS_FMIND64                         = 0xBC6 // 3014
+	SYS_FMIND128                        = 0xBC7 // 3015
+	SYS_FMODD32                         = 0xBC8 // 3016
+	SYS_FMODD64                         = 0xBC9 // 3017
+	SYS_FMODD128                        = 0xBCA // 3018
+	SYS___FP_CAST_D                     = 0xBCB // 3019
+	SYS_FREXPD32                        = 0xBCC // 3020
+	SYS_FREXPD64                        = 0xBCD // 3021
+	SYS_FREXPD128                       = 0xBCE // 3022
+	SYS_HYPOTD32                        = 0xBCF // 3023
+	SYS_HYPOTD64                        = 0xBD0 // 3024
+	SYS_HYPOTD128                       = 0xBD1 // 3025
+	SYS_ILOGBD32                        = 0xBD2 // 3026
+	SYS_ILOGBD64                        = 0xBD3 // 3027
+	SYS_ILOGBD128                       = 0xBD4 // 3028
+	SYS_LDEXPD32                        = 0xBD5 // 3029
+	SYS_LDEXPD64                        = 0xBD6 // 3030
+	SYS_LDEXPD128                       = 0xBD7 // 3031
+	SYS_LGAMMAD32                       = 0xBD8 // 3032
+	SYS_LGAMMAD64                       = 0xBD9 // 3033
+	SYS_LGAMMAD128                      = 0xBDA // 3034
+	SYS_LLRINTD32                       = 0xBDB // 3035
+	SYS_LLRINTD64                       = 0xBDC // 3036
+	SYS_LLRINTD128                      = 0xBDD // 3037
+	SYS_LLROUNDD32                      = 0xBDE // 3038
+	SYS_LLROUNDD64                      = 0xBDF // 3039
+	SYS_LLROUNDD128                     = 0xBE0 // 3040
+	SYS_LOGD32                          = 0xBE1 // 3041
+	SYS_LOGD64                          = 0xBE2 // 3042
+	SYS_LOGD128                         = 0xBE3 // 3043
+	SYS_LOG10D32                        = 0xBE4 // 3044
+	SYS_LOG10D64                        = 0xBE5 // 3045
+	SYS_LOG10D128                       = 0xBE6 // 3046
+	SYS_LOG1PD32                        = 0xBE7 // 3047
+	SYS_LOG1PD64                        = 0xBE8 // 3048
+	SYS_LOG1PD128                       = 0xBE9 // 3049
+	SYS_LOG2D32                         = 0xBEA // 3050
+	SYS_LOG2D64                         = 0xBEB // 3051
+	SYS_LOG2D128                        = 0xBEC // 3052
+	SYS_LOGBD32                         = 0xBED // 3053
+	SYS_LOGBD64                         = 0xBEE // 3054
+	SYS_LOGBD128                        = 0xBEF // 3055
+	SYS_LRINTD32                        = 0xBF0 // 3056
+	SYS_LRINTD64                        = 0xBF1 // 3057
+	SYS_LRINTD128                       = 0xBF2 // 3058
+	SYS_LROUNDD32                       = 0xBF3 // 3059
+	SYS_LROUNDD64                       = 0xBF4 // 3060
+	SYS_LROUNDD128                      = 0xBF5 // 3061
+	SYS_MODFD32                         = 0xBF6 // 3062
+	SYS_MODFD64                         = 0xBF7 // 3063
+	SYS_MODFD128                        = 0xBF8 // 3064
+	SYS_NAND32                          = 0xBF9 // 3065
+	SYS_NAND64                          = 0xBFA // 3066
+	SYS_NAND128                         = 0xBFB // 3067
+	SYS_NEARBYINTD32                    = 0xBFC // 3068
+	SYS_NEARBYINTD64                    = 0xBFD // 3069
+	SYS_NEARBYINTD128                   = 0xBFE // 3070
+	SYS_NEXTAFTERD32                    = 0xBFF // 3071
+	SYS_NEXTAFTERD64                    = 0xC00 // 3072
+	SYS_NEXTAFTERD128                   = 0xC01 // 3073
+	SYS_NEXTTOWARDD32                   = 0xC02 // 3074
+	SYS_NEXTTOWARDD64                   = 0xC03 // 3075
+	SYS_NEXTTOWARDD128                  = 0xC04 // 3076
+	SYS_POWD32                          = 0xC05 // 3077
+	SYS_POWD64                          = 0xC06 // 3078
+	SYS_POWD128                         = 0xC07 // 3079
+	SYS_QUANTIZED32                     = 0xC08 // 3080
+	SYS_QUANTIZED64                     = 0xC09 // 3081
+	SYS_QUANTIZED128                    = 0xC0A // 3082
+	SYS_REMAINDERD32                    = 0xC0B // 3083
+	SYS_REMAINDERD64                    = 0xC0C // 3084
+	SYS_REMAINDERD128                   = 0xC0D // 3085
+	SYS___REMQUOD32                     = 0xC0E // 3086
+	SYS___REMQUOD64                     = 0xC0F // 3087
+	SYS___REMQUOD128                    = 0xC10 // 3088
+	SYS_RINTD32                         = 0xC11 // 3089
+	SYS_RINTD64                         = 0xC12 // 3090
+	SYS_RINTD128                        = 0xC13 // 3091
+	SYS_ROUNDD32                        = 0xC14 // 3092
+	SYS_ROUNDD64                        = 0xC15 // 3093
+	SYS_ROUNDD128                       = 0xC16 // 3094
+	SYS_SAMEQUANTUMD32                  = 0xC17 // 3095
+	SYS_SAMEQUANTUMD64                  = 0xC18 // 3096
+	SYS_SAMEQUANTUMD128                 = 0xC19 // 3097
+	SYS_SCALBLND32                      = 0xC1A // 3098
+	SYS_SCALBLND64                      = 0xC1B // 3099
+	SYS_SCALBLND128                     = 0xC1C // 3100
+	SYS_SCALBND32                       = 0xC1D // 3101
+	SYS_SCALBND64                       = 0xC1E // 3102
+	SYS_SCALBND128                      = 0xC1F // 3103
+	SYS_SIND32                          = 0xC20 // 3104
+	SYS_SIND64                          = 0xC21 // 3105
+	SYS_SIND128                         = 0xC22 // 3106
+	SYS_SINHD32                         = 0xC23 // 3107
+	SYS_SINHD64                         = 0xC24 // 3108
+	SYS_SINHD128                        = 0xC25 // 3109
+	SYS_SQRTD32                         = 0xC26 // 3110
+	SYS_SQRTD64                         = 0xC27 // 3111
+	SYS_SQRTD128                        = 0xC28 // 3112
+	SYS_STRTOD32                        = 0xC29 // 3113
+	SYS_STRTOD64                        = 0xC2A // 3114
+	SYS_STRTOD128                       = 0xC2B // 3115
+	SYS_TAND32                          = 0xC2C // 3116
+	SYS_TAND64                          = 0xC2D // 3117
+	SYS_TAND128                         = 0xC2E // 3118
+	SYS_TANHD32                         = 0xC2F // 3119
+	SYS_TANHD64                         = 0xC30 // 3120
+	SYS_TANHD128                        = 0xC31 // 3121
+	SYS_TGAMMAD32                       = 0xC32 // 3122
+	SYS_TGAMMAD64                       = 0xC33 // 3123
+	SYS_TGAMMAD128                      = 0xC34 // 3124
+	SYS_TRUNCD32                        = 0xC3E // 3134
+	SYS_TRUNCD64                        = 0xC3F // 3135
+	SYS_TRUNCD128                       = 0xC40 // 3136
+	SYS_WCSTOD32                        = 0xC41 // 3137
+	SYS_WCSTOD64                        = 0xC42 // 3138
+	SYS_WCSTOD128                       = 0xC43 // 3139
+	SYS___CODEPAGE_INFO                 = 0xC64 // 3172
+	SYS_POSIX_OPENPT                    = 0xC66 // 3174
+	SYS_PSELECT                         = 0xC67 // 3175
+	SYS_SOCKATMARK                      = 0xC68 // 3176
+	SYS_AIO_FSYNC                       = 0xC69 // 3177
+	SYS_LIO_LISTIO                      = 0xC6A // 3178
+	SYS___ATANPID32                     = 0xC6B // 3179
+	SYS___ATANPID64                     = 0xC6C // 3180
+	SYS___ATANPID128                    = 0xC6D // 3181
+	SYS___COSPID32                      = 0xC6E // 3182
+	SYS___COSPID64                      = 0xC6F // 3183
+	SYS___COSPID128                     = 0xC70 // 3184
+	SYS___SINPID32                      = 0xC71 // 3185
+	SYS___SINPID64                      = 0xC72 // 3186
+	SYS___SINPID128                     = 0xC73 // 3187
+	SYS_SETIPV4SOURCEFILTER             = 0xC76 // 3190
+	SYS_GETIPV4SOURCEFILTER             = 0xC77 // 3191
+	SYS_SETSOURCEFILTER                 = 0xC78 // 3192
+	SYS_GETSOURCEFILTER                 = 0xC79 // 3193
+	SYS_FWRITE_UNLOCKED                 = 0xC7A // 3194
+	SYS_FREAD_UNLOCKED                  = 0xC7B // 3195
+	SYS_FGETS_UNLOCKED                  = 0xC7C // 3196
+	SYS_GETS_UNLOCKED                   = 0xC7D // 3197
+	SYS_FPUTS_UNLOCKED                  = 0xC7E // 3198
+	SYS_PUTS_UNLOCKED                   = 0xC7F // 3199
+	SYS_FGETC_UNLOCKED                  = 0xC80 // 3200
+	SYS_FPUTC_UNLOCKED                  = 0xC81 // 3201
+	SYS_DLADDR                          = 0xC82 // 3202
+	SYS_SHM_OPEN                        = 0xC8C // 3212
+	SYS_SHM_UNLINK                      = 0xC8D // 3213
+	SYS___CLASS2F                       = 0xC91 // 3217
+	SYS___CLASS2L                       = 0xC92 // 3218
+	SYS___CLASS2F_B                     = 0xC93 // 3219
+	SYS___CLASS2F_H                     = 0xC94 // 3220
+	SYS___CLASS2L_B                     = 0xC95 // 3221
+	SYS___CLASS2L_H                     = 0xC96 // 3222
+	SYS___CLASS2D32                     = 0xC97 // 3223
+	SYS___CLASS2D64                     = 0xC98 // 3224
+	SYS___CLASS2D128                    = 0xC99 // 3225
+	SYS___TOCSNAME2                     = 0xC9A // 3226
+	SYS___D1TOP                         = 0xC9B // 3227
+	SYS___D2TOP                         = 0xC9C // 3228
+	SYS___D4TOP                         = 0xC9D // 3229
+	SYS___PTOD1                         = 0xC9E // 3230
+	SYS___PTOD2                         = 0xC9F // 3231
+	SYS___PTOD4                         = 0xCA0 // 3232
+	SYS_CLEARERR_UNLOCKED               = 0xCA1 // 3233
+	SYS_FDELREC_UNLOCKED                = 0xCA2 // 3234
+	SYS_FEOF_UNLOCKED                   = 0xCA3 // 3235
+	SYS_FERROR_UNLOCKED                 = 0xCA4 // 3236
+	SYS_FFLUSH_UNLOCKED                 = 0xCA5 // 3237
+	SYS_FGETPOS_UNLOCKED                = 0xCA6 // 3238
+	SYS_FGETWC_UNLOCKED                 = 0xCA7 // 3239
+	SYS_FGETWS_UNLOCKED                 = 0xCA8 // 3240
+	SYS_FILENO_UNLOCKED                 = 0xCA9 // 3241
+	SYS_FLDATA_UNLOCKED                 = 0xCAA // 3242
+	SYS_FLOCATE_UNLOCKED                = 0xCAB // 3243
+	SYS_FPRINTF_UNLOCKED                = 0xCAC // 3244
+	SYS_FPUTWC_UNLOCKED                 = 0xCAD // 3245
+	SYS_FPUTWS_UNLOCKED                 = 0xCAE // 3246
+	SYS_FSCANF_UNLOCKED                 = 0xCAF // 3247
+	SYS_FSEEK_UNLOCKED                  = 0xCB0 // 3248
+	SYS_FSEEKO_UNLOCKED                 = 0xCB1 // 3249
+	SYS_FSETPOS_UNLOCKED                = 0xCB3 // 3251
+	SYS_FTELL_UNLOCKED                  = 0xCB4 // 3252
+	SYS_FTELLO_UNLOCKED                 = 0xCB5 // 3253
+	SYS_FUPDATE_UNLOCKED                = 0xCB7 // 3255
+	SYS_FWIDE_UNLOCKED                  = 0xCB8 // 3256
+	SYS_FWPRINTF_UNLOCKED               = 0xCB9 // 3257
+	SYS_FWSCANF_UNLOCKED                = 0xCBA // 3258
+	SYS_GETWC_UNLOCKED                  = 0xCBB // 3259
+	SYS_GETWCHAR_UNLOCKED               = 0xCBC // 3260
+	SYS_PERROR_UNLOCKED                 = 0xCBD // 3261
+	SYS_PRINTF_UNLOCKED                 = 0xCBE // 3262
+	SYS_PUTWC_UNLOCKED                  = 0xCBF // 3263
+	SYS_PUTWCHAR_UNLOCKED               = 0xCC0 // 3264
+	SYS_REWIND_UNLOCKED                 = 0xCC1 // 3265
+	SYS_SCANF_UNLOCKED                  = 0xCC2 // 3266
+	SYS_UNGETC_UNLOCKED                 = 0xCC3 // 3267
+	SYS_UNGETWC_UNLOCKED                = 0xCC4 // 3268
+	SYS_VFPRINTF_UNLOCKED               = 0xCC5 // 3269
+	SYS_VFSCANF_UNLOCKED                = 0xCC7 // 3271
+	SYS_VFWPRINTF_UNLOCKED              = 0xCC9 // 3273
+	SYS_VFWSCANF_UNLOCKED               = 0xCCB // 3275
+	SYS_VPRINTF_UNLOCKED                = 0xCCD // 3277
+	SYS_VSCANF_UNLOCKED                 = 0xCCF // 3279
+	SYS_VWPRINTF_UNLOCKED               = 0xCD1 // 3281
+	SYS_VWSCANF_UNLOCKED                = 0xCD3 // 3283
+	SYS_WPRINTF_UNLOCKED                = 0xCD5 // 3285
+	SYS_WSCANF_UNLOCKED                 = 0xCD6 // 3286
+	SYS_ASCTIME64                       = 0xCD7 // 3287
+	SYS_ASCTIME64_R                     = 0xCD8 // 3288
+	SYS_CTIME64                         = 0xCD9 // 3289
+	SYS_CTIME64_R                       = 0xCDA // 3290
+	SYS_DIFFTIME64                      = 0xCDB // 3291
+	SYS_GMTIME64                        = 0xCDC // 3292
+	SYS_GMTIME64_R                      = 0xCDD // 3293
+	SYS_LOCALTIME64                     = 0xCDE // 3294
+	SYS_LOCALTIME64_R                   = 0xCDF // 3295
+	SYS_MKTIME64                        = 0xCE0 // 3296
+	SYS_TIME64                          = 0xCE1 // 3297
+	SYS___LOGIN_APPLID                  = 0xCE2 // 3298
+	SYS___PASSWD_APPLID                 = 0xCE3 // 3299
+	SYS_PTHREAD_SECURITY_APPLID_NP      = 0xCE4 // 3300
+	SYS___GETTHENT                      = 0xCE5 // 3301
+	SYS_FREEIFADDRS                     = 0xCE6 // 3302
+	SYS_GETIFADDRS                      = 0xCE7 // 3303
+	SYS_POSIX_FALLOCATE                 = 0xCE8 // 3304
+	SYS_POSIX_MEMALIGN                  = 0xCE9 // 3305
+	SYS_SIZEOF_ALLOC                    = 0xCEA // 3306
+	SYS_RESIZE_ALLOC                    = 0xCEB // 3307
+	SYS_FREAD_NOUPDATE                  = 0xCEC // 3308
+	SYS_FREAD_NOUPDATE_UNLOCKED         = 0xCED // 3309
+	SYS_FGETPOS64                       = 0xCEE // 3310
+	SYS_FSEEK64                         = 0xCEF // 3311
+	SYS_FSEEKO64                        = 0xCF0 // 3312
+	SYS_FSETPOS64                       = 0xCF1 // 3313
+	SYS_FTELL64                         = 0xCF2 // 3314
+	SYS_FTELLO64                        = 0xCF3 // 3315
+	SYS_FGETPOS64_UNLOCKED              = 0xCF4 // 3316
+	SYS_FSEEK64_UNLOCKED                = 0xCF5 // 3317
+	SYS_FSEEKO64_UNLOCKED               = 0xCF6 // 3318
+	SYS_FSETPOS64_UNLOCKED              = 0xCF7 // 3319
+	SYS_FTELL64_UNLOCKED                = 0xCF8 // 3320
+	SYS_FTELLO64_UNLOCKED               = 0xCF9 // 3321
+	SYS_FOPEN_UNLOCKED                  = 0xCFA // 3322
+	SYS_FREOPEN_UNLOCKED                = 0xCFB // 3323
+	SYS_FDOPEN_UNLOCKED                 = 0xCFC // 3324
+	SYS_TMPFILE_UNLOCKED                = 0xCFD // 3325
+	SYS___MOSERVICES                    = 0xD3D // 3389
+	SYS___GETTOD                        = 0xD3E // 3390
+	SYS_C16RTOMB                        = 0xD40 // 3392
+	SYS_C32RTOMB                        = 0xD41 // 3393
+	SYS_MBRTOC16                        = 0xD42 // 3394
+	SYS_MBRTOC32                        = 0xD43 // 3395
+	SYS_QUANTEXPD32                     = 0xD44 // 3396
+	SYS_QUANTEXPD64                     = 0xD45 // 3397
+	SYS_QUANTEXPD128                    = 0xD46 // 3398
+	SYS___LOCALE_CTL                    = 0xD47 // 3399
+	SYS___SMF_RECORD2                   = 0xD48 // 3400
+	SYS_FOPEN64                         = 0xD49 // 3401
+	SYS_FOPEN64_UNLOCKED                = 0xD4A // 3402
+	SYS_FREOPEN64                       = 0xD4B // 3403
+	SYS_FREOPEN64_UNLOCKED              = 0xD4C // 3404
+	SYS_TMPFILE64                       = 0xD4D // 3405
+	SYS_TMPFILE64_UNLOCKED              = 0xD4E // 3406
+	SYS_GETDATE64                       = 0xD4F // 3407
+	SYS_GETTIMEOFDAY64                  = 0xD50 // 3408
+	SYS_BIND2ADDRSEL                    = 0xD59 // 3417
+	SYS_INET6_IS_SRCADDR                = 0xD5A // 3418
+	SYS___GETGRGID1                     = 0xD5B // 3419
+	SYS___GETGRNAM1                     = 0xD5C // 3420
+	SYS___FBUFSIZE                      = 0xD60 // 3424
+	SYS___FPENDING                      = 0xD61 // 3425
+	SYS___FLBF                          = 0xD62 // 3426
+	SYS___FREADABLE                     = 0xD63 // 3427
+	SYS___FWRITABLE                     = 0xD64 // 3428
+	SYS___FREADING                      = 0xD65 // 3429
+	SYS___FWRITING                      = 0xD66 // 3430
+	SYS___FSETLOCKING                   = 0xD67 // 3431
+	SYS__FLUSHLBF                       = 0xD68 // 3432
+	SYS___FPURGE                        = 0xD69 // 3433
+	SYS___FREADAHEAD                    = 0xD6A // 3434
+	SYS___FSETERR                       = 0xD6B // 3435
+	SYS___FPENDING_UNLOCKED             = 0xD6C // 3436
+	SYS___FREADING_UNLOCKED             = 0xD6D // 3437
+	SYS___FWRITING_UNLOCKED             = 0xD6E // 3438
+	SYS__FLUSHLBF_UNLOCKED              = 0xD6F // 3439
+	SYS___FPURGE_UNLOCKED               = 0xD70 // 3440
+	SYS___FREADAHEAD_UNLOCKED           = 0xD71 // 3441
+	SYS___LE_CEEGTJS                    = 0xD72 // 3442
+	SYS___LE_RECORD_DUMP                = 0xD73 // 3443
+	SYS_FSTAT64                         = 0xD74 // 3444
+	SYS_LSTAT64                         = 0xD75 // 3445
+	SYS_STAT64                          = 0xD76 // 3446
+	SYS___READDIR2_64                   = 0xD77 // 3447
+	SYS___OPEN_STAT64                   = 0xD78 // 3448
+	SYS_FTW64                           = 0xD79 // 3449
+	SYS_NFTW64                          = 0xD7A // 3450
+	SYS_UTIME64                         = 0xD7B // 3451
+	SYS_UTIMES64                        = 0xD7C // 3452
+	SYS___GETIPC64                      = 0xD7D // 3453
+	SYS_MSGCTL64                        = 0xD7E // 3454
+	SYS_SEMCTL64                        = 0xD7F // 3455
+	SYS_SHMCTL64                        = 0xD80 // 3456
+	SYS_MSGXRCV64                       = 0xD81 // 3457
+	SYS___MGXR64                        = 0xD81 // 3457
+	SYS_W_GETPSENT64                    = 0xD82 // 3458
+	SYS_PTHREAD_COND_TIMEDWAIT64        = 0xD83 // 3459
+	SYS_FTIME64                         = 0xD85 // 3461
+	SYS_GETUTXENT64                     = 0xD86 // 3462
+	SYS_GETUTXID64                      = 0xD87 // 3463
+	SYS_GETUTXLINE64                    = 0xD88 // 3464
+	SYS_PUTUTXLINE64                    = 0xD89 // 3465
+	SYS_NEWLOCALE                       = 0xD8A // 3466
+	SYS_FREELOCALE                      = 0xD8B // 3467
+	SYS_USELOCALE                       = 0xD8C // 3468
+	SYS_DUPLOCALE                       = 0xD8D // 3469
+	SYS___CHATTR64                      = 0xD9C // 3484
+	SYS___LCHATTR64                     = 0xD9D // 3485
+	SYS___FCHATTR64                     = 0xD9E // 3486
+	SYS_____CHATTR64_A                  = 0xD9F // 3487
+	SYS_____LCHATTR64_A                 = 0xDA0 // 3488
+	SYS___LE_CEEUSGD                    = 0xDA1 // 3489
+	SYS___LE_IFAM_CON                   = 0xDA2 // 3490
+	SYS___LE_IFAM_DSC                   = 0xDA3 // 3491
+	SYS___LE_IFAM_GET                   = 0xDA4 // 3492
+	SYS___LE_IFAM_QRY                   = 0xDA5 // 3493
+	SYS_ALIGNED_ALLOC                   = 0xDA6 // 3494
+	SYS_ACCEPT4                         = 0xDA7 // 3495
+	SYS___ACCEPT4_A                     = 0xDA8 // 3496
+	SYS_COPYFILERANGE                   = 0xDA9 // 3497
+	SYS_GETLINE                         = 0xDAA // 3498
+	SYS___GETLINE_A                     = 0xDAB // 3499
+	SYS_DIRFD                           = 0xDAC // 3500
+	SYS_CLOCK_GETTIME                   = 0xDAD // 3501
+	SYS_DUP3                            = 0xDAE // 3502
+	SYS_EPOLL_CREATE                    = 0xDAF // 3503
+	SYS_EPOLL_CREATE1                   = 0xDB0 // 3504
+	SYS_EPOLL_CTL                       = 0xDB1 // 3505
+	SYS_EPOLL_WAIT                      = 0xDB2 // 3506
+	SYS_EPOLL_PWAIT                     = 0xDB3 // 3507
+	SYS_EVENTFD                         = 0xDB4 // 3508
+	SYS_STATFS                          = 0xDB5 // 3509
+	SYS___STATFS_A                      = 0xDB6 // 3510
+	SYS_FSTATFS                         = 0xDB7 // 3511
+	SYS_INOTIFY_INIT                    = 0xDB8 // 3512
+	SYS_INOTIFY_INIT1                   = 0xDB9 // 3513
+	SYS_INOTIFY_ADD_WATCH               = 0xDBA // 3514
+	SYS___INOTIFY_ADD_WATCH_A           = 0xDBB // 3515
+	SYS_INOTIFY_RM_WATCH                = 0xDBC // 3516
+	SYS_PIPE2                           = 0xDBD // 3517
+	SYS_PIVOT_ROOT                      = 0xDBE // 3518
+	SYS___PIVOT_ROOT_A                  = 0xDBF // 3519
+	SYS_PRCTL                           = 0xDC0 // 3520
+	SYS_PRLIMIT                         = 0xDC1 // 3521
+	SYS_SETHOSTNAME                     = 0xDC2 // 3522
+	SYS___SETHOSTNAME_A                 = 0xDC3 // 3523
+	SYS_SETRESUID                       = 0xDC4 // 3524
+	SYS_SETRESGID                       = 0xDC5 // 3525
+	SYS_PTHREAD_CONDATTR_GETCLOCK       = 0xDC6 // 3526
+	SYS_FLOCK                           = 0xDC7 // 3527
+	SYS_FGETXATTR                       = 0xDC8 // 3528
+	SYS___FGETXATTR_A                   = 0xDC9 // 3529
+	SYS_FLISTXATTR                      = 0xDCA // 3530
+	SYS___FLISTXATTR_A                  = 0xDCB // 3531
+	SYS_FREMOVEXATTR                    = 0xDCC // 3532
+	SYS___FREMOVEXATTR_A                = 0xDCD // 3533
+	SYS_FSETXATTR                       = 0xDCE // 3534
+	SYS___FSETXATTR_A                   = 0xDCF // 3535
+	SYS_GETXATTR                        = 0xDD0 // 3536
+	SYS___GETXATTR_A                    = 0xDD1 // 3537
+	SYS_LGETXATTR                       = 0xDD2 // 3538
+	SYS___LGETXATTR_A                   = 0xDD3 // 3539
+	SYS_LISTXATTR                       = 0xDD4 // 3540
+	SYS___LISTXATTR_A                   = 0xDD5 // 3541
+	SYS_LLISTXATTR                      = 0xDD6 // 3542
+	SYS___LLISTXATTR_A                  = 0xDD7 // 3543
+	SYS_LREMOVEXATTR                    = 0xDD8 // 3544
+	SYS___LREMOVEXATTR_A                = 0xDD9 // 3545
+	SYS_LSETXATTR                       = 0xDDA // 3546
+	SYS___LSETXATTR_A                   = 0xDDB // 3547
+	SYS_REMOVEXATTR                     = 0xDDC // 3548
+	SYS___REMOVEXATTR_A                 = 0xDDD // 3549
+	SYS_SETXATTR                        = 0xDDE // 3550
+	SYS___SETXATTR_A                    = 0xDDF // 3551
+	SYS_FDATASYNC                       = 0xDE0 // 3552
+	SYS_SYNCFS                          = 0xDE1 // 3553
+	SYS_FUTIMES                         = 0xDE2 // 3554
+	SYS_FUTIMESAT                       = 0xDE3 // 3555
+	SYS___FUTIMESAT_A                   = 0xDE4 // 3556
+	SYS_LUTIMES                         = 0xDE5 // 3557
+	SYS___LUTIMES_A                     = 0xDE6 // 3558
+	SYS_INET_ATON                       = 0xDE7 // 3559
+	SYS_GETRANDOM                       = 0xDE8 // 3560
+	SYS_GETTID                          = 0xDE9 // 3561
+	SYS_MEMFD_CREATE                    = 0xDEA // 3562
+	SYS___MEMFD_CREATE_A                = 0xDEB // 3563
+	SYS_FACCESSAT                       = 0xDEC // 3564
+	SYS___FACCESSAT_A                   = 0xDED // 3565
+	SYS_FCHMODAT                        = 0xDEE // 3566
+	SYS___FCHMODAT_A                    = 0xDEF // 3567
+	SYS_FCHOWNAT                        = 0xDF0 // 3568
+	SYS___FCHOWNAT_A                    = 0xDF1 // 3569
+	SYS_FSTATAT                         = 0xDF2 // 3570
+	SYS___FSTATAT_A                     = 0xDF3 // 3571
+	SYS_LINKAT                          = 0xDF4 // 3572
+	SYS___LINKAT_A                      = 0xDF5 // 3573
+	SYS_MKDIRAT                         = 0xDF6 // 3574
+	SYS___MKDIRAT_A                     = 0xDF7 // 3575
+	SYS_MKFIFOAT                        = 0xDF8 // 3576
+	SYS___MKFIFOAT_A                    = 0xDF9 // 3577
+	SYS_MKNODAT                         = 0xDFA // 3578
+	SYS___MKNODAT_A                     = 0xDFB // 3579
+	SYS_OPENAT                          = 0xDFC // 3580
+	SYS___OPENAT_A                      = 0xDFD // 3581
+	SYS_READLINKAT                      = 0xDFE // 3582
+	SYS___READLINKAT_A                  = 0xDFF // 3583
+	SYS_RENAMEAT                        = 0xE00 // 3584
+	SYS___RENAMEAT_A                    = 0xE01 // 3585
+	SYS_RENAMEAT2                       = 0xE02 // 3586
+	SYS___RENAMEAT2_A                   = 0xE03 // 3587
+	SYS_SYMLINKAT                       = 0xE04 // 3588
+	SYS___SYMLINKAT_A                   = 0xE05 // 3589
+	SYS_UNLINKAT                        = 0xE06 // 3590
+	SYS___UNLINKAT_A                    = 0xE07 // 3591
+	SYS_SYSINFO                         = 0xE08 // 3592
+	SYS_WAIT4                           = 0xE0A // 3594
+	SYS_CLONE                           = 0xE0B // 3595
+	SYS_UNSHARE                         = 0xE0C // 3596
+	SYS_SETNS                           = 0xE0D // 3597
+	SYS_CAPGET                          = 0xE0E // 3598
+	SYS_CAPSET                          = 0xE0F // 3599
+	SYS_STRCHRNUL                       = 0xE10 // 3600
+	SYS_PTHREAD_CONDATTR_SETCLOCK       = 0xE12 // 3602
+	SYS_OPEN_BY_HANDLE_AT               = 0xE13 // 3603
+	SYS___OPEN_BY_HANDLE_AT_A           = 0xE14 // 3604
+	SYS___INET_ATON_A                   = 0xE15 // 3605
+	SYS_MOUNT1                          = 0xE16 // 3606
+	SYS___MOUNT1_A                      = 0xE17 // 3607
+	SYS_UMOUNT1                         = 0xE18 // 3608
+	SYS___UMOUNT1_A                     = 0xE19 // 3609
+	SYS_UMOUNT2                         = 0xE1A // 3610
+	SYS___UMOUNT2_A                     = 0xE1B // 3611
+	SYS___PRCTL_A                       = 0xE1C // 3612
+	SYS_LOCALTIME_R2                    = 0xE1D // 3613
+	SYS___LOCALTIME_R2_A                = 0xE1E // 3614
+	SYS_OPENAT2                         = 0xE1F // 3615
+	SYS___OPENAT2_A                     = 0xE20 // 3616
+	SYS___LE_CEEMICT                    = 0xE21 // 3617
+	SYS_GETENTROPY                      = 0xE22 // 3618
+	SYS_NANOSLEEP                       = 0xE23 // 3619
+	SYS_UTIMENSAT                       = 0xE24 // 3620
+	SYS___UTIMENSAT_A                   = 0xE25 // 3621
+	SYS_ASPRINTF                        = 0xE26 // 3622
+	SYS___ASPRINTF_A                    = 0xE27 // 3623
+	SYS_VASPRINTF                       = 0xE28 // 3624
+	SYS___VASPRINTF_A                   = 0xE29 // 3625
+	SYS_DPRINTF                         = 0xE2A // 3626
+	SYS___DPRINTF_A                     = 0xE2B // 3627
+	SYS_GETOPT_LONG                     = 0xE2C // 3628
+	SYS___GETOPT_LONG_A                 = 0xE2D // 3629
+	SYS_PSIGNAL                         = 0xE2E // 3630
+	SYS___PSIGNAL_A                     = 0xE2F // 3631
+	SYS_PSIGNAL_UNLOCKED                = 0xE30 // 3632
+	SYS___PSIGNAL_UNLOCKED_A            = 0xE31 // 3633
+	SYS_FSTATAT_O                       = 0xE32 // 3634
+	SYS___FSTATAT_O_A                   = 0xE33 // 3635
+	SYS_FSTATAT64                       = 0xE34 // 3636
+	SYS___FSTATAT64_A                   = 0xE35 // 3637
+	SYS___CHATTRAT                      = 0xE36 // 3638
+	SYS_____CHATTRAT_A                  = 0xE37 // 3639
+	SYS___CHATTRAT64                    = 0xE38 // 3640
+	SYS_____CHATTRAT64_A                = 0xE39 // 3641
+	SYS_MADVISE                         = 0xE3A // 3642
+	SYS___AUTHENTICATE                  = 0xE3B // 3643
+
 )
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go
index dc0c955e..4740b834 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go
@@ -836,6 +836,15 @@ const (
 	FSPICK_EMPTY_PATH       = 0x8
 
 	FSMOUNT_CLOEXEC = 0x1
+
+	FSCONFIG_SET_FLAG        = 0x0
+	FSCONFIG_SET_STRING      = 0x1
+	FSCONFIG_SET_BINARY      = 0x2
+	FSCONFIG_SET_PATH        = 0x3
+	FSCONFIG_SET_PATH_EMPTY  = 0x4
+	FSCONFIG_SET_FD          = 0x5
+	FSCONFIG_CMD_CREATE      = 0x6
+	FSCONFIG_CMD_RECONFIGURE = 0x7
 )
 
 type OpenHow struct {
@@ -1169,7 +1178,8 @@ const (
 	PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT    = 0x10
 	PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT     = 0x11
 	PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT    = 0x12
-	PERF_SAMPLE_BRANCH_MAX_SHIFT          = 0x13
+	PERF_SAMPLE_BRANCH_COUNTERS           = 0x80000
+	PERF_SAMPLE_BRANCH_MAX_SHIFT          = 0x14
 	PERF_SAMPLE_BRANCH_USER               = 0x1
 	PERF_SAMPLE_BRANCH_KERNEL             = 0x2
 	PERF_SAMPLE_BRANCH_HV                 = 0x4
@@ -1189,7 +1199,7 @@ const (
 	PERF_SAMPLE_BRANCH_TYPE_SAVE          = 0x10000
 	PERF_SAMPLE_BRANCH_HW_INDEX           = 0x20000
 	PERF_SAMPLE_BRANCH_PRIV_SAVE          = 0x40000
-	PERF_SAMPLE_BRANCH_MAX                = 0x80000
+	PERF_SAMPLE_BRANCH_MAX                = 0x100000
 	PERF_BR_UNKNOWN                       = 0x0
 	PERF_BR_COND                          = 0x1
 	PERF_BR_UNCOND                        = 0x2
@@ -1550,6 +1560,7 @@ const (
 	IFLA_DEVLINK_PORT                          = 0x3e
 	IFLA_GSO_IPV4_MAX_SIZE                     = 0x3f
 	IFLA_GRO_IPV4_MAX_SIZE                     = 0x40
+	IFLA_DPLL_PIN                              = 0x41
 	IFLA_PROTO_DOWN_REASON_UNSPEC              = 0x0
 	IFLA_PROTO_DOWN_REASON_MASK                = 0x1
 	IFLA_PROTO_DOWN_REASON_VALUE               = 0x2
@@ -1565,6 +1576,7 @@ const (
 	IFLA_INET6_ICMP6STATS                      = 0x6
 	IFLA_INET6_TOKEN                           = 0x7
 	IFLA_INET6_ADDR_GEN_MODE                   = 0x8
+	IFLA_INET6_RA_MTU                          = 0x9
 	IFLA_BR_UNSPEC                             = 0x0
 	IFLA_BR_FORWARD_DELAY                      = 0x1
 	IFLA_BR_HELLO_TIME                         = 0x2
@@ -1612,6 +1624,9 @@ const (
 	IFLA_BR_MCAST_MLD_VERSION                  = 0x2c
 	IFLA_BR_VLAN_STATS_PER_PORT                = 0x2d
 	IFLA_BR_MULTI_BOOLOPT                      = 0x2e
+	IFLA_BR_MCAST_QUERIER_STATE                = 0x2f
+	IFLA_BR_FDB_N_LEARNED                      = 0x30
+	IFLA_BR_FDB_MAX_LEARNED                    = 0x31
 	IFLA_BRPORT_UNSPEC                         = 0x0
 	IFLA_BRPORT_STATE                          = 0x1
 	IFLA_BRPORT_PRIORITY                       = 0x2
@@ -1649,6 +1664,14 @@ const (
 	IFLA_BRPORT_BACKUP_PORT                    = 0x22
 	IFLA_BRPORT_MRP_RING_OPEN                  = 0x23
 	IFLA_BRPORT_MRP_IN_OPEN                    = 0x24
+	IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT          = 0x25
+	IFLA_BRPORT_MCAST_EHT_HOSTS_CNT            = 0x26
+	IFLA_BRPORT_LOCKED                         = 0x27
+	IFLA_BRPORT_MAB                            = 0x28
+	IFLA_BRPORT_MCAST_N_GROUPS                 = 0x29
+	IFLA_BRPORT_MCAST_MAX_GROUPS               = 0x2a
+	IFLA_BRPORT_NEIGH_VLAN_SUPPRESS            = 0x2b
+	IFLA_BRPORT_BACKUP_NHID                    = 0x2c
 	IFLA_INFO_UNSPEC                           = 0x0
 	IFLA_INFO_KIND                             = 0x1
 	IFLA_INFO_DATA                             = 0x2
@@ -1670,6 +1693,9 @@ const (
 	IFLA_MACVLAN_MACADDR                       = 0x4
 	IFLA_MACVLAN_MACADDR_DATA                  = 0x5
 	IFLA_MACVLAN_MACADDR_COUNT                 = 0x6
+	IFLA_MACVLAN_BC_QUEUE_LEN                  = 0x7
+	IFLA_MACVLAN_BC_QUEUE_LEN_USED             = 0x8
+	IFLA_MACVLAN_BC_CUTOFF                     = 0x9
 	IFLA_VRF_UNSPEC                            = 0x0
 	IFLA_VRF_TABLE                             = 0x1
 	IFLA_VRF_PORT_UNSPEC                       = 0x0
@@ -1693,9 +1719,22 @@ const (
 	IFLA_XFRM_UNSPEC                           = 0x0
 	IFLA_XFRM_LINK                             = 0x1
 	IFLA_XFRM_IF_ID                            = 0x2
+	IFLA_XFRM_COLLECT_METADATA                 = 0x3
 	IFLA_IPVLAN_UNSPEC                         = 0x0
 	IFLA_IPVLAN_MODE                           = 0x1
 	IFLA_IPVLAN_FLAGS                          = 0x2
+	NETKIT_NEXT                                = -0x1
+	NETKIT_PASS                                = 0x0
+	NETKIT_DROP                                = 0x2
+	NETKIT_REDIRECT                            = 0x7
+	NETKIT_L2                                  = 0x0
+	NETKIT_L3                                  = 0x1
+	IFLA_NETKIT_UNSPEC                         = 0x0
+	IFLA_NETKIT_PEER_INFO                      = 0x1
+	IFLA_NETKIT_PRIMARY                        = 0x2
+	IFLA_NETKIT_POLICY                         = 0x3
+	IFLA_NETKIT_PEER_POLICY                    = 0x4
+	IFLA_NETKIT_MODE                           = 0x5
 	IFLA_VXLAN_UNSPEC                          = 0x0
 	IFLA_VXLAN_ID                              = 0x1
 	IFLA_VXLAN_GROUP                           = 0x2
@@ -1726,6 +1765,8 @@ const (
 	IFLA_VXLAN_GPE                             = 0x1b
 	IFLA_VXLAN_TTL_INHERIT                     = 0x1c
 	IFLA_VXLAN_DF                              = 0x1d
+	IFLA_VXLAN_VNIFILTER                       = 0x1e
+	IFLA_VXLAN_LOCALBYPASS                     = 0x1f
 	IFLA_GENEVE_UNSPEC                         = 0x0
 	IFLA_GENEVE_ID                             = 0x1
 	IFLA_GENEVE_REMOTE                         = 0x2
@@ -1740,6 +1781,7 @@ const (
 	IFLA_GENEVE_LABEL                          = 0xb
 	IFLA_GENEVE_TTL_INHERIT                    = 0xc
 	IFLA_GENEVE_DF                             = 0xd
+	IFLA_GENEVE_INNER_PROTO_INHERIT            = 0xe
 	IFLA_BAREUDP_UNSPEC                        = 0x0
 	IFLA_BAREUDP_PORT                          = 0x1
 	IFLA_BAREUDP_ETHERTYPE                     = 0x2
@@ -1752,6 +1794,8 @@ const (
 	IFLA_GTP_FD1                               = 0x2
 	IFLA_GTP_PDP_HASHSIZE                      = 0x3
 	IFLA_GTP_ROLE                              = 0x4
+	IFLA_GTP_CREATE_SOCKETS                    = 0x5
+	IFLA_GTP_RESTART_COUNT                     = 0x6
 	IFLA_BOND_UNSPEC                           = 0x0
 	IFLA_BOND_MODE                             = 0x1
 	IFLA_BOND_ACTIVE_SLAVE                     = 0x2
@@ -1781,6 +1825,9 @@ const (
 	IFLA_BOND_AD_ACTOR_SYSTEM                  = 0x1a
 	IFLA_BOND_TLB_DYNAMIC_LB                   = 0x1b
 	IFLA_BOND_PEER_NOTIF_DELAY                 = 0x1c
+	IFLA_BOND_AD_LACP_ACTIVE                   = 0x1d
+	IFLA_BOND_MISSED_MAX                       = 0x1e
+	IFLA_BOND_NS_IP6_TARGET                    = 0x1f
 	IFLA_BOND_AD_INFO_UNSPEC                   = 0x0
 	IFLA_BOND_AD_INFO_AGGREGATOR               = 0x1
 	IFLA_BOND_AD_INFO_NUM_PORTS                = 0x2
@@ -1796,6 +1843,7 @@ const (
 	IFLA_BOND_SLAVE_AD_AGGREGATOR_ID           = 0x6
 	IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE   = 0x7
 	IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE = 0x8
+	IFLA_BOND_SLAVE_PRIO                       = 0x9
 	IFLA_VF_INFO_UNSPEC                        = 0x0
 	IFLA_VF_INFO                               = 0x1
 	IFLA_VF_UNSPEC                             = 0x0
@@ -1854,8 +1902,16 @@ const (
 	IFLA_STATS_LINK_XSTATS_SLAVE               = 0x3
 	IFLA_STATS_LINK_OFFLOAD_XSTATS             = 0x4
 	IFLA_STATS_AF_SPEC                         = 0x5
+	IFLA_STATS_GETSET_UNSPEC                   = 0x0
+	IFLA_STATS_GET_FILTERS                     = 0x1
+	IFLA_STATS_SET_OFFLOAD_XSTATS_L3_STATS     = 0x2
 	IFLA_OFFLOAD_XSTATS_UNSPEC                 = 0x0
 	IFLA_OFFLOAD_XSTATS_CPU_HIT                = 0x1
+	IFLA_OFFLOAD_XSTATS_HW_S_INFO              = 0x2
+	IFLA_OFFLOAD_XSTATS_L3_STATS               = 0x3
+	IFLA_OFFLOAD_XSTATS_HW_S_INFO_UNSPEC       = 0x0
+	IFLA_OFFLOAD_XSTATS_HW_S_INFO_REQUEST      = 0x1
+	IFLA_OFFLOAD_XSTATS_HW_S_INFO_USED         = 0x2
 	IFLA_XDP_UNSPEC                            = 0x0
 	IFLA_XDP_FD                                = 0x1
 	IFLA_XDP_ATTACHED                          = 0x2
@@ -1885,6 +1941,11 @@ const (
 	IFLA_RMNET_UNSPEC                          = 0x0
 	IFLA_RMNET_MUX_ID                          = 0x1
 	IFLA_RMNET_FLAGS                           = 0x2
+	IFLA_MCTP_UNSPEC                           = 0x0
+	IFLA_MCTP_NET                              = 0x1
+	IFLA_DSA_UNSPEC                            = 0x0
+	IFLA_DSA_CONDUIT                           = 0x1
+	IFLA_DSA_MASTER                            = 0x1
 )
 
 const (
@@ -2421,6 +2482,15 @@ type XDPMmapOffsets struct {
 	Cr XDPRingOffset
 }
 
+type XDPUmemReg struct {
+	Addr            uint64
+	Len             uint64
+	Chunk_size      uint32
+	Headroom        uint32
+	Flags           uint32
+	Tx_metadata_len uint32
+}
+
 type XDPStatistics struct {
 	Rx_dropped               uint64
 	Rx_invalid_descs         uint64
@@ -2875,7 +2945,7 @@ const (
 	BPF_TCP_LISTEN                             = 0xa
 	BPF_TCP_CLOSING                            = 0xb
 	BPF_TCP_NEW_SYN_RECV                       = 0xc
-	BPF_TCP_MAX_STATES                         = 0xd
+	BPF_TCP_MAX_STATES                         = 0xe
 	TCP_BPF_IW                                 = 0x3e9
 	TCP_BPF_SNDCWND_CLAMP                      = 0x3ea
 	TCP_BPF_DELACK_MAX                         = 0x3eb
@@ -3151,7 +3221,7 @@ const (
 	DEVLINK_CMD_LINECARD_NEW                           = 0x50
 	DEVLINK_CMD_LINECARD_DEL                           = 0x51
 	DEVLINK_CMD_SELFTESTS_GET                          = 0x52
-	DEVLINK_CMD_MAX                                    = 0x53
+	DEVLINK_CMD_MAX                                    = 0x54
 	DEVLINK_PORT_TYPE_NOTSET                           = 0x0
 	DEVLINK_PORT_TYPE_AUTO                             = 0x1
 	DEVLINK_PORT_TYPE_ETH                              = 0x2
@@ -4535,7 +4605,7 @@ const (
 	NL80211_ATTR_MAC_HINT                                   = 0xc8
 	NL80211_ATTR_MAC_MASK                                   = 0xd7
 	NL80211_ATTR_MAX_AP_ASSOC_STA                           = 0xca
-	NL80211_ATTR_MAX                                        = 0x146
+	NL80211_ATTR_MAX                                        = 0x14a
 	NL80211_ATTR_MAX_CRIT_PROT_DURATION                     = 0xb4
 	NL80211_ATTR_MAX_CSA_COUNTERS                           = 0xce
 	NL80211_ATTR_MAX_MATCH_SETS                             = 0x85
@@ -4801,7 +4871,7 @@ const (
 	NL80211_BSS_FREQUENCY_OFFSET                            = 0x14
 	NL80211_BSS_INFORMATION_ELEMENTS                        = 0x6
 	NL80211_BSS_LAST_SEEN_BOOTTIME                          = 0xf
-	NL80211_BSS_MAX                                         = 0x16
+	NL80211_BSS_MAX                                         = 0x18
 	NL80211_BSS_MLD_ADDR                                    = 0x16
 	NL80211_BSS_MLO_LINK_ID                                 = 0x15
 	NL80211_BSS_PAD                                         = 0x10
@@ -4905,7 +4975,7 @@ const (
 	NL80211_CMD_LEAVE_IBSS                                  = 0x2c
 	NL80211_CMD_LEAVE_MESH                                  = 0x45
 	NL80211_CMD_LEAVE_OCB                                   = 0x6d
-	NL80211_CMD_MAX                                         = 0x9a
+	NL80211_CMD_MAX                                         = 0x9b
 	NL80211_CMD_MICHAEL_MIC_FAILURE                         = 0x29
 	NL80211_CMD_MODIFY_LINK_STA                             = 0x97
 	NL80211_CMD_NAN_MATCH                                   = 0x78
@@ -5139,7 +5209,7 @@ const (
 	NL80211_FREQUENCY_ATTR_GO_CONCURRENT                    = 0xf
 	NL80211_FREQUENCY_ATTR_INDOOR_ONLY                      = 0xe
 	NL80211_FREQUENCY_ATTR_IR_CONCURRENT                    = 0xf
-	NL80211_FREQUENCY_ATTR_MAX                              = 0x1c
+	NL80211_FREQUENCY_ATTR_MAX                              = 0x20
 	NL80211_FREQUENCY_ATTR_MAX_TX_POWER                     = 0x6
 	NL80211_FREQUENCY_ATTR_NO_10MHZ                         = 0x11
 	NL80211_FREQUENCY_ATTR_NO_160MHZ                        = 0xc
@@ -5633,7 +5703,7 @@ const (
 	NL80211_STA_FLAG_ASSOCIATED                             = 0x7
 	NL80211_STA_FLAG_AUTHENTICATED                          = 0x5
 	NL80211_STA_FLAG_AUTHORIZED                             = 0x1
-	NL80211_STA_FLAG_MAX                                    = 0x7
+	NL80211_STA_FLAG_MAX                                    = 0x8
 	NL80211_STA_FLAG_MAX_OLD_API                            = 0x6
 	NL80211_STA_FLAG_MFP                                    = 0x4
 	NL80211_STA_FLAG_SHORT_PREAMBLE                         = 0x2
@@ -5931,3 +6001,34 @@ type CachestatRange struct {
 	Off uint64
 	Len uint64
 }
+
+const (
+	SK_MEMINFO_RMEM_ALLOC          = 0x0
+	SK_MEMINFO_RCVBUF              = 0x1
+	SK_MEMINFO_WMEM_ALLOC          = 0x2
+	SK_MEMINFO_SNDBUF              = 0x3
+	SK_MEMINFO_FWD_ALLOC           = 0x4
+	SK_MEMINFO_WMEM_QUEUED         = 0x5
+	SK_MEMINFO_OPTMEM              = 0x6
+	SK_MEMINFO_BACKLOG             = 0x7
+	SK_MEMINFO_DROPS               = 0x8
+	SK_MEMINFO_VARS                = 0x9
+	SKNLGRP_NONE                   = 0x0
+	SKNLGRP_INET_TCP_DESTROY       = 0x1
+	SKNLGRP_INET_UDP_DESTROY       = 0x2
+	SKNLGRP_INET6_TCP_DESTROY      = 0x3
+	SKNLGRP_INET6_UDP_DESTROY      = 0x4
+	SK_DIAG_BPF_STORAGE_REQ_NONE   = 0x0
+	SK_DIAG_BPF_STORAGE_REQ_MAP_FD = 0x1
+	SK_DIAG_BPF_STORAGE_REP_NONE   = 0x0
+	SK_DIAG_BPF_STORAGE            = 0x1
+	SK_DIAG_BPF_STORAGE_NONE       = 0x0
+	SK_DIAG_BPF_STORAGE_PAD        = 0x1
+	SK_DIAG_BPF_STORAGE_MAP_ID     = 0x2
+	SK_DIAG_BPF_STORAGE_MAP_VALUE  = 0x3
+)
+
+type SockDiagReq struct {
+	Family   uint8
+	Protocol uint8
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
index 438a30af..fd402da4 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
@@ -477,14 +477,6 @@ const (
 	BLKPG = 0x1269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-}
-
 type CryptoUserAlg struct {
 	Name        [64]int8
 	Driver_name [64]int8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
index adceca35..eb7a5e18 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
@@ -492,15 +492,6 @@ const (
 	BLKPG = 0x1269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]int8
 	Driver_name [64]int8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
index eeaa00a3..d78ac108 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
@@ -470,15 +470,6 @@ const (
 	BLKPG = 0x1269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]uint8
 	Driver_name [64]uint8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
index 6739aa91..cd06d47f 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
@@ -471,15 +471,6 @@ const (
 	BLKPG = 0x1269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]int8
 	Driver_name [64]int8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go
index 9920ef63..2f28fe26 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go
@@ -472,15 +472,6 @@ const (
 	BLKPG = 0x1269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]int8
 	Driver_name [64]int8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
index 2923b799..71d6cac2 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
@@ -476,15 +476,6 @@ const (
 	BLKPG = 0x20001269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]int8
 	Driver_name [64]int8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
index ce2750ee..8596d453 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
@@ -474,15 +474,6 @@ const (
 	BLKPG = 0x20001269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]int8
 	Driver_name [64]int8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
index 3038811d..cd60ea18 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
@@ -474,15 +474,6 @@ const (
 	BLKPG = 0x20001269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]int8
 	Driver_name [64]int8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
index efc6fed1..b0ae420c 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
@@ -476,15 +476,6 @@ const (
 	BLKPG = 0x20001269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]int8
 	Driver_name [64]int8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go
index 9a654b75..83597287 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go
@@ -482,15 +482,6 @@ const (
 	BLKPG = 0x20001269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]uint8
 	Driver_name [64]uint8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
index 40d358e3..69eb6a5c 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
@@ -481,15 +481,6 @@ const (
 	BLKPG = 0x20001269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]uint8
 	Driver_name [64]uint8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
index 148c6ceb..5f583cb6 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
@@ -481,15 +481,6 @@ const (
 	BLKPG = 0x20001269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]uint8
 	Driver_name [64]uint8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
index 72ba8154..15adc041 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
@@ -499,15 +499,6 @@ const (
 	BLKPG = 0x1269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]uint8
 	Driver_name [64]uint8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
index 71e76550..cf3ce900 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
@@ -495,15 +495,6 @@ const (
 	BLKPG = 0x1269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]int8
 	Driver_name [64]int8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go
index 4abbdb9d..590b5673 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go
@@ -476,15 +476,6 @@ const (
 	BLKPG = 0x20001269
 )
 
-type XDPUmemReg struct {
-	Addr     uint64
-	Len      uint64
-	Size     uint32
-	Headroom uint32
-	Flags    uint32
-	_        [4]byte
-}
-
 type CryptoUserAlg struct {
 	Name        [64]int8
 	Driver_name [64]int8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go
index 54f31be6..d9a13af4 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go
@@ -25,10 +25,13 @@ const (
 	SizeofIPv6Mreq      = 20
 	SizeofICMPv6Filter  = 32
 	SizeofIPv6MTUInfo   = 32
+	SizeofInet4Pktinfo  = 8
+	SizeofInet6Pktinfo  = 20
 	SizeofLinger        = 8
 	SizeofSockaddrInet4 = 16
 	SizeofSockaddrInet6 = 28
 	SizeofTCPInfo       = 0x68
+	SizeofUcred         = 12
 )
 
 type (
@@ -69,12 +72,17 @@ type Utimbuf struct {
 }
 
 type Utsname struct {
-	Sysname    [65]byte
-	Nodename   [65]byte
-	Release    [65]byte
-	Version    [65]byte
-	Machine    [65]byte
-	Domainname [65]byte
+	Sysname  [16]byte
+	Nodename [32]byte
+	Release  [8]byte
+	Version  [8]byte
+	Machine  [16]byte
+}
+
+type Ucred struct {
+	Pid int32
+	Uid uint32
+	Gid uint32
 }
 
 type RawSockaddrInet4 struct {
@@ -325,7 +333,7 @@ type Statvfs_t struct {
 }
 
 type Statfs_t struct {
-	Type    uint32
+	Type    uint64
 	Bsize   uint64
 	Blocks  uint64
 	Bfree   uint64
@@ -336,6 +344,7 @@ type Statfs_t struct {
 	Namelen uint64
 	Frsize  uint64
 	Flags   uint64
+	_       [4]uint64
 }
 
 type direntLE struct {
@@ -412,3 +421,126 @@ type W_Mntent struct {
 	Quiesceowner [8]byte
 	_            [38]byte
 }
+
+type EpollEvent struct {
+	Events uint32
+	_      int32
+	Fd     int32
+	Pad    int32
+}
+
+type InotifyEvent struct {
+	Wd     int32
+	Mask   uint32
+	Cookie uint32
+	Len    uint32
+	Name   string
+}
+
+const (
+	SizeofInotifyEvent = 0x10
+)
+
+type ConsMsg2 struct {
+	Cm2Format       uint16
+	Cm2R1           uint16
+	Cm2Msglength    uint32
+	Cm2Msg          *byte
+	Cm2R2           [4]byte
+	Cm2R3           [4]byte
+	Cm2Routcde      *uint32
+	Cm2Descr        *uint32
+	Cm2Msgflag      uint32
+	Cm2Token        uint32
+	Cm2Msgid        *uint32
+	Cm2R4           [4]byte
+	Cm2DomToken     uint32
+	Cm2DomMsgid     *uint32
+	Cm2ModCartptr   *byte
+	Cm2ModConsidptr *byte
+	Cm2MsgCart      [8]byte
+	Cm2MsgConsid    [4]byte
+	Cm2R5           [12]byte
+}
+
+const (
+	CC_modify        = 1
+	CC_stop          = 2
+	CONSOLE_FORMAT_2 = 2
+	CONSOLE_FORMAT_3 = 3
+	CONSOLE_HRDCPY   = 0x80000000
+)
+
+type OpenHow struct {
+	Flags   uint64
+	Mode    uint64
+	Resolve uint64
+}
+
+const SizeofOpenHow = 0x18
+
+const (
+	RESOLVE_CACHED        = 0x20
+	RESOLVE_BENEATH       = 0x8
+	RESOLVE_IN_ROOT       = 0x10
+	RESOLVE_NO_MAGICLINKS = 0x2
+	RESOLVE_NO_SYMLINKS   = 0x4
+	RESOLVE_NO_XDEV       = 0x1
+)
+
+type Siginfo struct {
+	Signo int32
+	Errno int32
+	Code  int32
+	Pid   int32
+	Uid   uint32
+	_     [44]byte
+}
+
+type SysvIpcPerm struct {
+	Uid  uint32
+	Gid  uint32
+	Cuid uint32
+	Cgid uint32
+	Mode int32
+}
+
+type SysvShmDesc struct {
+	Perm   SysvIpcPerm
+	_      [4]byte
+	Lpid   int32
+	Cpid   int32
+	Nattch uint32
+	_      [4]byte
+	_      [4]byte
+	_      [4]byte
+	_      int32
+	_      uint8
+	_      uint8
+	_      uint16
+	_      *byte
+	Segsz  uint64
+	Atime  Time_t
+	Dtime  Time_t
+	Ctime  Time_t
+}
+
+type SysvShmDesc64 struct {
+	Perm   SysvIpcPerm
+	_      [4]byte
+	Lpid   int32
+	Cpid   int32
+	Nattch uint32
+	_      [4]byte
+	_      [4]byte
+	_      [4]byte
+	_      int32
+	_      byte
+	_      uint8
+	_      uint16
+	_      *byte
+	Segsz  uint64
+	Atime  int64
+	Dtime  int64
+	Ctime  int64
+}
diff --git a/vendor/golang.org/x/sys/windows/aliases.go b/vendor/golang.org/x/sys/windows/aliases.go
index ce2d713d..16f90560 100644
--- a/vendor/golang.org/x/sys/windows/aliases.go
+++ b/vendor/golang.org/x/sys/windows/aliases.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build windows && go1.9
+//go:build windows
 
 package windows
 
diff --git a/vendor/golang.org/x/sys/windows/empty.s b/vendor/golang.org/x/sys/windows/empty.s
deleted file mode 100644
index ba64caca..00000000
--- a/vendor/golang.org/x/sys/windows/empty.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !go1.12
-
-// This file is here to allow bodyless functions with go:linkname for Go 1.11
-// and earlier (see https://golang.org/issue/23311).
diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go
index 26be94a8..97651b5b 100644
--- a/vendor/golang.org/x/sys/windows/security_windows.go
+++ b/vendor/golang.org/x/sys/windows/security_windows.go
@@ -68,6 +68,7 @@ type UserInfo10 struct {
 //sys	NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
 //sys	NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
 //sys	NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
+//sys   NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) = netapi32.NetUserEnum
 
 const (
 	// do not reorder
@@ -893,7 +894,7 @@ type ACL struct {
 	aclRevision byte
 	sbz1        byte
 	aclSize     uint16
-	aceCount    uint16
+	AceCount    uint16
 	sbz2        uint16
 }
 
@@ -1086,6 +1087,27 @@ type EXPLICIT_ACCESS struct {
 	Trustee           TRUSTEE
 }
 
+// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
+type ACE_HEADER struct {
+	AceType  uint8
+	AceFlags uint8
+	AceSize  uint16
+}
+
+// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace
+type ACCESS_ALLOWED_ACE struct {
+	Header   ACE_HEADER
+	Mask     ACCESS_MASK
+	SidStart uint32
+}
+
+const (
+	// Constants for AceType
+	// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
+	ACCESS_ALLOWED_ACE_TYPE = 0
+	ACCESS_DENIED_ACE_TYPE  = 1
+)
+
 // This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
 type TrusteeValue uintptr
 
@@ -1157,6 +1179,7 @@ type OBJECTS_AND_NAME struct {
 //sys	makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
 
 //sys	setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW
+//sys	GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (ret error) = advapi32.GetAce
 
 // Control returns the security descriptor control bits.
 func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {
diff --git a/vendor/golang.org/x/sys/windows/svc/service.go b/vendor/golang.org/x/sys/windows/svc/service.go
index c96932d9..c4f74924 100644
--- a/vendor/golang.org/x/sys/windows/svc/service.go
+++ b/vendor/golang.org/x/sys/windows/svc/service.go
@@ -199,9 +199,8 @@ var (
 )
 
 func ctlHandler(ctl, evtype, evdata, context uintptr) uintptr {
-	s := (*service)(unsafe.Pointer(context))
 	e := ctlEvent{cmd: Cmd(ctl), eventType: uint32(evtype), eventData: evdata, context: 123456} // Set context to 123456 to test issue #25660.
-	s.c <- e
+	theService.c <- e
 	return 0
 }
 
@@ -210,7 +209,7 @@ var theService service // This is, unfortunately, a global, which means only one
 // serviceMain is the entry point called by the service manager, registered earlier by
 // the call to StartServiceCtrlDispatcher.
 func serviceMain(argc uint32, argv **uint16) uintptr {
-	handle, err := windows.RegisterServiceCtrlHandlerEx(windows.StringToUTF16Ptr(theService.name), ctlHandlerCallback, uintptr(unsafe.Pointer(&theService)))
+	handle, err := windows.RegisterServiceCtrlHandlerEx(windows.StringToUTF16Ptr(theService.name), ctlHandlerCallback, 0)
 	if sysErr, ok := err.(windows.Errno); ok {
 		return uintptr(sysErr)
 	} else if err != nil {
diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go
index 6395a031..6525c62f 100644
--- a/vendor/golang.org/x/sys/windows/syscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/syscall_windows.go
@@ -165,6 +165,7 @@ func NewCallbackCDecl(fn interface{}) uintptr {
 //sys	CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
 //sys	CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error)  [failretval==InvalidHandle] = CreateNamedPipeW
 //sys	ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error)
+//sys	DisconnectNamedPipe(pipe Handle) (err error)
 //sys	GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error)
 //sys	GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
 //sys	SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) = SetNamedPipeHandleState
@@ -348,8 +349,19 @@ func NewCallbackCDecl(fn interface{}) uintptr {
 //sys	SetProcessPriorityBoost(process Handle, disable bool) (err error) = kernel32.SetProcessPriorityBoost
 //sys	GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32)
 //sys	SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error)
+//sys	ClearCommBreak(handle Handle) (err error)
+//sys	ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error)
+//sys	EscapeCommFunction(handle Handle, dwFunc uint32) (err error)
+//sys	GetCommState(handle Handle, lpDCB *DCB) (err error)
+//sys	GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error)
 //sys	GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error)
+//sys	PurgeComm(handle Handle, dwFlags uint32) (err error)
+//sys	SetCommBreak(handle Handle) (err error)
+//sys	SetCommMask(handle Handle, dwEvtMask uint32) (err error)
+//sys	SetCommState(handle Handle, lpDCB *DCB) (err error)
 //sys	SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error)
+//sys	SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error)
+//sys	WaitCommEvent(handle Handle, lpEvtMask *uint32, lpOverlapped *Overlapped) (err error)
 //sys	GetActiveProcessorCount(groupNumber uint16) (ret uint32)
 //sys	GetMaximumProcessorCount(groupNumber uint16) (ret uint32)
 //sys	EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) = user32.EnumWindows
@@ -1834,3 +1846,73 @@ func ResizePseudoConsole(pconsole Handle, size Coord) error {
 	// accept arguments that can be casted to uintptr, and Coord can't.
 	return resizePseudoConsole(pconsole, *((*uint32)(unsafe.Pointer(&size))))
 }
+
+// DCB constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-dcb.
+const (
+	CBR_110    = 110
+	CBR_300    = 300
+	CBR_600    = 600
+	CBR_1200   = 1200
+	CBR_2400   = 2400
+	CBR_4800   = 4800
+	CBR_9600   = 9600
+	CBR_14400  = 14400
+	CBR_19200  = 19200
+	CBR_38400  = 38400
+	CBR_57600  = 57600
+	CBR_115200 = 115200
+	CBR_128000 = 128000
+	CBR_256000 = 256000
+
+	DTR_CONTROL_DISABLE   = 0x00000000
+	DTR_CONTROL_ENABLE    = 0x00000010
+	DTR_CONTROL_HANDSHAKE = 0x00000020
+
+	RTS_CONTROL_DISABLE   = 0x00000000
+	RTS_CONTROL_ENABLE    = 0x00001000
+	RTS_CONTROL_HANDSHAKE = 0x00002000
+	RTS_CONTROL_TOGGLE    = 0x00003000
+
+	NOPARITY    = 0
+	ODDPARITY   = 1
+	EVENPARITY  = 2
+	MARKPARITY  = 3
+	SPACEPARITY = 4
+
+	ONESTOPBIT   = 0
+	ONE5STOPBITS = 1
+	TWOSTOPBITS  = 2
+)
+
+// EscapeCommFunction constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-escapecommfunction.
+const (
+	SETXOFF  = 1
+	SETXON   = 2
+	SETRTS   = 3
+	CLRRTS   = 4
+	SETDTR   = 5
+	CLRDTR   = 6
+	SETBREAK = 8
+	CLRBREAK = 9
+)
+
+// PurgeComm constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-purgecomm.
+const (
+	PURGE_TXABORT = 0x0001
+	PURGE_RXABORT = 0x0002
+	PURGE_TXCLEAR = 0x0004
+	PURGE_RXCLEAR = 0x0008
+)
+
+// SetCommMask constants. See https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setcommmask.
+const (
+	EV_RXCHAR  = 0x0001
+	EV_RXFLAG  = 0x0002
+	EV_TXEMPTY = 0x0004
+	EV_CTS     = 0x0008
+	EV_DSR     = 0x0010
+	EV_RLSD    = 0x0020
+	EV_BREAK   = 0x0040
+	EV_ERR     = 0x0080
+	EV_RING    = 0x0100
+)
diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go
index 359780f6..d8cb71db 100644
--- a/vendor/golang.org/x/sys/windows/types_windows.go
+++ b/vendor/golang.org/x/sys/windows/types_windows.go
@@ -3380,3 +3380,27 @@ type BLOB struct {
 	Size     uint32
 	BlobData *byte
 }
+
+type ComStat struct {
+	Flags    uint32
+	CBInQue  uint32
+	CBOutQue uint32
+}
+
+type DCB struct {
+	DCBlength  uint32
+	BaudRate   uint32
+	Flags      uint32
+	wReserved  uint16
+	XonLim     uint16
+	XoffLim    uint16
+	ByteSize   uint8
+	Parity     uint8
+	StopBits   uint8
+	XonChar    byte
+	XoffChar   byte
+	ErrorChar  byte
+	EofChar    byte
+	EvtChar    byte
+	wReserved1 uint16
+}
diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
index e8791c82..eba76101 100644
--- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
@@ -91,6 +91,7 @@ var (
 	procEnumServicesStatusExW                                = modadvapi32.NewProc("EnumServicesStatusExW")
 	procEqualSid                                             = modadvapi32.NewProc("EqualSid")
 	procFreeSid                                              = modadvapi32.NewProc("FreeSid")
+	procGetAce                                               = modadvapi32.NewProc("GetAce")
 	procGetLengthSid                                         = modadvapi32.NewProc("GetLengthSid")
 	procGetNamedSecurityInfoW                                = modadvapi32.NewProc("GetNamedSecurityInfoW")
 	procGetSecurityDescriptorControl                         = modadvapi32.NewProc("GetSecurityDescriptorControl")
@@ -188,6 +189,8 @@ var (
 	procAssignProcessToJobObject                             = modkernel32.NewProc("AssignProcessToJobObject")
 	procCancelIo                                             = modkernel32.NewProc("CancelIo")
 	procCancelIoEx                                           = modkernel32.NewProc("CancelIoEx")
+	procClearCommBreak                                       = modkernel32.NewProc("ClearCommBreak")
+	procClearCommError                                       = modkernel32.NewProc("ClearCommError")
 	procCloseHandle                                          = modkernel32.NewProc("CloseHandle")
 	procClosePseudoConsole                                   = modkernel32.NewProc("ClosePseudoConsole")
 	procConnectNamedPipe                                     = modkernel32.NewProc("ConnectNamedPipe")
@@ -212,7 +215,9 @@ var (
 	procDeleteProcThreadAttributeList                        = modkernel32.NewProc("DeleteProcThreadAttributeList")
 	procDeleteVolumeMountPointW                              = modkernel32.NewProc("DeleteVolumeMountPointW")
 	procDeviceIoControl                                      = modkernel32.NewProc("DeviceIoControl")
+	procDisconnectNamedPipe                                  = modkernel32.NewProc("DisconnectNamedPipe")
 	procDuplicateHandle                                      = modkernel32.NewProc("DuplicateHandle")
+	procEscapeCommFunction                                   = modkernel32.NewProc("EscapeCommFunction")
 	procExitProcess                                          = modkernel32.NewProc("ExitProcess")
 	procExpandEnvironmentStringsW                            = modkernel32.NewProc("ExpandEnvironmentStringsW")
 	procFindClose                                            = modkernel32.NewProc("FindClose")
@@ -236,6 +241,8 @@ var (
 	procGenerateConsoleCtrlEvent                             = modkernel32.NewProc("GenerateConsoleCtrlEvent")
 	procGetACP                                               = modkernel32.NewProc("GetACP")
 	procGetActiveProcessorCount                              = modkernel32.NewProc("GetActiveProcessorCount")
+	procGetCommModemStatus                                   = modkernel32.NewProc("GetCommModemStatus")
+	procGetCommState                                         = modkernel32.NewProc("GetCommState")
 	procGetCommTimeouts                                      = modkernel32.NewProc("GetCommTimeouts")
 	procGetCommandLineW                                      = modkernel32.NewProc("GetCommandLineW")
 	procGetComputerNameExW                                   = modkernel32.NewProc("GetComputerNameExW")
@@ -322,6 +329,7 @@ var (
 	procProcess32NextW                                       = modkernel32.NewProc("Process32NextW")
 	procProcessIdToSessionId                                 = modkernel32.NewProc("ProcessIdToSessionId")
 	procPulseEvent                                           = modkernel32.NewProc("PulseEvent")
+	procPurgeComm                                            = modkernel32.NewProc("PurgeComm")
 	procQueryDosDeviceW                                      = modkernel32.NewProc("QueryDosDeviceW")
 	procQueryFullProcessImageNameW                           = modkernel32.NewProc("QueryFullProcessImageNameW")
 	procQueryInformationJobObject                            = modkernel32.NewProc("QueryInformationJobObject")
@@ -335,6 +343,9 @@ var (
 	procResetEvent                                           = modkernel32.NewProc("ResetEvent")
 	procResizePseudoConsole                                  = modkernel32.NewProc("ResizePseudoConsole")
 	procResumeThread                                         = modkernel32.NewProc("ResumeThread")
+	procSetCommBreak                                         = modkernel32.NewProc("SetCommBreak")
+	procSetCommMask                                          = modkernel32.NewProc("SetCommMask")
+	procSetCommState                                         = modkernel32.NewProc("SetCommState")
 	procSetCommTimeouts                                      = modkernel32.NewProc("SetCommTimeouts")
 	procSetConsoleCursorPosition                             = modkernel32.NewProc("SetConsoleCursorPosition")
 	procSetConsoleMode                                       = modkernel32.NewProc("SetConsoleMode")
@@ -342,7 +353,6 @@ var (
 	procSetDefaultDllDirectories                             = modkernel32.NewProc("SetDefaultDllDirectories")
 	procSetDllDirectoryW                                     = modkernel32.NewProc("SetDllDirectoryW")
 	procSetEndOfFile                                         = modkernel32.NewProc("SetEndOfFile")
-	procSetFileValidData                                     = modkernel32.NewProc("SetFileValidData")
 	procSetEnvironmentVariableW                              = modkernel32.NewProc("SetEnvironmentVariableW")
 	procSetErrorMode                                         = modkernel32.NewProc("SetErrorMode")
 	procSetEvent                                             = modkernel32.NewProc("SetEvent")
@@ -351,6 +361,7 @@ var (
 	procSetFileInformationByHandle                           = modkernel32.NewProc("SetFileInformationByHandle")
 	procSetFilePointer                                       = modkernel32.NewProc("SetFilePointer")
 	procSetFileTime                                          = modkernel32.NewProc("SetFileTime")
+	procSetFileValidData                                     = modkernel32.NewProc("SetFileValidData")
 	procSetHandleInformation                                 = modkernel32.NewProc("SetHandleInformation")
 	procSetInformationJobObject                              = modkernel32.NewProc("SetInformationJobObject")
 	procSetNamedPipeHandleState                              = modkernel32.NewProc("SetNamedPipeHandleState")
@@ -361,6 +372,7 @@ var (
 	procSetStdHandle                                         = modkernel32.NewProc("SetStdHandle")
 	procSetVolumeLabelW                                      = modkernel32.NewProc("SetVolumeLabelW")
 	procSetVolumeMountPointW                                 = modkernel32.NewProc("SetVolumeMountPointW")
+	procSetupComm                                            = modkernel32.NewProc("SetupComm")
 	procSizeofResource                                       = modkernel32.NewProc("SizeofResource")
 	procSleepEx                                              = modkernel32.NewProc("SleepEx")
 	procTerminateJobObject                                   = modkernel32.NewProc("TerminateJobObject")
@@ -379,6 +391,7 @@ var (
 	procVirtualQueryEx                                       = modkernel32.NewProc("VirtualQueryEx")
 	procVirtualUnlock                                        = modkernel32.NewProc("VirtualUnlock")
 	procWTSGetActiveConsoleSessionId                         = modkernel32.NewProc("WTSGetActiveConsoleSessionId")
+	procWaitCommEvent                                        = modkernel32.NewProc("WaitCommEvent")
 	procWaitForMultipleObjects                               = modkernel32.NewProc("WaitForMultipleObjects")
 	procWaitForSingleObject                                  = modkernel32.NewProc("WaitForSingleObject")
 	procWriteConsoleW                                        = modkernel32.NewProc("WriteConsoleW")
@@ -389,6 +402,7 @@ var (
 	procTransmitFile                                         = modmswsock.NewProc("TransmitFile")
 	procNetApiBufferFree                                     = modnetapi32.NewProc("NetApiBufferFree")
 	procNetGetJoinInformation                                = modnetapi32.NewProc("NetGetJoinInformation")
+	procNetUserEnum                                          = modnetapi32.NewProc("NetUserEnum")
 	procNetUserGetInfo                                       = modnetapi32.NewProc("NetUserGetInfo")
 	procNtCreateFile                                         = modntdll.NewProc("NtCreateFile")
 	procNtCreateNamedPipeFile                                = modntdll.NewProc("NtCreateNamedPipeFile")
@@ -1211,6 +1225,14 @@ func setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCE
 	return
 }
 
+func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (ret error) {
+	r0, _, _ := syscall.Syscall(procGetAce.Addr(), 3, uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce)))
+	if r0 == 0 {
+		ret = GetLastError()
+	}
+	return
+}
+
 func SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) {
 	r1, _, e1 := syscall.Syscall(procSetKernelObjectSecurity.Addr(), 3, uintptr(handle), uintptr(securityInformation), uintptr(unsafe.Pointer(securityDescriptor)))
 	if r1 == 0 {
@@ -1641,6 +1663,22 @@ func CancelIoEx(s Handle, o *Overlapped) (err error) {
 	return
 }
 
+func ClearCommBreak(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procClearCommBreak.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error) {
+	r1, _, e1 := syscall.Syscall(procClearCommError.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(lpErrors)), uintptr(unsafe.Pointer(lpStat)))
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func CloseHandle(handle Handle) (err error) {
 	r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0)
 	if r1 == 0 {
@@ -1845,6 +1883,14 @@ func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBuff
 	return
 }
 
+func DisconnectNamedPipe(pipe Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procDisconnectNamedPipe.Addr(), 1, uintptr(pipe), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
 	var _p0 uint32
 	if bInheritHandle {
@@ -1857,6 +1903,14 @@ func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetP
 	return
 }
 
+func EscapeCommFunction(handle Handle, dwFunc uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procEscapeCommFunction.Addr(), 2, uintptr(handle), uintptr(dwFunc), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func ExitProcess(exitcode uint32) {
 	syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0)
 	return
@@ -2058,6 +2112,22 @@ func GetActiveProcessorCount(groupNumber uint16) (ret uint32) {
 	return
 }
 
+func GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetCommModemStatus.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpModemStat)), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func GetCommState(handle Handle, lpDCB *DCB) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpDCB)), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
 	r1, _, e1 := syscall.Syscall(procGetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0)
 	if r1 == 0 {
@@ -2810,6 +2880,14 @@ func PulseEvent(event Handle) (err error) {
 	return
 }
 
+func PurgeComm(handle Handle, dwFlags uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procPurgeComm.Addr(), 2, uintptr(handle), uintptr(dwFlags), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) {
 	r0, _, e1 := syscall.Syscall(procQueryDosDeviceW.Addr(), 3, uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max))
 	n = uint32(r0)
@@ -2924,6 +3002,30 @@ func ResumeThread(thread Handle) (ret uint32, err error) {
 	return
 }
 
+func SetCommBreak(handle Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetCommBreak.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func SetCommMask(handle Handle, dwEvtMask uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetCommMask.Addr(), 2, uintptr(handle), uintptr(dwEvtMask), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func SetCommState(handle Handle, lpDCB *DCB) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpDCB)), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
 	r1, _, e1 := syscall.Syscall(procSetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0)
 	if r1 == 0 {
@@ -2989,14 +3091,6 @@ func SetEndOfFile(handle Handle) (err error) {
 	return
 }
 
-func SetFileValidData(handle Handle, validDataLength int64) (err error) {
-	r1, _, e1 := syscall.Syscall(procSetFileValidData.Addr(), 2, uintptr(handle), uintptr(validDataLength), 0)
-	if r1 == 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
 func SetEnvironmentVariable(name *uint16, value *uint16) (err error) {
 	r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0)
 	if r1 == 0 {
@@ -3060,6 +3154,14 @@ func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetim
 	return
 }
 
+func SetFileValidData(handle Handle, validDataLength int64) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetFileValidData.Addr(), 2, uintptr(handle), uintptr(validDataLength), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) {
 	r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags))
 	if r1 == 0 {
@@ -3145,6 +3247,14 @@ func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err erro
 	return
 }
 
+func SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetupComm.Addr(), 3, uintptr(handle), uintptr(dwInQueue), uintptr(dwOutQueue))
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func SizeofResource(module Handle, resInfo Handle) (size uint32, err error) {
 	r0, _, e1 := syscall.Syscall(procSizeofResource.Addr(), 2, uintptr(module), uintptr(resInfo), 0)
 	size = uint32(r0)
@@ -3291,6 +3401,14 @@ func WTSGetActiveConsoleSessionId() (sessionID uint32) {
 	return
 }
 
+func WaitCommEvent(handle Handle, lpEvtMask *uint32, lpOverlapped *Overlapped) (err error) {
+	r1, _, e1 := syscall.Syscall(procWaitCommEvent.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(lpEvtMask)), uintptr(unsafe.Pointer(lpOverlapped)))
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMilliseconds uint32) (event uint32, err error) {
 	var _p0 uint32
 	if waitAll {
@@ -3378,6 +3496,14 @@ func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (nete
 	return
 }
 
+func NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) {
+	r0, _, _ := syscall.Syscall9(procNetUserEnum.Addr(), 8, uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(filter), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), uintptr(unsafe.Pointer(resumeHandle)), 0)
+	if r0 != 0 {
+		neterr = syscall.Errno(r0)
+	}
+	return
+}
+
 func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) {
 	r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0)
 	if r0 != 0 {
diff --git a/vendor/gopkg.in/yaml.v2/.travis.yml b/vendor/gopkg.in/yaml.v2/.travis.yml
deleted file mode 100644
index 7348c50c..00000000
--- a/vendor/gopkg.in/yaml.v2/.travis.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-language: go
-
-go:
-    - "1.4.x"
-    - "1.5.x"
-    - "1.6.x"
-    - "1.7.x"
-    - "1.8.x"
-    - "1.9.x"
-    - "1.10.x"
-    - "1.11.x"
-    - "1.12.x"
-    - "1.13.x"
-    - "1.14.x"
-    - "tip"
-
-go_import_path: gopkg.in/yaml.v2
diff --git a/vendor/gopkg.in/yaml.v2/LICENSE.libyaml b/vendor/gopkg.in/yaml.v2/LICENSE.libyaml
deleted file mode 100644
index 8da58fbf..00000000
--- a/vendor/gopkg.in/yaml.v2/LICENSE.libyaml
+++ /dev/null
@@ -1,31 +0,0 @@
-The following files were ported to Go from C files of libyaml, and thus
-are still covered by their original copyright and license:
-
-    apic.go
-    emitterc.go
-    parserc.go
-    readerc.go
-    scannerc.go
-    writerc.go
-    yamlh.go
-    yamlprivateh.go
-
-Copyright (c) 2006 Kirill Simonov
-
-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/gopkg.in/yaml.v2/README.md b/vendor/gopkg.in/yaml.v2/README.md
deleted file mode 100644
index b50c6e87..00000000
--- a/vendor/gopkg.in/yaml.v2/README.md
+++ /dev/null
@@ -1,133 +0,0 @@
-# YAML support for the Go language
-
-Introduction
-------------
-
-The yaml package enables Go programs to comfortably encode and decode YAML
-values. It was developed within [Canonical](https://www.canonical.com) as
-part of the [juju](https://juju.ubuntu.com) project, and is based on a
-pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
-C library to parse and generate YAML data quickly and reliably.
-
-Compatibility
--------------
-
-The yaml package supports most of YAML 1.1 and 1.2, including support for
-anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
-implemented, and base-60 floats from YAML 1.1 are purposefully not
-supported since they're a poor design and are gone in YAML 1.2.
-
-Installation and usage
-----------------------
-
-The import path for the package is *gopkg.in/yaml.v2*.
-
-To install it, run:
-
-    go get gopkg.in/yaml.v2
-
-API documentation
------------------
-
-If opened in a browser, the import path itself leads to the API documentation:
-
-  * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2)
-
-API stability
--------------
-
-The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in).
-
-
-License
--------
-
-The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details.
-
-
-Example
--------
-
-```Go
-package main
-
-import (
-        "fmt"
-        "log"
-
-        "gopkg.in/yaml.v2"
-)
-
-var data = `
-a: Easy!
-b:
-  c: 2
-  d: [3, 4]
-`
-
-// Note: struct fields must be public in order for unmarshal to
-// correctly populate the data.
-type T struct {
-        A string
-        B struct {
-                RenamedC int   `yaml:"c"`
-                D        []int `yaml:",flow"`
-        }
-}
-
-func main() {
-        t := T{}
-    
-        err := yaml.Unmarshal([]byte(data), &t)
-        if err != nil {
-                log.Fatalf("error: %v", err)
-        }
-        fmt.Printf("--- t:\n%v\n\n", t)
-    
-        d, err := yaml.Marshal(&t)
-        if err != nil {
-                log.Fatalf("error: %v", err)
-        }
-        fmt.Printf("--- t dump:\n%s\n\n", string(d))
-    
-        m := make(map[interface{}]interface{})
-    
-        err = yaml.Unmarshal([]byte(data), &m)
-        if err != nil {
-                log.Fatalf("error: %v", err)
-        }
-        fmt.Printf("--- m:\n%v\n\n", m)
-    
-        d, err = yaml.Marshal(&m)
-        if err != nil {
-                log.Fatalf("error: %v", err)
-        }
-        fmt.Printf("--- m dump:\n%s\n\n", string(d))
-}
-```
-
-This example will generate the following output:
-
-```
---- t:
-{Easy! {2 [3 4]}}
-
---- t dump:
-a: Easy!
-b:
-  c: 2
-  d: [3, 4]
-
-
---- m:
-map[a:Easy! b:map[c:2 d:[3 4]]]
-
---- m dump:
-a: Easy!
-b:
-  c: 2
-  d:
-  - 3
-  - 4
-```
-
diff --git a/vendor/gopkg.in/yaml.v2/apic.go b/vendor/gopkg.in/yaml.v2/apic.go
deleted file mode 100644
index acf71402..00000000
--- a/vendor/gopkg.in/yaml.v2/apic.go
+++ /dev/null
@@ -1,744 +0,0 @@
-package yaml
-
-import (
-	"io"
-)
-
-func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
-	//fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens))
-
-	// Check if we can move the queue at the beginning of the buffer.
-	if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) {
-		if parser.tokens_head != len(parser.tokens) {
-			copy(parser.tokens, parser.tokens[parser.tokens_head:])
-		}
-		parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head]
-		parser.tokens_head = 0
-	}
-	parser.tokens = append(parser.tokens, *token)
-	if pos < 0 {
-		return
-	}
-	copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:])
-	parser.tokens[parser.tokens_head+pos] = *token
-}
-
-// Create a new parser object.
-func yaml_parser_initialize(parser *yaml_parser_t) bool {
-	*parser = yaml_parser_t{
-		raw_buffer: make([]byte, 0, input_raw_buffer_size),
-		buffer:     make([]byte, 0, input_buffer_size),
-	}
-	return true
-}
-
-// Destroy a parser object.
-func yaml_parser_delete(parser *yaml_parser_t) {
-	*parser = yaml_parser_t{}
-}
-
-// String read handler.
-func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
-	if parser.input_pos == len(parser.input) {
-		return 0, io.EOF
-	}
-	n = copy(buffer, parser.input[parser.input_pos:])
-	parser.input_pos += n
-	return n, nil
-}
-
-// Reader read handler.
-func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
-	return parser.input_reader.Read(buffer)
-}
-
-// Set a string input.
-func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {
-	if parser.read_handler != nil {
-		panic("must set the input source only once")
-	}
-	parser.read_handler = yaml_string_read_handler
-	parser.input = input
-	parser.input_pos = 0
-}
-
-// Set a file input.
-func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) {
-	if parser.read_handler != nil {
-		panic("must set the input source only once")
-	}
-	parser.read_handler = yaml_reader_read_handler
-	parser.input_reader = r
-}
-
-// Set the source encoding.
-func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
-	if parser.encoding != yaml_ANY_ENCODING {
-		panic("must set the encoding only once")
-	}
-	parser.encoding = encoding
-}
-
-var disableLineWrapping = false
-
-// Create a new emitter object.
-func yaml_emitter_initialize(emitter *yaml_emitter_t) {
-	*emitter = yaml_emitter_t{
-		buffer:     make([]byte, output_buffer_size),
-		raw_buffer: make([]byte, 0, output_raw_buffer_size),
-		states:     make([]yaml_emitter_state_t, 0, initial_stack_size),
-		events:     make([]yaml_event_t, 0, initial_queue_size),
-	}
-	if disableLineWrapping {
-		emitter.best_width = -1
-	}
-}
-
-// Destroy an emitter object.
-func yaml_emitter_delete(emitter *yaml_emitter_t) {
-	*emitter = yaml_emitter_t{}
-}
-
-// String write handler.
-func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
-	*emitter.output_buffer = append(*emitter.output_buffer, buffer...)
-	return nil
-}
-
-// yaml_writer_write_handler uses emitter.output_writer to write the
-// emitted text.
-func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
-	_, err := emitter.output_writer.Write(buffer)
-	return err
-}
-
-// Set a string output.
-func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) {
-	if emitter.write_handler != nil {
-		panic("must set the output target only once")
-	}
-	emitter.write_handler = yaml_string_write_handler
-	emitter.output_buffer = output_buffer
-}
-
-// Set a file output.
-func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) {
-	if emitter.write_handler != nil {
-		panic("must set the output target only once")
-	}
-	emitter.write_handler = yaml_writer_write_handler
-	emitter.output_writer = w
-}
-
-// Set the output encoding.
-func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) {
-	if emitter.encoding != yaml_ANY_ENCODING {
-		panic("must set the output encoding only once")
-	}
-	emitter.encoding = encoding
-}
-
-// Set the canonical output style.
-func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) {
-	emitter.canonical = canonical
-}
-
-//// Set the indentation increment.
-func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) {
-	if indent < 2 || indent > 9 {
-		indent = 2
-	}
-	emitter.best_indent = indent
-}
-
-// Set the preferred line width.
-func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) {
-	if width < 0 {
-		width = -1
-	}
-	emitter.best_width = width
-}
-
-// Set if unescaped non-ASCII characters are allowed.
-func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) {
-	emitter.unicode = unicode
-}
-
-// Set the preferred line break character.
-func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
-	emitter.line_break = line_break
-}
-
-///*
-// * Destroy a token object.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_token_delete(yaml_token_t *token)
-//{
-//    assert(token);  // Non-NULL token object expected.
-//
-//    switch (token.type)
-//    {
-//        case YAML_TAG_DIRECTIVE_TOKEN:
-//            yaml_free(token.data.tag_directive.handle);
-//            yaml_free(token.data.tag_directive.prefix);
-//            break;
-//
-//        case YAML_ALIAS_TOKEN:
-//            yaml_free(token.data.alias.value);
-//            break;
-//
-//        case YAML_ANCHOR_TOKEN:
-//            yaml_free(token.data.anchor.value);
-//            break;
-//
-//        case YAML_TAG_TOKEN:
-//            yaml_free(token.data.tag.handle);
-//            yaml_free(token.data.tag.suffix);
-//            break;
-//
-//        case YAML_SCALAR_TOKEN:
-//            yaml_free(token.data.scalar.value);
-//            break;
-//
-//        default:
-//            break;
-//    }
-//
-//    memset(token, 0, sizeof(yaml_token_t));
-//}
-//
-///*
-// * Check if a string is a valid UTF-8 sequence.
-// *
-// * Check 'reader.c' for more details on UTF-8 encoding.
-// */
-//
-//static int
-//yaml_check_utf8(yaml_char_t *start, size_t length)
-//{
-//    yaml_char_t *end = start+length;
-//    yaml_char_t *pointer = start;
-//
-//    while (pointer < end) {
-//        unsigned char octet;
-//        unsigned int width;
-//        unsigned int value;
-//        size_t k;
-//
-//        octet = pointer[0];
-//        width = (octet & 0x80) == 0x00 ? 1 :
-//                (octet & 0xE0) == 0xC0 ? 2 :
-//                (octet & 0xF0) == 0xE0 ? 3 :
-//                (octet & 0xF8) == 0xF0 ? 4 : 0;
-//        value = (octet & 0x80) == 0x00 ? octet & 0x7F :
-//                (octet & 0xE0) == 0xC0 ? octet & 0x1F :
-//                (octet & 0xF0) == 0xE0 ? octet & 0x0F :
-//                (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
-//        if (!width) return 0;
-//        if (pointer+width > end) return 0;
-//        for (k = 1; k < width; k ++) {
-//            octet = pointer[k];
-//            if ((octet & 0xC0) != 0x80) return 0;
-//            value = (value << 6) + (octet & 0x3F);
-//        }
-//        if (!((width == 1) ||
-//            (width == 2 && value >= 0x80) ||
-//            (width == 3 && value >= 0x800) ||
-//            (width == 4 && value >= 0x10000))) return 0;
-//
-//        pointer += width;
-//    }
-//
-//    return 1;
-//}
-//
-
-// Create STREAM-START.
-func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) {
-	*event = yaml_event_t{
-		typ:      yaml_STREAM_START_EVENT,
-		encoding: encoding,
-	}
-}
-
-// Create STREAM-END.
-func yaml_stream_end_event_initialize(event *yaml_event_t) {
-	*event = yaml_event_t{
-		typ: yaml_STREAM_END_EVENT,
-	}
-}
-
-// Create DOCUMENT-START.
-func yaml_document_start_event_initialize(
-	event *yaml_event_t,
-	version_directive *yaml_version_directive_t,
-	tag_directives []yaml_tag_directive_t,
-	implicit bool,
-) {
-	*event = yaml_event_t{
-		typ:               yaml_DOCUMENT_START_EVENT,
-		version_directive: version_directive,
-		tag_directives:    tag_directives,
-		implicit:          implicit,
-	}
-}
-
-// Create DOCUMENT-END.
-func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) {
-	*event = yaml_event_t{
-		typ:      yaml_DOCUMENT_END_EVENT,
-		implicit: implicit,
-	}
-}
-
-///*
-// * Create ALIAS.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_alias_event_initialize(event *yaml_event_t, anchor *yaml_char_t)
-//{
-//    mark yaml_mark_t = { 0, 0, 0 }
-//    anchor_copy *yaml_char_t = NULL
-//
-//    assert(event) // Non-NULL event object is expected.
-//    assert(anchor) // Non-NULL anchor is expected.
-//
-//    if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0
-//
-//    anchor_copy = yaml_strdup(anchor)
-//    if (!anchor_copy)
-//        return 0
-//
-//    ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark)
-//
-//    return 1
-//}
-
-// Create SCALAR.
-func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool {
-	*event = yaml_event_t{
-		typ:             yaml_SCALAR_EVENT,
-		anchor:          anchor,
-		tag:             tag,
-		value:           value,
-		implicit:        plain_implicit,
-		quoted_implicit: quoted_implicit,
-		style:           yaml_style_t(style),
-	}
-	return true
-}
-
-// Create SEQUENCE-START.
-func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool {
-	*event = yaml_event_t{
-		typ:      yaml_SEQUENCE_START_EVENT,
-		anchor:   anchor,
-		tag:      tag,
-		implicit: implicit,
-		style:    yaml_style_t(style),
-	}
-	return true
-}
-
-// Create SEQUENCE-END.
-func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
-	*event = yaml_event_t{
-		typ: yaml_SEQUENCE_END_EVENT,
-	}
-	return true
-}
-
-// Create MAPPING-START.
-func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) {
-	*event = yaml_event_t{
-		typ:      yaml_MAPPING_START_EVENT,
-		anchor:   anchor,
-		tag:      tag,
-		implicit: implicit,
-		style:    yaml_style_t(style),
-	}
-}
-
-// Create MAPPING-END.
-func yaml_mapping_end_event_initialize(event *yaml_event_t) {
-	*event = yaml_event_t{
-		typ: yaml_MAPPING_END_EVENT,
-	}
-}
-
-// Destroy an event object.
-func yaml_event_delete(event *yaml_event_t) {
-	*event = yaml_event_t{}
-}
-
-///*
-// * Create a document object.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_initialize(document *yaml_document_t,
-//        version_directive *yaml_version_directive_t,
-//        tag_directives_start *yaml_tag_directive_t,
-//        tag_directives_end *yaml_tag_directive_t,
-//        start_implicit int, end_implicit int)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//    struct {
-//        start *yaml_node_t
-//        end *yaml_node_t
-//        top *yaml_node_t
-//    } nodes = { NULL, NULL, NULL }
-//    version_directive_copy *yaml_version_directive_t = NULL
-//    struct {
-//        start *yaml_tag_directive_t
-//        end *yaml_tag_directive_t
-//        top *yaml_tag_directive_t
-//    } tag_directives_copy = { NULL, NULL, NULL }
-//    value yaml_tag_directive_t = { NULL, NULL }
-//    mark yaml_mark_t = { 0, 0, 0 }
-//
-//    assert(document) // Non-NULL document object is expected.
-//    assert((tag_directives_start && tag_directives_end) ||
-//            (tag_directives_start == tag_directives_end))
-//                            // Valid tag directives are expected.
-//
-//    if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error
-//
-//    if (version_directive) {
-//        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t))
-//        if (!version_directive_copy) goto error
-//        version_directive_copy.major = version_directive.major
-//        version_directive_copy.minor = version_directive.minor
-//    }
-//
-//    if (tag_directives_start != tag_directives_end) {
-//        tag_directive *yaml_tag_directive_t
-//        if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
-//            goto error
-//        for (tag_directive = tag_directives_start
-//                tag_directive != tag_directives_end; tag_directive ++) {
-//            assert(tag_directive.handle)
-//            assert(tag_directive.prefix)
-//            if (!yaml_check_utf8(tag_directive.handle,
-//                        strlen((char *)tag_directive.handle)))
-//                goto error
-//            if (!yaml_check_utf8(tag_directive.prefix,
-//                        strlen((char *)tag_directive.prefix)))
-//                goto error
-//            value.handle = yaml_strdup(tag_directive.handle)
-//            value.prefix = yaml_strdup(tag_directive.prefix)
-//            if (!value.handle || !value.prefix) goto error
-//            if (!PUSH(&context, tag_directives_copy, value))
-//                goto error
-//            value.handle = NULL
-//            value.prefix = NULL
-//        }
-//    }
-//
-//    DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
-//            tag_directives_copy.start, tag_directives_copy.top,
-//            start_implicit, end_implicit, mark, mark)
-//
-//    return 1
-//
-//error:
-//    STACK_DEL(&context, nodes)
-//    yaml_free(version_directive_copy)
-//    while (!STACK_EMPTY(&context, tag_directives_copy)) {
-//        value yaml_tag_directive_t = POP(&context, tag_directives_copy)
-//        yaml_free(value.handle)
-//        yaml_free(value.prefix)
-//    }
-//    STACK_DEL(&context, tag_directives_copy)
-//    yaml_free(value.handle)
-//    yaml_free(value.prefix)
-//
-//    return 0
-//}
-//
-///*
-// * Destroy a document object.
-// */
-//
-//YAML_DECLARE(void)
-//yaml_document_delete(document *yaml_document_t)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//    tag_directive *yaml_tag_directive_t
-//
-//    context.error = YAML_NO_ERROR // Eliminate a compiler warning.
-//
-//    assert(document) // Non-NULL document object is expected.
-//
-//    while (!STACK_EMPTY(&context, document.nodes)) {
-//        node yaml_node_t = POP(&context, document.nodes)
-//        yaml_free(node.tag)
-//        switch (node.type) {
-//            case YAML_SCALAR_NODE:
-//                yaml_free(node.data.scalar.value)
-//                break
-//            case YAML_SEQUENCE_NODE:
-//                STACK_DEL(&context, node.data.sequence.items)
-//                break
-//            case YAML_MAPPING_NODE:
-//                STACK_DEL(&context, node.data.mapping.pairs)
-//                break
-//            default:
-//                assert(0) // Should not happen.
-//        }
-//    }
-//    STACK_DEL(&context, document.nodes)
-//
-//    yaml_free(document.version_directive)
-//    for (tag_directive = document.tag_directives.start
-//            tag_directive != document.tag_directives.end
-//            tag_directive++) {
-//        yaml_free(tag_directive.handle)
-//        yaml_free(tag_directive.prefix)
-//    }
-//    yaml_free(document.tag_directives.start)
-//
-//    memset(document, 0, sizeof(yaml_document_t))
-//}
-//
-///**
-// * Get a document node.
-// */
-//
-//YAML_DECLARE(yaml_node_t *)
-//yaml_document_get_node(document *yaml_document_t, index int)
-//{
-//    assert(document) // Non-NULL document object is expected.
-//
-//    if (index > 0 && document.nodes.start + index <= document.nodes.top) {
-//        return document.nodes.start + index - 1
-//    }
-//    return NULL
-//}
-//
-///**
-// * Get the root object.
-// */
-//
-//YAML_DECLARE(yaml_node_t *)
-//yaml_document_get_root_node(document *yaml_document_t)
-//{
-//    assert(document) // Non-NULL document object is expected.
-//
-//    if (document.nodes.top != document.nodes.start) {
-//        return document.nodes.start
-//    }
-//    return NULL
-//}
-//
-///*
-// * Add a scalar node to a document.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_add_scalar(document *yaml_document_t,
-//        tag *yaml_char_t, value *yaml_char_t, length int,
-//        style yaml_scalar_style_t)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//    mark yaml_mark_t = { 0, 0, 0 }
-//    tag_copy *yaml_char_t = NULL
-//    value_copy *yaml_char_t = NULL
-//    node yaml_node_t
-//
-//    assert(document) // Non-NULL document object is expected.
-//    assert(value) // Non-NULL value is expected.
-//
-//    if (!tag) {
-//        tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG
-//    }
-//
-//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
-//    tag_copy = yaml_strdup(tag)
-//    if (!tag_copy) goto error
-//
-//    if (length < 0) {
-//        length = strlen((char *)value)
-//    }
-//
-//    if (!yaml_check_utf8(value, length)) goto error
-//    value_copy = yaml_malloc(length+1)
-//    if (!value_copy) goto error
-//    memcpy(value_copy, value, length)
-//    value_copy[length] = '\0'
-//
-//    SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark)
-//    if (!PUSH(&context, document.nodes, node)) goto error
-//
-//    return document.nodes.top - document.nodes.start
-//
-//error:
-//    yaml_free(tag_copy)
-//    yaml_free(value_copy)
-//
-//    return 0
-//}
-//
-///*
-// * Add a sequence node to a document.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_add_sequence(document *yaml_document_t,
-//        tag *yaml_char_t, style yaml_sequence_style_t)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//    mark yaml_mark_t = { 0, 0, 0 }
-//    tag_copy *yaml_char_t = NULL
-//    struct {
-//        start *yaml_node_item_t
-//        end *yaml_node_item_t
-//        top *yaml_node_item_t
-//    } items = { NULL, NULL, NULL }
-//    node yaml_node_t
-//
-//    assert(document) // Non-NULL document object is expected.
-//
-//    if (!tag) {
-//        tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG
-//    }
-//
-//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
-//    tag_copy = yaml_strdup(tag)
-//    if (!tag_copy) goto error
-//
-//    if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error
-//
-//    SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
-//            style, mark, mark)
-//    if (!PUSH(&context, document.nodes, node)) goto error
-//
-//    return document.nodes.top - document.nodes.start
-//
-//error:
-//    STACK_DEL(&context, items)
-//    yaml_free(tag_copy)
-//
-//    return 0
-//}
-//
-///*
-// * Add a mapping node to a document.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_add_mapping(document *yaml_document_t,
-//        tag *yaml_char_t, style yaml_mapping_style_t)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//    mark yaml_mark_t = { 0, 0, 0 }
-//    tag_copy *yaml_char_t = NULL
-//    struct {
-//        start *yaml_node_pair_t
-//        end *yaml_node_pair_t
-//        top *yaml_node_pair_t
-//    } pairs = { NULL, NULL, NULL }
-//    node yaml_node_t
-//
-//    assert(document) // Non-NULL document object is expected.
-//
-//    if (!tag) {
-//        tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG
-//    }
-//
-//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
-//    tag_copy = yaml_strdup(tag)
-//    if (!tag_copy) goto error
-//
-//    if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error
-//
-//    MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
-//            style, mark, mark)
-//    if (!PUSH(&context, document.nodes, node)) goto error
-//
-//    return document.nodes.top - document.nodes.start
-//
-//error:
-//    STACK_DEL(&context, pairs)
-//    yaml_free(tag_copy)
-//
-//    return 0
-//}
-//
-///*
-// * Append an item to a sequence node.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_append_sequence_item(document *yaml_document_t,
-//        sequence int, item int)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//
-//    assert(document) // Non-NULL document is required.
-//    assert(sequence > 0
-//            && document.nodes.start + sequence <= document.nodes.top)
-//                            // Valid sequence id is required.
-//    assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE)
-//                            // A sequence node is required.
-//    assert(item > 0 && document.nodes.start + item <= document.nodes.top)
-//                            // Valid item id is required.
-//
-//    if (!PUSH(&context,
-//                document.nodes.start[sequence-1].data.sequence.items, item))
-//        return 0
-//
-//    return 1
-//}
-//
-///*
-// * Append a pair of a key and a value to a mapping node.
-// */
-//
-//YAML_DECLARE(int)
-//yaml_document_append_mapping_pair(document *yaml_document_t,
-//        mapping int, key int, value int)
-//{
-//    struct {
-//        error yaml_error_type_t
-//    } context
-//
-//    pair yaml_node_pair_t
-//
-//    assert(document) // Non-NULL document is required.
-//    assert(mapping > 0
-//            && document.nodes.start + mapping <= document.nodes.top)
-//                            // Valid mapping id is required.
-//    assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE)
-//                            // A mapping node is required.
-//    assert(key > 0 && document.nodes.start + key <= document.nodes.top)
-//                            // Valid key id is required.
-//    assert(value > 0 && document.nodes.start + value <= document.nodes.top)
-//                            // Valid value id is required.
-//
-//    pair.key = key
-//    pair.value = value
-//
-//    if (!PUSH(&context,
-//                document.nodes.start[mapping-1].data.mapping.pairs, pair))
-//        return 0
-//
-//    return 1
-//}
-//
-//
diff --git a/vendor/gopkg.in/yaml.v2/decode.go b/vendor/gopkg.in/yaml.v2/decode.go
deleted file mode 100644
index 129bc2a9..00000000
--- a/vendor/gopkg.in/yaml.v2/decode.go
+++ /dev/null
@@ -1,815 +0,0 @@
-package yaml
-
-import (
-	"encoding"
-	"encoding/base64"
-	"fmt"
-	"io"
-	"math"
-	"reflect"
-	"strconv"
-	"time"
-)
-
-const (
-	documentNode = 1 << iota
-	mappingNode
-	sequenceNode
-	scalarNode
-	aliasNode
-)
-
-type node struct {
-	kind         int
-	line, column int
-	tag          string
-	// For an alias node, alias holds the resolved alias.
-	alias    *node
-	value    string
-	implicit bool
-	children []*node
-	anchors  map[string]*node
-}
-
-// ----------------------------------------------------------------------------
-// Parser, produces a node tree out of a libyaml event stream.
-
-type parser struct {
-	parser   yaml_parser_t
-	event    yaml_event_t
-	doc      *node
-	doneInit bool
-}
-
-func newParser(b []byte) *parser {
-	p := parser{}
-	if !yaml_parser_initialize(&p.parser) {
-		panic("failed to initialize YAML emitter")
-	}
-	if len(b) == 0 {
-		b = []byte{'\n'}
-	}
-	yaml_parser_set_input_string(&p.parser, b)
-	return &p
-}
-
-func newParserFromReader(r io.Reader) *parser {
-	p := parser{}
-	if !yaml_parser_initialize(&p.parser) {
-		panic("failed to initialize YAML emitter")
-	}
-	yaml_parser_set_input_reader(&p.parser, r)
-	return &p
-}
-
-func (p *parser) init() {
-	if p.doneInit {
-		return
-	}
-	p.expect(yaml_STREAM_START_EVENT)
-	p.doneInit = true
-}
-
-func (p *parser) destroy() {
-	if p.event.typ != yaml_NO_EVENT {
-		yaml_event_delete(&p.event)
-	}
-	yaml_parser_delete(&p.parser)
-}
-
-// expect consumes an event from the event stream and
-// checks that it's of the expected type.
-func (p *parser) expect(e yaml_event_type_t) {
-	if p.event.typ == yaml_NO_EVENT {
-		if !yaml_parser_parse(&p.parser, &p.event) {
-			p.fail()
-		}
-	}
-	if p.event.typ == yaml_STREAM_END_EVENT {
-		failf("attempted to go past the end of stream; corrupted value?")
-	}
-	if p.event.typ != e {
-		p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ)
-		p.fail()
-	}
-	yaml_event_delete(&p.event)
-	p.event.typ = yaml_NO_EVENT
-}
-
-// peek peeks at the next event in the event stream,
-// puts the results into p.event and returns the event type.
-func (p *parser) peek() yaml_event_type_t {
-	if p.event.typ != yaml_NO_EVENT {
-		return p.event.typ
-	}
-	if !yaml_parser_parse(&p.parser, &p.event) {
-		p.fail()
-	}
-	return p.event.typ
-}
-
-func (p *parser) fail() {
-	var where string
-	var line int
-	if p.parser.problem_mark.line != 0 {
-		line = p.parser.problem_mark.line
-		// Scanner errors don't iterate line before returning error
-		if p.parser.error == yaml_SCANNER_ERROR {
-			line++
-		}
-	} else if p.parser.context_mark.line != 0 {
-		line = p.parser.context_mark.line
-	}
-	if line != 0 {
-		where = "line " + strconv.Itoa(line) + ": "
-	}
-	var msg string
-	if len(p.parser.problem) > 0 {
-		msg = p.parser.problem
-	} else {
-		msg = "unknown problem parsing YAML content"
-	}
-	failf("%s%s", where, msg)
-}
-
-func (p *parser) anchor(n *node, anchor []byte) {
-	if anchor != nil {
-		p.doc.anchors[string(anchor)] = n
-	}
-}
-
-func (p *parser) parse() *node {
-	p.init()
-	switch p.peek() {
-	case yaml_SCALAR_EVENT:
-		return p.scalar()
-	case yaml_ALIAS_EVENT:
-		return p.alias()
-	case yaml_MAPPING_START_EVENT:
-		return p.mapping()
-	case yaml_SEQUENCE_START_EVENT:
-		return p.sequence()
-	case yaml_DOCUMENT_START_EVENT:
-		return p.document()
-	case yaml_STREAM_END_EVENT:
-		// Happens when attempting to decode an empty buffer.
-		return nil
-	default:
-		panic("attempted to parse unknown event: " + p.event.typ.String())
-	}
-}
-
-func (p *parser) node(kind int) *node {
-	return &node{
-		kind:   kind,
-		line:   p.event.start_mark.line,
-		column: p.event.start_mark.column,
-	}
-}
-
-func (p *parser) document() *node {
-	n := p.node(documentNode)
-	n.anchors = make(map[string]*node)
-	p.doc = n
-	p.expect(yaml_DOCUMENT_START_EVENT)
-	n.children = append(n.children, p.parse())
-	p.expect(yaml_DOCUMENT_END_EVENT)
-	return n
-}
-
-func (p *parser) alias() *node {
-	n := p.node(aliasNode)
-	n.value = string(p.event.anchor)
-	n.alias = p.doc.anchors[n.value]
-	if n.alias == nil {
-		failf("unknown anchor '%s' referenced", n.value)
-	}
-	p.expect(yaml_ALIAS_EVENT)
-	return n
-}
-
-func (p *parser) scalar() *node {
-	n := p.node(scalarNode)
-	n.value = string(p.event.value)
-	n.tag = string(p.event.tag)
-	n.implicit = p.event.implicit
-	p.anchor(n, p.event.anchor)
-	p.expect(yaml_SCALAR_EVENT)
-	return n
-}
-
-func (p *parser) sequence() *node {
-	n := p.node(sequenceNode)
-	p.anchor(n, p.event.anchor)
-	p.expect(yaml_SEQUENCE_START_EVENT)
-	for p.peek() != yaml_SEQUENCE_END_EVENT {
-		n.children = append(n.children, p.parse())
-	}
-	p.expect(yaml_SEQUENCE_END_EVENT)
-	return n
-}
-
-func (p *parser) mapping() *node {
-	n := p.node(mappingNode)
-	p.anchor(n, p.event.anchor)
-	p.expect(yaml_MAPPING_START_EVENT)
-	for p.peek() != yaml_MAPPING_END_EVENT {
-		n.children = append(n.children, p.parse(), p.parse())
-	}
-	p.expect(yaml_MAPPING_END_EVENT)
-	return n
-}
-
-// ----------------------------------------------------------------------------
-// Decoder, unmarshals a node into a provided value.
-
-type decoder struct {
-	doc     *node
-	aliases map[*node]bool
-	mapType reflect.Type
-	terrors []string
-	strict  bool
-
-	decodeCount int
-	aliasCount  int
-	aliasDepth  int
-}
-
-var (
-	mapItemType    = reflect.TypeOf(MapItem{})
-	durationType   = reflect.TypeOf(time.Duration(0))
-	defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
-	ifaceType      = defaultMapType.Elem()
-	timeType       = reflect.TypeOf(time.Time{})
-	ptrTimeType    = reflect.TypeOf(&time.Time{})
-)
-
-func newDecoder(strict bool) *decoder {
-	d := &decoder{mapType: defaultMapType, strict: strict}
-	d.aliases = make(map[*node]bool)
-	return d
-}
-
-func (d *decoder) terror(n *node, tag string, out reflect.Value) {
-	if n.tag != "" {
-		tag = n.tag
-	}
-	value := n.value
-	if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG {
-		if len(value) > 10 {
-			value = " `" + value[:7] + "...`"
-		} else {
-			value = " `" + value + "`"
-		}
-	}
-	d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type()))
-}
-
-func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
-	terrlen := len(d.terrors)
-	err := u.UnmarshalYAML(func(v interface{}) (err error) {
-		defer handleErr(&err)
-		d.unmarshal(n, reflect.ValueOf(v))
-		if len(d.terrors) > terrlen {
-			issues := d.terrors[terrlen:]
-			d.terrors = d.terrors[:terrlen]
-			return &TypeError{issues}
-		}
-		return nil
-	})
-	if e, ok := err.(*TypeError); ok {
-		d.terrors = append(d.terrors, e.Errors...)
-		return false
-	}
-	if err != nil {
-		fail(err)
-	}
-	return true
-}
-
-// d.prepare initializes and dereferences pointers and calls UnmarshalYAML
-// if a value is found to implement it.
-// It returns the initialized and dereferenced out value, whether
-// unmarshalling was already done by UnmarshalYAML, and if so whether
-// its types unmarshalled appropriately.
-//
-// If n holds a null value, prepare returns before doing anything.
-func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
-	if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) {
-		return out, false, false
-	}
-	again := true
-	for again {
-		again = false
-		if out.Kind() == reflect.Ptr {
-			if out.IsNil() {
-				out.Set(reflect.New(out.Type().Elem()))
-			}
-			out = out.Elem()
-			again = true
-		}
-		if out.CanAddr() {
-			if u, ok := out.Addr().Interface().(Unmarshaler); ok {
-				good = d.callUnmarshaler(n, u)
-				return out, true, good
-			}
-		}
-	}
-	return out, false, false
-}
-
-const (
-	// 400,000 decode operations is ~500kb of dense object declarations, or
-	// ~5kb of dense object declarations with 10000% alias expansion
-	alias_ratio_range_low = 400000
-
-	// 4,000,000 decode operations is ~5MB of dense object declarations, or
-	// ~4.5MB of dense object declarations with 10% alias expansion
-	alias_ratio_range_high = 4000000
-
-	// alias_ratio_range is the range over which we scale allowed alias ratios
-	alias_ratio_range = float64(alias_ratio_range_high - alias_ratio_range_low)
-)
-
-func allowedAliasRatio(decodeCount int) float64 {
-	switch {
-	case decodeCount <= alias_ratio_range_low:
-		// allow 99% to come from alias expansion for small-to-medium documents
-		return 0.99
-	case decodeCount >= alias_ratio_range_high:
-		// allow 10% to come from alias expansion for very large documents
-		return 0.10
-	default:
-		// scale smoothly from 99% down to 10% over the range.
-		// this maps to 396,000 - 400,000 allowed alias-driven decodes over the range.
-		// 400,000 decode operations is ~100MB of allocations in worst-case scenarios (single-item maps).
-		return 0.99 - 0.89*(float64(decodeCount-alias_ratio_range_low)/alias_ratio_range)
-	}
-}
-
-func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) {
-	d.decodeCount++
-	if d.aliasDepth > 0 {
-		d.aliasCount++
-	}
-	if d.aliasCount > 100 && d.decodeCount > 1000 && float64(d.aliasCount)/float64(d.decodeCount) > allowedAliasRatio(d.decodeCount) {
-		failf("document contains excessive aliasing")
-	}
-	switch n.kind {
-	case documentNode:
-		return d.document(n, out)
-	case aliasNode:
-		return d.alias(n, out)
-	}
-	out, unmarshaled, good := d.prepare(n, out)
-	if unmarshaled {
-		return good
-	}
-	switch n.kind {
-	case scalarNode:
-		good = d.scalar(n, out)
-	case mappingNode:
-		good = d.mapping(n, out)
-	case sequenceNode:
-		good = d.sequence(n, out)
-	default:
-		panic("internal error: unknown node kind: " + strconv.Itoa(n.kind))
-	}
-	return good
-}
-
-func (d *decoder) document(n *node, out reflect.Value) (good bool) {
-	if len(n.children) == 1 {
-		d.doc = n
-		d.unmarshal(n.children[0], out)
-		return true
-	}
-	return false
-}
-
-func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
-	if d.aliases[n] {
-		// TODO this could actually be allowed in some circumstances.
-		failf("anchor '%s' value contains itself", n.value)
-	}
-	d.aliases[n] = true
-	d.aliasDepth++
-	good = d.unmarshal(n.alias, out)
-	d.aliasDepth--
-	delete(d.aliases, n)
-	return good
-}
-
-var zeroValue reflect.Value
-
-func resetMap(out reflect.Value) {
-	for _, k := range out.MapKeys() {
-		out.SetMapIndex(k, zeroValue)
-	}
-}
-
-func (d *decoder) scalar(n *node, out reflect.Value) bool {
-	var tag string
-	var resolved interface{}
-	if n.tag == "" && !n.implicit {
-		tag = yaml_STR_TAG
-		resolved = n.value
-	} else {
-		tag, resolved = resolve(n.tag, n.value)
-		if tag == yaml_BINARY_TAG {
-			data, err := base64.StdEncoding.DecodeString(resolved.(string))
-			if err != nil {
-				failf("!!binary value contains invalid base64 data")
-			}
-			resolved = string(data)
-		}
-	}
-	if resolved == nil {
-		if out.Kind() == reflect.Map && !out.CanAddr() {
-			resetMap(out)
-		} else {
-			out.Set(reflect.Zero(out.Type()))
-		}
-		return true
-	}
-	if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
-		// We've resolved to exactly the type we want, so use that.
-		out.Set(resolvedv)
-		return true
-	}
-	// Perhaps we can use the value as a TextUnmarshaler to
-	// set its value.
-	if out.CanAddr() {
-		u, ok := out.Addr().Interface().(encoding.TextUnmarshaler)
-		if ok {
-			var text []byte
-			if tag == yaml_BINARY_TAG {
-				text = []byte(resolved.(string))
-			} else {
-				// We let any value be unmarshaled into TextUnmarshaler.
-				// That might be more lax than we'd like, but the
-				// TextUnmarshaler itself should bowl out any dubious values.
-				text = []byte(n.value)
-			}
-			err := u.UnmarshalText(text)
-			if err != nil {
-				fail(err)
-			}
-			return true
-		}
-	}
-	switch out.Kind() {
-	case reflect.String:
-		if tag == yaml_BINARY_TAG {
-			out.SetString(resolved.(string))
-			return true
-		}
-		if resolved != nil {
-			out.SetString(n.value)
-			return true
-		}
-	case reflect.Interface:
-		if resolved == nil {
-			out.Set(reflect.Zero(out.Type()))
-		} else if tag == yaml_TIMESTAMP_TAG {
-			// It looks like a timestamp but for backward compatibility
-			// reasons we set it as a string, so that code that unmarshals
-			// timestamp-like values into interface{} will continue to
-			// see a string and not a time.Time.
-			// TODO(v3) Drop this.
-			out.Set(reflect.ValueOf(n.value))
-		} else {
-			out.Set(reflect.ValueOf(resolved))
-		}
-		return true
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		switch resolved := resolved.(type) {
-		case int:
-			if !out.OverflowInt(int64(resolved)) {
-				out.SetInt(int64(resolved))
-				return true
-			}
-		case int64:
-			if !out.OverflowInt(resolved) {
-				out.SetInt(resolved)
-				return true
-			}
-		case uint64:
-			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
-				out.SetInt(int64(resolved))
-				return true
-			}
-		case float64:
-			if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
-				out.SetInt(int64(resolved))
-				return true
-			}
-		case string:
-			if out.Type() == durationType {
-				d, err := time.ParseDuration(resolved)
-				if err == nil {
-					out.SetInt(int64(d))
-					return true
-				}
-			}
-		}
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		switch resolved := resolved.(type) {
-		case int:
-			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
-				out.SetUint(uint64(resolved))
-				return true
-			}
-		case int64:
-			if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
-				out.SetUint(uint64(resolved))
-				return true
-			}
-		case uint64:
-			if !out.OverflowUint(uint64(resolved)) {
-				out.SetUint(uint64(resolved))
-				return true
-			}
-		case float64:
-			if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
-				out.SetUint(uint64(resolved))
-				return true
-			}
-		}
-	case reflect.Bool:
-		switch resolved := resolved.(type) {
-		case bool:
-			out.SetBool(resolved)
-			return true
-		}
-	case reflect.Float32, reflect.Float64:
-		switch resolved := resolved.(type) {
-		case int:
-			out.SetFloat(float64(resolved))
-			return true
-		case int64:
-			out.SetFloat(float64(resolved))
-			return true
-		case uint64:
-			out.SetFloat(float64(resolved))
-			return true
-		case float64:
-			out.SetFloat(resolved)
-			return true
-		}
-	case reflect.Struct:
-		if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
-			out.Set(resolvedv)
-			return true
-		}
-	case reflect.Ptr:
-		if out.Type().Elem() == reflect.TypeOf(resolved) {
-			// TODO DOes this make sense? When is out a Ptr except when decoding a nil value?
-			elem := reflect.New(out.Type().Elem())
-			elem.Elem().Set(reflect.ValueOf(resolved))
-			out.Set(elem)
-			return true
-		}
-	}
-	d.terror(n, tag, out)
-	return false
-}
-
-func settableValueOf(i interface{}) reflect.Value {
-	v := reflect.ValueOf(i)
-	sv := reflect.New(v.Type()).Elem()
-	sv.Set(v)
-	return sv
-}
-
-func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
-	l := len(n.children)
-
-	var iface reflect.Value
-	switch out.Kind() {
-	case reflect.Slice:
-		out.Set(reflect.MakeSlice(out.Type(), l, l))
-	case reflect.Array:
-		if l != out.Len() {
-			failf("invalid array: want %d elements but got %d", out.Len(), l)
-		}
-	case reflect.Interface:
-		// No type hints. Will have to use a generic sequence.
-		iface = out
-		out = settableValueOf(make([]interface{}, l))
-	default:
-		d.terror(n, yaml_SEQ_TAG, out)
-		return false
-	}
-	et := out.Type().Elem()
-
-	j := 0
-	for i := 0; i < l; i++ {
-		e := reflect.New(et).Elem()
-		if ok := d.unmarshal(n.children[i], e); ok {
-			out.Index(j).Set(e)
-			j++
-		}
-	}
-	if out.Kind() != reflect.Array {
-		out.Set(out.Slice(0, j))
-	}
-	if iface.IsValid() {
-		iface.Set(out)
-	}
-	return true
-}
-
-func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
-	switch out.Kind() {
-	case reflect.Struct:
-		return d.mappingStruct(n, out)
-	case reflect.Slice:
-		return d.mappingSlice(n, out)
-	case reflect.Map:
-		// okay
-	case reflect.Interface:
-		if d.mapType.Kind() == reflect.Map {
-			iface := out
-			out = reflect.MakeMap(d.mapType)
-			iface.Set(out)
-		} else {
-			slicev := reflect.New(d.mapType).Elem()
-			if !d.mappingSlice(n, slicev) {
-				return false
-			}
-			out.Set(slicev)
-			return true
-		}
-	default:
-		d.terror(n, yaml_MAP_TAG, out)
-		return false
-	}
-	outt := out.Type()
-	kt := outt.Key()
-	et := outt.Elem()
-
-	mapType := d.mapType
-	if outt.Key() == ifaceType && outt.Elem() == ifaceType {
-		d.mapType = outt
-	}
-
-	if out.IsNil() {
-		out.Set(reflect.MakeMap(outt))
-	}
-	l := len(n.children)
-	for i := 0; i < l; i += 2 {
-		if isMerge(n.children[i]) {
-			d.merge(n.children[i+1], out)
-			continue
-		}
-		k := reflect.New(kt).Elem()
-		if d.unmarshal(n.children[i], k) {
-			kkind := k.Kind()
-			if kkind == reflect.Interface {
-				kkind = k.Elem().Kind()
-			}
-			if kkind == reflect.Map || kkind == reflect.Slice {
-				failf("invalid map key: %#v", k.Interface())
-			}
-			e := reflect.New(et).Elem()
-			if d.unmarshal(n.children[i+1], e) {
-				d.setMapIndex(n.children[i+1], out, k, e)
-			}
-		}
-	}
-	d.mapType = mapType
-	return true
-}
-
-func (d *decoder) setMapIndex(n *node, out, k, v reflect.Value) {
-	if d.strict && out.MapIndex(k) != zeroValue {
-		d.terrors = append(d.terrors, fmt.Sprintf("line %d: key %#v already set in map", n.line+1, k.Interface()))
-		return
-	}
-	out.SetMapIndex(k, v)
-}
-
-func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
-	outt := out.Type()
-	if outt.Elem() != mapItemType {
-		d.terror(n, yaml_MAP_TAG, out)
-		return false
-	}
-
-	mapType := d.mapType
-	d.mapType = outt
-
-	var slice []MapItem
-	var l = len(n.children)
-	for i := 0; i < l; i += 2 {
-		if isMerge(n.children[i]) {
-			d.merge(n.children[i+1], out)
-			continue
-		}
-		item := MapItem{}
-		k := reflect.ValueOf(&item.Key).Elem()
-		if d.unmarshal(n.children[i], k) {
-			v := reflect.ValueOf(&item.Value).Elem()
-			if d.unmarshal(n.children[i+1], v) {
-				slice = append(slice, item)
-			}
-		}
-	}
-	out.Set(reflect.ValueOf(slice))
-	d.mapType = mapType
-	return true
-}
-
-func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
-	sinfo, err := getStructInfo(out.Type())
-	if err != nil {
-		panic(err)
-	}
-	name := settableValueOf("")
-	l := len(n.children)
-
-	var inlineMap reflect.Value
-	var elemType reflect.Type
-	if sinfo.InlineMap != -1 {
-		inlineMap = out.Field(sinfo.InlineMap)
-		inlineMap.Set(reflect.New(inlineMap.Type()).Elem())
-		elemType = inlineMap.Type().Elem()
-	}
-
-	var doneFields []bool
-	if d.strict {
-		doneFields = make([]bool, len(sinfo.FieldsList))
-	}
-	for i := 0; i < l; i += 2 {
-		ni := n.children[i]
-		if isMerge(ni) {
-			d.merge(n.children[i+1], out)
-			continue
-		}
-		if !d.unmarshal(ni, name) {
-			continue
-		}
-		if info, ok := sinfo.FieldsMap[name.String()]; ok {
-			if d.strict {
-				if doneFields[info.Id] {
-					d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.line+1, name.String(), out.Type()))
-					continue
-				}
-				doneFields[info.Id] = true
-			}
-			var field reflect.Value
-			if info.Inline == nil {
-				field = out.Field(info.Num)
-			} else {
-				field = out.FieldByIndex(info.Inline)
-			}
-			d.unmarshal(n.children[i+1], field)
-		} else if sinfo.InlineMap != -1 {
-			if inlineMap.IsNil() {
-				inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
-			}
-			value := reflect.New(elemType).Elem()
-			d.unmarshal(n.children[i+1], value)
-			d.setMapIndex(n.children[i+1], inlineMap, name, value)
-		} else if d.strict {
-			d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.line+1, name.String(), out.Type()))
-		}
-	}
-	return true
-}
-
-func failWantMap() {
-	failf("map merge requires map or sequence of maps as the value")
-}
-
-func (d *decoder) merge(n *node, out reflect.Value) {
-	switch n.kind {
-	case mappingNode:
-		d.unmarshal(n, out)
-	case aliasNode:
-		if n.alias != nil && n.alias.kind != mappingNode {
-			failWantMap()
-		}
-		d.unmarshal(n, out)
-	case sequenceNode:
-		// Step backwards as earlier nodes take precedence.
-		for i := len(n.children) - 1; i >= 0; i-- {
-			ni := n.children[i]
-			if ni.kind == aliasNode {
-				if ni.alias != nil && ni.alias.kind != mappingNode {
-					failWantMap()
-				}
-			} else if ni.kind != mappingNode {
-				failWantMap()
-			}
-			d.unmarshal(ni, out)
-		}
-	default:
-		failWantMap()
-	}
-}
-
-func isMerge(n *node) bool {
-	return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG)
-}
diff --git a/vendor/gopkg.in/yaml.v2/emitterc.go b/vendor/gopkg.in/yaml.v2/emitterc.go
deleted file mode 100644
index a1c2cc52..00000000
--- a/vendor/gopkg.in/yaml.v2/emitterc.go
+++ /dev/null
@@ -1,1685 +0,0 @@
-package yaml
-
-import (
-	"bytes"
-	"fmt"
-)
-
-// Flush the buffer if needed.
-func flush(emitter *yaml_emitter_t) bool {
-	if emitter.buffer_pos+5 >= len(emitter.buffer) {
-		return yaml_emitter_flush(emitter)
-	}
-	return true
-}
-
-// Put a character to the output buffer.
-func put(emitter *yaml_emitter_t, value byte) bool {
-	if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
-		return false
-	}
-	emitter.buffer[emitter.buffer_pos] = value
-	emitter.buffer_pos++
-	emitter.column++
-	return true
-}
-
-// Put a line break to the output buffer.
-func put_break(emitter *yaml_emitter_t) bool {
-	if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
-		return false
-	}
-	switch emitter.line_break {
-	case yaml_CR_BREAK:
-		emitter.buffer[emitter.buffer_pos] = '\r'
-		emitter.buffer_pos += 1
-	case yaml_LN_BREAK:
-		emitter.buffer[emitter.buffer_pos] = '\n'
-		emitter.buffer_pos += 1
-	case yaml_CRLN_BREAK:
-		emitter.buffer[emitter.buffer_pos+0] = '\r'
-		emitter.buffer[emitter.buffer_pos+1] = '\n'
-		emitter.buffer_pos += 2
-	default:
-		panic("unknown line break setting")
-	}
-	emitter.column = 0
-	emitter.line++
-	return true
-}
-
-// Copy a character from a string into buffer.
-func write(emitter *yaml_emitter_t, s []byte, i *int) bool {
-	if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
-		return false
-	}
-	p := emitter.buffer_pos
-	w := width(s[*i])
-	switch w {
-	case 4:
-		emitter.buffer[p+3] = s[*i+3]
-		fallthrough
-	case 3:
-		emitter.buffer[p+2] = s[*i+2]
-		fallthrough
-	case 2:
-		emitter.buffer[p+1] = s[*i+1]
-		fallthrough
-	case 1:
-		emitter.buffer[p+0] = s[*i+0]
-	default:
-		panic("unknown character width")
-	}
-	emitter.column++
-	emitter.buffer_pos += w
-	*i += w
-	return true
-}
-
-// Write a whole string into buffer.
-func write_all(emitter *yaml_emitter_t, s []byte) bool {
-	for i := 0; i < len(s); {
-		if !write(emitter, s, &i) {
-			return false
-		}
-	}
-	return true
-}
-
-// Copy a line break character from a string into buffer.
-func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool {
-	if s[*i] == '\n' {
-		if !put_break(emitter) {
-			return false
-		}
-		*i++
-	} else {
-		if !write(emitter, s, i) {
-			return false
-		}
-		emitter.column = 0
-		emitter.line++
-	}
-	return true
-}
-
-// Set an emitter error and return false.
-func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool {
-	emitter.error = yaml_EMITTER_ERROR
-	emitter.problem = problem
-	return false
-}
-
-// Emit an event.
-func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	emitter.events = append(emitter.events, *event)
-	for !yaml_emitter_need_more_events(emitter) {
-		event := &emitter.events[emitter.events_head]
-		if !yaml_emitter_analyze_event(emitter, event) {
-			return false
-		}
-		if !yaml_emitter_state_machine(emitter, event) {
-			return false
-		}
-		yaml_event_delete(event)
-		emitter.events_head++
-	}
-	return true
-}
-
-// Check if we need to accumulate more events before emitting.
-//
-// We accumulate extra
-//  - 1 event for DOCUMENT-START
-//  - 2 events for SEQUENCE-START
-//  - 3 events for MAPPING-START
-//
-func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool {
-	if emitter.events_head == len(emitter.events) {
-		return true
-	}
-	var accumulate int
-	switch emitter.events[emitter.events_head].typ {
-	case yaml_DOCUMENT_START_EVENT:
-		accumulate = 1
-		break
-	case yaml_SEQUENCE_START_EVENT:
-		accumulate = 2
-		break
-	case yaml_MAPPING_START_EVENT:
-		accumulate = 3
-		break
-	default:
-		return false
-	}
-	if len(emitter.events)-emitter.events_head > accumulate {
-		return false
-	}
-	var level int
-	for i := emitter.events_head; i < len(emitter.events); i++ {
-		switch emitter.events[i].typ {
-		case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT:
-			level++
-		case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT:
-			level--
-		}
-		if level == 0 {
-			return false
-		}
-	}
-	return true
-}
-
-// Append a directive to the directives stack.
-func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool {
-	for i := 0; i < len(emitter.tag_directives); i++ {
-		if bytes.Equal(value.handle, emitter.tag_directives[i].handle) {
-			if allow_duplicates {
-				return true
-			}
-			return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive")
-		}
-	}
-
-	// [Go] Do we actually need to copy this given garbage collection
-	// and the lack of deallocating destructors?
-	tag_copy := yaml_tag_directive_t{
-		handle: make([]byte, len(value.handle)),
-		prefix: make([]byte, len(value.prefix)),
-	}
-	copy(tag_copy.handle, value.handle)
-	copy(tag_copy.prefix, value.prefix)
-	emitter.tag_directives = append(emitter.tag_directives, tag_copy)
-	return true
-}
-
-// Increase the indentation level.
-func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {
-	emitter.indents = append(emitter.indents, emitter.indent)
-	if emitter.indent < 0 {
-		if flow {
-			emitter.indent = emitter.best_indent
-		} else {
-			emitter.indent = 0
-		}
-	} else if !indentless {
-		emitter.indent += emitter.best_indent
-	}
-	return true
-}
-
-// State dispatcher.
-func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	switch emitter.state {
-	default:
-	case yaml_EMIT_STREAM_START_STATE:
-		return yaml_emitter_emit_stream_start(emitter, event)
-
-	case yaml_EMIT_FIRST_DOCUMENT_START_STATE:
-		return yaml_emitter_emit_document_start(emitter, event, true)
-
-	case yaml_EMIT_DOCUMENT_START_STATE:
-		return yaml_emitter_emit_document_start(emitter, event, false)
-
-	case yaml_EMIT_DOCUMENT_CONTENT_STATE:
-		return yaml_emitter_emit_document_content(emitter, event)
-
-	case yaml_EMIT_DOCUMENT_END_STATE:
-		return yaml_emitter_emit_document_end(emitter, event)
-
-	case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
-		return yaml_emitter_emit_flow_sequence_item(emitter, event, true)
-
-	case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE:
-		return yaml_emitter_emit_flow_sequence_item(emitter, event, false)
-
-	case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
-		return yaml_emitter_emit_flow_mapping_key(emitter, event, true)
-
-	case yaml_EMIT_FLOW_MAPPING_KEY_STATE:
-		return yaml_emitter_emit_flow_mapping_key(emitter, event, false)
-
-	case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
-		return yaml_emitter_emit_flow_mapping_value(emitter, event, true)
-
-	case yaml_EMIT_FLOW_MAPPING_VALUE_STATE:
-		return yaml_emitter_emit_flow_mapping_value(emitter, event, false)
-
-	case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
-		return yaml_emitter_emit_block_sequence_item(emitter, event, true)
-
-	case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
-		return yaml_emitter_emit_block_sequence_item(emitter, event, false)
-
-	case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
-		return yaml_emitter_emit_block_mapping_key(emitter, event, true)
-
-	case yaml_EMIT_BLOCK_MAPPING_KEY_STATE:
-		return yaml_emitter_emit_block_mapping_key(emitter, event, false)
-
-	case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
-		return yaml_emitter_emit_block_mapping_value(emitter, event, true)
-
-	case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE:
-		return yaml_emitter_emit_block_mapping_value(emitter, event, false)
-
-	case yaml_EMIT_END_STATE:
-		return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END")
-	}
-	panic("invalid emitter state")
-}
-
-// Expect STREAM-START.
-func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	if event.typ != yaml_STREAM_START_EVENT {
-		return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START")
-	}
-	if emitter.encoding == yaml_ANY_ENCODING {
-		emitter.encoding = event.encoding
-		if emitter.encoding == yaml_ANY_ENCODING {
-			emitter.encoding = yaml_UTF8_ENCODING
-		}
-	}
-	if emitter.best_indent < 2 || emitter.best_indent > 9 {
-		emitter.best_indent = 2
-	}
-	if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 {
-		emitter.best_width = 80
-	}
-	if emitter.best_width < 0 {
-		emitter.best_width = 1<<31 - 1
-	}
-	if emitter.line_break == yaml_ANY_BREAK {
-		emitter.line_break = yaml_LN_BREAK
-	}
-
-	emitter.indent = -1
-	emitter.line = 0
-	emitter.column = 0
-	emitter.whitespace = true
-	emitter.indention = true
-
-	if emitter.encoding != yaml_UTF8_ENCODING {
-		if !yaml_emitter_write_bom(emitter) {
-			return false
-		}
-	}
-	emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE
-	return true
-}
-
-// Expect DOCUMENT-START or STREAM-END.
-func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
-
-	if event.typ == yaml_DOCUMENT_START_EVENT {
-
-		if event.version_directive != nil {
-			if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) {
-				return false
-			}
-		}
-
-		for i := 0; i < len(event.tag_directives); i++ {
-			tag_directive := &event.tag_directives[i]
-			if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) {
-				return false
-			}
-			if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) {
-				return false
-			}
-		}
-
-		for i := 0; i < len(default_tag_directives); i++ {
-			tag_directive := &default_tag_directives[i]
-			if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) {
-				return false
-			}
-		}
-
-		implicit := event.implicit
-		if !first || emitter.canonical {
-			implicit = false
-		}
-
-		if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) {
-			if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
-				return false
-			}
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-		}
-
-		if event.version_directive != nil {
-			implicit = false
-			if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) {
-				return false
-			}
-			if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) {
-				return false
-			}
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-		}
-
-		if len(event.tag_directives) > 0 {
-			implicit = false
-			for i := 0; i < len(event.tag_directives); i++ {
-				tag_directive := &event.tag_directives[i]
-				if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) {
-					return false
-				}
-				if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) {
-					return false
-				}
-				if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) {
-					return false
-				}
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-			}
-		}
-
-		if yaml_emitter_check_empty_document(emitter) {
-			implicit = false
-		}
-		if !implicit {
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-			if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) {
-				return false
-			}
-			if emitter.canonical {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-			}
-		}
-
-		emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE
-		return true
-	}
-
-	if event.typ == yaml_STREAM_END_EVENT {
-		if emitter.open_ended {
-			if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
-				return false
-			}
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-		}
-		if !yaml_emitter_flush(emitter) {
-			return false
-		}
-		emitter.state = yaml_EMIT_END_STATE
-		return true
-	}
-
-	return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END")
-}
-
-// Expect the root node.
-func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE)
-	return yaml_emitter_emit_node(emitter, event, true, false, false, false)
-}
-
-// Expect DOCUMENT-END.
-func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	if event.typ != yaml_DOCUMENT_END_EVENT {
-		return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END")
-	}
-	if !yaml_emitter_write_indent(emitter) {
-		return false
-	}
-	if !event.implicit {
-		// [Go] Allocate the slice elsewhere.
-		if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
-			return false
-		}
-		if !yaml_emitter_write_indent(emitter) {
-			return false
-		}
-	}
-	if !yaml_emitter_flush(emitter) {
-		return false
-	}
-	emitter.state = yaml_EMIT_DOCUMENT_START_STATE
-	emitter.tag_directives = emitter.tag_directives[:0]
-	return true
-}
-
-// Expect a flow item node.
-func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
-	if first {
-		if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) {
-			return false
-		}
-		if !yaml_emitter_increase_indent(emitter, true, false) {
-			return false
-		}
-		emitter.flow_level++
-	}
-
-	if event.typ == yaml_SEQUENCE_END_EVENT {
-		emitter.flow_level--
-		emitter.indent = emitter.indents[len(emitter.indents)-1]
-		emitter.indents = emitter.indents[:len(emitter.indents)-1]
-		if emitter.canonical && !first {
-			if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
-				return false
-			}
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-		}
-		if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) {
-			return false
-		}
-		emitter.state = emitter.states[len(emitter.states)-1]
-		emitter.states = emitter.states[:len(emitter.states)-1]
-
-		return true
-	}
-
-	if !first {
-		if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
-			return false
-		}
-	}
-
-	if emitter.canonical || emitter.column > emitter.best_width {
-		if !yaml_emitter_write_indent(emitter) {
-			return false
-		}
-	}
-	emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE)
-	return yaml_emitter_emit_node(emitter, event, false, true, false, false)
-}
-
-// Expect a flow key node.
-func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
-	if first {
-		if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) {
-			return false
-		}
-		if !yaml_emitter_increase_indent(emitter, true, false) {
-			return false
-		}
-		emitter.flow_level++
-	}
-
-	if event.typ == yaml_MAPPING_END_EVENT {
-		emitter.flow_level--
-		emitter.indent = emitter.indents[len(emitter.indents)-1]
-		emitter.indents = emitter.indents[:len(emitter.indents)-1]
-		if emitter.canonical && !first {
-			if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
-				return false
-			}
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-		}
-		if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) {
-			return false
-		}
-		emitter.state = emitter.states[len(emitter.states)-1]
-		emitter.states = emitter.states[:len(emitter.states)-1]
-		return true
-	}
-
-	if !first {
-		if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
-			return false
-		}
-	}
-	if emitter.canonical || emitter.column > emitter.best_width {
-		if !yaml_emitter_write_indent(emitter) {
-			return false
-		}
-	}
-
-	if !emitter.canonical && yaml_emitter_check_simple_key(emitter) {
-		emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)
-		return yaml_emitter_emit_node(emitter, event, false, false, true, true)
-	}
-	if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) {
-		return false
-	}
-	emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE)
-	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
-}
-
-// Expect a flow value node.
-func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
-	if simple {
-		if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
-			return false
-		}
-	} else {
-		if emitter.canonical || emitter.column > emitter.best_width {
-			if !yaml_emitter_write_indent(emitter) {
-				return false
-			}
-		}
-		if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) {
-			return false
-		}
-	}
-	emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE)
-	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
-}
-
-// Expect a block item node.
-func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
-	if first {
-		if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) {
-			return false
-		}
-	}
-	if event.typ == yaml_SEQUENCE_END_EVENT {
-		emitter.indent = emitter.indents[len(emitter.indents)-1]
-		emitter.indents = emitter.indents[:len(emitter.indents)-1]
-		emitter.state = emitter.states[len(emitter.states)-1]
-		emitter.states = emitter.states[:len(emitter.states)-1]
-		return true
-	}
-	if !yaml_emitter_write_indent(emitter) {
-		return false
-	}
-	if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) {
-		return false
-	}
-	emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE)
-	return yaml_emitter_emit_node(emitter, event, false, true, false, false)
-}
-
-// Expect a block key node.
-func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
-	if first {
-		if !yaml_emitter_increase_indent(emitter, false, false) {
-			return false
-		}
-	}
-	if event.typ == yaml_MAPPING_END_EVENT {
-		emitter.indent = emitter.indents[len(emitter.indents)-1]
-		emitter.indents = emitter.indents[:len(emitter.indents)-1]
-		emitter.state = emitter.states[len(emitter.states)-1]
-		emitter.states = emitter.states[:len(emitter.states)-1]
-		return true
-	}
-	if !yaml_emitter_write_indent(emitter) {
-		return false
-	}
-	if yaml_emitter_check_simple_key(emitter) {
-		emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)
-		return yaml_emitter_emit_node(emitter, event, false, false, true, true)
-	}
-	if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) {
-		return false
-	}
-	emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE)
-	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
-}
-
-// Expect a block value node.
-func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
-	if simple {
-		if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
-			return false
-		}
-	} else {
-		if !yaml_emitter_write_indent(emitter) {
-			return false
-		}
-		if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) {
-			return false
-		}
-	}
-	emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)
-	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
-}
-
-// Expect a node.
-func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
-	root bool, sequence bool, mapping bool, simple_key bool) bool {
-
-	emitter.root_context = root
-	emitter.sequence_context = sequence
-	emitter.mapping_context = mapping
-	emitter.simple_key_context = simple_key
-
-	switch event.typ {
-	case yaml_ALIAS_EVENT:
-		return yaml_emitter_emit_alias(emitter, event)
-	case yaml_SCALAR_EVENT:
-		return yaml_emitter_emit_scalar(emitter, event)
-	case yaml_SEQUENCE_START_EVENT:
-		return yaml_emitter_emit_sequence_start(emitter, event)
-	case yaml_MAPPING_START_EVENT:
-		return yaml_emitter_emit_mapping_start(emitter, event)
-	default:
-		return yaml_emitter_set_emitter_error(emitter,
-			fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))
-	}
-}
-
-// Expect ALIAS.
-func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	if !yaml_emitter_process_anchor(emitter) {
-		return false
-	}
-	emitter.state = emitter.states[len(emitter.states)-1]
-	emitter.states = emitter.states[:len(emitter.states)-1]
-	return true
-}
-
-// Expect SCALAR.
-func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	if !yaml_emitter_select_scalar_style(emitter, event) {
-		return false
-	}
-	if !yaml_emitter_process_anchor(emitter) {
-		return false
-	}
-	if !yaml_emitter_process_tag(emitter) {
-		return false
-	}
-	if !yaml_emitter_increase_indent(emitter, true, false) {
-		return false
-	}
-	if !yaml_emitter_process_scalar(emitter) {
-		return false
-	}
-	emitter.indent = emitter.indents[len(emitter.indents)-1]
-	emitter.indents = emitter.indents[:len(emitter.indents)-1]
-	emitter.state = emitter.states[len(emitter.states)-1]
-	emitter.states = emitter.states[:len(emitter.states)-1]
-	return true
-}
-
-// Expect SEQUENCE-START.
-func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	if !yaml_emitter_process_anchor(emitter) {
-		return false
-	}
-	if !yaml_emitter_process_tag(emitter) {
-		return false
-	}
-	if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE ||
-		yaml_emitter_check_empty_sequence(emitter) {
-		emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE
-	} else {
-		emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE
-	}
-	return true
-}
-
-// Expect MAPPING-START.
-func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-	if !yaml_emitter_process_anchor(emitter) {
-		return false
-	}
-	if !yaml_emitter_process_tag(emitter) {
-		return false
-	}
-	if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE ||
-		yaml_emitter_check_empty_mapping(emitter) {
-		emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE
-	} else {
-		emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE
-	}
-	return true
-}
-
-// Check if the document content is an empty scalar.
-func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool {
-	return false // [Go] Huh?
-}
-
-// Check if the next events represent an empty sequence.
-func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool {
-	if len(emitter.events)-emitter.events_head < 2 {
-		return false
-	}
-	return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT &&
-		emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT
-}
-
-// Check if the next events represent an empty mapping.
-func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool {
-	if len(emitter.events)-emitter.events_head < 2 {
-		return false
-	}
-	return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT &&
-		emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT
-}
-
-// Check if the next node can be expressed as a simple key.
-func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool {
-	length := 0
-	switch emitter.events[emitter.events_head].typ {
-	case yaml_ALIAS_EVENT:
-		length += len(emitter.anchor_data.anchor)
-	case yaml_SCALAR_EVENT:
-		if emitter.scalar_data.multiline {
-			return false
-		}
-		length += len(emitter.anchor_data.anchor) +
-			len(emitter.tag_data.handle) +
-			len(emitter.tag_data.suffix) +
-			len(emitter.scalar_data.value)
-	case yaml_SEQUENCE_START_EVENT:
-		if !yaml_emitter_check_empty_sequence(emitter) {
-			return false
-		}
-		length += len(emitter.anchor_data.anchor) +
-			len(emitter.tag_data.handle) +
-			len(emitter.tag_data.suffix)
-	case yaml_MAPPING_START_EVENT:
-		if !yaml_emitter_check_empty_mapping(emitter) {
-			return false
-		}
-		length += len(emitter.anchor_data.anchor) +
-			len(emitter.tag_data.handle) +
-			len(emitter.tag_data.suffix)
-	default:
-		return false
-	}
-	return length <= 128
-}
-
-// Determine an acceptable scalar style.
-func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-
-	no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0
-	if no_tag && !event.implicit && !event.quoted_implicit {
-		return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified")
-	}
-
-	style := event.scalar_style()
-	if style == yaml_ANY_SCALAR_STYLE {
-		style = yaml_PLAIN_SCALAR_STYLE
-	}
-	if emitter.canonical {
-		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
-	}
-	if emitter.simple_key_context && emitter.scalar_data.multiline {
-		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
-	}
-
-	if style == yaml_PLAIN_SCALAR_STYLE {
-		if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed ||
-			emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed {
-			style = yaml_SINGLE_QUOTED_SCALAR_STYLE
-		}
-		if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) {
-			style = yaml_SINGLE_QUOTED_SCALAR_STYLE
-		}
-		if no_tag && !event.implicit {
-			style = yaml_SINGLE_QUOTED_SCALAR_STYLE
-		}
-	}
-	if style == yaml_SINGLE_QUOTED_SCALAR_STYLE {
-		if !emitter.scalar_data.single_quoted_allowed {
-			style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
-		}
-	}
-	if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE {
-		if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context {
-			style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
-		}
-	}
-
-	if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE {
-		emitter.tag_data.handle = []byte{'!'}
-	}
-	emitter.scalar_data.style = style
-	return true
-}
-
-// Write an anchor.
-func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
-	if emitter.anchor_data.anchor == nil {
-		return true
-	}
-	c := []byte{'&'}
-	if emitter.anchor_data.alias {
-		c[0] = '*'
-	}
-	if !yaml_emitter_write_indicator(emitter, c, true, false, false) {
-		return false
-	}
-	return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor)
-}
-
-// Write a tag.
-func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool {
-	if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 {
-		return true
-	}
-	if len(emitter.tag_data.handle) > 0 {
-		if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) {
-			return false
-		}
-		if len(emitter.tag_data.suffix) > 0 {
-			if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
-				return false
-			}
-		}
-	} else {
-		// [Go] Allocate these slices elsewhere.
-		if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) {
-			return false
-		}
-		if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
-			return false
-		}
-		if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) {
-			return false
-		}
-	}
-	return true
-}
-
-// Write a scalar.
-func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool {
-	switch emitter.scalar_data.style {
-	case yaml_PLAIN_SCALAR_STYLE:
-		return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
-
-	case yaml_SINGLE_QUOTED_SCALAR_STYLE:
-		return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
-
-	case yaml_DOUBLE_QUOTED_SCALAR_STYLE:
-		return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
-
-	case yaml_LITERAL_SCALAR_STYLE:
-		return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value)
-
-	case yaml_FOLDED_SCALAR_STYLE:
-		return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value)
-	}
-	panic("unknown scalar style")
-}
-
-// Check if a %YAML directive is valid.
-func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool {
-	if version_directive.major != 1 || version_directive.minor != 1 {
-		return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive")
-	}
-	return true
-}
-
-// Check if a %TAG directive is valid.
-func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool {
-	handle := tag_directive.handle
-	prefix := tag_directive.prefix
-	if len(handle) == 0 {
-		return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty")
-	}
-	if handle[0] != '!' {
-		return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'")
-	}
-	if handle[len(handle)-1] != '!' {
-		return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'")
-	}
-	for i := 1; i < len(handle)-1; i += width(handle[i]) {
-		if !is_alpha(handle, i) {
-			return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only")
-		}
-	}
-	if len(prefix) == 0 {
-		return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty")
-	}
-	return true
-}
-
-// Check if an anchor is valid.
-func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool {
-	if len(anchor) == 0 {
-		problem := "anchor value must not be empty"
-		if alias {
-			problem = "alias value must not be empty"
-		}
-		return yaml_emitter_set_emitter_error(emitter, problem)
-	}
-	for i := 0; i < len(anchor); i += width(anchor[i]) {
-		if !is_alpha(anchor, i) {
-			problem := "anchor value must contain alphanumerical characters only"
-			if alias {
-				problem = "alias value must contain alphanumerical characters only"
-			}
-			return yaml_emitter_set_emitter_error(emitter, problem)
-		}
-	}
-	emitter.anchor_data.anchor = anchor
-	emitter.anchor_data.alias = alias
-	return true
-}
-
-// Check if a tag is valid.
-func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {
-	if len(tag) == 0 {
-		return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty")
-	}
-	for i := 0; i < len(emitter.tag_directives); i++ {
-		tag_directive := &emitter.tag_directives[i]
-		if bytes.HasPrefix(tag, tag_directive.prefix) {
-			emitter.tag_data.handle = tag_directive.handle
-			emitter.tag_data.suffix = tag[len(tag_directive.prefix):]
-			return true
-		}
-	}
-	emitter.tag_data.suffix = tag
-	return true
-}
-
-// Check if a scalar is valid.
-func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
-	var (
-		block_indicators   = false
-		flow_indicators    = false
-		line_breaks        = false
-		special_characters = false
-
-		leading_space  = false
-		leading_break  = false
-		trailing_space = false
-		trailing_break = false
-		break_space    = false
-		space_break    = false
-
-		preceded_by_whitespace = false
-		followed_by_whitespace = false
-		previous_space         = false
-		previous_break         = false
-	)
-
-	emitter.scalar_data.value = value
-
-	if len(value) == 0 {
-		emitter.scalar_data.multiline = false
-		emitter.scalar_data.flow_plain_allowed = false
-		emitter.scalar_data.block_plain_allowed = true
-		emitter.scalar_data.single_quoted_allowed = true
-		emitter.scalar_data.block_allowed = false
-		return true
-	}
-
-	if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) {
-		block_indicators = true
-		flow_indicators = true
-	}
-
-	preceded_by_whitespace = true
-	for i, w := 0, 0; i < len(value); i += w {
-		w = width(value[i])
-		followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
-
-		if i == 0 {
-			switch value[i] {
-			case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`':
-				flow_indicators = true
-				block_indicators = true
-			case '?', ':':
-				flow_indicators = true
-				if followed_by_whitespace {
-					block_indicators = true
-				}
-			case '-':
-				if followed_by_whitespace {
-					flow_indicators = true
-					block_indicators = true
-				}
-			}
-		} else {
-			switch value[i] {
-			case ',', '?', '[', ']', '{', '}':
-				flow_indicators = true
-			case ':':
-				flow_indicators = true
-				if followed_by_whitespace {
-					block_indicators = true
-				}
-			case '#':
-				if preceded_by_whitespace {
-					flow_indicators = true
-					block_indicators = true
-				}
-			}
-		}
-
-		if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode {
-			special_characters = true
-		}
-		if is_space(value, i) {
-			if i == 0 {
-				leading_space = true
-			}
-			if i+width(value[i]) == len(value) {
-				trailing_space = true
-			}
-			if previous_break {
-				break_space = true
-			}
-			previous_space = true
-			previous_break = false
-		} else if is_break(value, i) {
-			line_breaks = true
-			if i == 0 {
-				leading_break = true
-			}
-			if i+width(value[i]) == len(value) {
-				trailing_break = true
-			}
-			if previous_space {
-				space_break = true
-			}
-			previous_space = false
-			previous_break = true
-		} else {
-			previous_space = false
-			previous_break = false
-		}
-
-		// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
-		preceded_by_whitespace = is_blankz(value, i)
-	}
-
-	emitter.scalar_data.multiline = line_breaks
-	emitter.scalar_data.flow_plain_allowed = true
-	emitter.scalar_data.block_plain_allowed = true
-	emitter.scalar_data.single_quoted_allowed = true
-	emitter.scalar_data.block_allowed = true
-
-	if leading_space || leading_break || trailing_space || trailing_break {
-		emitter.scalar_data.flow_plain_allowed = false
-		emitter.scalar_data.block_plain_allowed = false
-	}
-	if trailing_space {
-		emitter.scalar_data.block_allowed = false
-	}
-	if break_space {
-		emitter.scalar_data.flow_plain_allowed = false
-		emitter.scalar_data.block_plain_allowed = false
-		emitter.scalar_data.single_quoted_allowed = false
-	}
-	if space_break || special_characters {
-		emitter.scalar_data.flow_plain_allowed = false
-		emitter.scalar_data.block_plain_allowed = false
-		emitter.scalar_data.single_quoted_allowed = false
-		emitter.scalar_data.block_allowed = false
-	}
-	if line_breaks {
-		emitter.scalar_data.flow_plain_allowed = false
-		emitter.scalar_data.block_plain_allowed = false
-	}
-	if flow_indicators {
-		emitter.scalar_data.flow_plain_allowed = false
-	}
-	if block_indicators {
-		emitter.scalar_data.block_plain_allowed = false
-	}
-	return true
-}
-
-// Check if the event data is valid.
-func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {
-
-	emitter.anchor_data.anchor = nil
-	emitter.tag_data.handle = nil
-	emitter.tag_data.suffix = nil
-	emitter.scalar_data.value = nil
-
-	switch event.typ {
-	case yaml_ALIAS_EVENT:
-		if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) {
-			return false
-		}
-
-	case yaml_SCALAR_EVENT:
-		if len(event.anchor) > 0 {
-			if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
-				return false
-			}
-		}
-		if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) {
-			if !yaml_emitter_analyze_tag(emitter, event.tag) {
-				return false
-			}
-		}
-		if !yaml_emitter_analyze_scalar(emitter, event.value) {
-			return false
-		}
-
-	case yaml_SEQUENCE_START_EVENT:
-		if len(event.anchor) > 0 {
-			if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
-				return false
-			}
-		}
-		if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
-			if !yaml_emitter_analyze_tag(emitter, event.tag) {
-				return false
-			}
-		}
-
-	case yaml_MAPPING_START_EVENT:
-		if len(event.anchor) > 0 {
-			if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
-				return false
-			}
-		}
-		if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
-			if !yaml_emitter_analyze_tag(emitter, event.tag) {
-				return false
-			}
-		}
-	}
-	return true
-}
-
-// Write the BOM character.
-func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool {
-	if !flush(emitter) {
-		return false
-	}
-	pos := emitter.buffer_pos
-	emitter.buffer[pos+0] = '\xEF'
-	emitter.buffer[pos+1] = '\xBB'
-	emitter.buffer[pos+2] = '\xBF'
-	emitter.buffer_pos += 3
-	return true
-}
-
-func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool {
-	indent := emitter.indent
-	if indent < 0 {
-		indent = 0
-	}
-	if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) {
-		if !put_break(emitter) {
-			return false
-		}
-	}
-	for emitter.column < indent {
-		if !put(emitter, ' ') {
-			return false
-		}
-	}
-	emitter.whitespace = true
-	emitter.indention = true
-	return true
-}
-
-func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool {
-	if need_whitespace && !emitter.whitespace {
-		if !put(emitter, ' ') {
-			return false
-		}
-	}
-	if !write_all(emitter, indicator) {
-		return false
-	}
-	emitter.whitespace = is_whitespace
-	emitter.indention = (emitter.indention && is_indention)
-	emitter.open_ended = false
-	return true
-}
-
-func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool {
-	if !write_all(emitter, value) {
-		return false
-	}
-	emitter.whitespace = false
-	emitter.indention = false
-	return true
-}
-
-func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool {
-	if !emitter.whitespace {
-		if !put(emitter, ' ') {
-			return false
-		}
-	}
-	if !write_all(emitter, value) {
-		return false
-	}
-	emitter.whitespace = false
-	emitter.indention = false
-	return true
-}
-
-func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool {
-	if need_whitespace && !emitter.whitespace {
-		if !put(emitter, ' ') {
-			return false
-		}
-	}
-	for i := 0; i < len(value); {
-		var must_write bool
-		switch value[i] {
-		case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']':
-			must_write = true
-		default:
-			must_write = is_alpha(value, i)
-		}
-		if must_write {
-			if !write(emitter, value, &i) {
-				return false
-			}
-		} else {
-			w := width(value[i])
-			for k := 0; k < w; k++ {
-				octet := value[i]
-				i++
-				if !put(emitter, '%') {
-					return false
-				}
-
-				c := octet >> 4
-				if c < 10 {
-					c += '0'
-				} else {
-					c += 'A' - 10
-				}
-				if !put(emitter, c) {
-					return false
-				}
-
-				c = octet & 0x0f
-				if c < 10 {
-					c += '0'
-				} else {
-					c += 'A' - 10
-				}
-				if !put(emitter, c) {
-					return false
-				}
-			}
-		}
-	}
-	emitter.whitespace = false
-	emitter.indention = false
-	return true
-}
-
-func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
-	if !emitter.whitespace {
-		if !put(emitter, ' ') {
-			return false
-		}
-	}
-
-	spaces := false
-	breaks := false
-	for i := 0; i < len(value); {
-		if is_space(value, i) {
-			if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-				i += width(value[i])
-			} else {
-				if !write(emitter, value, &i) {
-					return false
-				}
-			}
-			spaces = true
-		} else if is_break(value, i) {
-			if !breaks && value[i] == '\n' {
-				if !put_break(emitter) {
-					return false
-				}
-			}
-			if !write_break(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = true
-			breaks = true
-		} else {
-			if breaks {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-			}
-			if !write(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = false
-			spaces = false
-			breaks = false
-		}
-	}
-
-	emitter.whitespace = false
-	emitter.indention = false
-	if emitter.root_context {
-		emitter.open_ended = true
-	}
-
-	return true
-}
-
-func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
-
-	if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) {
-		return false
-	}
-
-	spaces := false
-	breaks := false
-	for i := 0; i < len(value); {
-		if is_space(value, i) {
-			if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-				i += width(value[i])
-			} else {
-				if !write(emitter, value, &i) {
-					return false
-				}
-			}
-			spaces = true
-		} else if is_break(value, i) {
-			if !breaks && value[i] == '\n' {
-				if !put_break(emitter) {
-					return false
-				}
-			}
-			if !write_break(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = true
-			breaks = true
-		} else {
-			if breaks {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-			}
-			if value[i] == '\'' {
-				if !put(emitter, '\'') {
-					return false
-				}
-			}
-			if !write(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = false
-			spaces = false
-			breaks = false
-		}
-	}
-	if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) {
-		return false
-	}
-	emitter.whitespace = false
-	emitter.indention = false
-	return true
-}
-
-func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
-	spaces := false
-	if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) {
-		return false
-	}
-
-	for i := 0; i < len(value); {
-		if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) ||
-			is_bom(value, i) || is_break(value, i) ||
-			value[i] == '"' || value[i] == '\\' {
-
-			octet := value[i]
-
-			var w int
-			var v rune
-			switch {
-			case octet&0x80 == 0x00:
-				w, v = 1, rune(octet&0x7F)
-			case octet&0xE0 == 0xC0:
-				w, v = 2, rune(octet&0x1F)
-			case octet&0xF0 == 0xE0:
-				w, v = 3, rune(octet&0x0F)
-			case octet&0xF8 == 0xF0:
-				w, v = 4, rune(octet&0x07)
-			}
-			for k := 1; k < w; k++ {
-				octet = value[i+k]
-				v = (v << 6) + (rune(octet) & 0x3F)
-			}
-			i += w
-
-			if !put(emitter, '\\') {
-				return false
-			}
-
-			var ok bool
-			switch v {
-			case 0x00:
-				ok = put(emitter, '0')
-			case 0x07:
-				ok = put(emitter, 'a')
-			case 0x08:
-				ok = put(emitter, 'b')
-			case 0x09:
-				ok = put(emitter, 't')
-			case 0x0A:
-				ok = put(emitter, 'n')
-			case 0x0b:
-				ok = put(emitter, 'v')
-			case 0x0c:
-				ok = put(emitter, 'f')
-			case 0x0d:
-				ok = put(emitter, 'r')
-			case 0x1b:
-				ok = put(emitter, 'e')
-			case 0x22:
-				ok = put(emitter, '"')
-			case 0x5c:
-				ok = put(emitter, '\\')
-			case 0x85:
-				ok = put(emitter, 'N')
-			case 0xA0:
-				ok = put(emitter, '_')
-			case 0x2028:
-				ok = put(emitter, 'L')
-			case 0x2029:
-				ok = put(emitter, 'P')
-			default:
-				if v <= 0xFF {
-					ok = put(emitter, 'x')
-					w = 2
-				} else if v <= 0xFFFF {
-					ok = put(emitter, 'u')
-					w = 4
-				} else {
-					ok = put(emitter, 'U')
-					w = 8
-				}
-				for k := (w - 1) * 4; ok && k >= 0; k -= 4 {
-					digit := byte((v >> uint(k)) & 0x0F)
-					if digit < 10 {
-						ok = put(emitter, digit+'0')
-					} else {
-						ok = put(emitter, digit+'A'-10)
-					}
-				}
-			}
-			if !ok {
-				return false
-			}
-			spaces = false
-		} else if is_space(value, i) {
-			if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-				if is_space(value, i+1) {
-					if !put(emitter, '\\') {
-						return false
-					}
-				}
-				i += width(value[i])
-			} else if !write(emitter, value, &i) {
-				return false
-			}
-			spaces = true
-		} else {
-			if !write(emitter, value, &i) {
-				return false
-			}
-			spaces = false
-		}
-	}
-	if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) {
-		return false
-	}
-	emitter.whitespace = false
-	emitter.indention = false
-	return true
-}
-
-func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool {
-	if is_space(value, 0) || is_break(value, 0) {
-		indent_hint := []byte{'0' + byte(emitter.best_indent)}
-		if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) {
-			return false
-		}
-	}
-
-	emitter.open_ended = false
-
-	var chomp_hint [1]byte
-	if len(value) == 0 {
-		chomp_hint[0] = '-'
-	} else {
-		i := len(value) - 1
-		for value[i]&0xC0 == 0x80 {
-			i--
-		}
-		if !is_break(value, i) {
-			chomp_hint[0] = '-'
-		} else if i == 0 {
-			chomp_hint[0] = '+'
-			emitter.open_ended = true
-		} else {
-			i--
-			for value[i]&0xC0 == 0x80 {
-				i--
-			}
-			if is_break(value, i) {
-				chomp_hint[0] = '+'
-				emitter.open_ended = true
-			}
-		}
-	}
-	if chomp_hint[0] != 0 {
-		if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) {
-			return false
-		}
-	}
-	return true
-}
-
-func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool {
-	if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) {
-		return false
-	}
-	if !yaml_emitter_write_block_scalar_hints(emitter, value) {
-		return false
-	}
-	if !put_break(emitter) {
-		return false
-	}
-	emitter.indention = true
-	emitter.whitespace = true
-	breaks := true
-	for i := 0; i < len(value); {
-		if is_break(value, i) {
-			if !write_break(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = true
-			breaks = true
-		} else {
-			if breaks {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-			}
-			if !write(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = false
-			breaks = false
-		}
-	}
-
-	return true
-}
-
-func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool {
-	if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) {
-		return false
-	}
-	if !yaml_emitter_write_block_scalar_hints(emitter, value) {
-		return false
-	}
-
-	if !put_break(emitter) {
-		return false
-	}
-	emitter.indention = true
-	emitter.whitespace = true
-
-	breaks := true
-	leading_spaces := true
-	for i := 0; i < len(value); {
-		if is_break(value, i) {
-			if !breaks && !leading_spaces && value[i] == '\n' {
-				k := 0
-				for is_break(value, k) {
-					k += width(value[k])
-				}
-				if !is_blankz(value, k) {
-					if !put_break(emitter) {
-						return false
-					}
-				}
-			}
-			if !write_break(emitter, value, &i) {
-				return false
-			}
-			emitter.indention = true
-			breaks = true
-		} else {
-			if breaks {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-				leading_spaces = is_blank(value, i)
-			}
-			if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width {
-				if !yaml_emitter_write_indent(emitter) {
-					return false
-				}
-				i += width(value[i])
-			} else {
-				if !write(emitter, value, &i) {
-					return false
-				}
-			}
-			emitter.indention = false
-			breaks = false
-		}
-	}
-	return true
-}
diff --git a/vendor/gopkg.in/yaml.v2/encode.go b/vendor/gopkg.in/yaml.v2/encode.go
deleted file mode 100644
index 0ee738e1..00000000
--- a/vendor/gopkg.in/yaml.v2/encode.go
+++ /dev/null
@@ -1,390 +0,0 @@
-package yaml
-
-import (
-	"encoding"
-	"fmt"
-	"io"
-	"reflect"
-	"regexp"
-	"sort"
-	"strconv"
-	"strings"
-	"time"
-	"unicode/utf8"
-)
-
-// jsonNumber is the interface of the encoding/json.Number datatype.
-// Repeating the interface here avoids a dependency on encoding/json, and also
-// supports other libraries like jsoniter, which use a similar datatype with
-// the same interface. Detecting this interface is useful when dealing with
-// structures containing json.Number, which is a string under the hood. The
-// encoder should prefer the use of Int64(), Float64() and string(), in that
-// order, when encoding this type.
-type jsonNumber interface {
-	Float64() (float64, error)
-	Int64() (int64, error)
-	String() string
-}
-
-type encoder struct {
-	emitter yaml_emitter_t
-	event   yaml_event_t
-	out     []byte
-	flow    bool
-	// doneInit holds whether the initial stream_start_event has been
-	// emitted.
-	doneInit bool
-}
-
-func newEncoder() *encoder {
-	e := &encoder{}
-	yaml_emitter_initialize(&e.emitter)
-	yaml_emitter_set_output_string(&e.emitter, &e.out)
-	yaml_emitter_set_unicode(&e.emitter, true)
-	return e
-}
-
-func newEncoderWithWriter(w io.Writer) *encoder {
-	e := &encoder{}
-	yaml_emitter_initialize(&e.emitter)
-	yaml_emitter_set_output_writer(&e.emitter, w)
-	yaml_emitter_set_unicode(&e.emitter, true)
-	return e
-}
-
-func (e *encoder) init() {
-	if e.doneInit {
-		return
-	}
-	yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)
-	e.emit()
-	e.doneInit = true
-}
-
-func (e *encoder) finish() {
-	e.emitter.open_ended = false
-	yaml_stream_end_event_initialize(&e.event)
-	e.emit()
-}
-
-func (e *encoder) destroy() {
-	yaml_emitter_delete(&e.emitter)
-}
-
-func (e *encoder) emit() {
-	// This will internally delete the e.event value.
-	e.must(yaml_emitter_emit(&e.emitter, &e.event))
-}
-
-func (e *encoder) must(ok bool) {
-	if !ok {
-		msg := e.emitter.problem
-		if msg == "" {
-			msg = "unknown problem generating YAML content"
-		}
-		failf("%s", msg)
-	}
-}
-
-func (e *encoder) marshalDoc(tag string, in reflect.Value) {
-	e.init()
-	yaml_document_start_event_initialize(&e.event, nil, nil, true)
-	e.emit()
-	e.marshal(tag, in)
-	yaml_document_end_event_initialize(&e.event, true)
-	e.emit()
-}
-
-func (e *encoder) marshal(tag string, in reflect.Value) {
-	if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
-		e.nilv()
-		return
-	}
-	iface := in.Interface()
-	switch m := iface.(type) {
-	case jsonNumber:
-		integer, err := m.Int64()
-		if err == nil {
-			// In this case the json.Number is a valid int64
-			in = reflect.ValueOf(integer)
-			break
-		}
-		float, err := m.Float64()
-		if err == nil {
-			// In this case the json.Number is a valid float64
-			in = reflect.ValueOf(float)
-			break
-		}
-		// fallback case - no number could be obtained
-		in = reflect.ValueOf(m.String())
-	case time.Time, *time.Time:
-		// Although time.Time implements TextMarshaler,
-		// we don't want to treat it as a string for YAML
-		// purposes because YAML has special support for
-		// timestamps.
-	case Marshaler:
-		v, err := m.MarshalYAML()
-		if err != nil {
-			fail(err)
-		}
-		if v == nil {
-			e.nilv()
-			return
-		}
-		in = reflect.ValueOf(v)
-	case encoding.TextMarshaler:
-		text, err := m.MarshalText()
-		if err != nil {
-			fail(err)
-		}
-		in = reflect.ValueOf(string(text))
-	case nil:
-		e.nilv()
-		return
-	}
-	switch in.Kind() {
-	case reflect.Interface:
-		e.marshal(tag, in.Elem())
-	case reflect.Map:
-		e.mapv(tag, in)
-	case reflect.Ptr:
-		if in.Type() == ptrTimeType {
-			e.timev(tag, in.Elem())
-		} else {
-			e.marshal(tag, in.Elem())
-		}
-	case reflect.Struct:
-		if in.Type() == timeType {
-			e.timev(tag, in)
-		} else {
-			e.structv(tag, in)
-		}
-	case reflect.Slice, reflect.Array:
-		if in.Type().Elem() == mapItemType {
-			e.itemsv(tag, in)
-		} else {
-			e.slicev(tag, in)
-		}
-	case reflect.String:
-		e.stringv(tag, in)
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		if in.Type() == durationType {
-			e.stringv(tag, reflect.ValueOf(iface.(time.Duration).String()))
-		} else {
-			e.intv(tag, in)
-		}
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		e.uintv(tag, in)
-	case reflect.Float32, reflect.Float64:
-		e.floatv(tag, in)
-	case reflect.Bool:
-		e.boolv(tag, in)
-	default:
-		panic("cannot marshal type: " + in.Type().String())
-	}
-}
-
-func (e *encoder) mapv(tag string, in reflect.Value) {
-	e.mappingv(tag, func() {
-		keys := keyList(in.MapKeys())
-		sort.Sort(keys)
-		for _, k := range keys {
-			e.marshal("", k)
-			e.marshal("", in.MapIndex(k))
-		}
-	})
-}
-
-func (e *encoder) itemsv(tag string, in reflect.Value) {
-	e.mappingv(tag, func() {
-		slice := in.Convert(reflect.TypeOf([]MapItem{})).Interface().([]MapItem)
-		for _, item := range slice {
-			e.marshal("", reflect.ValueOf(item.Key))
-			e.marshal("", reflect.ValueOf(item.Value))
-		}
-	})
-}
-
-func (e *encoder) structv(tag string, in reflect.Value) {
-	sinfo, err := getStructInfo(in.Type())
-	if err != nil {
-		panic(err)
-	}
-	e.mappingv(tag, func() {
-		for _, info := range sinfo.FieldsList {
-			var value reflect.Value
-			if info.Inline == nil {
-				value = in.Field(info.Num)
-			} else {
-				value = in.FieldByIndex(info.Inline)
-			}
-			if info.OmitEmpty && isZero(value) {
-				continue
-			}
-			e.marshal("", reflect.ValueOf(info.Key))
-			e.flow = info.Flow
-			e.marshal("", value)
-		}
-		if sinfo.InlineMap >= 0 {
-			m := in.Field(sinfo.InlineMap)
-			if m.Len() > 0 {
-				e.flow = false
-				keys := keyList(m.MapKeys())
-				sort.Sort(keys)
-				for _, k := range keys {
-					if _, found := sinfo.FieldsMap[k.String()]; found {
-						panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", k.String()))
-					}
-					e.marshal("", k)
-					e.flow = false
-					e.marshal("", m.MapIndex(k))
-				}
-			}
-		}
-	})
-}
-
-func (e *encoder) mappingv(tag string, f func()) {
-	implicit := tag == ""
-	style := yaml_BLOCK_MAPPING_STYLE
-	if e.flow {
-		e.flow = false
-		style = yaml_FLOW_MAPPING_STYLE
-	}
-	yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)
-	e.emit()
-	f()
-	yaml_mapping_end_event_initialize(&e.event)
-	e.emit()
-}
-
-func (e *encoder) slicev(tag string, in reflect.Value) {
-	implicit := tag == ""
-	style := yaml_BLOCK_SEQUENCE_STYLE
-	if e.flow {
-		e.flow = false
-		style = yaml_FLOW_SEQUENCE_STYLE
-	}
-	e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
-	e.emit()
-	n := in.Len()
-	for i := 0; i < n; i++ {
-		e.marshal("", in.Index(i))
-	}
-	e.must(yaml_sequence_end_event_initialize(&e.event))
-	e.emit()
-}
-
-// isBase60 returns whether s is in base 60 notation as defined in YAML 1.1.
-//
-// The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported
-// in YAML 1.2 and by this package, but these should be marshalled quoted for
-// the time being for compatibility with other parsers.
-func isBase60Float(s string) (result bool) {
-	// Fast path.
-	if s == "" {
-		return false
-	}
-	c := s[0]
-	if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 {
-		return false
-	}
-	// Do the full match.
-	return base60float.MatchString(s)
-}
-
-// From http://yaml.org/type/float.html, except the regular expression there
-// is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix.
-var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`)
-
-func (e *encoder) stringv(tag string, in reflect.Value) {
-	var style yaml_scalar_style_t
-	s := in.String()
-	canUsePlain := true
-	switch {
-	case !utf8.ValidString(s):
-		if tag == yaml_BINARY_TAG {
-			failf("explicitly tagged !!binary data must be base64-encoded")
-		}
-		if tag != "" {
-			failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
-		}
-		// It can't be encoded directly as YAML so use a binary tag
-		// and encode it as base64.
-		tag = yaml_BINARY_TAG
-		s = encodeBase64(s)
-	case tag == "":
-		// Check to see if it would resolve to a specific
-		// tag when encoded unquoted. If it doesn't,
-		// there's no need to quote it.
-		rtag, _ := resolve("", s)
-		canUsePlain = rtag == yaml_STR_TAG && !isBase60Float(s)
-	}
-	// Note: it's possible for user code to emit invalid YAML
-	// if they explicitly specify a tag and a string containing
-	// text that's incompatible with that tag.
-	switch {
-	case strings.Contains(s, "\n"):
-		style = yaml_LITERAL_SCALAR_STYLE
-	case canUsePlain:
-		style = yaml_PLAIN_SCALAR_STYLE
-	default:
-		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
-	}
-	e.emitScalar(s, "", tag, style)
-}
-
-func (e *encoder) boolv(tag string, in reflect.Value) {
-	var s string
-	if in.Bool() {
-		s = "true"
-	} else {
-		s = "false"
-	}
-	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) intv(tag string, in reflect.Value) {
-	s := strconv.FormatInt(in.Int(), 10)
-	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) uintv(tag string, in reflect.Value) {
-	s := strconv.FormatUint(in.Uint(), 10)
-	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) timev(tag string, in reflect.Value) {
-	t := in.Interface().(time.Time)
-	s := t.Format(time.RFC3339Nano)
-	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) floatv(tag string, in reflect.Value) {
-	// Issue #352: When formatting, use the precision of the underlying value
-	precision := 64
-	if in.Kind() == reflect.Float32 {
-		precision = 32
-	}
-
-	s := strconv.FormatFloat(in.Float(), 'g', -1, precision)
-	switch s {
-	case "+Inf":
-		s = ".inf"
-	case "-Inf":
-		s = "-.inf"
-	case "NaN":
-		s = ".nan"
-	}
-	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) nilv() {
-	e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE)
-}
-
-func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) {
-	implicit := tag == ""
-	e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style))
-	e.emit()
-}
diff --git a/vendor/gopkg.in/yaml.v2/parserc.go b/vendor/gopkg.in/yaml.v2/parserc.go
deleted file mode 100644
index 81d05dfe..00000000
--- a/vendor/gopkg.in/yaml.v2/parserc.go
+++ /dev/null
@@ -1,1095 +0,0 @@
-package yaml
-
-import (
-	"bytes"
-)
-
-// The parser implements the following grammar:
-//
-// stream               ::= STREAM-START implicit_document? explicit_document* STREAM-END
-// implicit_document    ::= block_node DOCUMENT-END*
-// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-// block_node_or_indentless_sequence    ::=
-//                          ALIAS
-//                          | properties (block_content | indentless_block_sequence)?
-//                          | block_content
-//                          | indentless_block_sequence
-// block_node           ::= ALIAS
-//                          | properties block_content?
-//                          | block_content
-// flow_node            ::= ALIAS
-//                          | properties flow_content?
-//                          | flow_content
-// properties           ::= TAG ANCHOR? | ANCHOR TAG?
-// block_content        ::= block_collection | flow_collection | SCALAR
-// flow_content         ::= flow_collection | SCALAR
-// block_collection     ::= block_sequence | block_mapping
-// flow_collection      ::= flow_sequence | flow_mapping
-// block_sequence       ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
-// indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
-// block_mapping        ::= BLOCK-MAPPING_START
-//                          ((KEY block_node_or_indentless_sequence?)?
-//                          (VALUE block_node_or_indentless_sequence?)?)*
-//                          BLOCK-END
-// flow_sequence        ::= FLOW-SEQUENCE-START
-//                          (flow_sequence_entry FLOW-ENTRY)*
-//                          flow_sequence_entry?
-//                          FLOW-SEQUENCE-END
-// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-// flow_mapping         ::= FLOW-MAPPING-START
-//                          (flow_mapping_entry FLOW-ENTRY)*
-//                          flow_mapping_entry?
-//                          FLOW-MAPPING-END
-// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-
-// Peek the next token in the token queue.
-func peek_token(parser *yaml_parser_t) *yaml_token_t {
-	if parser.token_available || yaml_parser_fetch_more_tokens(parser) {
-		return &parser.tokens[parser.tokens_head]
-	}
-	return nil
-}
-
-// Remove the next token from the queue (must be called after peek_token).
-func skip_token(parser *yaml_parser_t) {
-	parser.token_available = false
-	parser.tokens_parsed++
-	parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN
-	parser.tokens_head++
-}
-
-// Get the next event.
-func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool {
-	// Erase the event object.
-	*event = yaml_event_t{}
-
-	// No events after the end of the stream or error.
-	if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE {
-		return true
-	}
-
-	// Generate the next event.
-	return yaml_parser_state_machine(parser, event)
-}
-
-// Set parser error.
-func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool {
-	parser.error = yaml_PARSER_ERROR
-	parser.problem = problem
-	parser.problem_mark = problem_mark
-	return false
-}
-
-func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool {
-	parser.error = yaml_PARSER_ERROR
-	parser.context = context
-	parser.context_mark = context_mark
-	parser.problem = problem
-	parser.problem_mark = problem_mark
-	return false
-}
-
-// State dispatcher.
-func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool {
-	//trace("yaml_parser_state_machine", "state:", parser.state.String())
-
-	switch parser.state {
-	case yaml_PARSE_STREAM_START_STATE:
-		return yaml_parser_parse_stream_start(parser, event)
-
-	case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
-		return yaml_parser_parse_document_start(parser, event, true)
-
-	case yaml_PARSE_DOCUMENT_START_STATE:
-		return yaml_parser_parse_document_start(parser, event, false)
-
-	case yaml_PARSE_DOCUMENT_CONTENT_STATE:
-		return yaml_parser_parse_document_content(parser, event)
-
-	case yaml_PARSE_DOCUMENT_END_STATE:
-		return yaml_parser_parse_document_end(parser, event)
-
-	case yaml_PARSE_BLOCK_NODE_STATE:
-		return yaml_parser_parse_node(parser, event, true, false)
-
-	case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
-		return yaml_parser_parse_node(parser, event, true, true)
-
-	case yaml_PARSE_FLOW_NODE_STATE:
-		return yaml_parser_parse_node(parser, event, false, false)
-
-	case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
-		return yaml_parser_parse_block_sequence_entry(parser, event, true)
-
-	case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
-		return yaml_parser_parse_block_sequence_entry(parser, event, false)
-
-	case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
-		return yaml_parser_parse_indentless_sequence_entry(parser, event)
-
-	case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
-		return yaml_parser_parse_block_mapping_key(parser, event, true)
-
-	case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
-		return yaml_parser_parse_block_mapping_key(parser, event, false)
-
-	case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
-		return yaml_parser_parse_block_mapping_value(parser, event)
-
-	case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
-		return yaml_parser_parse_flow_sequence_entry(parser, event, true)
-
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
-		return yaml_parser_parse_flow_sequence_entry(parser, event, false)
-
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
-		return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event)
-
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
-		return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event)
-
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
-		return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event)
-
-	case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
-		return yaml_parser_parse_flow_mapping_key(parser, event, true)
-
-	case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
-		return yaml_parser_parse_flow_mapping_key(parser, event, false)
-
-	case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
-		return yaml_parser_parse_flow_mapping_value(parser, event, false)
-
-	case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
-		return yaml_parser_parse_flow_mapping_value(parser, event, true)
-
-	default:
-		panic("invalid parser state")
-	}
-}
-
-// Parse the production:
-// stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
-//              ************
-func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if token.typ != yaml_STREAM_START_TOKEN {
-		return yaml_parser_set_parser_error(parser, "did not find expected <stream-start>", token.start_mark)
-	}
-	parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE
-	*event = yaml_event_t{
-		typ:        yaml_STREAM_START_EVENT,
-		start_mark: token.start_mark,
-		end_mark:   token.end_mark,
-		encoding:   token.encoding,
-	}
-	skip_token(parser)
-	return true
-}
-
-// Parse the productions:
-// implicit_document    ::= block_node DOCUMENT-END*
-//                          *
-// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-//                          *************************
-func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool {
-
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	// Parse extra document end indicators.
-	if !implicit {
-		for token.typ == yaml_DOCUMENT_END_TOKEN {
-			skip_token(parser)
-			token = peek_token(parser)
-			if token == nil {
-				return false
-			}
-		}
-	}
-
-	if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN &&
-		token.typ != yaml_TAG_DIRECTIVE_TOKEN &&
-		token.typ != yaml_DOCUMENT_START_TOKEN &&
-		token.typ != yaml_STREAM_END_TOKEN {
-		// Parse an implicit document.
-		if !yaml_parser_process_directives(parser, nil, nil) {
-			return false
-		}
-		parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
-		parser.state = yaml_PARSE_BLOCK_NODE_STATE
-
-		*event = yaml_event_t{
-			typ:        yaml_DOCUMENT_START_EVENT,
-			start_mark: token.start_mark,
-			end_mark:   token.end_mark,
-		}
-
-	} else if token.typ != yaml_STREAM_END_TOKEN {
-		// Parse an explicit document.
-		var version_directive *yaml_version_directive_t
-		var tag_directives []yaml_tag_directive_t
-		start_mark := token.start_mark
-		if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) {
-			return false
-		}
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_DOCUMENT_START_TOKEN {
-			yaml_parser_set_parser_error(parser,
-				"did not find expected <document start>", token.start_mark)
-			return false
-		}
-		parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
-		parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE
-		end_mark := token.end_mark
-
-		*event = yaml_event_t{
-			typ:               yaml_DOCUMENT_START_EVENT,
-			start_mark:        start_mark,
-			end_mark:          end_mark,
-			version_directive: version_directive,
-			tag_directives:    tag_directives,
-			implicit:          false,
-		}
-		skip_token(parser)
-
-	} else {
-		// Parse the stream end.
-		parser.state = yaml_PARSE_END_STATE
-		*event = yaml_event_t{
-			typ:        yaml_STREAM_END_EVENT,
-			start_mark: token.start_mark,
-			end_mark:   token.end_mark,
-		}
-		skip_token(parser)
-	}
-
-	return true
-}
-
-// Parse the productions:
-// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-//                                                    ***********
-//
-func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if token.typ == yaml_VERSION_DIRECTIVE_TOKEN ||
-		token.typ == yaml_TAG_DIRECTIVE_TOKEN ||
-		token.typ == yaml_DOCUMENT_START_TOKEN ||
-		token.typ == yaml_DOCUMENT_END_TOKEN ||
-		token.typ == yaml_STREAM_END_TOKEN {
-		parser.state = parser.states[len(parser.states)-1]
-		parser.states = parser.states[:len(parser.states)-1]
-		return yaml_parser_process_empty_scalar(parser, event,
-			token.start_mark)
-	}
-	return yaml_parser_parse_node(parser, event, true, false)
-}
-
-// Parse the productions:
-// implicit_document    ::= block_node DOCUMENT-END*
-//                                     *************
-// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-//
-func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	start_mark := token.start_mark
-	end_mark := token.start_mark
-
-	implicit := true
-	if token.typ == yaml_DOCUMENT_END_TOKEN {
-		end_mark = token.end_mark
-		skip_token(parser)
-		implicit = false
-	}
-
-	parser.tag_directives = parser.tag_directives[:0]
-
-	parser.state = yaml_PARSE_DOCUMENT_START_STATE
-	*event = yaml_event_t{
-		typ:        yaml_DOCUMENT_END_EVENT,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-		implicit:   implicit,
-	}
-	return true
-}
-
-// Parse the productions:
-// block_node_or_indentless_sequence    ::=
-//                          ALIAS
-//                          *****
-//                          | properties (block_content | indentless_block_sequence)?
-//                            **********  *
-//                          | block_content | indentless_block_sequence
-//                            *
-// block_node           ::= ALIAS
-//                          *****
-//                          | properties block_content?
-//                            ********** *
-//                          | block_content
-//                            *
-// flow_node            ::= ALIAS
-//                          *****
-//                          | properties flow_content?
-//                            ********** *
-//                          | flow_content
-//                            *
-// properties           ::= TAG ANCHOR? | ANCHOR TAG?
-//                          *************************
-// block_content        ::= block_collection | flow_collection | SCALAR
-//                                                               ******
-// flow_content         ::= flow_collection | SCALAR
-//                                            ******
-func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool {
-	//defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)()
-
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	if token.typ == yaml_ALIAS_TOKEN {
-		parser.state = parser.states[len(parser.states)-1]
-		parser.states = parser.states[:len(parser.states)-1]
-		*event = yaml_event_t{
-			typ:        yaml_ALIAS_EVENT,
-			start_mark: token.start_mark,
-			end_mark:   token.end_mark,
-			anchor:     token.value,
-		}
-		skip_token(parser)
-		return true
-	}
-
-	start_mark := token.start_mark
-	end_mark := token.start_mark
-
-	var tag_token bool
-	var tag_handle, tag_suffix, anchor []byte
-	var tag_mark yaml_mark_t
-	if token.typ == yaml_ANCHOR_TOKEN {
-		anchor = token.value
-		start_mark = token.start_mark
-		end_mark = token.end_mark
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ == yaml_TAG_TOKEN {
-			tag_token = true
-			tag_handle = token.value
-			tag_suffix = token.suffix
-			tag_mark = token.start_mark
-			end_mark = token.end_mark
-			skip_token(parser)
-			token = peek_token(parser)
-			if token == nil {
-				return false
-			}
-		}
-	} else if token.typ == yaml_TAG_TOKEN {
-		tag_token = true
-		tag_handle = token.value
-		tag_suffix = token.suffix
-		start_mark = token.start_mark
-		tag_mark = token.start_mark
-		end_mark = token.end_mark
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ == yaml_ANCHOR_TOKEN {
-			anchor = token.value
-			end_mark = token.end_mark
-			skip_token(parser)
-			token = peek_token(parser)
-			if token == nil {
-				return false
-			}
-		}
-	}
-
-	var tag []byte
-	if tag_token {
-		if len(tag_handle) == 0 {
-			tag = tag_suffix
-			tag_suffix = nil
-		} else {
-			for i := range parser.tag_directives {
-				if bytes.Equal(parser.tag_directives[i].handle, tag_handle) {
-					tag = append([]byte(nil), parser.tag_directives[i].prefix...)
-					tag = append(tag, tag_suffix...)
-					break
-				}
-			}
-			if len(tag) == 0 {
-				yaml_parser_set_parser_error_context(parser,
-					"while parsing a node", start_mark,
-					"found undefined tag handle", tag_mark)
-				return false
-			}
-		}
-	}
-
-	implicit := len(tag) == 0
-	if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN {
-		end_mark = token.end_mark
-		parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
-		*event = yaml_event_t{
-			typ:        yaml_SEQUENCE_START_EVENT,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			anchor:     anchor,
-			tag:        tag,
-			implicit:   implicit,
-			style:      yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
-		}
-		return true
-	}
-	if token.typ == yaml_SCALAR_TOKEN {
-		var plain_implicit, quoted_implicit bool
-		end_mark = token.end_mark
-		if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') {
-			plain_implicit = true
-		} else if len(tag) == 0 {
-			quoted_implicit = true
-		}
-		parser.state = parser.states[len(parser.states)-1]
-		parser.states = parser.states[:len(parser.states)-1]
-
-		*event = yaml_event_t{
-			typ:             yaml_SCALAR_EVENT,
-			start_mark:      start_mark,
-			end_mark:        end_mark,
-			anchor:          anchor,
-			tag:             tag,
-			value:           token.value,
-			implicit:        plain_implicit,
-			quoted_implicit: quoted_implicit,
-			style:           yaml_style_t(token.style),
-		}
-		skip_token(parser)
-		return true
-	}
-	if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN {
-		// [Go] Some of the events below can be merged as they differ only on style.
-		end_mark = token.end_mark
-		parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE
-		*event = yaml_event_t{
-			typ:        yaml_SEQUENCE_START_EVENT,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			anchor:     anchor,
-			tag:        tag,
-			implicit:   implicit,
-			style:      yaml_style_t(yaml_FLOW_SEQUENCE_STYLE),
-		}
-		return true
-	}
-	if token.typ == yaml_FLOW_MAPPING_START_TOKEN {
-		end_mark = token.end_mark
-		parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE
-		*event = yaml_event_t{
-			typ:        yaml_MAPPING_START_EVENT,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			anchor:     anchor,
-			tag:        tag,
-			implicit:   implicit,
-			style:      yaml_style_t(yaml_FLOW_MAPPING_STYLE),
-		}
-		return true
-	}
-	if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN {
-		end_mark = token.end_mark
-		parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE
-		*event = yaml_event_t{
-			typ:        yaml_SEQUENCE_START_EVENT,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			anchor:     anchor,
-			tag:        tag,
-			implicit:   implicit,
-			style:      yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
-		}
-		return true
-	}
-	if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN {
-		end_mark = token.end_mark
-		parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE
-		*event = yaml_event_t{
-			typ:        yaml_MAPPING_START_EVENT,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			anchor:     anchor,
-			tag:        tag,
-			implicit:   implicit,
-			style:      yaml_style_t(yaml_BLOCK_MAPPING_STYLE),
-		}
-		return true
-	}
-	if len(anchor) > 0 || len(tag) > 0 {
-		parser.state = parser.states[len(parser.states)-1]
-		parser.states = parser.states[:len(parser.states)-1]
-
-		*event = yaml_event_t{
-			typ:             yaml_SCALAR_EVENT,
-			start_mark:      start_mark,
-			end_mark:        end_mark,
-			anchor:          anchor,
-			tag:             tag,
-			implicit:        implicit,
-			quoted_implicit: false,
-			style:           yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
-		}
-		return true
-	}
-
-	context := "while parsing a flow node"
-	if block {
-		context = "while parsing a block node"
-	}
-	yaml_parser_set_parser_error_context(parser, context, start_mark,
-		"did not find expected node content", token.start_mark)
-	return false
-}
-
-// Parse the productions:
-// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
-//                    ********************  *********** *             *********
-//
-func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
-	if first {
-		token := peek_token(parser)
-		parser.marks = append(parser.marks, token.start_mark)
-		skip_token(parser)
-	}
-
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	if token.typ == yaml_BLOCK_ENTRY_TOKEN {
-		mark := token.end_mark
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)
-			return yaml_parser_parse_node(parser, event, true, false)
-		} else {
-			parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE
-			return yaml_parser_process_empty_scalar(parser, event, mark)
-		}
-	}
-	if token.typ == yaml_BLOCK_END_TOKEN {
-		parser.state = parser.states[len(parser.states)-1]
-		parser.states = parser.states[:len(parser.states)-1]
-		parser.marks = parser.marks[:len(parser.marks)-1]
-
-		*event = yaml_event_t{
-			typ:        yaml_SEQUENCE_END_EVENT,
-			start_mark: token.start_mark,
-			end_mark:   token.end_mark,
-		}
-
-		skip_token(parser)
-		return true
-	}
-
-	context_mark := parser.marks[len(parser.marks)-1]
-	parser.marks = parser.marks[:len(parser.marks)-1]
-	return yaml_parser_set_parser_error_context(parser,
-		"while parsing a block collection", context_mark,
-		"did not find expected '-' indicator", token.start_mark)
-}
-
-// Parse the productions:
-// indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
-//                           *********** *
-func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	if token.typ == yaml_BLOCK_ENTRY_TOKEN {
-		mark := token.end_mark
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_BLOCK_ENTRY_TOKEN &&
-			token.typ != yaml_KEY_TOKEN &&
-			token.typ != yaml_VALUE_TOKEN &&
-			token.typ != yaml_BLOCK_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)
-			return yaml_parser_parse_node(parser, event, true, false)
-		}
-		parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
-		return yaml_parser_process_empty_scalar(parser, event, mark)
-	}
-	parser.state = parser.states[len(parser.states)-1]
-	parser.states = parser.states[:len(parser.states)-1]
-
-	*event = yaml_event_t{
-		typ:        yaml_SEQUENCE_END_EVENT,
-		start_mark: token.start_mark,
-		end_mark:   token.start_mark, // [Go] Shouldn't this be token.end_mark?
-	}
-	return true
-}
-
-// Parse the productions:
-// block_mapping        ::= BLOCK-MAPPING_START
-//                          *******************
-//                          ((KEY block_node_or_indentless_sequence?)?
-//                            *** *
-//                          (VALUE block_node_or_indentless_sequence?)?)*
-//
-//                          BLOCK-END
-//                          *********
-//
-func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
-	if first {
-		token := peek_token(parser)
-		parser.marks = append(parser.marks, token.start_mark)
-		skip_token(parser)
-	}
-
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	if token.typ == yaml_KEY_TOKEN {
-		mark := token.end_mark
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_KEY_TOKEN &&
-			token.typ != yaml_VALUE_TOKEN &&
-			token.typ != yaml_BLOCK_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE)
-			return yaml_parser_parse_node(parser, event, true, true)
-		} else {
-			parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE
-			return yaml_parser_process_empty_scalar(parser, event, mark)
-		}
-	} else if token.typ == yaml_BLOCK_END_TOKEN {
-		parser.state = parser.states[len(parser.states)-1]
-		parser.states = parser.states[:len(parser.states)-1]
-		parser.marks = parser.marks[:len(parser.marks)-1]
-		*event = yaml_event_t{
-			typ:        yaml_MAPPING_END_EVENT,
-			start_mark: token.start_mark,
-			end_mark:   token.end_mark,
-		}
-		skip_token(parser)
-		return true
-	}
-
-	context_mark := parser.marks[len(parser.marks)-1]
-	parser.marks = parser.marks[:len(parser.marks)-1]
-	return yaml_parser_set_parser_error_context(parser,
-		"while parsing a block mapping", context_mark,
-		"did not find expected key", token.start_mark)
-}
-
-// Parse the productions:
-// block_mapping        ::= BLOCK-MAPPING_START
-//
-//                          ((KEY block_node_or_indentless_sequence?)?
-//
-//                          (VALUE block_node_or_indentless_sequence?)?)*
-//                           ***** *
-//                          BLOCK-END
-//
-//
-func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if token.typ == yaml_VALUE_TOKEN {
-		mark := token.end_mark
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_KEY_TOKEN &&
-			token.typ != yaml_VALUE_TOKEN &&
-			token.typ != yaml_BLOCK_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE)
-			return yaml_parser_parse_node(parser, event, true, true)
-		}
-		parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
-		return yaml_parser_process_empty_scalar(parser, event, mark)
-	}
-	parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
-	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
-}
-
-// Parse the productions:
-// flow_sequence        ::= FLOW-SEQUENCE-START
-//                          *******************
-//                          (flow_sequence_entry FLOW-ENTRY)*
-//                           *                   **********
-//                          flow_sequence_entry?
-//                          *
-//                          FLOW-SEQUENCE-END
-//                          *****************
-// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-//                          *
-//
-func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
-	if first {
-		token := peek_token(parser)
-		parser.marks = append(parser.marks, token.start_mark)
-		skip_token(parser)
-	}
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
-		if !first {
-			if token.typ == yaml_FLOW_ENTRY_TOKEN {
-				skip_token(parser)
-				token = peek_token(parser)
-				if token == nil {
-					return false
-				}
-			} else {
-				context_mark := parser.marks[len(parser.marks)-1]
-				parser.marks = parser.marks[:len(parser.marks)-1]
-				return yaml_parser_set_parser_error_context(parser,
-					"while parsing a flow sequence", context_mark,
-					"did not find expected ',' or ']'", token.start_mark)
-			}
-		}
-
-		if token.typ == yaml_KEY_TOKEN {
-			parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE
-			*event = yaml_event_t{
-				typ:        yaml_MAPPING_START_EVENT,
-				start_mark: token.start_mark,
-				end_mark:   token.end_mark,
-				implicit:   true,
-				style:      yaml_style_t(yaml_FLOW_MAPPING_STYLE),
-			}
-			skip_token(parser)
-			return true
-		} else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE)
-			return yaml_parser_parse_node(parser, event, false, false)
-		}
-	}
-
-	parser.state = parser.states[len(parser.states)-1]
-	parser.states = parser.states[:len(parser.states)-1]
-	parser.marks = parser.marks[:len(parser.marks)-1]
-
-	*event = yaml_event_t{
-		typ:        yaml_SEQUENCE_END_EVENT,
-		start_mark: token.start_mark,
-		end_mark:   token.end_mark,
-	}
-
-	skip_token(parser)
-	return true
-}
-
-//
-// Parse the productions:
-// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-//                                      *** *
-//
-func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if token.typ != yaml_VALUE_TOKEN &&
-		token.typ != yaml_FLOW_ENTRY_TOKEN &&
-		token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
-		parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)
-		return yaml_parser_parse_node(parser, event, false, false)
-	}
-	mark := token.end_mark
-	skip_token(parser)
-	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE
-	return yaml_parser_process_empty_scalar(parser, event, mark)
-}
-
-// Parse the productions:
-// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-//                                                      ***** *
-//
-func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if token.typ == yaml_VALUE_TOKEN {
-		skip_token(parser)
-		token := peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)
-			return yaml_parser_parse_node(parser, event, false, false)
-		}
-	}
-	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE
-	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
-}
-
-// Parse the productions:
-// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-//                                                                      *
-//
-func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE
-	*event = yaml_event_t{
-		typ:        yaml_MAPPING_END_EVENT,
-		start_mark: token.start_mark,
-		end_mark:   token.start_mark, // [Go] Shouldn't this be end_mark?
-	}
-	return true
-}
-
-// Parse the productions:
-// flow_mapping         ::= FLOW-MAPPING-START
-//                          ******************
-//                          (flow_mapping_entry FLOW-ENTRY)*
-//                           *                  **********
-//                          flow_mapping_entry?
-//                          ******************
-//                          FLOW-MAPPING-END
-//                          ****************
-// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-//                          *           *** *
-//
-func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
-	if first {
-		token := peek_token(parser)
-		parser.marks = append(parser.marks, token.start_mark)
-		skip_token(parser)
-	}
-
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
-		if !first {
-			if token.typ == yaml_FLOW_ENTRY_TOKEN {
-				skip_token(parser)
-				token = peek_token(parser)
-				if token == nil {
-					return false
-				}
-			} else {
-				context_mark := parser.marks[len(parser.marks)-1]
-				parser.marks = parser.marks[:len(parser.marks)-1]
-				return yaml_parser_set_parser_error_context(parser,
-					"while parsing a flow mapping", context_mark,
-					"did not find expected ',' or '}'", token.start_mark)
-			}
-		}
-
-		if token.typ == yaml_KEY_TOKEN {
-			skip_token(parser)
-			token = peek_token(parser)
-			if token == nil {
-				return false
-			}
-			if token.typ != yaml_VALUE_TOKEN &&
-				token.typ != yaml_FLOW_ENTRY_TOKEN &&
-				token.typ != yaml_FLOW_MAPPING_END_TOKEN {
-				parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE)
-				return yaml_parser_parse_node(parser, event, false, false)
-			} else {
-				parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE
-				return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
-			}
-		} else if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)
-			return yaml_parser_parse_node(parser, event, false, false)
-		}
-	}
-
-	parser.state = parser.states[len(parser.states)-1]
-	parser.states = parser.states[:len(parser.states)-1]
-	parser.marks = parser.marks[:len(parser.marks)-1]
-	*event = yaml_event_t{
-		typ:        yaml_MAPPING_END_EVENT,
-		start_mark: token.start_mark,
-		end_mark:   token.end_mark,
-	}
-	skip_token(parser)
-	return true
-}
-
-// Parse the productions:
-// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-//                                   *                  ***** *
-//
-func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool {
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-	if empty {
-		parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
-		return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
-	}
-	if token.typ == yaml_VALUE_TOKEN {
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-		if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN {
-			parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE)
-			return yaml_parser_parse_node(parser, event, false, false)
-		}
-	}
-	parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
-	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
-}
-
-// Generate an empty scalar event.
-func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool {
-	*event = yaml_event_t{
-		typ:        yaml_SCALAR_EVENT,
-		start_mark: mark,
-		end_mark:   mark,
-		value:      nil, // Empty
-		implicit:   true,
-		style:      yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
-	}
-	return true
-}
-
-var default_tag_directives = []yaml_tag_directive_t{
-	{[]byte("!"), []byte("!")},
-	{[]byte("!!"), []byte("tag:yaml.org,2002:")},
-}
-
-// Parse directives.
-func yaml_parser_process_directives(parser *yaml_parser_t,
-	version_directive_ref **yaml_version_directive_t,
-	tag_directives_ref *[]yaml_tag_directive_t) bool {
-
-	var version_directive *yaml_version_directive_t
-	var tag_directives []yaml_tag_directive_t
-
-	token := peek_token(parser)
-	if token == nil {
-		return false
-	}
-
-	for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN {
-		if token.typ == yaml_VERSION_DIRECTIVE_TOKEN {
-			if version_directive != nil {
-				yaml_parser_set_parser_error(parser,
-					"found duplicate %YAML directive", token.start_mark)
-				return false
-			}
-			if token.major != 1 || token.minor != 1 {
-				yaml_parser_set_parser_error(parser,
-					"found incompatible YAML document", token.start_mark)
-				return false
-			}
-			version_directive = &yaml_version_directive_t{
-				major: token.major,
-				minor: token.minor,
-			}
-		} else if token.typ == yaml_TAG_DIRECTIVE_TOKEN {
-			value := yaml_tag_directive_t{
-				handle: token.value,
-				prefix: token.prefix,
-			}
-			if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) {
-				return false
-			}
-			tag_directives = append(tag_directives, value)
-		}
-
-		skip_token(parser)
-		token = peek_token(parser)
-		if token == nil {
-			return false
-		}
-	}
-
-	for i := range default_tag_directives {
-		if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) {
-			return false
-		}
-	}
-
-	if version_directive_ref != nil {
-		*version_directive_ref = version_directive
-	}
-	if tag_directives_ref != nil {
-		*tag_directives_ref = tag_directives
-	}
-	return true
-}
-
-// Append a tag directive to the directives stack.
-func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool {
-	for i := range parser.tag_directives {
-		if bytes.Equal(value.handle, parser.tag_directives[i].handle) {
-			if allow_duplicates {
-				return true
-			}
-			return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark)
-		}
-	}
-
-	// [Go] I suspect the copy is unnecessary. This was likely done
-	// because there was no way to track ownership of the data.
-	value_copy := yaml_tag_directive_t{
-		handle: make([]byte, len(value.handle)),
-		prefix: make([]byte, len(value.prefix)),
-	}
-	copy(value_copy.handle, value.handle)
-	copy(value_copy.prefix, value.prefix)
-	parser.tag_directives = append(parser.tag_directives, value_copy)
-	return true
-}
diff --git a/vendor/gopkg.in/yaml.v2/readerc.go b/vendor/gopkg.in/yaml.v2/readerc.go
deleted file mode 100644
index 7c1f5fac..00000000
--- a/vendor/gopkg.in/yaml.v2/readerc.go
+++ /dev/null
@@ -1,412 +0,0 @@
-package yaml
-
-import (
-	"io"
-)
-
-// Set the reader error and return 0.
-func yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool {
-	parser.error = yaml_READER_ERROR
-	parser.problem = problem
-	parser.problem_offset = offset
-	parser.problem_value = value
-	return false
-}
-
-// Byte order marks.
-const (
-	bom_UTF8    = "\xef\xbb\xbf"
-	bom_UTF16LE = "\xff\xfe"
-	bom_UTF16BE = "\xfe\xff"
-)
-
-// Determine the input stream encoding by checking the BOM symbol. If no BOM is
-// found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
-func yaml_parser_determine_encoding(parser *yaml_parser_t) bool {
-	// Ensure that we had enough bytes in the raw buffer.
-	for !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 {
-		if !yaml_parser_update_raw_buffer(parser) {
-			return false
-		}
-	}
-
-	// Determine the encoding.
-	buf := parser.raw_buffer
-	pos := parser.raw_buffer_pos
-	avail := len(buf) - pos
-	if avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] {
-		parser.encoding = yaml_UTF16LE_ENCODING
-		parser.raw_buffer_pos += 2
-		parser.offset += 2
-	} else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] {
-		parser.encoding = yaml_UTF16BE_ENCODING
-		parser.raw_buffer_pos += 2
-		parser.offset += 2
-	} else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] {
-		parser.encoding = yaml_UTF8_ENCODING
-		parser.raw_buffer_pos += 3
-		parser.offset += 3
-	} else {
-		parser.encoding = yaml_UTF8_ENCODING
-	}
-	return true
-}
-
-// Update the raw buffer.
-func yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool {
-	size_read := 0
-
-	// Return if the raw buffer is full.
-	if parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) {
-		return true
-	}
-
-	// Return on EOF.
-	if parser.eof {
-		return true
-	}
-
-	// Move the remaining bytes in the raw buffer to the beginning.
-	if parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) {
-		copy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:])
-	}
-	parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos]
-	parser.raw_buffer_pos = 0
-
-	// Call the read handler to fill the buffer.
-	size_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)])
-	parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read]
-	if err == io.EOF {
-		parser.eof = true
-	} else if err != nil {
-		return yaml_parser_set_reader_error(parser, "input error: "+err.Error(), parser.offset, -1)
-	}
-	return true
-}
-
-// Ensure that the buffer contains at least `length` characters.
-// Return true on success, false on failure.
-//
-// The length is supposed to be significantly less that the buffer size.
-func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
-	if parser.read_handler == nil {
-		panic("read handler must be set")
-	}
-
-	// [Go] This function was changed to guarantee the requested length size at EOF.
-	// The fact we need to do this is pretty awful, but the description above implies
-	// for that to be the case, and there are tests 
-
-	// If the EOF flag is set and the raw buffer is empty, do nothing.
-	if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
-		// [Go] ACTUALLY! Read the documentation of this function above.
-		// This is just broken. To return true, we need to have the
-		// given length in the buffer. Not doing that means every single
-		// check that calls this function to make sure the buffer has a
-		// given length is Go) panicking; or C) accessing invalid memory.
-		//return true
-	}
-
-	// Return if the buffer contains enough characters.
-	if parser.unread >= length {
-		return true
-	}
-
-	// Determine the input encoding if it is not known yet.
-	if parser.encoding == yaml_ANY_ENCODING {
-		if !yaml_parser_determine_encoding(parser) {
-			return false
-		}
-	}
-
-	// Move the unread characters to the beginning of the buffer.
-	buffer_len := len(parser.buffer)
-	if parser.buffer_pos > 0 && parser.buffer_pos < buffer_len {
-		copy(parser.buffer, parser.buffer[parser.buffer_pos:])
-		buffer_len -= parser.buffer_pos
-		parser.buffer_pos = 0
-	} else if parser.buffer_pos == buffer_len {
-		buffer_len = 0
-		parser.buffer_pos = 0
-	}
-
-	// Open the whole buffer for writing, and cut it before returning.
-	parser.buffer = parser.buffer[:cap(parser.buffer)]
-
-	// Fill the buffer until it has enough characters.
-	first := true
-	for parser.unread < length {
-
-		// Fill the raw buffer if necessary.
-		if !first || parser.raw_buffer_pos == len(parser.raw_buffer) {
-			if !yaml_parser_update_raw_buffer(parser) {
-				parser.buffer = parser.buffer[:buffer_len]
-				return false
-			}
-		}
-		first = false
-
-		// Decode the raw buffer.
-	inner:
-		for parser.raw_buffer_pos != len(parser.raw_buffer) {
-			var value rune
-			var width int
-
-			raw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos
-
-			// Decode the next character.
-			switch parser.encoding {
-			case yaml_UTF8_ENCODING:
-				// Decode a UTF-8 character.  Check RFC 3629
-				// (http://www.ietf.org/rfc/rfc3629.txt) for more details.
-				//
-				// The following table (taken from the RFC) is used for
-				// decoding.
-				//
-				//    Char. number range |        UTF-8 octet sequence
-				//      (hexadecimal)    |              (binary)
-				//   --------------------+------------------------------------
-				//   0000 0000-0000 007F | 0xxxxxxx
-				//   0000 0080-0000 07FF | 110xxxxx 10xxxxxx
-				//   0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
-				//   0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-				//
-				// Additionally, the characters in the range 0xD800-0xDFFF
-				// are prohibited as they are reserved for use with UTF-16
-				// surrogate pairs.
-
-				// Determine the length of the UTF-8 sequence.
-				octet := parser.raw_buffer[parser.raw_buffer_pos]
-				switch {
-				case octet&0x80 == 0x00:
-					width = 1
-				case octet&0xE0 == 0xC0:
-					width = 2
-				case octet&0xF0 == 0xE0:
-					width = 3
-				case octet&0xF8 == 0xF0:
-					width = 4
-				default:
-					// The leading octet is invalid.
-					return yaml_parser_set_reader_error(parser,
-						"invalid leading UTF-8 octet",
-						parser.offset, int(octet))
-				}
-
-				// Check if the raw buffer contains an incomplete character.
-				if width > raw_unread {
-					if parser.eof {
-						return yaml_parser_set_reader_error(parser,
-							"incomplete UTF-8 octet sequence",
-							parser.offset, -1)
-					}
-					break inner
-				}
-
-				// Decode the leading octet.
-				switch {
-				case octet&0x80 == 0x00:
-					value = rune(octet & 0x7F)
-				case octet&0xE0 == 0xC0:
-					value = rune(octet & 0x1F)
-				case octet&0xF0 == 0xE0:
-					value = rune(octet & 0x0F)
-				case octet&0xF8 == 0xF0:
-					value = rune(octet & 0x07)
-				default:
-					value = 0
-				}
-
-				// Check and decode the trailing octets.
-				for k := 1; k < width; k++ {
-					octet = parser.raw_buffer[parser.raw_buffer_pos+k]
-
-					// Check if the octet is valid.
-					if (octet & 0xC0) != 0x80 {
-						return yaml_parser_set_reader_error(parser,
-							"invalid trailing UTF-8 octet",
-							parser.offset+k, int(octet))
-					}
-
-					// Decode the octet.
-					value = (value << 6) + rune(octet&0x3F)
-				}
-
-				// Check the length of the sequence against the value.
-				switch {
-				case width == 1:
-				case width == 2 && value >= 0x80:
-				case width == 3 && value >= 0x800:
-				case width == 4 && value >= 0x10000:
-				default:
-					return yaml_parser_set_reader_error(parser,
-						"invalid length of a UTF-8 sequence",
-						parser.offset, -1)
-				}
-
-				// Check the range of the value.
-				if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF {
-					return yaml_parser_set_reader_error(parser,
-						"invalid Unicode character",
-						parser.offset, int(value))
-				}
-
-			case yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING:
-				var low, high int
-				if parser.encoding == yaml_UTF16LE_ENCODING {
-					low, high = 0, 1
-				} else {
-					low, high = 1, 0
-				}
-
-				// The UTF-16 encoding is not as simple as one might
-				// naively think.  Check RFC 2781
-				// (http://www.ietf.org/rfc/rfc2781.txt).
-				//
-				// Normally, two subsequent bytes describe a Unicode
-				// character.  However a special technique (called a
-				// surrogate pair) is used for specifying character
-				// values larger than 0xFFFF.
-				//
-				// A surrogate pair consists of two pseudo-characters:
-				//      high surrogate area (0xD800-0xDBFF)
-				//      low surrogate area (0xDC00-0xDFFF)
-				//
-				// The following formulas are used for decoding
-				// and encoding characters using surrogate pairs:
-				//
-				//  U  = U' + 0x10000   (0x01 00 00 <= U <= 0x10 FF FF)
-				//  U' = yyyyyyyyyyxxxxxxxxxx   (0 <= U' <= 0x0F FF FF)
-				//  W1 = 110110yyyyyyyyyy
-				//  W2 = 110111xxxxxxxxxx
-				//
-				// where U is the character value, W1 is the high surrogate
-				// area, W2 is the low surrogate area.
-
-				// Check for incomplete UTF-16 character.
-				if raw_unread < 2 {
-					if parser.eof {
-						return yaml_parser_set_reader_error(parser,
-							"incomplete UTF-16 character",
-							parser.offset, -1)
-					}
-					break inner
-				}
-
-				// Get the character.
-				value = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) +
-					(rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8)
-
-				// Check for unexpected low surrogate area.
-				if value&0xFC00 == 0xDC00 {
-					return yaml_parser_set_reader_error(parser,
-						"unexpected low surrogate area",
-						parser.offset, int(value))
-				}
-
-				// Check for a high surrogate area.
-				if value&0xFC00 == 0xD800 {
-					width = 4
-
-					// Check for incomplete surrogate pair.
-					if raw_unread < 4 {
-						if parser.eof {
-							return yaml_parser_set_reader_error(parser,
-								"incomplete UTF-16 surrogate pair",
-								parser.offset, -1)
-						}
-						break inner
-					}
-
-					// Get the next character.
-					value2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) +
-						(rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8)
-
-					// Check for a low surrogate area.
-					if value2&0xFC00 != 0xDC00 {
-						return yaml_parser_set_reader_error(parser,
-							"expected low surrogate area",
-							parser.offset+2, int(value2))
-					}
-
-					// Generate the value of the surrogate pair.
-					value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF)
-				} else {
-					width = 2
-				}
-
-			default:
-				panic("impossible")
-			}
-
-			// Check if the character is in the allowed range:
-			//      #x9 | #xA | #xD | [#x20-#x7E]               (8 bit)
-			//      | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD]    (16 bit)
-			//      | [#x10000-#x10FFFF]                        (32 bit)
-			switch {
-			case value == 0x09:
-			case value == 0x0A:
-			case value == 0x0D:
-			case value >= 0x20 && value <= 0x7E:
-			case value == 0x85:
-			case value >= 0xA0 && value <= 0xD7FF:
-			case value >= 0xE000 && value <= 0xFFFD:
-			case value >= 0x10000 && value <= 0x10FFFF:
-			default:
-				return yaml_parser_set_reader_error(parser,
-					"control characters are not allowed",
-					parser.offset, int(value))
-			}
-
-			// Move the raw pointers.
-			parser.raw_buffer_pos += width
-			parser.offset += width
-
-			// Finally put the character into the buffer.
-			if value <= 0x7F {
-				// 0000 0000-0000 007F . 0xxxxxxx
-				parser.buffer[buffer_len+0] = byte(value)
-				buffer_len += 1
-			} else if value <= 0x7FF {
-				// 0000 0080-0000 07FF . 110xxxxx 10xxxxxx
-				parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6))
-				parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F))
-				buffer_len += 2
-			} else if value <= 0xFFFF {
-				// 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx
-				parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12))
-				parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F))
-				parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F))
-				buffer_len += 3
-			} else {
-				// 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-				parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18))
-				parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F))
-				parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F))
-				parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F))
-				buffer_len += 4
-			}
-
-			parser.unread++
-		}
-
-		// On EOF, put NUL into the buffer and return.
-		if parser.eof {
-			parser.buffer[buffer_len] = 0
-			buffer_len++
-			parser.unread++
-			break
-		}
-	}
-	// [Go] Read the documentation of this function above. To return true,
-	// we need to have the given length in the buffer. Not doing that means
-	// every single check that calls this function to make sure the buffer
-	// has a given length is Go) panicking; or C) accessing invalid memory.
-	// This happens here due to the EOF above breaking early.
-	for buffer_len < length {
-		parser.buffer[buffer_len] = 0
-		buffer_len++
-	}
-	parser.buffer = parser.buffer[:buffer_len]
-	return true
-}
diff --git a/vendor/gopkg.in/yaml.v2/resolve.go b/vendor/gopkg.in/yaml.v2/resolve.go
deleted file mode 100644
index 4120e0c9..00000000
--- a/vendor/gopkg.in/yaml.v2/resolve.go
+++ /dev/null
@@ -1,258 +0,0 @@
-package yaml
-
-import (
-	"encoding/base64"
-	"math"
-	"regexp"
-	"strconv"
-	"strings"
-	"time"
-)
-
-type resolveMapItem struct {
-	value interface{}
-	tag   string
-}
-
-var resolveTable = make([]byte, 256)
-var resolveMap = make(map[string]resolveMapItem)
-
-func init() {
-	t := resolveTable
-	t[int('+')] = 'S' // Sign
-	t[int('-')] = 'S'
-	for _, c := range "0123456789" {
-		t[int(c)] = 'D' // Digit
-	}
-	for _, c := range "yYnNtTfFoO~" {
-		t[int(c)] = 'M' // In map
-	}
-	t[int('.')] = '.' // Float (potentially in map)
-
-	var resolveMapList = []struct {
-		v   interface{}
-		tag string
-		l   []string
-	}{
-		{true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}},
-		{true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}},
-		{true, yaml_BOOL_TAG, []string{"on", "On", "ON"}},
-		{false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}},
-		{false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}},
-		{false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}},
-		{nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}},
-		{math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}},
-		{math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}},
-		{math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}},
-		{math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}},
-		{"<<", yaml_MERGE_TAG, []string{"<<"}},
-	}
-
-	m := resolveMap
-	for _, item := range resolveMapList {
-		for _, s := range item.l {
-			m[s] = resolveMapItem{item.v, item.tag}
-		}
-	}
-}
-
-const longTagPrefix = "tag:yaml.org,2002:"
-
-func shortTag(tag string) string {
-	// TODO This can easily be made faster and produce less garbage.
-	if strings.HasPrefix(tag, longTagPrefix) {
-		return "!!" + tag[len(longTagPrefix):]
-	}
-	return tag
-}
-
-func longTag(tag string) string {
-	if strings.HasPrefix(tag, "!!") {
-		return longTagPrefix + tag[2:]
-	}
-	return tag
-}
-
-func resolvableTag(tag string) bool {
-	switch tag {
-	case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG, yaml_TIMESTAMP_TAG:
-		return true
-	}
-	return false
-}
-
-var yamlStyleFloat = regexp.MustCompile(`^[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?$`)
-
-func resolve(tag string, in string) (rtag string, out interface{}) {
-	if !resolvableTag(tag) {
-		return tag, in
-	}
-
-	defer func() {
-		switch tag {
-		case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
-			return
-		case yaml_FLOAT_TAG:
-			if rtag == yaml_INT_TAG {
-				switch v := out.(type) {
-				case int64:
-					rtag = yaml_FLOAT_TAG
-					out = float64(v)
-					return
-				case int:
-					rtag = yaml_FLOAT_TAG
-					out = float64(v)
-					return
-				}
-			}
-		}
-		failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
-	}()
-
-	// Any data is accepted as a !!str or !!binary.
-	// Otherwise, the prefix is enough of a hint about what it might be.
-	hint := byte('N')
-	if in != "" {
-		hint = resolveTable[in[0]]
-	}
-	if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG {
-		// Handle things we can lookup in a map.
-		if item, ok := resolveMap[in]; ok {
-			return item.tag, item.value
-		}
-
-		// Base 60 floats are a bad idea, were dropped in YAML 1.2, and
-		// are purposefully unsupported here. They're still quoted on
-		// the way out for compatibility with other parser, though.
-
-		switch hint {
-		case 'M':
-			// We've already checked the map above.
-
-		case '.':
-			// Not in the map, so maybe a normal float.
-			floatv, err := strconv.ParseFloat(in, 64)
-			if err == nil {
-				return yaml_FLOAT_TAG, floatv
-			}
-
-		case 'D', 'S':
-			// Int, float, or timestamp.
-			// Only try values as a timestamp if the value is unquoted or there's an explicit
-			// !!timestamp tag.
-			if tag == "" || tag == yaml_TIMESTAMP_TAG {
-				t, ok := parseTimestamp(in)
-				if ok {
-					return yaml_TIMESTAMP_TAG, t
-				}
-			}
-
-			plain := strings.Replace(in, "_", "", -1)
-			intv, err := strconv.ParseInt(plain, 0, 64)
-			if err == nil {
-				if intv == int64(int(intv)) {
-					return yaml_INT_TAG, int(intv)
-				} else {
-					return yaml_INT_TAG, intv
-				}
-			}
-			uintv, err := strconv.ParseUint(plain, 0, 64)
-			if err == nil {
-				return yaml_INT_TAG, uintv
-			}
-			if yamlStyleFloat.MatchString(plain) {
-				floatv, err := strconv.ParseFloat(plain, 64)
-				if err == nil {
-					return yaml_FLOAT_TAG, floatv
-				}
-			}
-			if strings.HasPrefix(plain, "0b") {
-				intv, err := strconv.ParseInt(plain[2:], 2, 64)
-				if err == nil {
-					if intv == int64(int(intv)) {
-						return yaml_INT_TAG, int(intv)
-					} else {
-						return yaml_INT_TAG, intv
-					}
-				}
-				uintv, err := strconv.ParseUint(plain[2:], 2, 64)
-				if err == nil {
-					return yaml_INT_TAG, uintv
-				}
-			} else if strings.HasPrefix(plain, "-0b") {
-				intv, err := strconv.ParseInt("-" + plain[3:], 2, 64)
-				if err == nil {
-					if true || intv == int64(int(intv)) {
-						return yaml_INT_TAG, int(intv)
-					} else {
-						return yaml_INT_TAG, intv
-					}
-				}
-			}
-		default:
-			panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
-		}
-	}
-	return yaml_STR_TAG, in
-}
-
-// encodeBase64 encodes s as base64 that is broken up into multiple lines
-// as appropriate for the resulting length.
-func encodeBase64(s string) string {
-	const lineLen = 70
-	encLen := base64.StdEncoding.EncodedLen(len(s))
-	lines := encLen/lineLen + 1
-	buf := make([]byte, encLen*2+lines)
-	in := buf[0:encLen]
-	out := buf[encLen:]
-	base64.StdEncoding.Encode(in, []byte(s))
-	k := 0
-	for i := 0; i < len(in); i += lineLen {
-		j := i + lineLen
-		if j > len(in) {
-			j = len(in)
-		}
-		k += copy(out[k:], in[i:j])
-		if lines > 1 {
-			out[k] = '\n'
-			k++
-		}
-	}
-	return string(out[:k])
-}
-
-// This is a subset of the formats allowed by the regular expression
-// defined at http://yaml.org/type/timestamp.html.
-var allowedTimestampFormats = []string{
-	"2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields.
-	"2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t".
-	"2006-1-2 15:4:5.999999999",       // space separated with no time zone
-	"2006-1-2",                        // date only
-	// Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5"
-	// from the set of examples.
-}
-
-// parseTimestamp parses s as a timestamp string and
-// returns the timestamp and reports whether it succeeded.
-// Timestamp formats are defined at http://yaml.org/type/timestamp.html
-func parseTimestamp(s string) (time.Time, bool) {
-	// TODO write code to check all the formats supported by
-	// http://yaml.org/type/timestamp.html instead of using time.Parse.
-
-	// Quick check: all date formats start with YYYY-.
-	i := 0
-	for ; i < len(s); i++ {
-		if c := s[i]; c < '0' || c > '9' {
-			break
-		}
-	}
-	if i != 4 || i == len(s) || s[i] != '-' {
-		return time.Time{}, false
-	}
-	for _, format := range allowedTimestampFormats {
-		if t, err := time.Parse(format, s); err == nil {
-			return t, true
-		}
-	}
-	return time.Time{}, false
-}
diff --git a/vendor/gopkg.in/yaml.v2/scannerc.go b/vendor/gopkg.in/yaml.v2/scannerc.go
deleted file mode 100644
index 0b9bb603..00000000
--- a/vendor/gopkg.in/yaml.v2/scannerc.go
+++ /dev/null
@@ -1,2711 +0,0 @@
-package yaml
-
-import (
-	"bytes"
-	"fmt"
-)
-
-// Introduction
-// ************
-//
-// The following notes assume that you are familiar with the YAML specification
-// (http://yaml.org/spec/1.2/spec.html).  We mostly follow it, although in
-// some cases we are less restrictive that it requires.
-//
-// The process of transforming a YAML stream into a sequence of events is
-// divided on two steps: Scanning and Parsing.
-//
-// The Scanner transforms the input stream into a sequence of tokens, while the
-// parser transform the sequence of tokens produced by the Scanner into a
-// sequence of parsing events.
-//
-// The Scanner is rather clever and complicated. The Parser, on the contrary,
-// is a straightforward implementation of a recursive-descendant parser (or,
-// LL(1) parser, as it is usually called).
-//
-// Actually there are two issues of Scanning that might be called "clever", the
-// rest is quite straightforward.  The issues are "block collection start" and
-// "simple keys".  Both issues are explained below in details.
-//
-// Here the Scanning step is explained and implemented.  We start with the list
-// of all the tokens produced by the Scanner together with short descriptions.
-//
-// Now, tokens:
-//
-//      STREAM-START(encoding)          # The stream start.
-//      STREAM-END                      # The stream end.
-//      VERSION-DIRECTIVE(major,minor)  # The '%YAML' directive.
-//      TAG-DIRECTIVE(handle,prefix)    # The '%TAG' directive.
-//      DOCUMENT-START                  # '---'
-//      DOCUMENT-END                    # '...'
-//      BLOCK-SEQUENCE-START            # Indentation increase denoting a block
-//      BLOCK-MAPPING-START             # sequence or a block mapping.
-//      BLOCK-END                       # Indentation decrease.
-//      FLOW-SEQUENCE-START             # '['
-//      FLOW-SEQUENCE-END               # ']'
-//      BLOCK-SEQUENCE-START            # '{'
-//      BLOCK-SEQUENCE-END              # '}'
-//      BLOCK-ENTRY                     # '-'
-//      FLOW-ENTRY                      # ','
-//      KEY                             # '?' or nothing (simple keys).
-//      VALUE                           # ':'
-//      ALIAS(anchor)                   # '*anchor'
-//      ANCHOR(anchor)                  # '&anchor'
-//      TAG(handle,suffix)              # '!handle!suffix'
-//      SCALAR(value,style)             # A scalar.
-//
-// The following two tokens are "virtual" tokens denoting the beginning and the
-// end of the stream:
-//
-//      STREAM-START(encoding)
-//      STREAM-END
-//
-// We pass the information about the input stream encoding with the
-// STREAM-START token.
-//
-// The next two tokens are responsible for tags:
-//
-//      VERSION-DIRECTIVE(major,minor)
-//      TAG-DIRECTIVE(handle,prefix)
-//
-// Example:
-//
-//      %YAML   1.1
-//      %TAG    !   !foo
-//      %TAG    !yaml!  tag:yaml.org,2002:
-//      ---
-//
-// The correspoding sequence of tokens:
-//
-//      STREAM-START(utf-8)
-//      VERSION-DIRECTIVE(1,1)
-//      TAG-DIRECTIVE("!","!foo")
-//      TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:")
-//      DOCUMENT-START
-//      STREAM-END
-//
-// Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole
-// line.
-//
-// The document start and end indicators are represented by:
-//
-//      DOCUMENT-START
-//      DOCUMENT-END
-//
-// Note that if a YAML stream contains an implicit document (without '---'
-// and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be
-// produced.
-//
-// In the following examples, we present whole documents together with the
-// produced tokens.
-//
-//      1. An implicit document:
-//
-//          'a scalar'
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          SCALAR("a scalar",single-quoted)
-//          STREAM-END
-//
-//      2. An explicit document:
-//
-//          ---
-//          'a scalar'
-//          ...
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          DOCUMENT-START
-//          SCALAR("a scalar",single-quoted)
-//          DOCUMENT-END
-//          STREAM-END
-//
-//      3. Several documents in a stream:
-//
-//          'a scalar'
-//          ---
-//          'another scalar'
-//          ---
-//          'yet another scalar'
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          SCALAR("a scalar",single-quoted)
-//          DOCUMENT-START
-//          SCALAR("another scalar",single-quoted)
-//          DOCUMENT-START
-//          SCALAR("yet another scalar",single-quoted)
-//          STREAM-END
-//
-// We have already introduced the SCALAR token above.  The following tokens are
-// used to describe aliases, anchors, tag, and scalars:
-//
-//      ALIAS(anchor)
-//      ANCHOR(anchor)
-//      TAG(handle,suffix)
-//      SCALAR(value,style)
-//
-// The following series of examples illustrate the usage of these tokens:
-//
-//      1. A recursive sequence:
-//
-//          &A [ *A ]
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          ANCHOR("A")
-//          FLOW-SEQUENCE-START
-//          ALIAS("A")
-//          FLOW-SEQUENCE-END
-//          STREAM-END
-//
-//      2. A tagged scalar:
-//
-//          !!float "3.14"  # A good approximation.
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          TAG("!!","float")
-//          SCALAR("3.14",double-quoted)
-//          STREAM-END
-//
-//      3. Various scalar styles:
-//
-//          --- # Implicit empty plain scalars do not produce tokens.
-//          --- a plain scalar
-//          --- 'a single-quoted scalar'
-//          --- "a double-quoted scalar"
-//          --- |-
-//            a literal scalar
-//          --- >-
-//            a folded
-//            scalar
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          DOCUMENT-START
-//          DOCUMENT-START
-//          SCALAR("a plain scalar",plain)
-//          DOCUMENT-START
-//          SCALAR("a single-quoted scalar",single-quoted)
-//          DOCUMENT-START
-//          SCALAR("a double-quoted scalar",double-quoted)
-//          DOCUMENT-START
-//          SCALAR("a literal scalar",literal)
-//          DOCUMENT-START
-//          SCALAR("a folded scalar",folded)
-//          STREAM-END
-//
-// Now it's time to review collection-related tokens. We will start with
-// flow collections:
-//
-//      FLOW-SEQUENCE-START
-//      FLOW-SEQUENCE-END
-//      FLOW-MAPPING-START
-//      FLOW-MAPPING-END
-//      FLOW-ENTRY
-//      KEY
-//      VALUE
-//
-// The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and
-// FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}'
-// correspondingly.  FLOW-ENTRY represent the ',' indicator.  Finally the
-// indicators '?' and ':', which are used for denoting mapping keys and values,
-// are represented by the KEY and VALUE tokens.
-//
-// The following examples show flow collections:
-//
-//      1. A flow sequence:
-//
-//          [item 1, item 2, item 3]
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          FLOW-SEQUENCE-START
-//          SCALAR("item 1",plain)
-//          FLOW-ENTRY
-//          SCALAR("item 2",plain)
-//          FLOW-ENTRY
-//          SCALAR("item 3",plain)
-//          FLOW-SEQUENCE-END
-//          STREAM-END
-//
-//      2. A flow mapping:
-//
-//          {
-//              a simple key: a value,  # Note that the KEY token is produced.
-//              ? a complex key: another value,
-//          }
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          FLOW-MAPPING-START
-//          KEY
-//          SCALAR("a simple key",plain)
-//          VALUE
-//          SCALAR("a value",plain)
-//          FLOW-ENTRY
-//          KEY
-//          SCALAR("a complex key",plain)
-//          VALUE
-//          SCALAR("another value",plain)
-//          FLOW-ENTRY
-//          FLOW-MAPPING-END
-//          STREAM-END
-//
-// A simple key is a key which is not denoted by the '?' indicator.  Note that
-// the Scanner still produce the KEY token whenever it encounters a simple key.
-//
-// For scanning block collections, the following tokens are used (note that we
-// repeat KEY and VALUE here):
-//
-//      BLOCK-SEQUENCE-START
-//      BLOCK-MAPPING-START
-//      BLOCK-END
-//      BLOCK-ENTRY
-//      KEY
-//      VALUE
-//
-// The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation
-// increase that precedes a block collection (cf. the INDENT token in Python).
-// The token BLOCK-END denote indentation decrease that ends a block collection
-// (cf. the DEDENT token in Python).  However YAML has some syntax pecularities
-// that makes detections of these tokens more complex.
-//
-// The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators
-// '-', '?', and ':' correspondingly.
-//
-// The following examples show how the tokens BLOCK-SEQUENCE-START,
-// BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner:
-//
-//      1. Block sequences:
-//
-//          - item 1
-//          - item 2
-//          -
-//            - item 3.1
-//            - item 3.2
-//          -
-//            key 1: value 1
-//            key 2: value 2
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          BLOCK-SEQUENCE-START
-//          BLOCK-ENTRY
-//          SCALAR("item 1",plain)
-//          BLOCK-ENTRY
-//          SCALAR("item 2",plain)
-//          BLOCK-ENTRY
-//          BLOCK-SEQUENCE-START
-//          BLOCK-ENTRY
-//          SCALAR("item 3.1",plain)
-//          BLOCK-ENTRY
-//          SCALAR("item 3.2",plain)
-//          BLOCK-END
-//          BLOCK-ENTRY
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("key 1",plain)
-//          VALUE
-//          SCALAR("value 1",plain)
-//          KEY
-//          SCALAR("key 2",plain)
-//          VALUE
-//          SCALAR("value 2",plain)
-//          BLOCK-END
-//          BLOCK-END
-//          STREAM-END
-//
-//      2. Block mappings:
-//
-//          a simple key: a value   # The KEY token is produced here.
-//          ? a complex key
-//          : another value
-//          a mapping:
-//            key 1: value 1
-//            key 2: value 2
-//          a sequence:
-//            - item 1
-//            - item 2
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("a simple key",plain)
-//          VALUE
-//          SCALAR("a value",plain)
-//          KEY
-//          SCALAR("a complex key",plain)
-//          VALUE
-//          SCALAR("another value",plain)
-//          KEY
-//          SCALAR("a mapping",plain)
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("key 1",plain)
-//          VALUE
-//          SCALAR("value 1",plain)
-//          KEY
-//          SCALAR("key 2",plain)
-//          VALUE
-//          SCALAR("value 2",plain)
-//          BLOCK-END
-//          KEY
-//          SCALAR("a sequence",plain)
-//          VALUE
-//          BLOCK-SEQUENCE-START
-//          BLOCK-ENTRY
-//          SCALAR("item 1",plain)
-//          BLOCK-ENTRY
-//          SCALAR("item 2",plain)
-//          BLOCK-END
-//          BLOCK-END
-//          STREAM-END
-//
-// YAML does not always require to start a new block collection from a new
-// line.  If the current line contains only '-', '?', and ':' indicators, a new
-// block collection may start at the current line.  The following examples
-// illustrate this case:
-//
-//      1. Collections in a sequence:
-//
-//          - - item 1
-//            - item 2
-//          - key 1: value 1
-//            key 2: value 2
-//          - ? complex key
-//            : complex value
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          BLOCK-SEQUENCE-START
-//          BLOCK-ENTRY
-//          BLOCK-SEQUENCE-START
-//          BLOCK-ENTRY
-//          SCALAR("item 1",plain)
-//          BLOCK-ENTRY
-//          SCALAR("item 2",plain)
-//          BLOCK-END
-//          BLOCK-ENTRY
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("key 1",plain)
-//          VALUE
-//          SCALAR("value 1",plain)
-//          KEY
-//          SCALAR("key 2",plain)
-//          VALUE
-//          SCALAR("value 2",plain)
-//          BLOCK-END
-//          BLOCK-ENTRY
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("complex key")
-//          VALUE
-//          SCALAR("complex value")
-//          BLOCK-END
-//          BLOCK-END
-//          STREAM-END
-//
-//      2. Collections in a mapping:
-//
-//          ? a sequence
-//          : - item 1
-//            - item 2
-//          ? a mapping
-//          : key 1: value 1
-//            key 2: value 2
-//
-//      Tokens:
-//
-//          STREAM-START(utf-8)
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("a sequence",plain)
-//          VALUE
-//          BLOCK-SEQUENCE-START
-//          BLOCK-ENTRY
-//          SCALAR("item 1",plain)
-//          BLOCK-ENTRY
-//          SCALAR("item 2",plain)
-//          BLOCK-END
-//          KEY
-//          SCALAR("a mapping",plain)
-//          VALUE
-//          BLOCK-MAPPING-START
-//          KEY
-//          SCALAR("key 1",plain)
-//          VALUE
-//          SCALAR("value 1",plain)
-//          KEY
-//          SCALAR("key 2",plain)
-//          VALUE
-//          SCALAR("value 2",plain)
-//          BLOCK-END
-//          BLOCK-END
-//          STREAM-END
-//
-// YAML also permits non-indented sequences if they are included into a block
-// mapping.  In this case, the token BLOCK-SEQUENCE-START is not produced:
-//
-//      key:
-//      - item 1    # BLOCK-SEQUENCE-START is NOT produced here.
-//      - item 2
-//
-// Tokens:
-//
-//      STREAM-START(utf-8)
-//      BLOCK-MAPPING-START
-//      KEY
-//      SCALAR("key",plain)
-//      VALUE
-//      BLOCK-ENTRY
-//      SCALAR("item 1",plain)
-//      BLOCK-ENTRY
-//      SCALAR("item 2",plain)
-//      BLOCK-END
-//
-
-// Ensure that the buffer contains the required number of characters.
-// Return true on success, false on failure (reader error or memory error).
-func cache(parser *yaml_parser_t, length int) bool {
-	// [Go] This was inlined: !cache(A, B) -> unread < B && !update(A, B)
-	return parser.unread >= length || yaml_parser_update_buffer(parser, length)
-}
-
-// Advance the buffer pointer.
-func skip(parser *yaml_parser_t) {
-	parser.mark.index++
-	parser.mark.column++
-	parser.unread--
-	parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
-}
-
-func skip_line(parser *yaml_parser_t) {
-	if is_crlf(parser.buffer, parser.buffer_pos) {
-		parser.mark.index += 2
-		parser.mark.column = 0
-		parser.mark.line++
-		parser.unread -= 2
-		parser.buffer_pos += 2
-	} else if is_break(parser.buffer, parser.buffer_pos) {
-		parser.mark.index++
-		parser.mark.column = 0
-		parser.mark.line++
-		parser.unread--
-		parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
-	}
-}
-
-// Copy a character to a string buffer and advance pointers.
-func read(parser *yaml_parser_t, s []byte) []byte {
-	w := width(parser.buffer[parser.buffer_pos])
-	if w == 0 {
-		panic("invalid character sequence")
-	}
-	if len(s) == 0 {
-		s = make([]byte, 0, 32)
-	}
-	if w == 1 && len(s)+w <= cap(s) {
-		s = s[:len(s)+1]
-		s[len(s)-1] = parser.buffer[parser.buffer_pos]
-		parser.buffer_pos++
-	} else {
-		s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...)
-		parser.buffer_pos += w
-	}
-	parser.mark.index++
-	parser.mark.column++
-	parser.unread--
-	return s
-}
-
-// Copy a line break character to a string buffer and advance pointers.
-func read_line(parser *yaml_parser_t, s []byte) []byte {
-	buf := parser.buffer
-	pos := parser.buffer_pos
-	switch {
-	case buf[pos] == '\r' && buf[pos+1] == '\n':
-		// CR LF . LF
-		s = append(s, '\n')
-		parser.buffer_pos += 2
-		parser.mark.index++
-		parser.unread--
-	case buf[pos] == '\r' || buf[pos] == '\n':
-		// CR|LF . LF
-		s = append(s, '\n')
-		parser.buffer_pos += 1
-	case buf[pos] == '\xC2' && buf[pos+1] == '\x85':
-		// NEL . LF
-		s = append(s, '\n')
-		parser.buffer_pos += 2
-	case buf[pos] == '\xE2' && buf[pos+1] == '\x80' && (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9'):
-		// LS|PS . LS|PS
-		s = append(s, buf[parser.buffer_pos:pos+3]...)
-		parser.buffer_pos += 3
-	default:
-		return s
-	}
-	parser.mark.index++
-	parser.mark.column = 0
-	parser.mark.line++
-	parser.unread--
-	return s
-}
-
-// Get the next token.
-func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool {
-	// Erase the token object.
-	*token = yaml_token_t{} // [Go] Is this necessary?
-
-	// No tokens after STREAM-END or error.
-	if parser.stream_end_produced || parser.error != yaml_NO_ERROR {
-		return true
-	}
-
-	// Ensure that the tokens queue contains enough tokens.
-	if !parser.token_available {
-		if !yaml_parser_fetch_more_tokens(parser) {
-			return false
-		}
-	}
-
-	// Fetch the next token from the queue.
-	*token = parser.tokens[parser.tokens_head]
-	parser.tokens_head++
-	parser.tokens_parsed++
-	parser.token_available = false
-
-	if token.typ == yaml_STREAM_END_TOKEN {
-		parser.stream_end_produced = true
-	}
-	return true
-}
-
-// Set the scanner error and return false.
-func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool {
-	parser.error = yaml_SCANNER_ERROR
-	parser.context = context
-	parser.context_mark = context_mark
-	parser.problem = problem
-	parser.problem_mark = parser.mark
-	return false
-}
-
-func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool {
-	context := "while parsing a tag"
-	if directive {
-		context = "while parsing a %TAG directive"
-	}
-	return yaml_parser_set_scanner_error(parser, context, context_mark, problem)
-}
-
-func trace(args ...interface{}) func() {
-	pargs := append([]interface{}{"+++"}, args...)
-	fmt.Println(pargs...)
-	pargs = append([]interface{}{"---"}, args...)
-	return func() { fmt.Println(pargs...) }
-}
-
-// Ensure that the tokens queue contains at least one token which can be
-// returned to the Parser.
-func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {
-	// While we need more tokens to fetch, do it.
-	for {
-		if parser.tokens_head != len(parser.tokens) {
-			// If queue is non-empty, check if any potential simple key may
-			// occupy the head position.
-			head_tok_idx, ok := parser.simple_keys_by_tok[parser.tokens_parsed]
-			if !ok {
-				break
-			} else if valid, ok := yaml_simple_key_is_valid(parser, &parser.simple_keys[head_tok_idx]); !ok {
-				return false
-			} else if !valid {
-				break
-			}
-		}
-		// Fetch the next token.
-		if !yaml_parser_fetch_next_token(parser) {
-			return false
-		}
-	}
-
-	parser.token_available = true
-	return true
-}
-
-// The dispatcher for token fetchers.
-func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool {
-	// Ensure that the buffer is initialized.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	// Check if we just started scanning.  Fetch STREAM-START then.
-	if !parser.stream_start_produced {
-		return yaml_parser_fetch_stream_start(parser)
-	}
-
-	// Eat whitespaces and comments until we reach the next token.
-	if !yaml_parser_scan_to_next_token(parser) {
-		return false
-	}
-
-	// Check the indentation level against the current column.
-	if !yaml_parser_unroll_indent(parser, parser.mark.column) {
-		return false
-	}
-
-	// Ensure that the buffer contains at least 4 characters.  4 is the length
-	// of the longest indicators ('--- ' and '... ').
-	if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
-		return false
-	}
-
-	// Is it the end of the stream?
-	if is_z(parser.buffer, parser.buffer_pos) {
-		return yaml_parser_fetch_stream_end(parser)
-	}
-
-	// Is it a directive?
-	if parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' {
-		return yaml_parser_fetch_directive(parser)
-	}
-
-	buf := parser.buffer
-	pos := parser.buffer_pos
-
-	// Is it the document start indicator?
-	if parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) {
-		return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN)
-	}
-
-	// Is it the document end indicator?
-	if parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) {
-		return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN)
-	}
-
-	// Is it the flow sequence start indicator?
-	if buf[pos] == '[' {
-		return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN)
-	}
-
-	// Is it the flow mapping start indicator?
-	if parser.buffer[parser.buffer_pos] == '{' {
-		return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN)
-	}
-
-	// Is it the flow sequence end indicator?
-	if parser.buffer[parser.buffer_pos] == ']' {
-		return yaml_parser_fetch_flow_collection_end(parser,
-			yaml_FLOW_SEQUENCE_END_TOKEN)
-	}
-
-	// Is it the flow mapping end indicator?
-	if parser.buffer[parser.buffer_pos] == '}' {
-		return yaml_parser_fetch_flow_collection_end(parser,
-			yaml_FLOW_MAPPING_END_TOKEN)
-	}
-
-	// Is it the flow entry indicator?
-	if parser.buffer[parser.buffer_pos] == ',' {
-		return yaml_parser_fetch_flow_entry(parser)
-	}
-
-	// Is it the block entry indicator?
-	if parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) {
-		return yaml_parser_fetch_block_entry(parser)
-	}
-
-	// Is it the key indicator?
-	if parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
-		return yaml_parser_fetch_key(parser)
-	}
-
-	// Is it the value indicator?
-	if parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
-		return yaml_parser_fetch_value(parser)
-	}
-
-	// Is it an alias?
-	if parser.buffer[parser.buffer_pos] == '*' {
-		return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN)
-	}
-
-	// Is it an anchor?
-	if parser.buffer[parser.buffer_pos] == '&' {
-		return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN)
-	}
-
-	// Is it a tag?
-	if parser.buffer[parser.buffer_pos] == '!' {
-		return yaml_parser_fetch_tag(parser)
-	}
-
-	// Is it a literal scalar?
-	if parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 {
-		return yaml_parser_fetch_block_scalar(parser, true)
-	}
-
-	// Is it a folded scalar?
-	if parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 {
-		return yaml_parser_fetch_block_scalar(parser, false)
-	}
-
-	// Is it a single-quoted scalar?
-	if parser.buffer[parser.buffer_pos] == '\'' {
-		return yaml_parser_fetch_flow_scalar(parser, true)
-	}
-
-	// Is it a double-quoted scalar?
-	if parser.buffer[parser.buffer_pos] == '"' {
-		return yaml_parser_fetch_flow_scalar(parser, false)
-	}
-
-	// Is it a plain scalar?
-	//
-	// A plain scalar may start with any non-blank characters except
-	//
-	//      '-', '?', ':', ',', '[', ']', '{', '}',
-	//      '#', '&', '*', '!', '|', '>', '\'', '\"',
-	//      '%', '@', '`'.
-	//
-	// In the block context (and, for the '-' indicator, in the flow context
-	// too), it may also start with the characters
-	//
-	//      '-', '?', ':'
-	//
-	// if it is followed by a non-space character.
-	//
-	// The last rule is more restrictive than the specification requires.
-	// [Go] Make this logic more reasonable.
-	//switch parser.buffer[parser.buffer_pos] {
-	//case '-', '?', ':', ',', '?', '-', ',', ':', ']', '[', '}', '{', '&', '#', '!', '*', '>', '|', '"', '\'', '@', '%', '-', '`':
-	//}
-	if !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' ||
-		parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' ||
-		parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' ||
-		parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
-		parser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' ||
-		parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' ||
-		parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' ||
-		parser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\'' ||
-		parser.buffer[parser.buffer_pos] == '"' || parser.buffer[parser.buffer_pos] == '%' ||
-		parser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') ||
-		(parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) ||
-		(parser.flow_level == 0 &&
-			(parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') &&
-			!is_blankz(parser.buffer, parser.buffer_pos+1)) {
-		return yaml_parser_fetch_plain_scalar(parser)
-	}
-
-	// If we don't determine the token type so far, it is an error.
-	return yaml_parser_set_scanner_error(parser,
-		"while scanning for the next token", parser.mark,
-		"found character that cannot start any token")
-}
-
-func yaml_simple_key_is_valid(parser *yaml_parser_t, simple_key *yaml_simple_key_t) (valid, ok bool) {
-	if !simple_key.possible {
-		return false, true
-	}
-
-	// The 1.2 specification says:
-	//
-	//     "If the ? indicator is omitted, parsing needs to see past the
-	//     implicit key to recognize it as such. To limit the amount of
-	//     lookahead required, the “:” indicator must appear at most 1024
-	//     Unicode characters beyond the start of the key. In addition, the key
-	//     is restricted to a single line."
-	//
-	if simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index {
-		// Check if the potential simple key to be removed is required.
-		if simple_key.required {
-			return false, yaml_parser_set_scanner_error(parser,
-				"while scanning a simple key", simple_key.mark,
-				"could not find expected ':'")
-		}
-		simple_key.possible = false
-		return false, true
-	}
-	return true, true
-}
-
-// Check if a simple key may start at the current position and add it if
-// needed.
-func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
-	// A simple key is required at the current position if the scanner is in
-	// the block context and the current column coincides with the indentation
-	// level.
-
-	required := parser.flow_level == 0 && parser.indent == parser.mark.column
-
-	//
-	// If the current position may start a simple key, save it.
-	//
-	if parser.simple_key_allowed {
-		simple_key := yaml_simple_key_t{
-			possible:     true,
-			required:     required,
-			token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
-			mark:         parser.mark,
-		}
-
-		if !yaml_parser_remove_simple_key(parser) {
-			return false
-		}
-		parser.simple_keys[len(parser.simple_keys)-1] = simple_key
-		parser.simple_keys_by_tok[simple_key.token_number] = len(parser.simple_keys) - 1
-	}
-	return true
-}
-
-// Remove a potential simple key at the current flow level.
-func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool {
-	i := len(parser.simple_keys) - 1
-	if parser.simple_keys[i].possible {
-		// If the key is required, it is an error.
-		if parser.simple_keys[i].required {
-			return yaml_parser_set_scanner_error(parser,
-				"while scanning a simple key", parser.simple_keys[i].mark,
-				"could not find expected ':'")
-		}
-		// Remove the key from the stack.
-		parser.simple_keys[i].possible = false
-		delete(parser.simple_keys_by_tok, parser.simple_keys[i].token_number)
-	}
-	return true
-}
-
-// max_flow_level limits the flow_level
-const max_flow_level = 10000
-
-// Increase the flow level and resize the simple key list if needed.
-func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {
-	// Reset the simple key on the next level.
-	parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{
-		possible:     false,
-		required:     false,
-		token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
-		mark:         parser.mark,
-	})
-
-	// Increase the flow level.
-	parser.flow_level++
-	if parser.flow_level > max_flow_level {
-		return yaml_parser_set_scanner_error(parser,
-			"while increasing flow level", parser.simple_keys[len(parser.simple_keys)-1].mark,
-			fmt.Sprintf("exceeded max depth of %d", max_flow_level))
-	}
-	return true
-}
-
-// Decrease the flow level.
-func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool {
-	if parser.flow_level > 0 {
-		parser.flow_level--
-		last := len(parser.simple_keys) - 1
-		delete(parser.simple_keys_by_tok, parser.simple_keys[last].token_number)
-		parser.simple_keys = parser.simple_keys[:last]
-	}
-	return true
-}
-
-// max_indents limits the indents stack size
-const max_indents = 10000
-
-// Push the current indentation level to the stack and set the new level
-// the current column is greater than the indentation level.  In this case,
-// append or insert the specified token into the token queue.
-func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool {
-	// In the flow context, do nothing.
-	if parser.flow_level > 0 {
-		return true
-	}
-
-	if parser.indent < column {
-		// Push the current indentation level to the stack and set the new
-		// indentation level.
-		parser.indents = append(parser.indents, parser.indent)
-		parser.indent = column
-		if len(parser.indents) > max_indents {
-			return yaml_parser_set_scanner_error(parser,
-				"while increasing indent level", parser.simple_keys[len(parser.simple_keys)-1].mark,
-				fmt.Sprintf("exceeded max depth of %d", max_indents))
-		}
-
-		// Create a token and insert it into the queue.
-		token := yaml_token_t{
-			typ:        typ,
-			start_mark: mark,
-			end_mark:   mark,
-		}
-		if number > -1 {
-			number -= parser.tokens_parsed
-		}
-		yaml_insert_token(parser, number, &token)
-	}
-	return true
-}
-
-// Pop indentation levels from the indents stack until the current level
-// becomes less or equal to the column.  For each indentation level, append
-// the BLOCK-END token.
-func yaml_parser_unroll_indent(parser *yaml_parser_t, column int) bool {
-	// In the flow context, do nothing.
-	if parser.flow_level > 0 {
-		return true
-	}
-
-	// Loop through the indentation levels in the stack.
-	for parser.indent > column {
-		// Create a token and append it to the queue.
-		token := yaml_token_t{
-			typ:        yaml_BLOCK_END_TOKEN,
-			start_mark: parser.mark,
-			end_mark:   parser.mark,
-		}
-		yaml_insert_token(parser, -1, &token)
-
-		// Pop the indentation level.
-		parser.indent = parser.indents[len(parser.indents)-1]
-		parser.indents = parser.indents[:len(parser.indents)-1]
-	}
-	return true
-}
-
-// Initialize the scanner and produce the STREAM-START token.
-func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool {
-
-	// Set the initial indentation.
-	parser.indent = -1
-
-	// Initialize the simple key stack.
-	parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
-
-	parser.simple_keys_by_tok = make(map[int]int)
-
-	// A simple key is allowed at the beginning of the stream.
-	parser.simple_key_allowed = true
-
-	// We have started.
-	parser.stream_start_produced = true
-
-	// Create the STREAM-START token and append it to the queue.
-	token := yaml_token_t{
-		typ:        yaml_STREAM_START_TOKEN,
-		start_mark: parser.mark,
-		end_mark:   parser.mark,
-		encoding:   parser.encoding,
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the STREAM-END token and shut down the scanner.
-func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool {
-
-	// Force new line.
-	if parser.mark.column != 0 {
-		parser.mark.column = 0
-		parser.mark.line++
-	}
-
-	// Reset the indentation level.
-	if !yaml_parser_unroll_indent(parser, -1) {
-		return false
-	}
-
-	// Reset simple keys.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	parser.simple_key_allowed = false
-
-	// Create the STREAM-END token and append it to the queue.
-	token := yaml_token_t{
-		typ:        yaml_STREAM_END_TOKEN,
-		start_mark: parser.mark,
-		end_mark:   parser.mark,
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token.
-func yaml_parser_fetch_directive(parser *yaml_parser_t) bool {
-	// Reset the indentation level.
-	if !yaml_parser_unroll_indent(parser, -1) {
-		return false
-	}
-
-	// Reset simple keys.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	parser.simple_key_allowed = false
-
-	// Create the YAML-DIRECTIVE or TAG-DIRECTIVE token.
-	token := yaml_token_t{}
-	if !yaml_parser_scan_directive(parser, &token) {
-		return false
-	}
-	// Append the token to the queue.
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the DOCUMENT-START or DOCUMENT-END token.
-func yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool {
-	// Reset the indentation level.
-	if !yaml_parser_unroll_indent(parser, -1) {
-		return false
-	}
-
-	// Reset simple keys.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	parser.simple_key_allowed = false
-
-	// Consume the token.
-	start_mark := parser.mark
-
-	skip(parser)
-	skip(parser)
-	skip(parser)
-
-	end_mark := parser.mark
-
-	// Create the DOCUMENT-START or DOCUMENT-END token.
-	token := yaml_token_t{
-		typ:        typ,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	// Append the token to the queue.
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token.
-func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool {
-	// The indicators '[' and '{' may start a simple key.
-	if !yaml_parser_save_simple_key(parser) {
-		return false
-	}
-
-	// Increase the flow level.
-	if !yaml_parser_increase_flow_level(parser) {
-		return false
-	}
-
-	// A simple key may follow the indicators '[' and '{'.
-	parser.simple_key_allowed = true
-
-	// Consume the token.
-	start_mark := parser.mark
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token.
-	token := yaml_token_t{
-		typ:        typ,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	// Append the token to the queue.
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token.
-func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool {
-	// Reset any potential simple key on the current flow level.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	// Decrease the flow level.
-	if !yaml_parser_decrease_flow_level(parser) {
-		return false
-	}
-
-	// No simple keys after the indicators ']' and '}'.
-	parser.simple_key_allowed = false
-
-	// Consume the token.
-
-	start_mark := parser.mark
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token.
-	token := yaml_token_t{
-		typ:        typ,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	// Append the token to the queue.
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the FLOW-ENTRY token.
-func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool {
-	// Reset any potential simple keys on the current flow level.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	// Simple keys are allowed after ','.
-	parser.simple_key_allowed = true
-
-	// Consume the token.
-	start_mark := parser.mark
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create the FLOW-ENTRY token and append it to the queue.
-	token := yaml_token_t{
-		typ:        yaml_FLOW_ENTRY_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the BLOCK-ENTRY token.
-func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool {
-	// Check if the scanner is in the block context.
-	if parser.flow_level == 0 {
-		// Check if we are allowed to start a new entry.
-		if !parser.simple_key_allowed {
-			return yaml_parser_set_scanner_error(parser, "", parser.mark,
-				"block sequence entries are not allowed in this context")
-		}
-		// Add the BLOCK-SEQUENCE-START token if needed.
-		if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) {
-			return false
-		}
-	} else {
-		// It is an error for the '-' indicator to occur in the flow context,
-		// but we let the Parser detect and report about it because the Parser
-		// is able to point to the context.
-	}
-
-	// Reset any potential simple keys on the current flow level.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	// Simple keys are allowed after '-'.
-	parser.simple_key_allowed = true
-
-	// Consume the token.
-	start_mark := parser.mark
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create the BLOCK-ENTRY token and append it to the queue.
-	token := yaml_token_t{
-		typ:        yaml_BLOCK_ENTRY_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the KEY token.
-func yaml_parser_fetch_key(parser *yaml_parser_t) bool {
-
-	// In the block context, additional checks are required.
-	if parser.flow_level == 0 {
-		// Check if we are allowed to start a new key (not nessesary simple).
-		if !parser.simple_key_allowed {
-			return yaml_parser_set_scanner_error(parser, "", parser.mark,
-				"mapping keys are not allowed in this context")
-		}
-		// Add the BLOCK-MAPPING-START token if needed.
-		if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
-			return false
-		}
-	}
-
-	// Reset any potential simple keys on the current flow level.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	// Simple keys are allowed after '?' in the block context.
-	parser.simple_key_allowed = parser.flow_level == 0
-
-	// Consume the token.
-	start_mark := parser.mark
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create the KEY token and append it to the queue.
-	token := yaml_token_t{
-		typ:        yaml_KEY_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the VALUE token.
-func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
-
-	simple_key := &parser.simple_keys[len(parser.simple_keys)-1]
-
-	// Have we found a simple key?
-	if valid, ok := yaml_simple_key_is_valid(parser, simple_key); !ok {
-		return false
-
-	} else if valid {
-
-		// Create the KEY token and insert it into the queue.
-		token := yaml_token_t{
-			typ:        yaml_KEY_TOKEN,
-			start_mark: simple_key.mark,
-			end_mark:   simple_key.mark,
-		}
-		yaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token)
-
-		// In the block context, we may need to add the BLOCK-MAPPING-START token.
-		if !yaml_parser_roll_indent(parser, simple_key.mark.column,
-			simple_key.token_number,
-			yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) {
-			return false
-		}
-
-		// Remove the simple key.
-		simple_key.possible = false
-		delete(parser.simple_keys_by_tok, simple_key.token_number)
-
-		// A simple key cannot follow another simple key.
-		parser.simple_key_allowed = false
-
-	} else {
-		// The ':' indicator follows a complex key.
-
-		// In the block context, extra checks are required.
-		if parser.flow_level == 0 {
-
-			// Check if we are allowed to start a complex value.
-			if !parser.simple_key_allowed {
-				return yaml_parser_set_scanner_error(parser, "", parser.mark,
-					"mapping values are not allowed in this context")
-			}
-
-			// Add the BLOCK-MAPPING-START token if needed.
-			if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
-				return false
-			}
-		}
-
-		// Simple keys after ':' are allowed in the block context.
-		parser.simple_key_allowed = parser.flow_level == 0
-	}
-
-	// Consume the token.
-	start_mark := parser.mark
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create the VALUE token and append it to the queue.
-	token := yaml_token_t{
-		typ:        yaml_VALUE_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the ALIAS or ANCHOR token.
-func yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool {
-	// An anchor or an alias could be a simple key.
-	if !yaml_parser_save_simple_key(parser) {
-		return false
-	}
-
-	// A simple key cannot follow an anchor or an alias.
-	parser.simple_key_allowed = false
-
-	// Create the ALIAS or ANCHOR token and append it to the queue.
-	var token yaml_token_t
-	if !yaml_parser_scan_anchor(parser, &token, typ) {
-		return false
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the TAG token.
-func yaml_parser_fetch_tag(parser *yaml_parser_t) bool {
-	// A tag could be a simple key.
-	if !yaml_parser_save_simple_key(parser) {
-		return false
-	}
-
-	// A simple key cannot follow a tag.
-	parser.simple_key_allowed = false
-
-	// Create the TAG token and append it to the queue.
-	var token yaml_token_t
-	if !yaml_parser_scan_tag(parser, &token) {
-		return false
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens.
-func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool {
-	// Remove any potential simple keys.
-	if !yaml_parser_remove_simple_key(parser) {
-		return false
-	}
-
-	// A simple key may follow a block scalar.
-	parser.simple_key_allowed = true
-
-	// Create the SCALAR token and append it to the queue.
-	var token yaml_token_t
-	if !yaml_parser_scan_block_scalar(parser, &token, literal) {
-		return false
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens.
-func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool {
-	// A plain scalar could be a simple key.
-	if !yaml_parser_save_simple_key(parser) {
-		return false
-	}
-
-	// A simple key cannot follow a flow scalar.
-	parser.simple_key_allowed = false
-
-	// Create the SCALAR token and append it to the queue.
-	var token yaml_token_t
-	if !yaml_parser_scan_flow_scalar(parser, &token, single) {
-		return false
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Produce the SCALAR(...,plain) token.
-func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool {
-	// A plain scalar could be a simple key.
-	if !yaml_parser_save_simple_key(parser) {
-		return false
-	}
-
-	// A simple key cannot follow a flow scalar.
-	parser.simple_key_allowed = false
-
-	// Create the SCALAR token and append it to the queue.
-	var token yaml_token_t
-	if !yaml_parser_scan_plain_scalar(parser, &token) {
-		return false
-	}
-	yaml_insert_token(parser, -1, &token)
-	return true
-}
-
-// Eat whitespaces and comments until the next token is found.
-func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool {
-
-	// Until the next token is not found.
-	for {
-		// Allow the BOM mark to start a line.
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-		if parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) {
-			skip(parser)
-		}
-
-		// Eat whitespaces.
-		// Tabs are allowed:
-		//  - in the flow context
-		//  - in the block context, but not at the beginning of the line or
-		//  after '-', '?', or ':' (complex value).
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-
-		for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') {
-			skip(parser)
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-
-		// Eat a comment until a line break.
-		if parser.buffer[parser.buffer_pos] == '#' {
-			for !is_breakz(parser.buffer, parser.buffer_pos) {
-				skip(parser)
-				if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-					return false
-				}
-			}
-		}
-
-		// If it is a line break, eat it.
-		if is_break(parser.buffer, parser.buffer_pos) {
-			if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-				return false
-			}
-			skip_line(parser)
-
-			// In the block context, a new line may start a simple key.
-			if parser.flow_level == 0 {
-				parser.simple_key_allowed = true
-			}
-		} else {
-			break // We have found a token.
-		}
-	}
-
-	return true
-}
-
-// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token.
-//
-// Scope:
-//      %YAML    1.1    # a comment \n
-//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//      %TAG    !yaml!  tag:yaml.org,2002:  \n
-//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//
-func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool {
-	// Eat '%'.
-	start_mark := parser.mark
-	skip(parser)
-
-	// Scan the directive name.
-	var name []byte
-	if !yaml_parser_scan_directive_name(parser, start_mark, &name) {
-		return false
-	}
-
-	// Is it a YAML directive?
-	if bytes.Equal(name, []byte("YAML")) {
-		// Scan the VERSION directive value.
-		var major, minor int8
-		if !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) {
-			return false
-		}
-		end_mark := parser.mark
-
-		// Create a VERSION-DIRECTIVE token.
-		*token = yaml_token_t{
-			typ:        yaml_VERSION_DIRECTIVE_TOKEN,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			major:      major,
-			minor:      minor,
-		}
-
-		// Is it a TAG directive?
-	} else if bytes.Equal(name, []byte("TAG")) {
-		// Scan the TAG directive value.
-		var handle, prefix []byte
-		if !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) {
-			return false
-		}
-		end_mark := parser.mark
-
-		// Create a TAG-DIRECTIVE token.
-		*token = yaml_token_t{
-			typ:        yaml_TAG_DIRECTIVE_TOKEN,
-			start_mark: start_mark,
-			end_mark:   end_mark,
-			value:      handle,
-			prefix:     prefix,
-		}
-
-		// Unknown directive.
-	} else {
-		yaml_parser_set_scanner_error(parser, "while scanning a directive",
-			start_mark, "found unknown directive name")
-		return false
-	}
-
-	// Eat the rest of the line including any comments.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	for is_blank(parser.buffer, parser.buffer_pos) {
-		skip(parser)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	if parser.buffer[parser.buffer_pos] == '#' {
-		for !is_breakz(parser.buffer, parser.buffer_pos) {
-			skip(parser)
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-	}
-
-	// Check if we are at the end of the line.
-	if !is_breakz(parser.buffer, parser.buffer_pos) {
-		yaml_parser_set_scanner_error(parser, "while scanning a directive",
-			start_mark, "did not find expected comment or line break")
-		return false
-	}
-
-	// Eat a line break.
-	if is_break(parser.buffer, parser.buffer_pos) {
-		if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-			return false
-		}
-		skip_line(parser)
-	}
-
-	return true
-}
-
-// Scan the directive name.
-//
-// Scope:
-//      %YAML   1.1     # a comment \n
-//       ^^^^
-//      %TAG    !yaml!  tag:yaml.org,2002:  \n
-//       ^^^
-//
-func yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool {
-	// Consume the directive name.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	var s []byte
-	for is_alpha(parser.buffer, parser.buffer_pos) {
-		s = read(parser, s)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	// Check if the name is empty.
-	if len(s) == 0 {
-		yaml_parser_set_scanner_error(parser, "while scanning a directive",
-			start_mark, "could not find expected directive name")
-		return false
-	}
-
-	// Check for an blank character after the name.
-	if !is_blankz(parser.buffer, parser.buffer_pos) {
-		yaml_parser_set_scanner_error(parser, "while scanning a directive",
-			start_mark, "found unexpected non-alphabetical character")
-		return false
-	}
-	*name = s
-	return true
-}
-
-// Scan the value of VERSION-DIRECTIVE.
-//
-// Scope:
-//      %YAML   1.1     # a comment \n
-//           ^^^^^^
-func yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool {
-	// Eat whitespaces.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	for is_blank(parser.buffer, parser.buffer_pos) {
-		skip(parser)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	// Consume the major version number.
-	if !yaml_parser_scan_version_directive_number(parser, start_mark, major) {
-		return false
-	}
-
-	// Eat '.'.
-	if parser.buffer[parser.buffer_pos] != '.' {
-		return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
-			start_mark, "did not find expected digit or '.' character")
-	}
-
-	skip(parser)
-
-	// Consume the minor version number.
-	if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) {
-		return false
-	}
-	return true
-}
-
-const max_number_length = 2
-
-// Scan the version number of VERSION-DIRECTIVE.
-//
-// Scope:
-//      %YAML   1.1     # a comment \n
-//              ^
-//      %YAML   1.1     # a comment \n
-//                ^
-func yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool {
-
-	// Repeat while the next character is digit.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	var value, length int8
-	for is_digit(parser.buffer, parser.buffer_pos) {
-		// Check if the number is too long.
-		length++
-		if length > max_number_length {
-			return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
-				start_mark, "found extremely long version number")
-		}
-		value = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos))
-		skip(parser)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	// Check if the number was present.
-	if length == 0 {
-		return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
-			start_mark, "did not find expected version number")
-	}
-	*number = value
-	return true
-}
-
-// Scan the value of a TAG-DIRECTIVE token.
-//
-// Scope:
-//      %TAG    !yaml!  tag:yaml.org,2002:  \n
-//          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//
-func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool {
-	var handle_value, prefix_value []byte
-
-	// Eat whitespaces.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	for is_blank(parser.buffer, parser.buffer_pos) {
-		skip(parser)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	// Scan a handle.
-	if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) {
-		return false
-	}
-
-	// Expect a whitespace.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	if !is_blank(parser.buffer, parser.buffer_pos) {
-		yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
-			start_mark, "did not find expected whitespace")
-		return false
-	}
-
-	// Eat whitespaces.
-	for is_blank(parser.buffer, parser.buffer_pos) {
-		skip(parser)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	// Scan a prefix.
-	if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) {
-		return false
-	}
-
-	// Expect a whitespace or line break.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	if !is_blankz(parser.buffer, parser.buffer_pos) {
-		yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
-			start_mark, "did not find expected whitespace or line break")
-		return false
-	}
-
-	*handle = handle_value
-	*prefix = prefix_value
-	return true
-}
-
-func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool {
-	var s []byte
-
-	// Eat the indicator character.
-	start_mark := parser.mark
-	skip(parser)
-
-	// Consume the value.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	for is_alpha(parser.buffer, parser.buffer_pos) {
-		s = read(parser, s)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	end_mark := parser.mark
-
-	/*
-	 * Check if length of the anchor is greater than 0 and it is followed by
-	 * a whitespace character or one of the indicators:
-	 *
-	 *      '?', ':', ',', ']', '}', '%', '@', '`'.
-	 */
-
-	if len(s) == 0 ||
-		!(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' ||
-			parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' ||
-			parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' ||
-			parser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' ||
-			parser.buffer[parser.buffer_pos] == '`') {
-		context := "while scanning an alias"
-		if typ == yaml_ANCHOR_TOKEN {
-			context = "while scanning an anchor"
-		}
-		yaml_parser_set_scanner_error(parser, context, start_mark,
-			"did not find expected alphabetic or numeric character")
-		return false
-	}
-
-	// Create a token.
-	*token = yaml_token_t{
-		typ:        typ,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-		value:      s,
-	}
-
-	return true
-}
-
-/*
- * Scan a TAG token.
- */
-
-func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool {
-	var handle, suffix []byte
-
-	start_mark := parser.mark
-
-	// Check if the tag is in the canonical form.
-	if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-		return false
-	}
-
-	if parser.buffer[parser.buffer_pos+1] == '<' {
-		// Keep the handle as ''
-
-		// Eat '!<'
-		skip(parser)
-		skip(parser)
-
-		// Consume the tag value.
-		if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
-			return false
-		}
-
-		// Check for '>' and eat it.
-		if parser.buffer[parser.buffer_pos] != '>' {
-			yaml_parser_set_scanner_error(parser, "while scanning a tag",
-				start_mark, "did not find the expected '>'")
-			return false
-		}
-
-		skip(parser)
-	} else {
-		// The tag has either the '!suffix' or the '!handle!suffix' form.
-
-		// First, try to scan a handle.
-		if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) {
-			return false
-		}
-
-		// Check if it is, indeed, handle.
-		if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' {
-			// Scan the suffix now.
-			if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
-				return false
-			}
-		} else {
-			// It wasn't a handle after all.  Scan the rest of the tag.
-			if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) {
-				return false
-			}
-
-			// Set the handle to '!'.
-			handle = []byte{'!'}
-
-			// A special case: the '!' tag.  Set the handle to '' and the
-			// suffix to '!'.
-			if len(suffix) == 0 {
-				handle, suffix = suffix, handle
-			}
-		}
-	}
-
-	// Check the character which ends the tag.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	if !is_blankz(parser.buffer, parser.buffer_pos) {
-		yaml_parser_set_scanner_error(parser, "while scanning a tag",
-			start_mark, "did not find expected whitespace or line break")
-		return false
-	}
-
-	end_mark := parser.mark
-
-	// Create a token.
-	*token = yaml_token_t{
-		typ:        yaml_TAG_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-		value:      handle,
-		suffix:     suffix,
-	}
-	return true
-}
-
-// Scan a tag handle.
-func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool {
-	// Check the initial '!' character.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	if parser.buffer[parser.buffer_pos] != '!' {
-		yaml_parser_set_scanner_tag_error(parser, directive,
-			start_mark, "did not find expected '!'")
-		return false
-	}
-
-	var s []byte
-
-	// Copy the '!' character.
-	s = read(parser, s)
-
-	// Copy all subsequent alphabetical and numerical characters.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	for is_alpha(parser.buffer, parser.buffer_pos) {
-		s = read(parser, s)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-
-	// Check if the trailing character is '!' and copy it.
-	if parser.buffer[parser.buffer_pos] == '!' {
-		s = read(parser, s)
-	} else {
-		// It's either the '!' tag or not really a tag handle.  If it's a %TAG
-		// directive, it's an error.  If it's a tag token, it must be a part of URI.
-		if directive && string(s) != "!" {
-			yaml_parser_set_scanner_tag_error(parser, directive,
-				start_mark, "did not find expected '!'")
-			return false
-		}
-	}
-
-	*handle = s
-	return true
-}
-
-// Scan a tag.
-func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
-	//size_t length = head ? strlen((char *)head) : 0
-	var s []byte
-	hasTag := len(head) > 0
-
-	// Copy the head if needed.
-	//
-	// Note that we don't copy the leading '!' character.
-	if len(head) > 1 {
-		s = append(s, head[1:]...)
-	}
-
-	// Scan the tag.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	// The set of characters that may appear in URI is as follows:
-	//
-	//      '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
-	//      '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
-	//      '%'.
-	// [Go] Convert this into more reasonable logic.
-	for is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' ||
-		parser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' ||
-		parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' ||
-		parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' ||
-		parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' ||
-		parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' ||
-		parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' ||
-		parser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\'' ||
-		parser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' ||
-		parser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' ||
-		parser.buffer[parser.buffer_pos] == '%' {
-		// Check if it is a URI-escape sequence.
-		if parser.buffer[parser.buffer_pos] == '%' {
-			if !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) {
-				return false
-			}
-		} else {
-			s = read(parser, s)
-		}
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-		hasTag = true
-	}
-
-	if !hasTag {
-		yaml_parser_set_scanner_tag_error(parser, directive,
-			start_mark, "did not find expected tag URI")
-		return false
-	}
-	*uri = s
-	return true
-}
-
-// Decode an URI-escape sequence corresponding to a single UTF-8 character.
-func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool {
-
-	// Decode the required number of characters.
-	w := 1024
-	for w > 0 {
-		// Check for a URI-escaped octet.
-		if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
-			return false
-		}
-
-		if !(parser.buffer[parser.buffer_pos] == '%' &&
-			is_hex(parser.buffer, parser.buffer_pos+1) &&
-			is_hex(parser.buffer, parser.buffer_pos+2)) {
-			return yaml_parser_set_scanner_tag_error(parser, directive,
-				start_mark, "did not find URI escaped octet")
-		}
-
-		// Get the octet.
-		octet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2))
-
-		// If it is the leading octet, determine the length of the UTF-8 sequence.
-		if w == 1024 {
-			w = width(octet)
-			if w == 0 {
-				return yaml_parser_set_scanner_tag_error(parser, directive,
-					start_mark, "found an incorrect leading UTF-8 octet")
-			}
-		} else {
-			// Check if the trailing octet is correct.
-			if octet&0xC0 != 0x80 {
-				return yaml_parser_set_scanner_tag_error(parser, directive,
-					start_mark, "found an incorrect trailing UTF-8 octet")
-			}
-		}
-
-		// Copy the octet and move the pointers.
-		*s = append(*s, octet)
-		skip(parser)
-		skip(parser)
-		skip(parser)
-		w--
-	}
-	return true
-}
-
-// Scan a block scalar.
-func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool {
-	// Eat the indicator '|' or '>'.
-	start_mark := parser.mark
-	skip(parser)
-
-	// Scan the additional block scalar indicators.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-
-	// Check for a chomping indicator.
-	var chomping, increment int
-	if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
-		// Set the chomping method and eat the indicator.
-		if parser.buffer[parser.buffer_pos] == '+' {
-			chomping = +1
-		} else {
-			chomping = -1
-		}
-		skip(parser)
-
-		// Check for an indentation indicator.
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-		if is_digit(parser.buffer, parser.buffer_pos) {
-			// Check that the indentation is greater than 0.
-			if parser.buffer[parser.buffer_pos] == '0' {
-				yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-					start_mark, "found an indentation indicator equal to 0")
-				return false
-			}
-
-			// Get the indentation level and eat the indicator.
-			increment = as_digit(parser.buffer, parser.buffer_pos)
-			skip(parser)
-		}
-
-	} else if is_digit(parser.buffer, parser.buffer_pos) {
-		// Do the same as above, but in the opposite order.
-
-		if parser.buffer[parser.buffer_pos] == '0' {
-			yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-				start_mark, "found an indentation indicator equal to 0")
-			return false
-		}
-		increment = as_digit(parser.buffer, parser.buffer_pos)
-		skip(parser)
-
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-		if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
-			if parser.buffer[parser.buffer_pos] == '+' {
-				chomping = +1
-			} else {
-				chomping = -1
-			}
-			skip(parser)
-		}
-	}
-
-	// Eat whitespaces and comments to the end of the line.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	for is_blank(parser.buffer, parser.buffer_pos) {
-		skip(parser)
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-	}
-	if parser.buffer[parser.buffer_pos] == '#' {
-		for !is_breakz(parser.buffer, parser.buffer_pos) {
-			skip(parser)
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-	}
-
-	// Check if we are at the end of the line.
-	if !is_breakz(parser.buffer, parser.buffer_pos) {
-		yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-			start_mark, "did not find expected comment or line break")
-		return false
-	}
-
-	// Eat a line break.
-	if is_break(parser.buffer, parser.buffer_pos) {
-		if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-			return false
-		}
-		skip_line(parser)
-	}
-
-	end_mark := parser.mark
-
-	// Set the indentation level if it was specified.
-	var indent int
-	if increment > 0 {
-		if parser.indent >= 0 {
-			indent = parser.indent + increment
-		} else {
-			indent = increment
-		}
-	}
-
-	// Scan the leading line breaks and determine the indentation level if needed.
-	var s, leading_break, trailing_breaks []byte
-	if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
-		return false
-	}
-
-	// Scan the block scalar content.
-	if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-		return false
-	}
-	var leading_blank, trailing_blank bool
-	for parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) {
-		// We are at the beginning of a non-empty line.
-
-		// Is it a trailing whitespace?
-		trailing_blank = is_blank(parser.buffer, parser.buffer_pos)
-
-		// Check if we need to fold the leading line break.
-		if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' {
-			// Do we need to join the lines by space?
-			if len(trailing_breaks) == 0 {
-				s = append(s, ' ')
-			}
-		} else {
-			s = append(s, leading_break...)
-		}
-		leading_break = leading_break[:0]
-
-		// Append the remaining line breaks.
-		s = append(s, trailing_breaks...)
-		trailing_breaks = trailing_breaks[:0]
-
-		// Is it a leading whitespace?
-		leading_blank = is_blank(parser.buffer, parser.buffer_pos)
-
-		// Consume the current line.
-		for !is_breakz(parser.buffer, parser.buffer_pos) {
-			s = read(parser, s)
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-
-		// Consume the line break.
-		if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-			return false
-		}
-
-		leading_break = read_line(parser, leading_break)
-
-		// Eat the following indentation spaces and line breaks.
-		if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
-			return false
-		}
-	}
-
-	// Chomp the tail.
-	if chomping != -1 {
-		s = append(s, leading_break...)
-	}
-	if chomping == 1 {
-		s = append(s, trailing_breaks...)
-	}
-
-	// Create a token.
-	*token = yaml_token_t{
-		typ:        yaml_SCALAR_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-		value:      s,
-		style:      yaml_LITERAL_SCALAR_STYLE,
-	}
-	if !literal {
-		token.style = yaml_FOLDED_SCALAR_STYLE
-	}
-	return true
-}
-
-// Scan indentation spaces and line breaks for a block scalar.  Determine the
-// indentation level if needed.
-func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool {
-	*end_mark = parser.mark
-
-	// Eat the indentation spaces and line breaks.
-	max_indent := 0
-	for {
-		// Eat the indentation spaces.
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-		for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) {
-			skip(parser)
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-		if parser.mark.column > max_indent {
-			max_indent = parser.mark.column
-		}
-
-		// Check for a tab character messing the indentation.
-		if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) {
-			return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
-				start_mark, "found a tab character where an indentation space is expected")
-		}
-
-		// Have we found a non-empty line?
-		if !is_break(parser.buffer, parser.buffer_pos) {
-			break
-		}
-
-		// Consume the line break.
-		if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-			return false
-		}
-		// [Go] Should really be returning breaks instead.
-		*breaks = read_line(parser, *breaks)
-		*end_mark = parser.mark
-	}
-
-	// Determine the indentation level if needed.
-	if *indent == 0 {
-		*indent = max_indent
-		if *indent < parser.indent+1 {
-			*indent = parser.indent + 1
-		}
-		if *indent < 1 {
-			*indent = 1
-		}
-	}
-	return true
-}
-
-// Scan a quoted scalar.
-func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool {
-	// Eat the left quote.
-	start_mark := parser.mark
-	skip(parser)
-
-	// Consume the content of the quoted scalar.
-	var s, leading_break, trailing_breaks, whitespaces []byte
-	for {
-		// Check that there are no document indicators at the beginning of the line.
-		if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
-			return false
-		}
-
-		if parser.mark.column == 0 &&
-			((parser.buffer[parser.buffer_pos+0] == '-' &&
-				parser.buffer[parser.buffer_pos+1] == '-' &&
-				parser.buffer[parser.buffer_pos+2] == '-') ||
-				(parser.buffer[parser.buffer_pos+0] == '.' &&
-					parser.buffer[parser.buffer_pos+1] == '.' &&
-					parser.buffer[parser.buffer_pos+2] == '.')) &&
-			is_blankz(parser.buffer, parser.buffer_pos+3) {
-			yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
-				start_mark, "found unexpected document indicator")
-			return false
-		}
-
-		// Check for EOF.
-		if is_z(parser.buffer, parser.buffer_pos) {
-			yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
-				start_mark, "found unexpected end of stream")
-			return false
-		}
-
-		// Consume non-blank characters.
-		leading_blanks := false
-		for !is_blankz(parser.buffer, parser.buffer_pos) {
-			if single && parser.buffer[parser.buffer_pos] == '\'' && parser.buffer[parser.buffer_pos+1] == '\'' {
-				// Is is an escaped single quote.
-				s = append(s, '\'')
-				skip(parser)
-				skip(parser)
-
-			} else if single && parser.buffer[parser.buffer_pos] == '\'' {
-				// It is a right single quote.
-				break
-			} else if !single && parser.buffer[parser.buffer_pos] == '"' {
-				// It is a right double quote.
-				break
-
-			} else if !single && parser.buffer[parser.buffer_pos] == '\\' && is_break(parser.buffer, parser.buffer_pos+1) {
-				// It is an escaped line break.
-				if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
-					return false
-				}
-				skip(parser)
-				skip_line(parser)
-				leading_blanks = true
-				break
-
-			} else if !single && parser.buffer[parser.buffer_pos] == '\\' {
-				// It is an escape sequence.
-				code_length := 0
-
-				// Check the escape character.
-				switch parser.buffer[parser.buffer_pos+1] {
-				case '0':
-					s = append(s, 0)
-				case 'a':
-					s = append(s, '\x07')
-				case 'b':
-					s = append(s, '\x08')
-				case 't', '\t':
-					s = append(s, '\x09')
-				case 'n':
-					s = append(s, '\x0A')
-				case 'v':
-					s = append(s, '\x0B')
-				case 'f':
-					s = append(s, '\x0C')
-				case 'r':
-					s = append(s, '\x0D')
-				case 'e':
-					s = append(s, '\x1B')
-				case ' ':
-					s = append(s, '\x20')
-				case '"':
-					s = append(s, '"')
-				case '\'':
-					s = append(s, '\'')
-				case '\\':
-					s = append(s, '\\')
-				case 'N': // NEL (#x85)
-					s = append(s, '\xC2')
-					s = append(s, '\x85')
-				case '_': // #xA0
-					s = append(s, '\xC2')
-					s = append(s, '\xA0')
-				case 'L': // LS (#x2028)
-					s = append(s, '\xE2')
-					s = append(s, '\x80')
-					s = append(s, '\xA8')
-				case 'P': // PS (#x2029)
-					s = append(s, '\xE2')
-					s = append(s, '\x80')
-					s = append(s, '\xA9')
-				case 'x':
-					code_length = 2
-				case 'u':
-					code_length = 4
-				case 'U':
-					code_length = 8
-				default:
-					yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
-						start_mark, "found unknown escape character")
-					return false
-				}
-
-				skip(parser)
-				skip(parser)
-
-				// Consume an arbitrary escape code.
-				if code_length > 0 {
-					var value int
-
-					// Scan the character value.
-					if parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) {
-						return false
-					}
-					for k := 0; k < code_length; k++ {
-						if !is_hex(parser.buffer, parser.buffer_pos+k) {
-							yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
-								start_mark, "did not find expected hexdecimal number")
-							return false
-						}
-						value = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k)
-					}
-
-					// Check the value and write the character.
-					if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF {
-						yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
-							start_mark, "found invalid Unicode character escape code")
-						return false
-					}
-					if value <= 0x7F {
-						s = append(s, byte(value))
-					} else if value <= 0x7FF {
-						s = append(s, byte(0xC0+(value>>6)))
-						s = append(s, byte(0x80+(value&0x3F)))
-					} else if value <= 0xFFFF {
-						s = append(s, byte(0xE0+(value>>12)))
-						s = append(s, byte(0x80+((value>>6)&0x3F)))
-						s = append(s, byte(0x80+(value&0x3F)))
-					} else {
-						s = append(s, byte(0xF0+(value>>18)))
-						s = append(s, byte(0x80+((value>>12)&0x3F)))
-						s = append(s, byte(0x80+((value>>6)&0x3F)))
-						s = append(s, byte(0x80+(value&0x3F)))
-					}
-
-					// Advance the pointer.
-					for k := 0; k < code_length; k++ {
-						skip(parser)
-					}
-				}
-			} else {
-				// It is a non-escaped non-blank character.
-				s = read(parser, s)
-			}
-			if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-				return false
-			}
-		}
-
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-
-		// Check if we are at the end of the scalar.
-		if single {
-			if parser.buffer[parser.buffer_pos] == '\'' {
-				break
-			}
-		} else {
-			if parser.buffer[parser.buffer_pos] == '"' {
-				break
-			}
-		}
-
-		// Consume blank characters.
-		for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
-			if is_blank(parser.buffer, parser.buffer_pos) {
-				// Consume a space or a tab character.
-				if !leading_blanks {
-					whitespaces = read(parser, whitespaces)
-				} else {
-					skip(parser)
-				}
-			} else {
-				if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-					return false
-				}
-
-				// Check if it is a first line break.
-				if !leading_blanks {
-					whitespaces = whitespaces[:0]
-					leading_break = read_line(parser, leading_break)
-					leading_blanks = true
-				} else {
-					trailing_breaks = read_line(parser, trailing_breaks)
-				}
-			}
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-
-		// Join the whitespaces or fold line breaks.
-		if leading_blanks {
-			// Do we need to fold line breaks?
-			if len(leading_break) > 0 && leading_break[0] == '\n' {
-				if len(trailing_breaks) == 0 {
-					s = append(s, ' ')
-				} else {
-					s = append(s, trailing_breaks...)
-				}
-			} else {
-				s = append(s, leading_break...)
-				s = append(s, trailing_breaks...)
-			}
-			trailing_breaks = trailing_breaks[:0]
-			leading_break = leading_break[:0]
-		} else {
-			s = append(s, whitespaces...)
-			whitespaces = whitespaces[:0]
-		}
-	}
-
-	// Eat the right quote.
-	skip(parser)
-	end_mark := parser.mark
-
-	// Create a token.
-	*token = yaml_token_t{
-		typ:        yaml_SCALAR_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-		value:      s,
-		style:      yaml_SINGLE_QUOTED_SCALAR_STYLE,
-	}
-	if !single {
-		token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
-	}
-	return true
-}
-
-// Scan a plain scalar.
-func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool {
-
-	var s, leading_break, trailing_breaks, whitespaces []byte
-	var leading_blanks bool
-	var indent = parser.indent + 1
-
-	start_mark := parser.mark
-	end_mark := parser.mark
-
-	// Consume the content of the plain scalar.
-	for {
-		// Check for a document indicator.
-		if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
-			return false
-		}
-		if parser.mark.column == 0 &&
-			((parser.buffer[parser.buffer_pos+0] == '-' &&
-				parser.buffer[parser.buffer_pos+1] == '-' &&
-				parser.buffer[parser.buffer_pos+2] == '-') ||
-				(parser.buffer[parser.buffer_pos+0] == '.' &&
-					parser.buffer[parser.buffer_pos+1] == '.' &&
-					parser.buffer[parser.buffer_pos+2] == '.')) &&
-			is_blankz(parser.buffer, parser.buffer_pos+3) {
-			break
-		}
-
-		// Check for a comment.
-		if parser.buffer[parser.buffer_pos] == '#' {
-			break
-		}
-
-		// Consume non-blank characters.
-		for !is_blankz(parser.buffer, parser.buffer_pos) {
-
-			// Check for indicators that may end a plain scalar.
-			if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
-				(parser.flow_level > 0 &&
-					(parser.buffer[parser.buffer_pos] == ',' ||
-						parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
-						parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
-						parser.buffer[parser.buffer_pos] == '}')) {
-				break
-			}
-
-			// Check if we need to join whitespaces and breaks.
-			if leading_blanks || len(whitespaces) > 0 {
-				if leading_blanks {
-					// Do we need to fold line breaks?
-					if leading_break[0] == '\n' {
-						if len(trailing_breaks) == 0 {
-							s = append(s, ' ')
-						} else {
-							s = append(s, trailing_breaks...)
-						}
-					} else {
-						s = append(s, leading_break...)
-						s = append(s, trailing_breaks...)
-					}
-					trailing_breaks = trailing_breaks[:0]
-					leading_break = leading_break[:0]
-					leading_blanks = false
-				} else {
-					s = append(s, whitespaces...)
-					whitespaces = whitespaces[:0]
-				}
-			}
-
-			// Copy the character.
-			s = read(parser, s)
-
-			end_mark = parser.mark
-			if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-				return false
-			}
-		}
-
-		// Is it the end?
-		if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) {
-			break
-		}
-
-		// Consume blank characters.
-		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-			return false
-		}
-
-		for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
-			if is_blank(parser.buffer, parser.buffer_pos) {
-
-				// Check for tab characters that abuse indentation.
-				if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
-					yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
-						start_mark, "found a tab character that violates indentation")
-					return false
-				}
-
-				// Consume a space or a tab character.
-				if !leading_blanks {
-					whitespaces = read(parser, whitespaces)
-				} else {
-					skip(parser)
-				}
-			} else {
-				if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
-					return false
-				}
-
-				// Check if it is a first line break.
-				if !leading_blanks {
-					whitespaces = whitespaces[:0]
-					leading_break = read_line(parser, leading_break)
-					leading_blanks = true
-				} else {
-					trailing_breaks = read_line(parser, trailing_breaks)
-				}
-			}
-			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
-				return false
-			}
-		}
-
-		// Check indentation level.
-		if parser.flow_level == 0 && parser.mark.column < indent {
-			break
-		}
-	}
-
-	// Create a token.
-	*token = yaml_token_t{
-		typ:        yaml_SCALAR_TOKEN,
-		start_mark: start_mark,
-		end_mark:   end_mark,
-		value:      s,
-		style:      yaml_PLAIN_SCALAR_STYLE,
-	}
-
-	// Note that we change the 'simple_key_allowed' flag.
-	if leading_blanks {
-		parser.simple_key_allowed = true
-	}
-	return true
-}
diff --git a/vendor/gopkg.in/yaml.v2/sorter.go b/vendor/gopkg.in/yaml.v2/sorter.go
deleted file mode 100644
index 4c45e660..00000000
--- a/vendor/gopkg.in/yaml.v2/sorter.go
+++ /dev/null
@@ -1,113 +0,0 @@
-package yaml
-
-import (
-	"reflect"
-	"unicode"
-)
-
-type keyList []reflect.Value
-
-func (l keyList) Len() int      { return len(l) }
-func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
-func (l keyList) Less(i, j int) bool {
-	a := l[i]
-	b := l[j]
-	ak := a.Kind()
-	bk := b.Kind()
-	for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() {
-		a = a.Elem()
-		ak = a.Kind()
-	}
-	for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() {
-		b = b.Elem()
-		bk = b.Kind()
-	}
-	af, aok := keyFloat(a)
-	bf, bok := keyFloat(b)
-	if aok && bok {
-		if af != bf {
-			return af < bf
-		}
-		if ak != bk {
-			return ak < bk
-		}
-		return numLess(a, b)
-	}
-	if ak != reflect.String || bk != reflect.String {
-		return ak < bk
-	}
-	ar, br := []rune(a.String()), []rune(b.String())
-	for i := 0; i < len(ar) && i < len(br); i++ {
-		if ar[i] == br[i] {
-			continue
-		}
-		al := unicode.IsLetter(ar[i])
-		bl := unicode.IsLetter(br[i])
-		if al && bl {
-			return ar[i] < br[i]
-		}
-		if al || bl {
-			return bl
-		}
-		var ai, bi int
-		var an, bn int64
-		if ar[i] == '0' || br[i] == '0' {
-			for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- {
-				if ar[j] != '0' {
-					an = 1
-					bn = 1
-					break
-				}
-			}
-		}
-		for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
-			an = an*10 + int64(ar[ai]-'0')
-		}
-		for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ {
-			bn = bn*10 + int64(br[bi]-'0')
-		}
-		if an != bn {
-			return an < bn
-		}
-		if ai != bi {
-			return ai < bi
-		}
-		return ar[i] < br[i]
-	}
-	return len(ar) < len(br)
-}
-
-// keyFloat returns a float value for v if it is a number/bool
-// and whether it is a number/bool or not.
-func keyFloat(v reflect.Value) (f float64, ok bool) {
-	switch v.Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return float64(v.Int()), true
-	case reflect.Float32, reflect.Float64:
-		return v.Float(), true
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return float64(v.Uint()), true
-	case reflect.Bool:
-		if v.Bool() {
-			return 1, true
-		}
-		return 0, true
-	}
-	return 0, false
-}
-
-// numLess returns whether a < b.
-// a and b must necessarily have the same kind.
-func numLess(a, b reflect.Value) bool {
-	switch a.Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return a.Int() < b.Int()
-	case reflect.Float32, reflect.Float64:
-		return a.Float() < b.Float()
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return a.Uint() < b.Uint()
-	case reflect.Bool:
-		return !a.Bool() && b.Bool()
-	}
-	panic("not a number")
-}
diff --git a/vendor/gopkg.in/yaml.v2/writerc.go b/vendor/gopkg.in/yaml.v2/writerc.go
deleted file mode 100644
index a2dde608..00000000
--- a/vendor/gopkg.in/yaml.v2/writerc.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package yaml
-
-// Set the writer error and return false.
-func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {
-	emitter.error = yaml_WRITER_ERROR
-	emitter.problem = problem
-	return false
-}
-
-// Flush the output buffer.
-func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
-	if emitter.write_handler == nil {
-		panic("write handler not set")
-	}
-
-	// Check if the buffer is empty.
-	if emitter.buffer_pos == 0 {
-		return true
-	}
-
-	if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
-		return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
-	}
-	emitter.buffer_pos = 0
-	return true
-}
diff --git a/vendor/gopkg.in/yaml.v2/yaml.go b/vendor/gopkg.in/yaml.v2/yaml.go
deleted file mode 100644
index 30813884..00000000
--- a/vendor/gopkg.in/yaml.v2/yaml.go
+++ /dev/null
@@ -1,478 +0,0 @@
-// Package yaml implements YAML support for the Go language.
-//
-// Source code and other details for the project are available at GitHub:
-//
-//   https://github.com/go-yaml/yaml
-//
-package yaml
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"reflect"
-	"strings"
-	"sync"
-)
-
-// MapSlice encodes and decodes as a YAML map.
-// The order of keys is preserved when encoding and decoding.
-type MapSlice []MapItem
-
-// MapItem is an item in a MapSlice.
-type MapItem struct {
-	Key, Value interface{}
-}
-
-// The Unmarshaler interface may be implemented by types to customize their
-// behavior when being unmarshaled from a YAML document. The UnmarshalYAML
-// method receives a function that may be called to unmarshal the original
-// YAML value into a field or variable. It is safe to call the unmarshal
-// function parameter more than once if necessary.
-type Unmarshaler interface {
-	UnmarshalYAML(unmarshal func(interface{}) error) error
-}
-
-// The Marshaler interface may be implemented by types to customize their
-// behavior when being marshaled into a YAML document. The returned value
-// is marshaled in place of the original value implementing Marshaler.
-//
-// If an error is returned by MarshalYAML, the marshaling procedure stops
-// and returns with the provided error.
-type Marshaler interface {
-	MarshalYAML() (interface{}, error)
-}
-
-// Unmarshal decodes the first document found within the in byte slice
-// and assigns decoded values into the out value.
-//
-// Maps and pointers (to a struct, string, int, etc) are accepted as out
-// values. If an internal pointer within a struct is not initialized,
-// the yaml package will initialize it if necessary for unmarshalling
-// the provided data. The out parameter must not be nil.
-//
-// The type of the decoded values should be compatible with the respective
-// values in out. If one or more values cannot be decoded due to a type
-// mismatches, decoding continues partially until the end of the YAML
-// content, and a *yaml.TypeError is returned with details for all
-// missed values.
-//
-// Struct fields are only unmarshalled if they are exported (have an
-// upper case first letter), and are unmarshalled using the field name
-// lowercased as the default key. Custom keys may be defined via the
-// "yaml" name in the field tag: the content preceding the first comma
-// is used as the key, and the following comma-separated options are
-// used to tweak the marshalling process (see Marshal).
-// Conflicting names result in a runtime error.
-//
-// For example:
-//
-//     type T struct {
-//         F int `yaml:"a,omitempty"`
-//         B int
-//     }
-//     var t T
-//     yaml.Unmarshal([]byte("a: 1\nb: 2"), &t)
-//
-// See the documentation of Marshal for the format of tags and a list of
-// supported tag options.
-//
-func Unmarshal(in []byte, out interface{}) (err error) {
-	return unmarshal(in, out, false)
-}
-
-// UnmarshalStrict is like Unmarshal except that any fields that are found
-// in the data that do not have corresponding struct members, or mapping
-// keys that are duplicates, will result in
-// an error.
-func UnmarshalStrict(in []byte, out interface{}) (err error) {
-	return unmarshal(in, out, true)
-}
-
-// A Decoder reads and decodes YAML values from an input stream.
-type Decoder struct {
-	strict bool
-	parser *parser
-}
-
-// NewDecoder returns a new decoder that reads from r.
-//
-// The decoder introduces its own buffering and may read
-// data from r beyond the YAML values requested.
-func NewDecoder(r io.Reader) *Decoder {
-	return &Decoder{
-		parser: newParserFromReader(r),
-	}
-}
-
-// SetStrict sets whether strict decoding behaviour is enabled when
-// decoding items in the data (see UnmarshalStrict). By default, decoding is not strict.
-func (dec *Decoder) SetStrict(strict bool) {
-	dec.strict = strict
-}
-
-// Decode reads the next YAML-encoded value from its input
-// and stores it in the value pointed to by v.
-//
-// See the documentation for Unmarshal for details about the
-// conversion of YAML into a Go value.
-func (dec *Decoder) Decode(v interface{}) (err error) {
-	d := newDecoder(dec.strict)
-	defer handleErr(&err)
-	node := dec.parser.parse()
-	if node == nil {
-		return io.EOF
-	}
-	out := reflect.ValueOf(v)
-	if out.Kind() == reflect.Ptr && !out.IsNil() {
-		out = out.Elem()
-	}
-	d.unmarshal(node, out)
-	if len(d.terrors) > 0 {
-		return &TypeError{d.terrors}
-	}
-	return nil
-}
-
-func unmarshal(in []byte, out interface{}, strict bool) (err error) {
-	defer handleErr(&err)
-	d := newDecoder(strict)
-	p := newParser(in)
-	defer p.destroy()
-	node := p.parse()
-	if node != nil {
-		v := reflect.ValueOf(out)
-		if v.Kind() == reflect.Ptr && !v.IsNil() {
-			v = v.Elem()
-		}
-		d.unmarshal(node, v)
-	}
-	if len(d.terrors) > 0 {
-		return &TypeError{d.terrors}
-	}
-	return nil
-}
-
-// Marshal serializes the value provided into a YAML document. The structure
-// of the generated document will reflect the structure of the value itself.
-// Maps and pointers (to struct, string, int, etc) are accepted as the in value.
-//
-// Struct fields are only marshalled if they are exported (have an upper case
-// first letter), and are marshalled using the field name lowercased as the
-// default key. Custom keys may be defined via the "yaml" name in the field
-// tag: the content preceding the first comma is used as the key, and the
-// following comma-separated options are used to tweak the marshalling process.
-// Conflicting names result in a runtime error.
-//
-// The field tag format accepted is:
-//
-//     `(...) yaml:"[<key>][,<flag1>[,<flag2>]]" (...)`
-//
-// The following flags are currently supported:
-//
-//     omitempty    Only include the field if it's not set to the zero
-//                  value for the type or to empty slices or maps.
-//                  Zero valued structs will be omitted if all their public
-//                  fields are zero, unless they implement an IsZero
-//                  method (see the IsZeroer interface type), in which
-//                  case the field will be excluded if IsZero returns true.
-//
-//     flow         Marshal using a flow style (useful for structs,
-//                  sequences and maps).
-//
-//     inline       Inline the field, which must be a struct or a map,
-//                  causing all of its fields or keys to be processed as if
-//                  they were part of the outer struct. For maps, keys must
-//                  not conflict with the yaml keys of other struct fields.
-//
-// In addition, if the key is "-", the field is ignored.
-//
-// For example:
-//
-//     type T struct {
-//         F int `yaml:"a,omitempty"`
-//         B int
-//     }
-//     yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
-//     yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n"
-//
-func Marshal(in interface{}) (out []byte, err error) {
-	defer handleErr(&err)
-	e := newEncoder()
-	defer e.destroy()
-	e.marshalDoc("", reflect.ValueOf(in))
-	e.finish()
-	out = e.out
-	return
-}
-
-// An Encoder writes YAML values to an output stream.
-type Encoder struct {
-	encoder *encoder
-}
-
-// NewEncoder returns a new encoder that writes to w.
-// The Encoder should be closed after use to flush all data
-// to w.
-func NewEncoder(w io.Writer) *Encoder {
-	return &Encoder{
-		encoder: newEncoderWithWriter(w),
-	}
-}
-
-// Encode writes the YAML encoding of v to the stream.
-// If multiple items are encoded to the stream, the
-// second and subsequent document will be preceded
-// with a "---" document separator, but the first will not.
-//
-// See the documentation for Marshal for details about the conversion of Go
-// values to YAML.
-func (e *Encoder) Encode(v interface{}) (err error) {
-	defer handleErr(&err)
-	e.encoder.marshalDoc("", reflect.ValueOf(v))
-	return nil
-}
-
-// Close closes the encoder by writing any remaining data.
-// It does not write a stream terminating string "...".
-func (e *Encoder) Close() (err error) {
-	defer handleErr(&err)
-	e.encoder.finish()
-	return nil
-}
-
-func handleErr(err *error) {
-	if v := recover(); v != nil {
-		if e, ok := v.(yamlError); ok {
-			*err = e.err
-		} else {
-			panic(v)
-		}
-	}
-}
-
-type yamlError struct {
-	err error
-}
-
-func fail(err error) {
-	panic(yamlError{err})
-}
-
-func failf(format string, args ...interface{}) {
-	panic(yamlError{fmt.Errorf("yaml: "+format, args...)})
-}
-
-// A TypeError is returned by Unmarshal when one or more fields in
-// the YAML document cannot be properly decoded into the requested
-// types. When this error is returned, the value is still
-// unmarshaled partially.
-type TypeError struct {
-	Errors []string
-}
-
-func (e *TypeError) Error() string {
-	return fmt.Sprintf("yaml: unmarshal errors:\n  %s", strings.Join(e.Errors, "\n  "))
-}
-
-// --------------------------------------------------------------------------
-// Maintain a mapping of keys to structure field indexes
-
-// The code in this section was copied from mgo/bson.
-
-// structInfo holds details for the serialization of fields of
-// a given struct.
-type structInfo struct {
-	FieldsMap  map[string]fieldInfo
-	FieldsList []fieldInfo
-
-	// InlineMap is the number of the field in the struct that
-	// contains an ,inline map, or -1 if there's none.
-	InlineMap int
-}
-
-type fieldInfo struct {
-	Key       string
-	Num       int
-	OmitEmpty bool
-	Flow      bool
-	// Id holds the unique field identifier, so we can cheaply
-	// check for field duplicates without maintaining an extra map.
-	Id int
-
-	// Inline holds the field index if the field is part of an inlined struct.
-	Inline []int
-}
-
-var structMap = make(map[reflect.Type]*structInfo)
-var fieldMapMutex sync.RWMutex
-
-func getStructInfo(st reflect.Type) (*structInfo, error) {
-	fieldMapMutex.RLock()
-	sinfo, found := structMap[st]
-	fieldMapMutex.RUnlock()
-	if found {
-		return sinfo, nil
-	}
-
-	n := st.NumField()
-	fieldsMap := make(map[string]fieldInfo)
-	fieldsList := make([]fieldInfo, 0, n)
-	inlineMap := -1
-	for i := 0; i != n; i++ {
-		field := st.Field(i)
-		if field.PkgPath != "" && !field.Anonymous {
-			continue // Private field
-		}
-
-		info := fieldInfo{Num: i}
-
-		tag := field.Tag.Get("yaml")
-		if tag == "" && strings.Index(string(field.Tag), ":") < 0 {
-			tag = string(field.Tag)
-		}
-		if tag == "-" {
-			continue
-		}
-
-		inline := false
-		fields := strings.Split(tag, ",")
-		if len(fields) > 1 {
-			for _, flag := range fields[1:] {
-				switch flag {
-				case "omitempty":
-					info.OmitEmpty = true
-				case "flow":
-					info.Flow = true
-				case "inline":
-					inline = true
-				default:
-					return nil, errors.New(fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st))
-				}
-			}
-			tag = fields[0]
-		}
-
-		if inline {
-			switch field.Type.Kind() {
-			case reflect.Map:
-				if inlineMap >= 0 {
-					return nil, errors.New("Multiple ,inline maps in struct " + st.String())
-				}
-				if field.Type.Key() != reflect.TypeOf("") {
-					return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String())
-				}
-				inlineMap = info.Num
-			case reflect.Struct:
-				sinfo, err := getStructInfo(field.Type)
-				if err != nil {
-					return nil, err
-				}
-				for _, finfo := range sinfo.FieldsList {
-					if _, found := fieldsMap[finfo.Key]; found {
-						msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String()
-						return nil, errors.New(msg)
-					}
-					if finfo.Inline == nil {
-						finfo.Inline = []int{i, finfo.Num}
-					} else {
-						finfo.Inline = append([]int{i}, finfo.Inline...)
-					}
-					finfo.Id = len(fieldsList)
-					fieldsMap[finfo.Key] = finfo
-					fieldsList = append(fieldsList, finfo)
-				}
-			default:
-				//return nil, errors.New("Option ,inline needs a struct value or map field")
-				return nil, errors.New("Option ,inline needs a struct value field")
-			}
-			continue
-		}
-
-		if tag != "" {
-			info.Key = tag
-		} else {
-			info.Key = strings.ToLower(field.Name)
-		}
-
-		if _, found = fieldsMap[info.Key]; found {
-			msg := "Duplicated key '" + info.Key + "' in struct " + st.String()
-			return nil, errors.New(msg)
-		}
-
-		info.Id = len(fieldsList)
-		fieldsList = append(fieldsList, info)
-		fieldsMap[info.Key] = info
-	}
-
-	sinfo = &structInfo{
-		FieldsMap:  fieldsMap,
-		FieldsList: fieldsList,
-		InlineMap:  inlineMap,
-	}
-
-	fieldMapMutex.Lock()
-	structMap[st] = sinfo
-	fieldMapMutex.Unlock()
-	return sinfo, nil
-}
-
-// IsZeroer is used to check whether an object is zero to
-// determine whether it should be omitted when marshaling
-// with the omitempty flag. One notable implementation
-// is time.Time.
-type IsZeroer interface {
-	IsZero() bool
-}
-
-func isZero(v reflect.Value) bool {
-	kind := v.Kind()
-	if z, ok := v.Interface().(IsZeroer); ok {
-		if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() {
-			return true
-		}
-		return z.IsZero()
-	}
-	switch kind {
-	case reflect.String:
-		return len(v.String()) == 0
-	case reflect.Interface, reflect.Ptr:
-		return v.IsNil()
-	case reflect.Slice:
-		return v.Len() == 0
-	case reflect.Map:
-		return v.Len() == 0
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return v.Int() == 0
-	case reflect.Float32, reflect.Float64:
-		return v.Float() == 0
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return v.Uint() == 0
-	case reflect.Bool:
-		return !v.Bool()
-	case reflect.Struct:
-		vt := v.Type()
-		for i := v.NumField() - 1; i >= 0; i-- {
-			if vt.Field(i).PkgPath != "" {
-				continue // Private field
-			}
-			if !isZero(v.Field(i)) {
-				return false
-			}
-		}
-		return true
-	}
-	return false
-}
-
-// FutureLineWrap globally disables line wrapping when encoding long strings.
-// This is a temporary and thus deprecated method introduced to faciliate
-// migration towards v3, which offers more control of line lengths on
-// individual encodings, and has a default matching the behavior introduced
-// by this function.
-//
-// The default formatting of v2 was erroneously changed in v2.3.0 and reverted
-// in v2.4.0, at which point this function was introduced to help migration.
-func FutureLineWrap() {
-	disableLineWrapping = true
-}
diff --git a/vendor/gopkg.in/yaml.v2/yamlh.go b/vendor/gopkg.in/yaml.v2/yamlh.go
deleted file mode 100644
index f6a9c8e3..00000000
--- a/vendor/gopkg.in/yaml.v2/yamlh.go
+++ /dev/null
@@ -1,739 +0,0 @@
-package yaml
-
-import (
-	"fmt"
-	"io"
-)
-
-// The version directive data.
-type yaml_version_directive_t struct {
-	major int8 // The major version number.
-	minor int8 // The minor version number.
-}
-
-// The tag directive data.
-type yaml_tag_directive_t struct {
-	handle []byte // The tag handle.
-	prefix []byte // The tag prefix.
-}
-
-type yaml_encoding_t int
-
-// The stream encoding.
-const (
-	// Let the parser choose the encoding.
-	yaml_ANY_ENCODING yaml_encoding_t = iota
-
-	yaml_UTF8_ENCODING    // The default UTF-8 encoding.
-	yaml_UTF16LE_ENCODING // The UTF-16-LE encoding with BOM.
-	yaml_UTF16BE_ENCODING // The UTF-16-BE encoding with BOM.
-)
-
-type yaml_break_t int
-
-// Line break types.
-const (
-	// Let the parser choose the break type.
-	yaml_ANY_BREAK yaml_break_t = iota
-
-	yaml_CR_BREAK   // Use CR for line breaks (Mac style).
-	yaml_LN_BREAK   // Use LN for line breaks (Unix style).
-	yaml_CRLN_BREAK // Use CR LN for line breaks (DOS style).
-)
-
-type yaml_error_type_t int
-
-// Many bad things could happen with the parser and emitter.
-const (
-	// No error is produced.
-	yaml_NO_ERROR yaml_error_type_t = iota
-
-	yaml_MEMORY_ERROR   // Cannot allocate or reallocate a block of memory.
-	yaml_READER_ERROR   // Cannot read or decode the input stream.
-	yaml_SCANNER_ERROR  // Cannot scan the input stream.
-	yaml_PARSER_ERROR   // Cannot parse the input stream.
-	yaml_COMPOSER_ERROR // Cannot compose a YAML document.
-	yaml_WRITER_ERROR   // Cannot write to the output stream.
-	yaml_EMITTER_ERROR  // Cannot emit a YAML stream.
-)
-
-// The pointer position.
-type yaml_mark_t struct {
-	index  int // The position index.
-	line   int // The position line.
-	column int // The position column.
-}
-
-// Node Styles
-
-type yaml_style_t int8
-
-type yaml_scalar_style_t yaml_style_t
-
-// Scalar styles.
-const (
-	// Let the emitter choose the style.
-	yaml_ANY_SCALAR_STYLE yaml_scalar_style_t = iota
-
-	yaml_PLAIN_SCALAR_STYLE         // The plain scalar style.
-	yaml_SINGLE_QUOTED_SCALAR_STYLE // The single-quoted scalar style.
-	yaml_DOUBLE_QUOTED_SCALAR_STYLE // The double-quoted scalar style.
-	yaml_LITERAL_SCALAR_STYLE       // The literal scalar style.
-	yaml_FOLDED_SCALAR_STYLE        // The folded scalar style.
-)
-
-type yaml_sequence_style_t yaml_style_t
-
-// Sequence styles.
-const (
-	// Let the emitter choose the style.
-	yaml_ANY_SEQUENCE_STYLE yaml_sequence_style_t = iota
-
-	yaml_BLOCK_SEQUENCE_STYLE // The block sequence style.
-	yaml_FLOW_SEQUENCE_STYLE  // The flow sequence style.
-)
-
-type yaml_mapping_style_t yaml_style_t
-
-// Mapping styles.
-const (
-	// Let the emitter choose the style.
-	yaml_ANY_MAPPING_STYLE yaml_mapping_style_t = iota
-
-	yaml_BLOCK_MAPPING_STYLE // The block mapping style.
-	yaml_FLOW_MAPPING_STYLE  // The flow mapping style.
-)
-
-// Tokens
-
-type yaml_token_type_t int
-
-// Token types.
-const (
-	// An empty token.
-	yaml_NO_TOKEN yaml_token_type_t = iota
-
-	yaml_STREAM_START_TOKEN // A STREAM-START token.
-	yaml_STREAM_END_TOKEN   // A STREAM-END token.
-
-	yaml_VERSION_DIRECTIVE_TOKEN // A VERSION-DIRECTIVE token.
-	yaml_TAG_DIRECTIVE_TOKEN     // A TAG-DIRECTIVE token.
-	yaml_DOCUMENT_START_TOKEN    // A DOCUMENT-START token.
-	yaml_DOCUMENT_END_TOKEN      // A DOCUMENT-END token.
-
-	yaml_BLOCK_SEQUENCE_START_TOKEN // A BLOCK-SEQUENCE-START token.
-	yaml_BLOCK_MAPPING_START_TOKEN  // A BLOCK-SEQUENCE-END token.
-	yaml_BLOCK_END_TOKEN            // A BLOCK-END token.
-
-	yaml_FLOW_SEQUENCE_START_TOKEN // A FLOW-SEQUENCE-START token.
-	yaml_FLOW_SEQUENCE_END_TOKEN   // A FLOW-SEQUENCE-END token.
-	yaml_FLOW_MAPPING_START_TOKEN  // A FLOW-MAPPING-START token.
-	yaml_FLOW_MAPPING_END_TOKEN    // A FLOW-MAPPING-END token.
-
-	yaml_BLOCK_ENTRY_TOKEN // A BLOCK-ENTRY token.
-	yaml_FLOW_ENTRY_TOKEN  // A FLOW-ENTRY token.
-	yaml_KEY_TOKEN         // A KEY token.
-	yaml_VALUE_TOKEN       // A VALUE token.
-
-	yaml_ALIAS_TOKEN  // An ALIAS token.
-	yaml_ANCHOR_TOKEN // An ANCHOR token.
-	yaml_TAG_TOKEN    // A TAG token.
-	yaml_SCALAR_TOKEN // A SCALAR token.
-)
-
-func (tt yaml_token_type_t) String() string {
-	switch tt {
-	case yaml_NO_TOKEN:
-		return "yaml_NO_TOKEN"
-	case yaml_STREAM_START_TOKEN:
-		return "yaml_STREAM_START_TOKEN"
-	case yaml_STREAM_END_TOKEN:
-		return "yaml_STREAM_END_TOKEN"
-	case yaml_VERSION_DIRECTIVE_TOKEN:
-		return "yaml_VERSION_DIRECTIVE_TOKEN"
-	case yaml_TAG_DIRECTIVE_TOKEN:
-		return "yaml_TAG_DIRECTIVE_TOKEN"
-	case yaml_DOCUMENT_START_TOKEN:
-		return "yaml_DOCUMENT_START_TOKEN"
-	case yaml_DOCUMENT_END_TOKEN:
-		return "yaml_DOCUMENT_END_TOKEN"
-	case yaml_BLOCK_SEQUENCE_START_TOKEN:
-		return "yaml_BLOCK_SEQUENCE_START_TOKEN"
-	case yaml_BLOCK_MAPPING_START_TOKEN:
-		return "yaml_BLOCK_MAPPING_START_TOKEN"
-	case yaml_BLOCK_END_TOKEN:
-		return "yaml_BLOCK_END_TOKEN"
-	case yaml_FLOW_SEQUENCE_START_TOKEN:
-		return "yaml_FLOW_SEQUENCE_START_TOKEN"
-	case yaml_FLOW_SEQUENCE_END_TOKEN:
-		return "yaml_FLOW_SEQUENCE_END_TOKEN"
-	case yaml_FLOW_MAPPING_START_TOKEN:
-		return "yaml_FLOW_MAPPING_START_TOKEN"
-	case yaml_FLOW_MAPPING_END_TOKEN:
-		return "yaml_FLOW_MAPPING_END_TOKEN"
-	case yaml_BLOCK_ENTRY_TOKEN:
-		return "yaml_BLOCK_ENTRY_TOKEN"
-	case yaml_FLOW_ENTRY_TOKEN:
-		return "yaml_FLOW_ENTRY_TOKEN"
-	case yaml_KEY_TOKEN:
-		return "yaml_KEY_TOKEN"
-	case yaml_VALUE_TOKEN:
-		return "yaml_VALUE_TOKEN"
-	case yaml_ALIAS_TOKEN:
-		return "yaml_ALIAS_TOKEN"
-	case yaml_ANCHOR_TOKEN:
-		return "yaml_ANCHOR_TOKEN"
-	case yaml_TAG_TOKEN:
-		return "yaml_TAG_TOKEN"
-	case yaml_SCALAR_TOKEN:
-		return "yaml_SCALAR_TOKEN"
-	}
-	return "<unknown token>"
-}
-
-// The token structure.
-type yaml_token_t struct {
-	// The token type.
-	typ yaml_token_type_t
-
-	// The start/end of the token.
-	start_mark, end_mark yaml_mark_t
-
-	// The stream encoding (for yaml_STREAM_START_TOKEN).
-	encoding yaml_encoding_t
-
-	// The alias/anchor/scalar value or tag/tag directive handle
-	// (for yaml_ALIAS_TOKEN, yaml_ANCHOR_TOKEN, yaml_SCALAR_TOKEN, yaml_TAG_TOKEN, yaml_TAG_DIRECTIVE_TOKEN).
-	value []byte
-
-	// The tag suffix (for yaml_TAG_TOKEN).
-	suffix []byte
-
-	// The tag directive prefix (for yaml_TAG_DIRECTIVE_TOKEN).
-	prefix []byte
-
-	// The scalar style (for yaml_SCALAR_TOKEN).
-	style yaml_scalar_style_t
-
-	// The version directive major/minor (for yaml_VERSION_DIRECTIVE_TOKEN).
-	major, minor int8
-}
-
-// Events
-
-type yaml_event_type_t int8
-
-// Event types.
-const (
-	// An empty event.
-	yaml_NO_EVENT yaml_event_type_t = iota
-
-	yaml_STREAM_START_EVENT   // A STREAM-START event.
-	yaml_STREAM_END_EVENT     // A STREAM-END event.
-	yaml_DOCUMENT_START_EVENT // A DOCUMENT-START event.
-	yaml_DOCUMENT_END_EVENT   // A DOCUMENT-END event.
-	yaml_ALIAS_EVENT          // An ALIAS event.
-	yaml_SCALAR_EVENT         // A SCALAR event.
-	yaml_SEQUENCE_START_EVENT // A SEQUENCE-START event.
-	yaml_SEQUENCE_END_EVENT   // A SEQUENCE-END event.
-	yaml_MAPPING_START_EVENT  // A MAPPING-START event.
-	yaml_MAPPING_END_EVENT    // A MAPPING-END event.
-)
-
-var eventStrings = []string{
-	yaml_NO_EVENT:             "none",
-	yaml_STREAM_START_EVENT:   "stream start",
-	yaml_STREAM_END_EVENT:     "stream end",
-	yaml_DOCUMENT_START_EVENT: "document start",
-	yaml_DOCUMENT_END_EVENT:   "document end",
-	yaml_ALIAS_EVENT:          "alias",
-	yaml_SCALAR_EVENT:         "scalar",
-	yaml_SEQUENCE_START_EVENT: "sequence start",
-	yaml_SEQUENCE_END_EVENT:   "sequence end",
-	yaml_MAPPING_START_EVENT:  "mapping start",
-	yaml_MAPPING_END_EVENT:    "mapping end",
-}
-
-func (e yaml_event_type_t) String() string {
-	if e < 0 || int(e) >= len(eventStrings) {
-		return fmt.Sprintf("unknown event %d", e)
-	}
-	return eventStrings[e]
-}
-
-// The event structure.
-type yaml_event_t struct {
-
-	// The event type.
-	typ yaml_event_type_t
-
-	// The start and end of the event.
-	start_mark, end_mark yaml_mark_t
-
-	// The document encoding (for yaml_STREAM_START_EVENT).
-	encoding yaml_encoding_t
-
-	// The version directive (for yaml_DOCUMENT_START_EVENT).
-	version_directive *yaml_version_directive_t
-
-	// The list of tag directives (for yaml_DOCUMENT_START_EVENT).
-	tag_directives []yaml_tag_directive_t
-
-	// The anchor (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_ALIAS_EVENT).
-	anchor []byte
-
-	// The tag (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
-	tag []byte
-
-	// The scalar value (for yaml_SCALAR_EVENT).
-	value []byte
-
-	// Is the document start/end indicator implicit, or the tag optional?
-	// (for yaml_DOCUMENT_START_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_SCALAR_EVENT).
-	implicit bool
-
-	// Is the tag optional for any non-plain style? (for yaml_SCALAR_EVENT).
-	quoted_implicit bool
-
-	// The style (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
-	style yaml_style_t
-}
-
-func (e *yaml_event_t) scalar_style() yaml_scalar_style_t     { return yaml_scalar_style_t(e.style) }
-func (e *yaml_event_t) sequence_style() yaml_sequence_style_t { return yaml_sequence_style_t(e.style) }
-func (e *yaml_event_t) mapping_style() yaml_mapping_style_t   { return yaml_mapping_style_t(e.style) }
-
-// Nodes
-
-const (
-	yaml_NULL_TAG      = "tag:yaml.org,2002:null"      // The tag !!null with the only possible value: null.
-	yaml_BOOL_TAG      = "tag:yaml.org,2002:bool"      // The tag !!bool with the values: true and false.
-	yaml_STR_TAG       = "tag:yaml.org,2002:str"       // The tag !!str for string values.
-	yaml_INT_TAG       = "tag:yaml.org,2002:int"       // The tag !!int for integer values.
-	yaml_FLOAT_TAG     = "tag:yaml.org,2002:float"     // The tag !!float for float values.
-	yaml_TIMESTAMP_TAG = "tag:yaml.org,2002:timestamp" // The tag !!timestamp for date and time values.
-
-	yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences.
-	yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping.
-
-	// Not in original libyaml.
-	yaml_BINARY_TAG = "tag:yaml.org,2002:binary"
-	yaml_MERGE_TAG  = "tag:yaml.org,2002:merge"
-
-	yaml_DEFAULT_SCALAR_TAG   = yaml_STR_TAG // The default scalar tag is !!str.
-	yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq.
-	yaml_DEFAULT_MAPPING_TAG  = yaml_MAP_TAG // The default mapping tag is !!map.
-)
-
-type yaml_node_type_t int
-
-// Node types.
-const (
-	// An empty node.
-	yaml_NO_NODE yaml_node_type_t = iota
-
-	yaml_SCALAR_NODE   // A scalar node.
-	yaml_SEQUENCE_NODE // A sequence node.
-	yaml_MAPPING_NODE  // A mapping node.
-)
-
-// An element of a sequence node.
-type yaml_node_item_t int
-
-// An element of a mapping node.
-type yaml_node_pair_t struct {
-	key   int // The key of the element.
-	value int // The value of the element.
-}
-
-// The node structure.
-type yaml_node_t struct {
-	typ yaml_node_type_t // The node type.
-	tag []byte           // The node tag.
-
-	// The node data.
-
-	// The scalar parameters (for yaml_SCALAR_NODE).
-	scalar struct {
-		value  []byte              // The scalar value.
-		length int                 // The length of the scalar value.
-		style  yaml_scalar_style_t // The scalar style.
-	}
-
-	// The sequence parameters (for YAML_SEQUENCE_NODE).
-	sequence struct {
-		items_data []yaml_node_item_t    // The stack of sequence items.
-		style      yaml_sequence_style_t // The sequence style.
-	}
-
-	// The mapping parameters (for yaml_MAPPING_NODE).
-	mapping struct {
-		pairs_data  []yaml_node_pair_t   // The stack of mapping pairs (key, value).
-		pairs_start *yaml_node_pair_t    // The beginning of the stack.
-		pairs_end   *yaml_node_pair_t    // The end of the stack.
-		pairs_top   *yaml_node_pair_t    // The top of the stack.
-		style       yaml_mapping_style_t // The mapping style.
-	}
-
-	start_mark yaml_mark_t // The beginning of the node.
-	end_mark   yaml_mark_t // The end of the node.
-
-}
-
-// The document structure.
-type yaml_document_t struct {
-
-	// The document nodes.
-	nodes []yaml_node_t
-
-	// The version directive.
-	version_directive *yaml_version_directive_t
-
-	// The list of tag directives.
-	tag_directives_data  []yaml_tag_directive_t
-	tag_directives_start int // The beginning of the tag directives list.
-	tag_directives_end   int // The end of the tag directives list.
-
-	start_implicit int // Is the document start indicator implicit?
-	end_implicit   int // Is the document end indicator implicit?
-
-	// The start/end of the document.
-	start_mark, end_mark yaml_mark_t
-}
-
-// The prototype of a read handler.
-//
-// The read handler is called when the parser needs to read more bytes from the
-// source. The handler should write not more than size bytes to the buffer.
-// The number of written bytes should be set to the size_read variable.
-//
-// [in,out]   data        A pointer to an application data specified by
-//                        yaml_parser_set_input().
-// [out]      buffer      The buffer to write the data from the source.
-// [in]       size        The size of the buffer.
-// [out]      size_read   The actual number of bytes read from the source.
-//
-// On success, the handler should return 1.  If the handler failed,
-// the returned value should be 0. On EOF, the handler should set the
-// size_read to 0 and return 1.
-type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error)
-
-// This structure holds information about a potential simple key.
-type yaml_simple_key_t struct {
-	possible     bool        // Is a simple key possible?
-	required     bool        // Is a simple key required?
-	token_number int         // The number of the token.
-	mark         yaml_mark_t // The position mark.
-}
-
-// The states of the parser.
-type yaml_parser_state_t int
-
-const (
-	yaml_PARSE_STREAM_START_STATE yaml_parser_state_t = iota
-
-	yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE           // Expect the beginning of an implicit document.
-	yaml_PARSE_DOCUMENT_START_STATE                    // Expect DOCUMENT-START.
-	yaml_PARSE_DOCUMENT_CONTENT_STATE                  // Expect the content of a document.
-	yaml_PARSE_DOCUMENT_END_STATE                      // Expect DOCUMENT-END.
-	yaml_PARSE_BLOCK_NODE_STATE                        // Expect a block node.
-	yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE // Expect a block node or indentless sequence.
-	yaml_PARSE_FLOW_NODE_STATE                         // Expect a flow node.
-	yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE        // Expect the first entry of a block sequence.
-	yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE              // Expect an entry of a block sequence.
-	yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE         // Expect an entry of an indentless sequence.
-	yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE           // Expect the first key of a block mapping.
-	yaml_PARSE_BLOCK_MAPPING_KEY_STATE                 // Expect a block mapping key.
-	yaml_PARSE_BLOCK_MAPPING_VALUE_STATE               // Expect a block mapping value.
-	yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE         // Expect the first entry of a flow sequence.
-	yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE               // Expect an entry of a flow sequence.
-	yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE   // Expect a key of an ordered mapping.
-	yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE // Expect a value of an ordered mapping.
-	yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE   // Expect the and of an ordered mapping entry.
-	yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE            // Expect the first key of a flow mapping.
-	yaml_PARSE_FLOW_MAPPING_KEY_STATE                  // Expect a key of a flow mapping.
-	yaml_PARSE_FLOW_MAPPING_VALUE_STATE                // Expect a value of a flow mapping.
-	yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE          // Expect an empty value of a flow mapping.
-	yaml_PARSE_END_STATE                               // Expect nothing.
-)
-
-func (ps yaml_parser_state_t) String() string {
-	switch ps {
-	case yaml_PARSE_STREAM_START_STATE:
-		return "yaml_PARSE_STREAM_START_STATE"
-	case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
-		return "yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE"
-	case yaml_PARSE_DOCUMENT_START_STATE:
-		return "yaml_PARSE_DOCUMENT_START_STATE"
-	case yaml_PARSE_DOCUMENT_CONTENT_STATE:
-		return "yaml_PARSE_DOCUMENT_CONTENT_STATE"
-	case yaml_PARSE_DOCUMENT_END_STATE:
-		return "yaml_PARSE_DOCUMENT_END_STATE"
-	case yaml_PARSE_BLOCK_NODE_STATE:
-		return "yaml_PARSE_BLOCK_NODE_STATE"
-	case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
-		return "yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE"
-	case yaml_PARSE_FLOW_NODE_STATE:
-		return "yaml_PARSE_FLOW_NODE_STATE"
-	case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
-		return "yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE"
-	case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
-		return "yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE"
-	case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
-		return "yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE"
-	case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
-		return "yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE"
-	case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
-		return "yaml_PARSE_BLOCK_MAPPING_KEY_STATE"
-	case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
-		return "yaml_PARSE_BLOCK_MAPPING_VALUE_STATE"
-	case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
-		return "yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE"
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
-		return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE"
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
-		return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE"
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
-		return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE"
-	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
-		return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE"
-	case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
-		return "yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE"
-	case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
-		return "yaml_PARSE_FLOW_MAPPING_KEY_STATE"
-	case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
-		return "yaml_PARSE_FLOW_MAPPING_VALUE_STATE"
-	case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
-		return "yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE"
-	case yaml_PARSE_END_STATE:
-		return "yaml_PARSE_END_STATE"
-	}
-	return "<unknown parser state>"
-}
-
-// This structure holds aliases data.
-type yaml_alias_data_t struct {
-	anchor []byte      // The anchor.
-	index  int         // The node id.
-	mark   yaml_mark_t // The anchor mark.
-}
-
-// The parser structure.
-//
-// All members are internal. Manage the structure using the
-// yaml_parser_ family of functions.
-type yaml_parser_t struct {
-
-	// Error handling
-
-	error yaml_error_type_t // Error type.
-
-	problem string // Error description.
-
-	// The byte about which the problem occurred.
-	problem_offset int
-	problem_value  int
-	problem_mark   yaml_mark_t
-
-	// The error context.
-	context      string
-	context_mark yaml_mark_t
-
-	// Reader stuff
-
-	read_handler yaml_read_handler_t // Read handler.
-
-	input_reader io.Reader // File input data.
-	input        []byte    // String input data.
-	input_pos    int
-
-	eof bool // EOF flag
-
-	buffer     []byte // The working buffer.
-	buffer_pos int    // The current position of the buffer.
-
-	unread int // The number of unread characters in the buffer.
-
-	raw_buffer     []byte // The raw buffer.
-	raw_buffer_pos int    // The current position of the buffer.
-
-	encoding yaml_encoding_t // The input encoding.
-
-	offset int         // The offset of the current position (in bytes).
-	mark   yaml_mark_t // The mark of the current position.
-
-	// Scanner stuff
-
-	stream_start_produced bool // Have we started to scan the input stream?
-	stream_end_produced   bool // Have we reached the end of the input stream?
-
-	flow_level int // The number of unclosed '[' and '{' indicators.
-
-	tokens          []yaml_token_t // The tokens queue.
-	tokens_head     int            // The head of the tokens queue.
-	tokens_parsed   int            // The number of tokens fetched from the queue.
-	token_available bool           // Does the tokens queue contain a token ready for dequeueing.
-
-	indent  int   // The current indentation level.
-	indents []int // The indentation levels stack.
-
-	simple_key_allowed bool                // May a simple key occur at the current position?
-	simple_keys        []yaml_simple_key_t // The stack of simple keys.
-	simple_keys_by_tok map[int]int         // possible simple_key indexes indexed by token_number
-
-	// Parser stuff
-
-	state          yaml_parser_state_t    // The current parser state.
-	states         []yaml_parser_state_t  // The parser states stack.
-	marks          []yaml_mark_t          // The stack of marks.
-	tag_directives []yaml_tag_directive_t // The list of TAG directives.
-
-	// Dumper stuff
-
-	aliases []yaml_alias_data_t // The alias data.
-
-	document *yaml_document_t // The currently parsed document.
-}
-
-// Emitter Definitions
-
-// The prototype of a write handler.
-//
-// The write handler is called when the emitter needs to flush the accumulated
-// characters to the output.  The handler should write @a size bytes of the
-// @a buffer to the output.
-//
-// @param[in,out]   data        A pointer to an application data specified by
-//                              yaml_emitter_set_output().
-// @param[in]       buffer      The buffer with bytes to be written.
-// @param[in]       size        The size of the buffer.
-//
-// @returns On success, the handler should return @c 1.  If the handler failed,
-// the returned value should be @c 0.
-//
-type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error
-
-type yaml_emitter_state_t int
-
-// The emitter states.
-const (
-	// Expect STREAM-START.
-	yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota
-
-	yaml_EMIT_FIRST_DOCUMENT_START_STATE       // Expect the first DOCUMENT-START or STREAM-END.
-	yaml_EMIT_DOCUMENT_START_STATE             // Expect DOCUMENT-START or STREAM-END.
-	yaml_EMIT_DOCUMENT_CONTENT_STATE           // Expect the content of a document.
-	yaml_EMIT_DOCUMENT_END_STATE               // Expect DOCUMENT-END.
-	yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE   // Expect the first item of a flow sequence.
-	yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE         // Expect an item of a flow sequence.
-	yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE     // Expect the first key of a flow mapping.
-	yaml_EMIT_FLOW_MAPPING_KEY_STATE           // Expect a key of a flow mapping.
-	yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE  // Expect a value for a simple key of a flow mapping.
-	yaml_EMIT_FLOW_MAPPING_VALUE_STATE         // Expect a value of a flow mapping.
-	yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE  // Expect the first item of a block sequence.
-	yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE        // Expect an item of a block sequence.
-	yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE    // Expect the first key of a block mapping.
-	yaml_EMIT_BLOCK_MAPPING_KEY_STATE          // Expect the key of a block mapping.
-	yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping.
-	yaml_EMIT_BLOCK_MAPPING_VALUE_STATE        // Expect a value of a block mapping.
-	yaml_EMIT_END_STATE                        // Expect nothing.
-)
-
-// The emitter structure.
-//
-// All members are internal.  Manage the structure using the @c yaml_emitter_
-// family of functions.
-type yaml_emitter_t struct {
-
-	// Error handling
-
-	error   yaml_error_type_t // Error type.
-	problem string            // Error description.
-
-	// Writer stuff
-
-	write_handler yaml_write_handler_t // Write handler.
-
-	output_buffer *[]byte   // String output data.
-	output_writer io.Writer // File output data.
-
-	buffer     []byte // The working buffer.
-	buffer_pos int    // The current position of the buffer.
-
-	raw_buffer     []byte // The raw buffer.
-	raw_buffer_pos int    // The current position of the buffer.
-
-	encoding yaml_encoding_t // The stream encoding.
-
-	// Emitter stuff
-
-	canonical   bool         // If the output is in the canonical style?
-	best_indent int          // The number of indentation spaces.
-	best_width  int          // The preferred width of the output lines.
-	unicode     bool         // Allow unescaped non-ASCII characters?
-	line_break  yaml_break_t // The preferred line break.
-
-	state  yaml_emitter_state_t   // The current emitter state.
-	states []yaml_emitter_state_t // The stack of states.
-
-	events      []yaml_event_t // The event queue.
-	events_head int            // The head of the event queue.
-
-	indents []int // The stack of indentation levels.
-
-	tag_directives []yaml_tag_directive_t // The list of tag directives.
-
-	indent int // The current indentation level.
-
-	flow_level int // The current flow level.
-
-	root_context       bool // Is it the document root context?
-	sequence_context   bool // Is it a sequence context?
-	mapping_context    bool // Is it a mapping context?
-	simple_key_context bool // Is it a simple mapping key context?
-
-	line       int  // The current line.
-	column     int  // The current column.
-	whitespace bool // If the last character was a whitespace?
-	indention  bool // If the last character was an indentation character (' ', '-', '?', ':')?
-	open_ended bool // If an explicit document end is required?
-
-	// Anchor analysis.
-	anchor_data struct {
-		anchor []byte // The anchor value.
-		alias  bool   // Is it an alias?
-	}
-
-	// Tag analysis.
-	tag_data struct {
-		handle []byte // The tag handle.
-		suffix []byte // The tag suffix.
-	}
-
-	// Scalar analysis.
-	scalar_data struct {
-		value                 []byte              // The scalar value.
-		multiline             bool                // Does the scalar contain line breaks?
-		flow_plain_allowed    bool                // Can the scalar be expessed in the flow plain style?
-		block_plain_allowed   bool                // Can the scalar be expressed in the block plain style?
-		single_quoted_allowed bool                // Can the scalar be expressed in the single quoted style?
-		block_allowed         bool                // Can the scalar be expressed in the literal or folded styles?
-		style                 yaml_scalar_style_t // The output style.
-	}
-
-	// Dumper stuff
-
-	opened bool // If the stream was already opened?
-	closed bool // If the stream was already closed?
-
-	// The information associated with the document nodes.
-	anchors *struct {
-		references int  // The number of references.
-		anchor     int  // The anchor id.
-		serialized bool // If the node has been emitted?
-	}
-
-	last_anchor_id int // The last assigned anchor id.
-
-	document *yaml_document_t // The currently emitted document.
-}
diff --git a/vendor/gopkg.in/yaml.v2/yamlprivateh.go b/vendor/gopkg.in/yaml.v2/yamlprivateh.go
deleted file mode 100644
index 8110ce3c..00000000
--- a/vendor/gopkg.in/yaml.v2/yamlprivateh.go
+++ /dev/null
@@ -1,173 +0,0 @@
-package yaml
-
-const (
-	// The size of the input raw buffer.
-	input_raw_buffer_size = 512
-
-	// The size of the input buffer.
-	// It should be possible to decode the whole raw buffer.
-	input_buffer_size = input_raw_buffer_size * 3
-
-	// The size of the output buffer.
-	output_buffer_size = 128
-
-	// The size of the output raw buffer.
-	// It should be possible to encode the whole output buffer.
-	output_raw_buffer_size = (output_buffer_size*2 + 2)
-
-	// The size of other stacks and queues.
-	initial_stack_size  = 16
-	initial_queue_size  = 16
-	initial_string_size = 16
-)
-
-// Check if the character at the specified position is an alphabetical
-// character, a digit, '_', or '-'.
-func is_alpha(b []byte, i int) bool {
-	return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-'
-}
-
-// Check if the character at the specified position is a digit.
-func is_digit(b []byte, i int) bool {
-	return b[i] >= '0' && b[i] <= '9'
-}
-
-// Get the value of a digit.
-func as_digit(b []byte, i int) int {
-	return int(b[i]) - '0'
-}
-
-// Check if the character at the specified position is a hex-digit.
-func is_hex(b []byte, i int) bool {
-	return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f'
-}
-
-// Get the value of a hex-digit.
-func as_hex(b []byte, i int) int {
-	bi := b[i]
-	if bi >= 'A' && bi <= 'F' {
-		return int(bi) - 'A' + 10
-	}
-	if bi >= 'a' && bi <= 'f' {
-		return int(bi) - 'a' + 10
-	}
-	return int(bi) - '0'
-}
-
-// Check if the character is ASCII.
-func is_ascii(b []byte, i int) bool {
-	return b[i] <= 0x7F
-}
-
-// Check if the character at the start of the buffer can be printed unescaped.
-func is_printable(b []byte, i int) bool {
-	return ((b[i] == 0x0A) || // . == #x0A
-		(b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E
-		(b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF
-		(b[i] > 0xC2 && b[i] < 0xED) ||
-		(b[i] == 0xED && b[i+1] < 0xA0) ||
-		(b[i] == 0xEE) ||
-		(b[i] == 0xEF && // #xE000 <= . <= #xFFFD
-			!(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF
-			!(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF))))
-}
-
-// Check if the character at the specified position is NUL.
-func is_z(b []byte, i int) bool {
-	return b[i] == 0x00
-}
-
-// Check if the beginning of the buffer is a BOM.
-func is_bom(b []byte, i int) bool {
-	return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF
-}
-
-// Check if the character at the specified position is space.
-func is_space(b []byte, i int) bool {
-	return b[i] == ' '
-}
-
-// Check if the character at the specified position is tab.
-func is_tab(b []byte, i int) bool {
-	return b[i] == '\t'
-}
-
-// Check if the character at the specified position is blank (space or tab).
-func is_blank(b []byte, i int) bool {
-	//return is_space(b, i) || is_tab(b, i)
-	return b[i] == ' ' || b[i] == '\t'
-}
-
-// Check if the character at the specified position is a line break.
-func is_break(b []byte, i int) bool {
-	return (b[i] == '\r' || // CR (#xD)
-		b[i] == '\n' || // LF (#xA)
-		b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029)
-}
-
-func is_crlf(b []byte, i int) bool {
-	return b[i] == '\r' && b[i+1] == '\n'
-}
-
-// Check if the character is a line break or NUL.
-func is_breakz(b []byte, i int) bool {
-	//return is_break(b, i) || is_z(b, i)
-	return (        // is_break:
-	b[i] == '\r' || // CR (#xD)
-		b[i] == '\n' || // LF (#xA)
-		b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
-		// is_z:
-		b[i] == 0)
-}
-
-// Check if the character is a line break, space, or NUL.
-func is_spacez(b []byte, i int) bool {
-	//return is_space(b, i) || is_breakz(b, i)
-	return ( // is_space:
-	b[i] == ' ' ||
-		// is_breakz:
-		b[i] == '\r' || // CR (#xD)
-		b[i] == '\n' || // LF (#xA)
-		b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
-		b[i] == 0)
-}
-
-// Check if the character is a line break, space, tab, or NUL.
-func is_blankz(b []byte, i int) bool {
-	//return is_blank(b, i) || is_breakz(b, i)
-	return ( // is_blank:
-	b[i] == ' ' || b[i] == '\t' ||
-		// is_breakz:
-		b[i] == '\r' || // CR (#xD)
-		b[i] == '\n' || // LF (#xA)
-		b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
-		b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
-		b[i] == 0)
-}
-
-// Determine the width of the character.
-func width(b byte) int {
-	// Don't replace these by a switch without first
-	// confirming that it is being inlined.
-	if b&0x80 == 0x00 {
-		return 1
-	}
-	if b&0xE0 == 0xC0 {
-		return 2
-	}
-	if b&0xF0 == 0xE0 {
-		return 3
-	}
-	if b&0xF8 == 0xF0 {
-		return 4
-	}
-	return 0
-
-}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 807ebea4..87511d8c 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -28,9 +28,10 @@ git.torproject.org/pluggable-transports/snowflake.git/common/util
 # github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a
 ## explicit
 github.com/ProtonMail/go-autostart
-# github.com/andybalholm/brotli v1.0.5
-## explicit; go 1.12
+# github.com/andybalholm/brotli v1.1.0
+## explicit; go 1.13
 github.com/andybalholm/brotli
+github.com/andybalholm/brotli/matchfinder
 # github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
 ## explicit; go 1.13
 github.com/asaskevich/govalidator
@@ -45,6 +46,48 @@ github.com/asdine/storm/v3/q
 # github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6
 ## explicit; go 1.15
 github.com/babolivier/go-doh-client
+# github.com/cloudflare/circl v1.3.9
+## explicit; go 1.21
+github.com/cloudflare/circl/dh/x25519
+github.com/cloudflare/circl/dh/x448
+github.com/cloudflare/circl/ecc/goldilocks
+github.com/cloudflare/circl/ecc/p384
+github.com/cloudflare/circl/hpke
+github.com/cloudflare/circl/internal/conv
+github.com/cloudflare/circl/internal/sha3
+github.com/cloudflare/circl/kem
+github.com/cloudflare/circl/kem/hybrid
+github.com/cloudflare/circl/kem/kyber/kyber1024
+github.com/cloudflare/circl/kem/kyber/kyber512
+github.com/cloudflare/circl/kem/kyber/kyber768
+github.com/cloudflare/circl/math
+github.com/cloudflare/circl/math/fp25519
+github.com/cloudflare/circl/math/fp448
+github.com/cloudflare/circl/math/mlsbset
+github.com/cloudflare/circl/pke/kyber/internal/common
+github.com/cloudflare/circl/pke/kyber/internal/common/params
+github.com/cloudflare/circl/pke/kyber/kyber1024
+github.com/cloudflare/circl/pke/kyber/kyber1024/internal
+github.com/cloudflare/circl/pke/kyber/kyber512
+github.com/cloudflare/circl/pke/kyber/kyber512/internal
+github.com/cloudflare/circl/pke/kyber/kyber768
+github.com/cloudflare/circl/pke/kyber/kyber768/internal
+github.com/cloudflare/circl/pki
+github.com/cloudflare/circl/sign
+github.com/cloudflare/circl/sign/dilithium/internal/common
+github.com/cloudflare/circl/sign/dilithium/internal/common/params
+github.com/cloudflare/circl/sign/dilithium/mode2
+github.com/cloudflare/circl/sign/dilithium/mode2/internal
+github.com/cloudflare/circl/sign/dilithium/mode3
+github.com/cloudflare/circl/sign/dilithium/mode3/internal
+github.com/cloudflare/circl/sign/ed25519
+github.com/cloudflare/circl/sign/ed448
+github.com/cloudflare/circl/sign/eddilithium2
+github.com/cloudflare/circl/sign/eddilithium3
+github.com/cloudflare/circl/sign/schemes
+github.com/cloudflare/circl/simd/keccakf1600
+github.com/cloudflare/circl/xof
+github.com/cloudflare/circl/xof/k12
 # github.com/cretz/bine v0.2.0
 ## explicit; go 1.15
 github.com/cretz/bine/control
@@ -59,18 +102,15 @@ github.com/davecgh/go-spew/spew
 # github.com/dchest/siphash v1.2.3
 ## explicit; go 1.16
 github.com/dchest/siphash
-# github.com/gaukas/godicttls v0.0.3
-## explicit; go 1.19
-github.com/gaukas/godicttls
-# github.com/go-logr/logr v1.2.3
-## explicit; go 1.16
+# github.com/go-logr/logr v1.4.2
+## explicit; go 1.18
 github.com/go-logr/logr
 github.com/go-logr/logr/funcr
 # github.com/go-logr/stdr v1.2.2
 ## explicit; go 1.16
 github.com/go-logr/stdr
-# github.com/go-openapi/analysis v0.21.4
-## explicit; go 1.13
+# github.com/go-openapi/analysis v0.23.0
+## explicit; go 1.20
 github.com/go-openapi/analysis
 github.com/go-openapi/analysis/internal/debug
 github.com/go-openapi/analysis/internal/flatten/normalize
@@ -78,21 +118,21 @@ github.com/go-openapi/analysis/internal/flatten/operations
 github.com/go-openapi/analysis/internal/flatten/replace
 github.com/go-openapi/analysis/internal/flatten/schutils
 github.com/go-openapi/analysis/internal/flatten/sortref
-# github.com/go-openapi/errors v0.20.4
-## explicit; go 1.14
+# github.com/go-openapi/errors v0.22.0
+## explicit; go 1.20
 github.com/go-openapi/errors
-# github.com/go-openapi/jsonpointer v0.19.5
-## explicit; go 1.13
+# github.com/go-openapi/jsonpointer v0.21.0
+## explicit; go 1.20
 github.com/go-openapi/jsonpointer
-# github.com/go-openapi/jsonreference v0.20.0
-## explicit; go 1.13
+# github.com/go-openapi/jsonreference v0.21.0
+## explicit; go 1.20
 github.com/go-openapi/jsonreference
 github.com/go-openapi/jsonreference/internal
-# github.com/go-openapi/loads v0.21.2
-## explicit; go 1.13
+# github.com/go-openapi/loads v0.22.0
+## explicit; go 1.20
 github.com/go-openapi/loads
-# github.com/go-openapi/runtime v0.26.0
-## explicit; go 1.18
+# github.com/go-openapi/runtime v0.28.0
+## explicit; go 1.20
 github.com/go-openapi/runtime
 github.com/go-openapi/runtime/client
 github.com/go-openapi/runtime/logger
@@ -102,17 +142,17 @@ github.com/go-openapi/runtime/middleware/header
 github.com/go-openapi/runtime/middleware/untyped
 github.com/go-openapi/runtime/security
 github.com/go-openapi/runtime/yamlpc
-# github.com/go-openapi/spec v0.20.8
-## explicit; go 1.13
+# github.com/go-openapi/spec v0.21.0
+## explicit; go 1.20
 github.com/go-openapi/spec
-# github.com/go-openapi/strfmt v0.21.7
-## explicit; go 1.19
+# github.com/go-openapi/strfmt v0.23.0
+## explicit; go 1.20
 github.com/go-openapi/strfmt
-# github.com/go-openapi/swag v0.22.4
-## explicit; go 1.18
+# github.com/go-openapi/swag v0.23.0
+## explicit; go 1.20
 github.com/go-openapi/swag
-# github.com/go-openapi/validate v0.22.1
-## explicit; go 1.14
+# github.com/go-openapi/validate v0.24.0
+## explicit; go 1.20
 github.com/go-openapi/validate
 # github.com/google/uuid v1.6.0
 ## explicit
@@ -133,8 +173,8 @@ github.com/kardianos/osext
 ## explicit
 github.com/keybase/go-ps
 github.com/keybase/go-ps/darwincgo
-# github.com/klauspost/compress v1.16.6
-## explicit; go 1.18
+# github.com/klauspost/compress v1.17.9
+## explicit; go 1.20
 github.com/klauspost/compress
 github.com/klauspost/compress/fse
 github.com/klauspost/compress/huff0
@@ -142,10 +182,10 @@ github.com/klauspost/compress/internal/cpuinfo
 github.com/klauspost/compress/internal/snapref
 github.com/klauspost/compress/zstd
 github.com/klauspost/compress/zstd/internal/xxhash
-# github.com/klauspost/cpuid/v2 v2.2.6
+# github.com/klauspost/cpuid/v2 v2.2.8
 ## explicit; go 1.15
 github.com/klauspost/cpuid/v2
-# github.com/klauspost/reedsolomon v1.12.1
+# github.com/klauspost/reedsolomon v1.12.2
 ## explicit; go 1.18
 github.com/klauspost/reedsolomon
 # github.com/mailru/easyjson v0.7.7
@@ -156,7 +196,7 @@ github.com/mailru/easyjson/jwriter
 # github.com/mattn/go-colorable v0.1.13
 ## explicit; go 1.15
 github.com/mattn/go-colorable
-# github.com/mattn/go-isatty v0.0.19
+# github.com/mattn/go-isatty v0.0.20
 ## explicit; go 1.15
 github.com/mattn/go-isatty
 # github.com/mitchellh/go-homedir v1.1.0
@@ -176,10 +216,10 @@ github.com/oklog/ulid
 github.com/opentracing/opentracing-go
 github.com/opentracing/opentracing-go/ext
 github.com/opentracing/opentracing-go/log
-# github.com/pion/datachannel v1.5.5
-## explicit; go 1.13
+# github.com/pion/datachannel v1.5.7
+## explicit; go 1.19
 github.com/pion/datachannel
-# github.com/pion/dtls/v2 v2.2.9
+# github.com/pion/dtls/v2 v2.2.11
 ## explicit; go 1.13
 github.com/pion/dtls/v2
 github.com/pion/dtls/v2/internal/ciphersuite
@@ -200,14 +240,14 @@ github.com/pion/dtls/v2/pkg/protocol/alert
 github.com/pion/dtls/v2/pkg/protocol/extension
 github.com/pion/dtls/v2/pkg/protocol/handshake
 github.com/pion/dtls/v2/pkg/protocol/recordlayer
-# github.com/pion/ice/v2 v2.3.12
+# github.com/pion/ice/v2 v2.3.28
 ## explicit; go 1.13
 github.com/pion/ice/v2
 github.com/pion/ice/v2/internal/atomic
 github.com/pion/ice/v2/internal/fakenet
 github.com/pion/ice/v2/internal/stun
-# github.com/pion/interceptor v0.1.25
-## explicit; go 1.15
+# github.com/pion/interceptor v0.1.29
+## explicit; go 1.19
 github.com/pion/interceptor
 github.com/pion/interceptor/internal/ntp
 github.com/pion/interceptor/internal/sequencenumber
@@ -217,24 +257,24 @@ github.com/pion/interceptor/pkg/twcc
 # github.com/pion/logging v0.2.2
 ## explicit; go 1.12
 github.com/pion/logging
-# github.com/pion/mdns v0.0.9
-## explicit; go 1.12
+# github.com/pion/mdns v0.0.12
+## explicit; go 1.19
 github.com/pion/mdns
 # github.com/pion/randutil v0.1.0
 ## explicit; go 1.14
 github.com/pion/randutil
-# github.com/pion/rtcp v1.2.13
+# github.com/pion/rtcp v1.2.14
 ## explicit; go 1.13
 github.com/pion/rtcp
-# github.com/pion/rtp v1.8.3
+# github.com/pion/rtp v1.8.6
 ## explicit; go 1.19
 github.com/pion/rtp
 github.com/pion/rtp/codecs
 github.com/pion/rtp/codecs/av1/obu
-# github.com/pion/sctp v1.8.9
-## explicit; go 1.13
+# github.com/pion/sctp v1.8.18
+## explicit; go 1.19
 github.com/pion/sctp
-# github.com/pion/sdp/v3 v3.0.6
+# github.com/pion/sdp/v3 v3.0.9
 ## explicit; go 1.13
 github.com/pion/sdp/v3
 # github.com/pion/srtp/v2 v2.0.18
@@ -244,7 +284,7 @@ github.com/pion/srtp/v2
 ## explicit; go 1.12
 github.com/pion/stun
 github.com/pion/stun/internal/hmac
-# github.com/pion/transport/v2 v2.2.4
+# github.com/pion/transport/v2 v2.2.5
 ## explicit; go 1.12
 github.com/pion/transport/v2
 github.com/pion/transport/v2/connctx
@@ -255,7 +295,7 @@ github.com/pion/transport/v2/stdnet
 github.com/pion/transport/v2/udp
 github.com/pion/transport/v2/utils/xor
 github.com/pion/transport/v2/vnet
-# github.com/pion/turn/v2 v2.1.4
+# github.com/pion/turn/v2 v2.1.6
 ## explicit; go 1.13
 github.com/pion/turn/v2
 github.com/pion/turn/v2/internal/allocation
@@ -263,8 +303,8 @@ github.com/pion/turn/v2/internal/client
 github.com/pion/turn/v2/internal/ipnet
 github.com/pion/turn/v2/internal/proto
 github.com/pion/turn/v2/internal/server
-# github.com/pion/webrtc/v3 v3.2.24
-## explicit; go 1.13
+# github.com/pion/webrtc/v3 v3.2.44
+## explicit; go 1.17
 github.com/pion/webrtc/v3
 github.com/pion/webrtc/v3/internal/fmtp
 github.com/pion/webrtc/v3/internal/mux
@@ -280,11 +320,15 @@ github.com/pmezard/go-difflib/difflib
 # github.com/prometheus-community/pro-bing v0.4.0
 ## explicit; go 1.19
 github.com/prometheus-community/pro-bing
-# github.com/refraction-networking/utls v1.3.3
-## explicit; go 1.19
+# github.com/refraction-networking/utls v1.6.7
+## explicit; go 1.21
 github.com/refraction-networking/utls
+github.com/refraction-networking/utls/dicttls
+github.com/refraction-networking/utls/internal/boring
 github.com/refraction-networking/utls/internal/helper
-# github.com/rs/zerolog v1.32.0
+github.com/refraction-networking/utls/internal/quicvarint
+github.com/refraction-networking/utls/internal/quicvarint/protocol
+# github.com/rs/zerolog v1.33.0
 ## explicit; go 1.15
 github.com/rs/zerolog
 github.com/rs/zerolog/internal/cbor
@@ -303,8 +347,8 @@ github.com/smartystreets/assertions/internal/oglematchers
 github.com/smartystreets/goconvey/convey
 github.com/smartystreets/goconvey/convey/gotest
 github.com/smartystreets/goconvey/convey/reporting
-# github.com/stretchr/testify v1.8.4
-## explicit; go 1.20
+# github.com/stretchr/testify v1.9.0
+## explicit; go 1.17
 github.com/stretchr/testify/assert
 github.com/stretchr/testify/require
 # github.com/templexxx/cpu v0.1.0
@@ -325,7 +369,7 @@ github.com/tjfoc/gmsm/sm4
 # github.com/xtaci/kcp-go v5.4.20+incompatible
 ## explicit
 github.com/xtaci/kcp-go
-# github.com/xtaci/kcp-go/v5 v5.6.3
+# github.com/xtaci/kcp-go/v5 v5.6.8
 ## explicit; go 1.21
 github.com/xtaci/kcp-go/v5
 # github.com/xtaci/smux v1.5.24
@@ -349,11 +393,11 @@ gitlab.com/yawning/obfs4.git/transports/obfs4/framing
 # gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.5.0
 ## explicit; go 1.11
 gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib
-# go.etcd.io/bbolt v1.3.7
-## explicit; go 1.17
+# go.etcd.io/bbolt v1.3.10
+## explicit; go 1.21
 go.etcd.io/bbolt
-# go.mongodb.org/mongo-driver v1.11.3
-## explicit; go 1.13
+# go.mongodb.org/mongo-driver v1.16.0
+## explicit; go 1.18
 go.mongodb.org/mongo-driver/bson
 go.mongodb.org/mongo-driver/bson/bsoncodec
 go.mongodb.org/mongo-driver/bson/bsonoptions
@@ -361,8 +405,8 @@ go.mongodb.org/mongo-driver/bson/bsonrw
 go.mongodb.org/mongo-driver/bson/bsontype
 go.mongodb.org/mongo-driver/bson/primitive
 go.mongodb.org/mongo-driver/x/bsonx/bsoncore
-# go.opentelemetry.io/otel v1.14.0
-## explicit; go 1.18
+# go.opentelemetry.io/otel v1.28.0
+## explicit; go 1.21
 go.opentelemetry.io/otel
 go.opentelemetry.io/otel/attribute
 go.opentelemetry.io/otel/baggage
@@ -372,13 +416,21 @@ go.opentelemetry.io/otel/internal/attribute
 go.opentelemetry.io/otel/internal/baggage
 go.opentelemetry.io/otel/internal/global
 go.opentelemetry.io/otel/propagation
-go.opentelemetry.io/otel/semconv/internal
-go.opentelemetry.io/otel/semconv/v1.12.0
-# go.opentelemetry.io/otel/trace v1.14.0
-## explicit; go 1.18
+go.opentelemetry.io/otel/semconv/internal/v2
+go.opentelemetry.io/otel/semconv/v1.17.0
+go.opentelemetry.io/otel/semconv/v1.17.0/httpconv
+# go.opentelemetry.io/otel/metric v1.28.0
+## explicit; go 1.21
+go.opentelemetry.io/otel/metric
+go.opentelemetry.io/otel/metric/embedded
+# go.opentelemetry.io/otel/trace v1.28.0
+## explicit; go 1.21
 go.opentelemetry.io/otel/trace
-# golang.org/x/crypto v0.19.0
-## explicit; go 1.18
+go.opentelemetry.io/otel/trace/embedded
+# golang.org/x/crypto v0.25.0
+## explicit; go 1.20
+golang.org/x/crypto/blake2b
+golang.org/x/crypto/blake2s
 golang.org/x/crypto/blowfish
 golang.org/x/crypto/cast5
 golang.org/x/crypto/chacha20
@@ -386,7 +438,6 @@ golang.org/x/crypto/chacha20poly1305
 golang.org/x/crypto/cryptobyte
 golang.org/x/crypto/cryptobyte/asn1
 golang.org/x/crypto/curve25519
-golang.org/x/crypto/curve25519/internal/field
 golang.org/x/crypto/ed25519
 golang.org/x/crypto/hkdf
 golang.org/x/crypto/internal/alias
@@ -399,7 +450,7 @@ golang.org/x/crypto/sha3
 golang.org/x/crypto/tea
 golang.org/x/crypto/twofish
 golang.org/x/crypto/xtea
-# golang.org/x/net v0.21.0
+# golang.org/x/net v0.27.0
 ## explicit; go 1.18
 golang.org/x/net/bpf
 golang.org/x/net/dns/dnsmessage
@@ -414,10 +465,10 @@ golang.org/x/net/internal/socks
 golang.org/x/net/ipv4
 golang.org/x/net/ipv6
 golang.org/x/net/proxy
-# golang.org/x/sync v0.6.0
+# golang.org/x/sync v0.7.0
 ## explicit; go 1.18
 golang.org/x/sync/errgroup
-# golang.org/x/sys v0.17.0
+# golang.org/x/sys v0.22.0
 ## explicit; go 1.18
 golang.org/x/sys/cpu
 golang.org/x/sys/unix
@@ -427,7 +478,7 @@ golang.org/x/sys/windows/svc
 golang.org/x/sys/windows/svc/debug
 golang.org/x/sys/windows/svc/eventlog
 golang.org/x/sys/windows/svc/mgr
-# golang.org/x/text v0.14.0
+# golang.org/x/text v0.16.0
 ## explicit; go 1.18
 golang.org/x/text/secure/bidirule
 golang.org/x/text/transform
@@ -435,9 +486,6 @@ golang.org/x/text/unicode/bidi
 golang.org/x/text/unicode/norm
 # gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
 ## explicit
-# gopkg.in/yaml.v2 v2.4.0
-## explicit; go 1.15
-gopkg.in/yaml.v2
 # gopkg.in/yaml.v3 v3.0.1
 ## explicit
 gopkg.in/yaml.v3
-- 
GitLab